diff options
Diffstat (limited to 'Northstar.CustomServers/mod/scripts/vscripts/mp')
6 files changed, 593 insertions, 12 deletions
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut index a4c6e187..362407b3 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype.gnut @@ -1412,15 +1412,28 @@ void function CodeCallback_WeaponFireInCloak( entity player ) //player.SetCloakFlicker( 1.0, 2.0 ) DisableCloak( player, 0.5 ) - entity weapon = player.GetOffhandWeapon( OFFHAND_LEFT ) - //printt( "weapon", weapon.GetWeaponClassName() ) - // JFS; need code feature to properly reset next attack time/cooldown stuff - if ( IsValid( weapon ) && weapon.GetWeaponClassName() == "mp_ability_cloak" ) + entity cloakWeapon + int offhandSlot + for ( int i = 0; i <= OFFHAND_MELEE; i++ ) // OFFHAND_MELEE is the largest { - player.TakeOffhandWeapon( OFFHAND_LEFT ) - player.GiveOffhandWeapon( "mp_ability_cloak", OFFHAND_LEFT ) - weapon = player.GetOffhandWeapon( OFFHAND_LEFT ) - weapon.SetWeaponPrimaryClipCountAbsolute( 0 ) + entity nowWeapon = player.GetOffhandWeapon( i ) + if( IsValid( nowWeapon )) + { + if( nowWeapon.GetWeaponClassName() == "mp_ability_cloak" ) + { + cloakWeapon = nowWeapon + offhandSlot = i + } + } + } + if( IsValid( cloakWeapon ) ) + { + array<string> mods = cloakWeapon.GetMods() + // can't reset cooldown properly in script, let's give player a empty one + player.TakeWeapon( "mp_ability_cloak" ) // not using TakeWeaponNow() to fit vanilla behavior + player.GiveOffhandWeapon( "mp_ability_cloak", offhandSlot, mods ) + cloakWeapon = player.GetOffhandWeapon( offhandSlot ) + cloakWeapon.SetWeaponPrimaryClipCountAbsolute( 0 ) } } else diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut index ca8dc5f1..ec426754 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_base_gametype_mp.gnut @@ -19,6 +19,8 @@ global function ShouldEntTakeDamage_SPMP global function GetTitanBuildTime global function TitanPlayerHotDropsIntoLevel +global function SetRecalculateRespawnAsTitanStartPointCallback + struct { bool killcamsEnabled = true bool playerDeathsHidden = false @@ -26,6 +28,8 @@ struct { entity intermissionCamera array<entity> specCams + + entity functionref( entity player, entity basePoint ) recalculateRespawnAsTitanStartPointCallback } file void function BaseGametype_Init_MPSP() @@ -443,6 +447,9 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) player.isSpawning = true entity spawnpoint = FindSpawnPoint( player, true, ( ShouldStartSpawn( player ) || Flag( "ForceStartSpawn" ) ) && !IsFFAGame() ) + if ( file.recalculateRespawnAsTitanStartPointCallback != null ) + spawnpoint = file.recalculateRespawnAsTitanStartPointCallback( player, spawnpoint ) + TitanLoadoutDef titanLoadout = GetTitanLoadoutForPlayer( player ) asset model = GetPlayerSettingsAssetForClassName( titanLoadout.setFile, "bodymodel" ) @@ -500,7 +507,7 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) titan.Destroy() // pilotbecomestitan leaves an npc titan that we need to delete else RespawnAsPilot( player ) // this is 100% an edgecase, just avoid softlocking if we ever hit it in playable gamestates - + camera.Fire( "Disable", "!activator", 0, player ) camera.Destroy() }) @@ -509,6 +516,7 @@ void function RespawnAsTitan( entity player, bool manualPosition = false ) player.RespawnPlayer( null ) // spawn player as pilot so they get their pilot loadout on embark player.SetOrigin( titan.GetOrigin() ) + ClearTitanAvailable( player ) // titanfall succeed, clear titan availability // don't make player titan when entity batteryContainer is not valid. // This will prevent a servercrash that sometimes occur when evac is disabled and somebody is calling a titan in the defeat screen. @@ -577,6 +585,11 @@ void function CheckForAutoTitanDeath( entity victim, entity attacker, var damage } } +void function SetRecalculateRespawnAsTitanStartPointCallback( entity functionref( entity player, entity basePoint ) callbackFunc ) +{ + file.recalculateRespawnAsTitanStartPointCallback = callbackFunc +} + // stuff to change later bool function ShouldEntTakeDamage_SPMP( entity ent, var damageInfo ) diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut index 37b89169..ea88c1bc 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_battery_port.gnut @@ -1 +1,219 @@ -//fuck
\ No newline at end of file +untyped +global function InitTurretBatteryPort // only for fw turrets! + +void function InitTurretBatteryPort( entity batteryPort ) +{ + + batteryPort.s.beingUsed <- false // bool + batteryPort.s.hackAvaliable <- true // bool, for controlling hacking avaliablity + + // SetUsableByGroup() updates is done in TurretStateWatcher() + batteryPort.SetUsableByGroup( "pilot" ) // show hind to any pilots + batteryPort.SetUsePrompts( "#RODEO_APPLY_BATTERY_HINT", "#RODEO_APPLY_BATTERY_HINT" ) // don't know what to use + AddCallback_OnUseEntity( batteryPort, OnUseTurretBatteryPort ) +} + +function OnUseTurretBatteryPort( entBeingUse, user ) +{ + expect entity( entBeingUse ) + expect entity( user ) + + //print( "try to use batteryPort" ) + thread TryUseTurretBatteryPort( user, entBeingUse ) +} + +void function TryUseTurretBatteryPort( entity player, entity batteryPort ) +{ + if( batteryPort.s.beingUsed ) // already being using + return + + player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) + player.EndSignal( "ScriptAnimStop" ) // so you can jump off animation + AddButtonPressedPlayerInputCallback( player, IN_JUMP, ForceStopUseBatteryPort ) + + OnThreadEnd( + function():( player ) + { + RemoveButtonPressedPlayerInputCallback( player, IN_JUMP, ForceStopUseBatteryPort ) + } + ) + + + var BatteryPortUsable = batteryPort.s.isUsable + + if( expect bool( BatteryPortUsable( batteryPort, player ) ) ) + { + // friendly try to apply one, or enemy try to hack this turret + waitthread PlayerApplesBatteryPackToPort( player, batteryPort ) + } +} + +void function ForceStopUseBatteryPort( entity player ) +{ + player.Signal( "ScriptAnimStop" ) +} + +void function PlayerApplesBatteryPackToPort( entity player, entity batteryPort ) +{ + table result = {} + result.success <- false + batteryPort.s.beingUsed = true + + BatteryPortSequenceStruct dataStruct = DisableCloakBeforeBatteryPortSequence( player ) + + // these are from _rodeo_titan.gnut + entity battery = GetBatteryOnBack( player ) + battery.Hide() //Hide it because the animation has a battery model already + Battery_StopFX( battery ) + + entity tempBattery3p + tempBattery3p = CreatePropDynamic( RODEO_BATTERY_MODEL_FOR_RODEO_ANIMS ) + tempBattery3p.SetParent( player, "R_HAND", false, 0.0 ) + tempBattery3p.RemoveFromSpatialPartition() + + entity tempBattery1p + tempBattery1p = CreatePropDynamic( RODEO_BATTERY_MODEL_FOR_RODEO_ANIMS ) + tempBattery1p.SetParent( player.GetFirstPersonProxy(), "R_HAND", false, 0.0 ) + tempBattery1p.RemoveFromSpatialPartition() + + player.p.rodeoAnimTempProps.append( tempBattery3p ) + player.p.rodeoAnimTempProps.append( tempBattery1p ) + + OnThreadEnd( + function() : ( battery, batteryPort, player, result, dataStruct ) + { + if ( IsValid( battery ) ) // animation interrupted, otherwise the battery will be destroyed + { + battery.Show() + Battery_StartFX( battery ) + } + + if ( IsValid( batteryPort ) ) + { + batteryPort.s.beingUsed = false + batteryPort.Anim_Stop() + } + + if ( IsValid( player ) ) + { + // restore control + DeployAndEnableWeapons( player ) + //ViewConeFree( player ) // no need to lock viewcone + + // clean up + ClearBatteryAnimTempProps( player ) + PutEntityInSafeSpot( player, player, null, player.GetOrigin() + <0, 0, 32>, player.GetOrigin() ) + + CleanUpBatterySequenceForPlayer( player ) + RestoreCloakAfterBatteryPortSequence( player, dataStruct ) + } + } + ) + + FirstPersonSequenceStruct sequence + sequence.attachment = "REF" // only ref the batteryPort has + + sequence.thirdPersonAnim = "pt_mp_battery_port_insert" //"pt_rodeo_ride_r_return_battery" + sequence.firstPersonAnim = "ptpov_mp_battery_port_insert" //"ptpov_rodeo_ride_r_return_battery" + + // player stats + HolsterAndDisableWeapons( player ) + //ViewConeZero( player ) // no need to lock viewcone + + batteryPort.Anim_Play( "bp_mp_battery_port_insert" ) + + thread WaitForActivateBattery( player, battery, batteryPort ) + waitthread FirstPersonSequence( sequence, player, batteryPort ) +} + +void function WaitForActivateBattery( entity player, entity battery, entity batteryPort ) +{ + player.EndSignal( "OnDeath" ) + player.EndSignal( "OnDestroy" ) + player.EndSignal( "ScriptAnimStop" ) // so you can jump off animation + battery.EndSignal( "OnDestroy" ) + + player.WaitSignal( "BatteryActivate" ) // this is registered in _gamemode_fw.nut! + ApplyBatteryToBatteryPort( player, batteryPort ) +} + +void function ApplyBatteryToBatteryPort( entity player, entity batteryPort ) +{ + if ( player.GetPlayerNetInt( "batteryCount" ) <= 0 ) // player actually not carrying a battery + return + + entity battery = Rodeo_TakeBatteryAwayFromPilot( player ) + if ( !IsValid( battery ) ) + return + + // player can apply battery + + // disable hacking + batteryPort.s.hackAvaliable = false // can't be hacked again until completely killed + + + var useBatteryPort = batteryPort.s.useBattery + useBatteryPort( batteryPort, player ) + + // all things done, destroy this batt + battery.Destroy() +} + +// for disabling cloak +struct BatteryPortSequenceStruct +{ + bool wasCloaked = false + float cloakEndTime = 0.0 +} + +BatteryPortSequenceStruct function DisableCloakBeforeBatteryPortSequence( entity player ) +{ + BatteryPortSequenceStruct dataStruct + if ( !IsCloaked( player ) ) + return dataStruct // empty struct! + + dataStruct.wasCloaked = true + dataStruct.cloakEndTime = player.GetCloakEndTime() + DisableCloak( player, 0.0 ) + + return dataStruct +} + +bool function RestoreCloakAfterBatteryPortSequence( entity player, BatteryPortSequenceStruct dataStruct ) +{ + if ( !IsAlive( player ) ) + return false + + if ( !dataStruct.wasCloaked ) + return false + + if ( dataStruct.cloakEndTime <= 0.0 ) + return false + + float remainingCloakDuration = max( 0.0, dataStruct.cloakEndTime - Time() ) + if ( remainingCloakDuration <= CLOAK_FADE_IN ) //Has to be greater than 1.0 fade in duration, otherwise will cloak forever + return false + + EnableCloak( player, remainingCloakDuration, CLOAK_FADE_IN ) + return true +} + +void function CleanUpBatterySequenceForPlayer( entity player ) +{ + ClearPlayerAnimViewEntity( player ) + player.AnimViewEntity_SetLerpOutTime( 0.4 ) // blend out the clear anim view entity + player.ClearParent() + player.Anim_Stop() +} + +void function ClearBatteryAnimTempProps( entity player ) +{ + foreach( tempProp in player.p.rodeoAnimTempProps ) + { + if ( IsValid( tempProp ) ) + tempProp.Destroy() + } + + player.p.rodeoAnimTempProps.clear() +}
\ No newline at end of file diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut index 6cde4655..46b39ebc 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_gamestate_mp.nut @@ -220,6 +220,8 @@ void function GameStateEnter_Playing_Threaded() { WaitFrame() // ensure timelimits are all properly set + thread DialoguePlayNormal() // runs dialogue play function + while ( GetGameState() == eGameState.Playing ) { // could cache these, but what if we update it midgame? @@ -268,6 +270,8 @@ void function GameStateEnter_WinnerDetermined_Threaded() // do win announcement int winningTeam = GetWinningTeamWithFFASupport() + DialoguePlayWinnerDetermined() // play a faction dialogue when winner is determined + foreach ( entity player in GetPlayerArray() ) { int announcementSubstr @@ -509,6 +513,20 @@ void function GameStateEnter_SuddenDeath() { // disable respawns, suddendeath calling is done on a kill callback SetRespawnsEnabled( false ) + + // defensive fixes, so game won't stuck in SuddenDeath forever + bool mltElimited = false + bool imcElimited = false + if( GetPlayerArrayOfTeam_Alive( TEAM_MILITIA ).len() < 1 ) + mltElimited = true + if( GetPlayerArrayOfTeam_Alive( TEAM_IMC ).len() < 1 ) + imcElimited = true + if( mltElimited && imcElimited ) + SetWinner( TEAM_UNASSIGNED ) + else if( mltElimited ) + SetWinner( TEAM_IMC ) + else if( imcElimited ) + SetWinner( TEAM_MILITIA ) } @@ -874,3 +892,90 @@ float function GetTimeLimit_ForGameMode() // default to 10 mins, because that seems reasonable return GetCurrentPlaylistVarFloat( playlistString, 10 ) } + +// faction dialogue + +void function DialoguePlayNormal() +{ + int totalScore = GameMode_GetScoreLimit( GameRules_GetGameMode() ) + int winningTeam + int losingTeam + float diagIntervel = 71 // play a faction dailogue every 70 + 1s to prevent play together with winner dialogue + + while( GetGameState() == eGameState.Playing ) + { + wait diagIntervel + if( GameRules_GetTeamScore( TEAM_MILITIA ) < GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_IMC + losingTeam = TEAM_MILITIA + } + if( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_MILITIA + losingTeam = TEAM_IMC + } + if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) >= totalScore * 0.4 ) + { + PlayFactionDialogueToTeam( "scoring_winningLarge", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losingLarge", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) <= totalScore * 0.2 ) + { + PlayFactionDialogueToTeam( "scoring_winningClose", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losingClose", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) == GameRules_GetTeamScore( losingTeam ) ) + { + continue + } + else + { + PlayFactionDialogueToTeam( "scoring_winning", winningTeam ) + PlayFactionDialogueToTeam( "scoring_losing", losingTeam ) + } + } +} + +void function DialoguePlayWinnerDetermined() +{ + int totalScore = GameMode_GetScoreLimit( GameRules_GetGameMode() ) + int winningTeam + int losingTeam + + if( GameRules_GetTeamScore( TEAM_MILITIA ) < GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_IMC + losingTeam = TEAM_MILITIA + } + if( GameRules_GetTeamScore( TEAM_MILITIA ) > GameRules_GetTeamScore( TEAM_IMC ) ) + { + winningTeam = TEAM_MILITIA + losingTeam = TEAM_IMC + } + if( IsRoundBased() ) // check for round based modes + { + if( GameRules_GetTeamScore( winningTeam ) != GameMode_GetRoundScoreLimit( GAMETYPE ) ) // no winner dialogue till game really ends + return + } + if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) >= totalScore * 0.4 ) + { + PlayFactionDialogueToTeam( "scoring_wonMercy", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lostMercy", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) - GameRules_GetTeamScore( losingTeam ) <= totalScore * 0.2 ) + { + PlayFactionDialogueToTeam( "scoring_wonClose", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lostClose", losingTeam ) + } + else if( GameRules_GetTeamScore( winningTeam ) == GameRules_GetTeamScore( losingTeam ) ) + { + PlayFactionDialogueToTeam( "scoring_tied", winningTeam ) + PlayFactionDialogueToTeam( "scoring_tied", losingTeam ) + } + else + { + PlayFactionDialogueToTeam( "scoring_won", winningTeam ) + PlayFactionDialogueToTeam( "scoring_lost", losingTeam ) + } +} diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut new file mode 100644 index 00000000..c33f4ef0 --- /dev/null +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_model_viewer.nut @@ -0,0 +1,180 @@ +untyped
+
+
+global function ModelViewer_Init
+
+global function ToggleModelViewer
+
+global modelViewerModels = []
+
+#if DEV
+struct
+{
+ bool initialized
+ bool active
+ entity gameUIFreezeControls
+ array<string> playerWeapons
+ array<string> playerOffhands
+ bool dpadUpPressed = true
+ bool dpadDownPressed = true
+ var lastTitanAvailability
+} file
+#endif // DEV
+
+function ModelViewer_Init()
+{
+ #if DEV
+ if ( reloadingScripts )
+ return
+ AddClientCommandCallback( "ModelViewer", ClientCommand_ModelViewer )
+ #endif
+}
+
+function ToggleModelViewer()
+{
+ #if DEV
+ entity player = GetPlayerArray()[ 0 ]
+ if ( !file.active )
+ {
+ file.active = true
+
+ DisablePrecacheErrors()
+ wait 0.5
+
+ ModelViewerDisableConflicts()
+ Remote_CallFunction_NonReplay( player, "ServerCallback_ModelViewerDisableConflicts" )
+
+ ReloadShared()
+
+ if ( !file.initialized )
+ {
+ file.initialized = true
+ ControlsInit()
+ }
+
+ Remote_CallFunction_NonReplay( player, "ServerCallback_MVEnable" )
+
+ file.lastTitanAvailability = level.nv.titanAvailability
+ Riff_ForceTitanAvailability( eTitanAvailability.Never )
+
+ WeaponsRemove()
+ thread UpdateModelBounds()
+ }
+ else
+ {
+ file.active = false
+
+ Remote_CallFunction_NonReplay( player, "ServerCallback_MVDisable" )
+ RestorePrecacheErrors()
+
+ Riff_ForceTitanAvailability( file.lastTitanAvailability )
+
+ WeaponsRestore()
+ }
+ #endif
+}
+
+#if DEV
+function ModelViewerDisableConflicts()
+{
+ disable_npcs() //Just disable_npcs() for now, will probably add things later
+}
+
+function ReloadShared()
+{
+ modelViewerModels = GetModelViewerList()
+}
+
+function ControlsInit()
+{
+ file.gameUIFreezeControls = CreateEntity( "game_ui" )
+ file.gameUIFreezeControls.kv.spawnflags = 32
+ file.gameUIFreezeControls.kv.FieldOfView = -1.0
+
+ DispatchSpawn( file.gameUIFreezeControls )
+}
+
+bool function ClientCommand_ModelViewer( entity player, array<string> args )
+{
+ string command = args[ 0 ]
+ switch ( command )
+ {
+ case "freeze_player":
+ file.gameUIFreezeControls.Fire( "Activate", "!player", 0 )
+ break
+
+ case "unfreeze_player":
+ file.gameUIFreezeControls.Fire( "Deactivate", "!player", 0 )
+ break
+ }
+
+ return true
+}
+
+function UpdateModelBounds()
+{
+ wait( 0.3 )
+
+ foreach ( index, modelName in modelViewerModels )
+ {
+ entity model = CreatePropDynamic( expect asset( modelName ) )
+ local mins = model.GetBoundingMins()
+ local maxs = model.GetBoundingMaxs()
+
+ mins.x = min( -8.0, mins.x )
+ mins.y = min( -8.0, mins.y )
+ mins.z = min( -8.0, mins.z )
+
+ maxs.x = max( 8.0, maxs.x )
+ maxs.y = max( 8.0, maxs.y )
+ maxs.z = max( 8.0, maxs.z )
+
+ Remote_CallFunction_NonReplay( GetPlayerArray()[ 0 ], "ServerCallback_MVUpdateModelBounds", index, mins.x, mins.y, mins.z, maxs.x, maxs.y, maxs.z )
+ model.Destroy()
+ }
+}
+
+function WeaponsRemove()
+{
+ entity player = GetPlayerArray()[0]
+ if ( !IsValid( player ) )
+ return
+
+ file.playerWeapons.clear()
+ file.playerOffhands.clear()
+
+ array<entity> weapons = player.GetMainWeapons()
+ foreach ( weaponEnt in weapons )
+ {
+ string weapon = weaponEnt.GetWeaponClassName()
+ file.playerWeapons.append( weapon )
+ player.TakeWeapon( weapon )
+ }
+
+ array<entity> offhands = player.GetOffhandWeapons()
+ foreach ( index, offhandEnt in offhands )
+ {
+ string offhand = offhandEnt.GetWeaponClassName()
+ file.playerOffhands.append( offhand )
+ player.TakeOffhandWeapon( index )
+ }
+}
+
+function WeaponsRestore()
+{
+ entity player = GetPlayerArray()[0]
+ if ( !IsValid( player ) )
+ return
+
+ foreach ( weapon in file.playerWeapons )
+ {
+ player.GiveWeapon( weapon )
+ }
+
+ foreach ( index, offhand in file.playerOffhands )
+ {
+ player.GiveOffhandWeapon( offhand, index )
+ }
+}
+
+#endif // DEV
diff --git a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut index 2d1ff074..dacd43b0 100644 --- a/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut +++ b/Northstar.CustomServers/mod/scripts/vscripts/mp/_score.nut @@ -187,9 +187,19 @@ void function ScoreEvent_TitanKilled( entity victim, entity attacker, var damage return if ( attacker.IsTitan() ) - AddPlayerScore( attacker, "TitanKillTitan", victim.GetTitanSoul().GetOwner() ) + { + if( victim.GetBossPlayer() || victim.IsPlayer() ) // to confirm this is a pet titan or player titan + AddPlayerScore( attacker, "TitanKillTitan", attacker ) // this will show the "Titan Kill" callsign event + else + AddPlayerScore( attacker, "TitanKillTitan" ) + } else - AddPlayerScore( attacker, "KillTitan", victim.GetTitanSoul().GetOwner() ) + { + if( victim.GetBossPlayer() || victim.IsPlayer() ) + AddPlayerScore( attacker, "KillTitan", attacker ) + else + AddPlayerScore( attacker, "KillTitan" ) + } table<int, bool> alreadyAssisted foreach( DamageHistoryStruct attackerInfo in victim.e.recentDamageHistory ) @@ -205,6 +215,9 @@ void function ScoreEvent_TitanKilled( entity victim, entity attacker, var damage Remote_CallFunction_NonReplay( attackerInfo.attacker, "ServerCallback_SetAssistInformation", attackerInfo.damageSourceId, attacker.GetEncodedEHandle(), victim.GetEncodedEHandle(), attackerInfo.time ) } } + + if( !victim.IsNPC() ) // don't let killing a npc titan plays dialogue + KilledPlayerTitanDialogue( attacker, victim ) } void function ScoreEvent_NPCKilled( entity victim, entity attacker, var damageInfo ) @@ -251,3 +264,42 @@ void function ScoreEvent_SetupEarnMeterValuesForTitanModes() { // relatively sure we don't have to do anything here but leaving this function for consistency } + +// faction dialogue +void function KilledPlayerTitanDialogue( entity attacker, entity victim ) +{ + if( !attacker.IsPlayer() ) + return + entity titan + if ( victim.IsTitan() ) + titan = victim + + if( !IsValid( titan ) ) + return + string titanCharacterName = GetTitanCharacterName( titan ) + + switch( titanCharacterName ) + { + case "ion": + PlayFactionDialogueToPlayer( "kc_pilotkillIon", attacker ) + return + case "tone": + PlayFactionDialogueToPlayer( "kc_pilotkillTone", attacker ) + return + case "legion": + PlayFactionDialogueToPlayer( "kc_pilotkillLegion", attacker ) + return + case "scorch": + PlayFactionDialogueToPlayer( "kc_pilotkillScorch", attacker ) + return + case "ronin": + PlayFactionDialogueToPlayer( "kc_pilotkillRonin", attacker ) + return + case "northstar": + PlayFactionDialogueToPlayer( "kc_pilotkillNorthstar", attacker ) + return + default: + PlayFactionDialogueToPlayer( "kc_pilotkilltitan", attacker ) + return + } +} |