1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
untyped
global function PowerUps_Init
struct {
array<entity> powerupSpawns
} file
void function PowerUps_Init()
{
SH_PowerUp_Init()
AddSpawnCallbackEditorClass( "script_ref", "script_power_up_other", AddPowerupSpawn )
AddCallback_OnTouchHealthKit( "item_powerup", OnPowerupCollected )
AddCallback_GameStateEnter( eGameState.Prematch, RespawnPowerups )
}
void function AddPowerupSpawn( entity spawnpoint )
{
file.powerupSpawns.append( spawnpoint )
}
void function RespawnPowerups()
{
foreach ( entity spawnpoint in file.powerupSpawns )
{
PowerUp powerupDef = GetPowerUpFromItemRef( expect string( spawnpoint.kv.powerUpType ) )
thread PowerupSpawnerThink( spawnpoint, powerupDef )
}
}
void function PowerupSpawnerThink( entity spawnpoint, PowerUp powerupDef )
{
svGlobal.levelEnt.EndSignal( "CleanUpEntitiesForRoundEnd" )
entity base = CreatePropDynamic( powerupDef.baseModel, spawnpoint.GetOrigin(), spawnpoint.GetAngles(), 2 )
OnThreadEnd( function() : ( base )
{
base.Destroy()
})
while ( true )
{
if ( !powerupDef.spawnFunc() )
return
entity powerup = CreateEntity( "item_powerup" )
powerup.SetOrigin( base.GetOrigin() + powerupDef.modelOffset )
powerup.SetAngles( base.GetAngles() + powerupDef.modelAngles )
powerup.SetValueForModelKey( powerupDef.model )
powerup.s.powerupRef <- powerupDef.itemRef // this needs to be done before dispatchspawn since OnPowerupCollected will run as soon as we call dispatchspawn if there's a player on battery as it spawns
DispatchSpawn( powerup )
// unless i'm doing something really dumb, this all has to be done after dispatchspawn to get the powerup to not have gravity
powerup.StopPhysics()
powerup.SetOrigin( base.GetOrigin() + powerupDef.modelOffset )
powerup.SetAngles( base.GetAngles() + powerupDef.modelAngles )
powerup.SetModel( powerupDef.model )
PickupGlow glow = CreatePickupGlow( powerup, powerupDef.glowColor.x.tointeger(), powerupDef.glowColor.y.tointeger(), powerupDef.glowColor.z.tointeger() )
glow.glowFX.SetOrigin( spawnpoint.GetOrigin() ) // want the glow to be parented to the powerup, but have the position of the spawnpoint
OnThreadEnd( function() : ( powerup )
{
if ( IsValid( powerup ) )
powerup.Destroy()
})
powerup.WaitSignal( "OnDestroy" )
wait powerupDef.respawnDelay
}
}
bool function OnPowerupCollected( entity player, entity healthpack )
{
PowerUp powerup = GetPowerUpFromItemRef( expect string( healthpack.s.powerupRef ) )
if ( powerup.titanPickup == player.IsTitan() )
{
// hack because i couldn't figure out any other way to do this without modifying sh_powerup
// ensure we don't kill the powerup if it's a battery the player can't pickup
if ( powerup.index == ePowerUps.titanTimeReduction || powerup.index == ePowerUps.LTS_TitanTimeReduction )
{
if ( player.IsTitan() )
return false
if ( PlayerHasMaxBatteryCount( player ) )
return false
// this is seemingly innacurate to what fra actually did, but for whatever reason embarking with >1 bat crashes in vanilla code
// so idk this is easier
if ( GAMETYPE == FREE_AGENCY && ( IsValid( player.GetPetTitan() ) || IsTitanAvailable( player ) ) && GetPlayerBatteryCount( player ) > 0 )
return false
}
// idk why the powerup.destroyFunc doesn't just return a bool? would mean they could just handle stuff like this in powerup code
powerup.destroyFunc( player )
return true // destroys the powerup
}
return false // keeps powerup alive
}
|