aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut177
1 files changed, 86 insertions, 91 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
index 23ae37a1..7b6c7e9f 100644
--- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
+++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_classic_mp_dropship_intro.gnut
@@ -26,18 +26,9 @@ const int MAX_DROPSHIP_PLAYERS = 4
global const float DROPSHIP_INTRO_LENGTH = 15.0 // TODO tweak this
-struct IntroDropship
-{
- entity dropship
-
- int playersInDropship
- entity[MAX_DROPSHIP_PLAYERS] players
-}
-
struct {
- // these used to be IntroDropship[2]s but i wanted to be able to use array.getrandom so they have to be actual arrays
- array<IntroDropship> militiaDropships
- array<IntroDropship> imcDropships
+ table< entity, array<entity> > militiaDropships
+ table< entity, array<entity> > imcDropships
float introStartTime
} file
@@ -52,7 +43,12 @@ void function ClassicMP_DefaultDropshipIntro_Setup()
void function DropshipIntro_OnClientConnected( entity player )
{
if ( GetGameState() == eGameState.Prematch )
- thread SpawnPlayerIntoDropship( player )
+ {
+ if( PlayerCanSpawn( player ) )
+ DoRespawnPlayer( player, null )
+
+ PutPlayerInDropship( player )
+ }
}
void function OnPrematchStart()
@@ -62,11 +58,11 @@ void function OnPrematchStart()
print( "starting dropship intro!" )
file.introStartTime = Time()
- // make 2 empty dropship structs per team
- IntroDropship emptyDropship
+ // Clear Dropship arrays of Teams for Match Restarts (i.e Half-Times)
file.militiaDropships.clear()
file.imcDropships.clear()
+ // Try to gather all possible Dropship spawn points for Team
array<entity> validDropshipSpawns
array<entity> dropshipSpawns = GetEntArrayByClass_Expensive( "info_spawnpoint_dropship_start" )
foreach ( entity dropshipSpawn in dropshipSpawns )
@@ -78,47 +74,47 @@ void function OnPrematchStart()
validDropshipSpawns.append( dropshipSpawn )
}
- // if no dropship spawns for this mode, just allow any dropship spawns
+ // Use any spawn point if not enough valid for this Gamemode exists
if ( validDropshipSpawns.len() < 2 )
validDropshipSpawns = dropshipSpawns
// spawn dropships
foreach ( entity dropshipSpawn in validDropshipSpawns )
{
- // todo: possibly make this only spawn dropships if we've got enough players to need them
int createTeam = HasSwitchedSides() ? GetOtherTeam( dropshipSpawn.GetTeam() ) : dropshipSpawn.GetTeam()
- array<IntroDropship> teamDropships = createTeam == TEAM_MILITIA ? file.militiaDropships : file.imcDropships
+ table< entity, array<entity> > teamDropships = createTeam == TEAM_MILITIA ? file.militiaDropships : file.imcDropships
if ( teamDropships.len() >= 2 )
- continue
+ break
- // create entity
entity dropship = CreateDropship( createTeam, dropshipSpawn.GetOrigin(), dropshipSpawn.GetAngles() )
-
- teamDropships.append( clone emptyDropship )
- teamDropships[ teamDropships.len() - 1 ].dropship = dropship
-
AddAnimEvent( dropship, "dropship_warpout", WarpoutEffect )
+
dropship.SetValueForModelKey( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" )
- dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" )
+ if ( dropshipSpawn.GetTeam() == TEAM_IMC )
+ dropship.SetValueForModelKey( $"models/vehicle/goblin_dropship/goblin_dropship_hero.mdl" )
DispatchSpawn( dropship )
- // have to do this after dispatch otherwise it won't work for some reason
- // weirdly enough, tf2 actually does use different dropships for imc and militia, despite these concepts not really being a thing for players in tf2
- // probably was just missed by devs, but keeping it in for accuracy
+ dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" )
if ( dropshipSpawn.GetTeam() == TEAM_IMC )
dropship.SetModel( $"models/vehicle/goblin_dropship/goblin_dropship_hero.mdl" )
- else
- dropship.SetModel( $"models/vehicle/crow_dropship/crow_dropship_hero.mdl" )
+
+ teamDropships[ dropship ] <- [ null, null, null, null ]
thread PlayAnim( dropship, "dropship_classic_mp_flyin" )
}
+ // Populate Dropships
foreach ( entity player in GetPlayerArray() )
{
if ( !IsPrivateMatchSpectator( player ) )
- thread SpawnPlayerIntoDropship( player )
+ {
+ if( PlayerCanSpawn( player ) )
+ DoRespawnPlayer( player, null )
+
+ PutPlayerInDropship( player )
+ }
else
RespawnPrivateMatchSpectator( player )
}
@@ -128,68 +124,69 @@ void function OnPrematchStart()
void function EndIntroWhenFinished()
{
- wait 15.0
+ wait DROPSHIP_INTRO_LENGTH
ClassicMP_OnIntroFinished()
}
-void function SpawnPlayerIntoDropship( entity player )
+void function PutPlayerInDropship( entity player )
{
- player.EndSignal( "OnDestroy" )
+ //Find the player's dropship and seat
+ table< entity, array<entity> > teamDropships
+ if ( player.GetTeam() == TEAM_MILITIA )
+ teamDropships = file.militiaDropships
+ else
+ teamDropships = file.imcDropships
+
+ entity playerDropship
+ array< int > availableShipSlots
+ array< entity > introDropships
+ int playerDropshipIndex = RandomInt( MAX_DROPSHIP_PLAYERS )
+ foreach( dropship, playerslot in teamDropships )
+ {
+ introDropships.append( dropship )
+ for ( int i = 0; i < MAX_DROPSHIP_PLAYERS; i++ )
+ {
+ if ( !IsValidPlayer( playerslot[i] ) )
+ availableShipSlots.append( i )
+ }
+
+ if( !availableShipSlots.len() )
+ continue
+
+ int slotPick = availableShipSlots.getrandom()
+ playerslot[slotPick] = player
+ playerDropship = dropship
+ playerDropshipIndex = slotPick
+ break
+ }
+
+ if( !IsAlive( playerDropship ) ) //If we're at this point, we have more players than we do dropships, so just pick a random one
+ playerDropship = introDropships.getrandom()
+
+ thread SpawnPlayerIntoDropship( player, playerDropshipIndex, playerDropship )
+}
- if ( IsAlive( player ) )
- player.Die() // kill them so we don't have any issues respawning them later
+void function SpawnPlayerIntoDropship( entity player, int playerDropshipIndex, entity playerDropship )
+{
+ player.EndSignal( "OnDestroy" )
+ player.EndSignal( "OnDeath" )
- player.s.dropshipIntroIsJumping <- false
- OnThreadEnd( function() : ( player )
+ OnThreadEnd( function() : ( player, playerDropshipIndex, playerDropship )
{
if ( IsValid( player ) )
{
player.ClearParent()
ClearPlayerAnimViewEntity( player )
-
- if ( !player.s.dropshipIntroIsJumping )
- {
- player.MovementEnable()
- player.EnableWeaponViewModel()
- RemoveCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING )
- }
+ }
+ if( IsAlive( playerDropship ) )
+ {
+ if ( playerDropship.GetTeam() == TEAM_MILITIA )
+ file.militiaDropships[ playerDropship ][ playerDropshipIndex ] = null
+ else
+ file.imcDropships[ playerDropship ][ playerDropshipIndex ] = null
}
})
- WaitFrame()
-
- player.EndSignal( "OnDeath" )
-
- // find the player's dropship and seat
- array<IntroDropship> teamDropships
- if ( player.GetTeam() == TEAM_MILITIA )
- teamDropships = file.militiaDropships
- else
- teamDropships = file.imcDropships
-
- IntroDropship playerDropship
- int playerDropshipIndex = -1
- foreach ( IntroDropship dropship in teamDropships )
- for ( int i = 0; i < dropship.players.len(); i++ )
- if ( dropship.players[ i ] == null )
- {
- playerDropship = dropship
- playerDropshipIndex = i
-
- dropship.players[ i ] = player
- break
- }
-
- if ( playerDropship.dropship == null )
- {
- // if we're at this point, we have more players than we do dropships, so just pick a random one
- playerDropship = teamDropships.getrandom()
- playerDropshipIndex = RandomInt( MAX_DROPSHIP_PLAYERS )
- }
-
- // respawn player and holster their weapons so they aren't out
- if ( !IsAlive( player ) )
- player.RespawnPlayer( null )
HolsterAndDisableWeapons(player)
player.DisableWeaponViewModel()
@@ -208,9 +205,7 @@ void function SpawnPlayerIntoDropship( entity player )
idleSequence.viewConeFunction = ViewConeRampFree
idleSequence.hideProxy = true
idleSequence.setInitialTime = Time() - file.introStartTime
- thread FirstPersonSequence( idleSequence, player, playerDropship.dropship )
- WaittillAnimDone( player )
-
+ waitthread FirstPersonSequence( idleSequence, player, playerDropship )
// todo: possibly rework this to actually get the time the idle anim takes and start the starttime of the jump sequence for very late joiners using that
// jump sequence
@@ -218,13 +213,12 @@ void function SpawnPlayerIntoDropship( entity player )
jumpSequence.firstPersonAnim = DROPSHIP_JUMP_ANIMS_POV[ playerDropshipIndex ]
jumpSequence.thirdPersonAnim = DROPSHIP_JUMP_ANIMS[ playerDropshipIndex ]
jumpSequence.attachment = "ORIGIN"
+ jumpSequence.viewConeFunction = ViewConeFree
jumpSequence.setInitialTime = max( 0.0, Time() - ( file.introStartTime + 11.0 ) ) // pretty sure you should do this with GetScriptedAnimEventCycleFrac?
// idk unsure how to use that, all i know is getsequenceduration > the length it actually should be
- thread FirstPersonSequence( jumpSequence, player, playerDropship.dropship )
- WaittillAnimDone( player ) // somehow this is better than just waiting for the blocking FirstPersonSequence call?
+ waitthread FirstPersonSequence( jumpSequence, player, playerDropship )
- player.s.dropshipIntroIsJumping <- true
thread PlayerJumpsFromDropship( player )
}
@@ -244,16 +238,17 @@ void function PlayerJumpsFromDropship( entity player )
RemoveCinematicFlag( player, CE_FLAG_CLASSIC_MP_SPAWNING )
}
})
-
- // wait for intro timer to be fully done
- wait ( file.introStartTime + DROPSHIP_INTRO_LENGTH ) - Time()
- player.MovementDisable() // disable all movement but let them look around still
- player.ConsumeDoubleJump() // movementdisable doesn't prevent double jumps
// wait for player to hit the ground
- wait 0.1 // assume players will never actually hit ground before this
+ player.ClearParent()
+ WaitFrame()
+ player.SetVelocity( < 0, 0, -100 > ) // Toss players a bit down so it makes a smoother transition when jumping off the Dropship
+ player.MovementDisable() // Disable all movement but let them look around still
+ player.ConsumeDoubleJump() // MovementDisable doesn't prevent double jumps
+ WaitFrame()
while ( !player.IsOnGround() && !player.IsWallRunning() && !player.IsWallHanging() ) // todo this needs tweaking
WaitFrame()
- TryGameModeAnnouncement( player )
+ if ( GetRoundsPlayed() == 0 ) //Intro is announced only for the first round in Vanilla as certain gamemodes have different announcements for rounds restarts
+ TryGameModeAnnouncement( player )
}