Skip to content

Commit

Permalink
patch
Browse files Browse the repository at this point in the history
- Fixed a timing issue causing healing items to be removed after being given
- Added the ability to decide between infinite heal items or auto health regen in playlist settings
- Fixed auto healing thread, with event driven performance optimizations.
- Fixed giving ammo stacks defined in playlist for winterexpress
  • Loading branch information
ttvmkos committed Nov 19, 2024
1 parent f21dcfc commit ef93021
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 33 deletions.
2 changes: 2 additions & 0 deletions vscripts/class/CBaseEntity.nut
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ function CodeCallback_RegisterClass_CBaseEntity()
CBaseEntity.__KeyValueFromString <- CBaseEntity.SetValueForKey
CBaseEntity.__KeyValueFromInt <- CBaseEntity.SetValueForKey

RegisterSignal( "TookDamage" )

function CBaseEntity::constructor()
{
#if DEVELOPER
Expand Down
9 changes: 9 additions & 0 deletions vscripts/gamemodes/fs_1v1/_gamemode_1v1.nut
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ global function Gamemode1v1_SetPlayerGamestate
global function Gamemode1v1_SetRestEnabled
global function Gamemode1v1_CreatePanels
global function Gamemode1v1_GetRestEnabled
global function Gamemode1v1_SetWeaponAmmoStackAmount
global function IsCurrentState
global function ValidateBlacklistedWeapons

Expand Down Expand Up @@ -5863,6 +5864,9 @@ void function SetupPlayerReserveAmmo( entity player, entity weapon )
//Clean up ammo. Cafe
foreach ( ammo, type in eAmmoPoolType )
{
if( type == eAmmoPoolType.explosive )
continue //(mk): temp hack until kral fixes explosives

if( !IsAmmoInUse( player, ammo ) )
{
int count = SURVIVAL_CountItemsInInventory( player, ammo )
Expand All @@ -5881,4 +5885,9 @@ void function SetupPlayerReserveAmmo( entity player, entity weapon )
#if DEVELOPER
printw( "added", amountToAdd, "for ref", ammoRef, "to player", string( player ) )
#endif
}

void function Gamemode1v1_SetWeaponAmmoStackAmount( int amount )
{
settings.give_weapon_stack_count_amount = amount
}
9 changes: 6 additions & 3 deletions vscripts/gamemodes/fs_tdm/_gamemode_fsdm.nut
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,8 @@ void function __GiveWeapon( entity player, array<string> WeaponData, int slot, i
Mods.append( strip(mod) )
}

try{
try
{
entity weaponNew
if(IsValid(player))
{
Expand Down Expand Up @@ -2031,8 +2032,10 @@ void function __GiveWeapon( entity player, array<string> WeaponData, int slot, i
player.SetActiveWeaponBySlot(eActiveInventorySlot.mainHand, WEAPON_INVENTORY_SLOT_PRIMARY_0)
player.ClearFirstDeployForAllWeapons()
}
}catch(e420){
printt("Invalid weapon name for tgive command.")
}
catch(e420)
{
printt( "Invalid weapon name for tgive command?: " + e420 )
}
}

Expand Down
48 changes: 33 additions & 15 deletions vscripts/gamemodes/sh_gamemode_winterexpress.nut
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,12 @@ void function WinterExpress_Init()
settings.winter_express_wave_respawn = GetCurrentPlaylistVarBool( "winter_express_wave_respawn", false )
settings.winter_express_wave_respawn_interval = GetCurrentPlaylistVarFloat( "winter_express_wave_respawn_interval", 10.0 )
settings.winter_express_round_based_respawn = GetCurrentPlaylistVarBool( "winter_express_round_based_respawn", true )

#if SERVER
//(mk):Gamemode uses 1v1 features for weapons/ammo
Gamemode1v1_SetWeaponAmmoStackAmount( GetCurrentPlaylistVarInt( "give_weapon_stack_count_amount", 0 ) )
#endif

//Flowstate custom
settings.winter_express_show_player_cards = GetCurrentPlaylistVarBool( "winter_express_show_player_cards", true )

Expand Down Expand Up @@ -2035,6 +2041,7 @@ void function OnPlayerMatchStateChanged( entity player, int oldValue, int newVal
// LoadoutSelection_GivePlayerInventoryAndLoadout( player, false, true, false )
}
}

const array<string> STANDARD_INV_LOOT = [ "health_pickup_combo_small", "health_pickup_health_small" ] //"health_pickup_combo_large", "health_pickup_health_large"

void function Flowstate_GivePlayerLoadoutOnGameStart_Copy( entity player, bool fromRespawning )
Expand Down Expand Up @@ -2120,6 +2127,15 @@ void function Flowstate_GivePlayerLoadoutOnGameStart_Copy( entity player, bool f
GiveRandomPrimaryWeaponMetagame( player )
GiveRandomSecondaryWeaponMetagame( player )
}

Inventory_SetPlayerEquipment( player, "incapshield_pickup_lv3", "incapshield")
Inventory_SetPlayerEquipment( player, "backpack_pickup_lv3", "backpack")

foreach( item in STANDARD_INV_LOOT )
SURVIVAL_AddToPlayerInventory( player, item, 1 )

foreach( mainhand in GetPrimaryWeapons( player ) )
SetupPlayerReserveAmmo( player, mainhand )

if ( IsValid( player ) && !file.playersThatHaveHeardRespawnLine.contains( player ) && fromRespawning )
{
Expand Down Expand Up @@ -2170,7 +2186,7 @@ void function GivePlayerLoadoutOnGameStart( entity player )

void function ResetPlayerInventoryAndLoadoutOnRespawn( entity player, bool shouldOnlyGiveEquipmentLoadout = false )
{
if ( !IsValid( player ) || !IsAlive(player))
if ( !IsValid( player ) || !IsAlive( player ) )
return

ResetPlayerInventory( player )
Expand All @@ -2182,19 +2198,17 @@ void function ResetPlayerInventoryAndLoadoutOnRespawn( entity player, bool shoul
player.SetNameVisibleToEnemy( true )
}

//Setup starting loadout
PlayerRestoreHP_1v1(player, 100, Equipment_GetDefaultShieldHP() )
PlayerRestoreHP_1v1( player, 100, Equipment_GetDefaultShieldHP() )
DeployAndEnableWeapons( player )
CheckAutoHealPassive( player )
}

if ( GetCurrentPlaylistVarBool( "infinite_heal_items", true ) )
void function CheckAutoHealPassive( entity player )
{
if ( settings.infinite_heal_items )
GivePassive( player, ePassives.PAS_INFINITE_HEAL )

Inventory_SetPlayerEquipment( player, "incapshield_pickup_lv3", "incapshield")
Inventory_SetPlayerEquipment( player, "backpack_pickup_lv3", "backpack")

foreach( item in STANDARD_INV_LOOT )
SURVIVAL_AddToPlayerInventory(player, item, 1)

DeployAndEnableWeapons( player )
else
GivePassive( player, ePassives.PAS_PILOT_BLOOD )
}

// Loadout info has been updated for Clients, make sure weapon icons are updated on screens that use them
Expand All @@ -2216,6 +2230,8 @@ void function OnPlayerClassChanged( entity player )
{
if ( IsValid( player ) && !player.IsBot() )
Remote_CallFunction_NonReplay( player, "ServerCallback_CL_UpdateCurrentLoadoutHUD" )

CheckAutoHealPassive( player )
}

void function OnPlayerKilled_Inventory( entity victim, entity attacker, var attackerDamageInfo )
Expand Down Expand Up @@ -2559,6 +2575,7 @@ void function WinterExpress_OnPlayerRespawnedThread( entity player, bool startin
}

Flowstate_GivePlayerLoadoutOnGameStart_Copy( player, startingGame )
CheckAutoHealPassive( player ) //^ gets reset above

if( settings.winter_express_show_player_cards && !startingGame )
{
Expand Down Expand Up @@ -2634,9 +2651,9 @@ bool function WinterExpress_RespawnOnTrain( entity player, bool isGameStartLerp
thread WinterExpress_AdjustEyesAfterDelay( lerpAdjustmentTime, player, false )
Remote_CallFunction_NonReplay( player, "ServerCallback_CL_CameraLerpTrain", player, pointAhead, file.trainRef, isGameStartLerp )
thread ScreenFadeThread( player, lerpAdjustmentTime - 1 )
ResetPlayerInventoryAndLoadoutOnRespawn( player )

player.SetPlayerNetBool( "WinterExpress_IsPlayerAllowedLegendChange", false )

ResetPlayerInventoryAndLoadoutOnRespawn( player )

return true
}
Expand Down Expand Up @@ -3020,9 +3037,10 @@ bool function WinterExpress_RespawnAroundStation( entity player )
player.SnapToAbsOrigin( spawnPoints[ spawnIndex ].origin + <0, 0, 2> )
player.SnapEyeAngles( spawnPoints[ spawnIndex ].angles )
player.SnapFeetToEyes()
ResetPlayerInventoryAndLoadoutOnRespawn( player )
player.SetPlayerNetBool( "WinterExpress_IsPlayerAllowedLegendChange", false )

ResetPlayerInventoryAndLoadoutOnRespawn( player )

return true
}

Expand Down
1 change: 1 addition & 0 deletions vscripts/mp/_codecallbacks.gnut
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ void function CodeCallback_DamagePlayerOrNPC( entity ent, var damageInfo )
#endif

attacker.Signal( "DamagedPlayerOrNPC" )
ent.Signal( "TookDamage", { damageInfo = damageInfo } )
}

void function EarnMeterDamageConversion( var damageInfo, entity attacker, entity ent, float savedDamage )
Expand Down
15 changes: 12 additions & 3 deletions vscripts/sh_mapname_playlist_gamemode_enums.gnut
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ const array<int> gamemode1v1Types = [

]

const PRINT_GAMEMODE_DEBUGS = false
const PRINT_GAMEMODE_DEBUGS = true
//////////////////////////////////////////
// internal functions //
//////////////////////////////////////////
Expand Down Expand Up @@ -233,8 +233,17 @@ void function PlayLists_Mapnames_Gamemodes_Init()
{
#endif

SH_globals.currentPlaylist = getPlaylistEnumFromName( GetCurrentPlaylistName() )
mAssert( SH_globals.currentPlaylist != -1, format( "Current playlist \"%s\" is not registered in sh_mapname_playlist_gamemode_enums.nut", GetCurrentPlaylistName() ) )
string currentPlaylistName = GetCurrentPlaylistName()
{
if( currentPlaylistName == "can_launch" )
{
mAssert( false, "Please specify a playlist file when launching. You \"can_launch\", but chose not to." )
return
}
}

SH_globals.currentPlaylist = getPlaylistEnumFromName( currentPlaylistName )
mAssert( SH_globals.currentPlaylist != -1, format( "Current playlist \"%s\" is not registered in sh_mapname_playlist_gamemode_enums.nut", currentPlaylistName ) )

#if UI
}
Expand Down
60 changes: 48 additions & 12 deletions vscripts/sh_passives.gnut
Original file line number Diff line number Diff line change
Expand Up @@ -668,39 +668,75 @@ void function PilotBlood_Passive( entity player, int passive, bool didHave, bool
}
}

void function PilotBlood_Passive_Body( entity player )
//spawns threads to heal after regen delay
void function PilotBlood_Passive_Body( entity player ) //monitor for passive ability
{
float healthRegenStartDelay = 5.0
float healthRegenRate = 1.0
float tickTime = HEALTH_REGEN_TICK_TIME

EndSignal( player, "EndPilotBloodThread" )
EndSignal( player, "EndPilotBloodThread", "OnDestroy" )

if( Gamemode() == eGamemodes.fs_duckhunt || Gamemode() == eGamemodes.fs_infected || Flowstate_IsHaloMode() || Playlist() == ePlaylists.fs_movementgym || Gamemode() == eGamemodes.WINTEREXPRESS )
if( Gamemode() == eGamemodes.fs_duckhunt || Gamemode() == eGamemodes.fs_infected || Flowstate_IsHaloMode() || Playlist() == ePlaylists.fs_movementgym )//|| Gamemode() == eGamemodes.WINTEREXPRESS )
tickTime = 0.05

if( Gamemode() == eGamemodes.fs_duckhunt || Gamemode() == eGamemodes.fs_infected || Playlist() == ePlaylists.fs_movementgym )
healthRegenRate = 2.0

//(mk):
// when a player's passive is removed with the global function TakePassive,
// it leads to callback PilotBlood_Passive firing which ends this thread if player had passive. (we want this)
// if a scripter is manually removing the passive with a native function,
// they are now responsible for cleanup/callbacks, as these threads will leak.

// Notice: During damage rework, "OnDamaged" was setup to fire for client,
// however "TookDamage" was never setup for server. Now this is done.

for( ; ; )//while ( IsValid( player ) && PlayerHasPassive( player, ePassives.PAS_PILOT_BLOOD ) )
{
player.WaitSignal( "TookDamage" ) //sleep until damaged

for( ; ; )
{
if( Time() - player.p.lastDamageTime < healthRegenStartDelay )
{
WaitFrame()
continue //wait until player has not been damaged in some time before spawning heal thread
}

break
}

waitthread DispatchHeal( player, tickTime, healthRegenStartDelay, healthRegenRate )
}
}

while ( IsValid( player ) && PlayerHasPassive( player, ePassives.PAS_PILOT_BLOOD ) )
void function DispatchHeal( entity player, float tickTime, float healthRegenStartDelay, float healthRegenRate )
{
player.EndSignal( "TookDamage", "OnDestroy", "OnDeath" )

bool bHealthFull = false
bool bShieldsFull = false

while( !bHealthFull || !bShieldsFull )
{
wait tickTime

if ( !IsAlive( player ) || Bleedout_IsBleedingOut(player) || Time() - player.p.lastDamageTime < healthRegenStartDelay || player.IsPhaseShifted())
if ( Bleedout_IsBleedingOut( player ) || player.IsPhaseShifted() )
{
WaitFrame()
continue
}

if ( player.GetHealth() != player.GetMaxHealth() )
{
player.SetHealth( min( player.GetMaxHealth(), player.GetHealth() + healthRegenRate ) )

}
else if( player.GetShieldHealth() != player.GetShieldHealthMax() && Gamemode() != eGamemodes.WINTEREXPRESS )
{
player.SetHealth( min( player.GetMaxHealth(), player.GetHealth() + healthRegenRate ) )
else
bHealthFull = true

if( player.GetShieldHealth() != player.GetShieldHealthMax() )
player.SetShieldHealth( min( player.GetShieldHealthMax(), player.GetShieldHealth() + healthRegenRate * 5 ) )
}
else
bShieldsFull = true
}
}

Expand Down

0 comments on commit ef93021

Please sign in to comment.