diff --git a/scripts/sp/callbacks.gsc b/scripts/sp/callbacks.gsc new file mode 100644 index 0000000..98f447f --- /dev/null +++ b/scripts/sp/callbacks.gsc @@ -0,0 +1,81 @@ +#include maps\_utility; +#include common_scripts\utility; + +main() +{ + level.callbackActorDamage = ::Callback_ActorDamage; + level.callbackActorKilled = ::Callback_ActorKilled; +} + +init() +{ + level thread watchRoundChanges(); +} + +watchRoundChanges() +{ + current_round = 0; + setDvar( "sv_zombieRoundNumber", current_round ); + + flag_wait( "all_players_connected" ); + waittillframeend; + + for ( ;; ) + { + while ( !isDefined( level.round_number ) || current_round == level.round_number ) + wait 0.05; + + current_round = level.round_number; + setDvar( "sv_zombieRoundNumber", current_round ); + level notify( "new_zombie_round", current_round ); + } +} + +Callback_ActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ) +{ +/* + PrintConsole( "Callback_ActorDamage:" ); + PrintConsole( "self.classname: " + self.classname ); + PrintConsole( "eInflictor.classname: " + eInflictor.classname ); + PrintConsole( "eAttacker.classname: " + eAttacker.classname ); + PrintConsole( "iDamage: " + iDamage ); + PrintConsole( "iDFlags: " + iDFlags ); + PrintConsole( "sMeansOfDeath: " + sMeansOfDeath ); + PrintConsole( "sWeapon: " + sWeapon ); + PrintConsole( "vPoint: " + vPoint ); + PrintConsole( "vDir: " + vDir ); + PrintConsole( "sHitLoc: " + sHitLoc ); + PrintConsole( "iModelIndex: " + iModelIndex ); + PrintConsole( "iTimeOffset: " + iTimeOffset ); + PrintConsole( "" ); +*/ + + self FinishActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ); +} + +Callback_ActorKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, iTimeOffset ) +{ +/* + PrintConsole( "Callback_ActorKilled:" ); + PrintConsole( "self.classname: " + self.classname ); + PrintConsole( "eInflictor.classname: " + eInflictor.classname ); + PrintConsole( "eAttacker.classname: " + eAttacker.classname ); + PrintConsole( "iDamage: " + iDamage ); + PrintConsole( "sMeansOfDeath: " + sMeansOfDeath ); + PrintConsole( "sWeapon: " + sWeapon ); + PrintConsole( "vDir: " + vDir ); + PrintConsole( "sHitLoc: " + sHitLoc ); + PrintConsole( "iTimeOffset: " + iTimeOffset ); + PrintConsole( "" ); +*/ +} + +CodeCallback_ActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ) +{ + self [[level.callbackActorDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ); +} + +CodeCallback_ActorKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, iTimeOffset ) +{ + self [[level.callbackActorKilled]]( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, iTimeOffset ); +} diff --git a/scripts/sp/killtest.gsc b/scripts/sp/killtest.gsc index 6182d04..f3dde09 100644 --- a/scripts/sp/killtest.gsc +++ b/scripts/sp/killtest.gsc @@ -16,6 +16,8 @@ init() level thread print_new_rounds(); level thread onPlayerConnect(); level thread spitOutTime(); + + setDvar( "killtest_bot_debug", 1 ); level thread addBot(); level thread setupcallbacks(); @@ -198,6 +200,9 @@ spitOutTime() addBot() { + if ( !getDvarInt( "killtest_bot_debug" ) ) + return; + // level waittill("connected", player); wait 5; diff --git a/scripts/sp/nazi_zombie_ccube_u/fix_ccube_u.gsc b/scripts/sp/nazi_zombie_ccube_u/fix_ccube_u.gsc new file mode 100644 index 0000000..ab679d5 --- /dev/null +++ b/scripts/sp/nazi_zombie_ccube_u/fix_ccube_u.gsc @@ -0,0 +1,117 @@ +#include common_scripts\utility; +#include maps\_utility; + +main() +{ + // kek + replacefunc( getFunction( "maps/nazi_zombie_ccube_u", "anti_cheat" ), ::noop ); + + // this is BAD gsc, use new impl + replacefunc( getFunction( "maps/nazi_zombie_ccube_u", "damage_test" ), ::noop ); +} + +noop() +{ +} + +init() +{ + // fixes points for hotjoiners + level thread onPlayerConnect(); + + // our impl of memes + level thread damage_goo(); +} + +onPlayerConnect() +{ + for ( ;; ) + { + level waittill( "connected", player ); + + player thread onConnect(); + } +} + +onConnect() +{ + self endon( "disconnect" ); + + self.mk1_suit = 0; + self.mk3_suit = 0; + self.mk4_suit = 0; + self.mk5_suit = 0; + self.mk6_suit = 0; + self.mk16_suit = 0; + self.is_cloaked = false; //needed for Mark 16 + self.is_authorized = false; //needed for Mark 16 + self.wm_suit = 0; + self.part_hud = []; + self.used_suit = undefined; + self disableInvulnerability(); + self setClientDvar( "ui_hud_hardcore", 0 ); +} + +damage_goo() +{ + //damage_trig = getEnt("damage_trig", "targetname"); + cheese_bottom = getEnt( "cheese_bottom", "targetname" ); + level.quick_revive_ending_game = 0; + //cheese_bottom notSolid(); + + while ( 1 ) + { + wait .05; + + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + player = players[i]; + + player thread check_goo_damage( cheese_bottom ); + } + } +} + +check_goo_damage( cheese_bottom ) +{ + self endon( "disconnect" ); + + players = get_players(); + + if ( self IsTouching( cheese_bottom ) && self.sessionstate != "intermission" && self.sessionstate != "spectator" ) + { + if ( self hasPerk( "specialty_quickrevive" ) && players.size == 1 ) + { + level.quick_revive_ending_game = 1; + self DoDamage( self.health + 666, self.origin ); + wait .5; + iprintln( "Quick Revive has no power against the dark side of the cheese" ); + level notify( "end_game" ); + wait 3.5; + iprintln( self.playername + " has touched the dark side of the cheese" ); + } + + if ( !( self hasPerk( "specialty_quickrevive" ) ) && players.size == 1 ) + { + self DoDamage( self.health + 666, self.origin ); + level notify( "end_game" ); + iprintln( self.playername + " has touched the dark side of the cheese" ); + wait 4; + } + else + { + self DoDamage( self.health + 666, self.origin ); + iprintln( self.playername + " has touched the dark side of the cheese" ); + //RadiusDamage(self.origin,10,self.health+666,self.health+666); + wait 5; + } + + for ( i = 0; i < players.size; i++ ) + { + players[i] disableInvulnerability(); + wait .1; + } + } +} diff --git a/scripts/sp/sanatorium/fix_sanatorium.gsc b/scripts/sp/sanatorium/fix_sanatorium.gsc new file mode 100644 index 0000000..a04df81 --- /dev/null +++ b/scripts/sp/sanatorium/fix_sanatorium.gsc @@ -0,0 +1,93 @@ +#include common_scripts\utility; +#include maps\_utility; + +main() +{ + replaceFunc( getFunction( "maps/sanatorium", "ch_ds" ), ::noop ); + replaceFunc( getFunction( "maps/sanatorium", "wurst" ), ::noop ); + replaceFunc( getFunction( "maps/sanatorium", "staminup" ), ::noop ); + + replaceFunc( getFunction( "maps/_zombiemode_weap_zombie_shield", "shield_destroy_player_model" ), ::fix_shield_destroy_player_model ); + replaceFunc( getFunction( "maps/altmelee_mod", "get_galvaknuckles" ), ::fix_get_galvaknuckles ); + replaceFunc( getFunction( "maps/_zombiemode_weap_zombie_shield", "shield_bowie_watcher" ), ::fix_shield_bowie_watcher ); + replaceFunc( getFunction( "maps/walking_anim", "walk_main" ), ::fix_walk_main ); + replaceFunc( getFunction( "maps/walking_anim", "rot_main" ), ::fix_rot_main ); + replaceFunc( getFunction( "maps/walking_anim", "prone_checks" ), ::fix_prone_checks ); + replaceFunc( getFunction( "maps/sanatorium", "staminup_sprint" ), ::fix_staminup_sprint ); +} + +fix_staminup_sprint() +{ + self endon( "disconnect" ); + + func = getFunction( "maps/sanatorium", "staminup_sprint" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_walk_main() +{ + self endon( "disconnect" ); + + func = getFunction( "maps/walking_anim", "walk_main" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_prone_checks() +{ + self endon( "disconnect" ); + + func = getFunction( "maps/walking_anim", "prone_checks" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_rot_main() +{ + self endon( "disconnect" ); + + func = getFunction( "maps/walking_anim", "rot_main" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_shield_destroy_player_model() +{ + if ( !isDefined( self ) ) + return; + + temp_size = self getAttachSize(); + + if ( !isDefined( temp_size ) ) + return; + + func = getFunction( "maps/_zombiemode_weap_zombie_shield", "shield_destroy_player_model" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_get_galvaknuckles() +{ + galva_trig = getent( "galvaknuckles", "targetname" ); + + if ( !isDefined( galva_trig ) ) + return; + + func = getFunction( "maps/altmelee_mod", "get_galvaknuckles" ); + disableDetourOnce( func ); + self [[func]](); +} + +fix_shield_bowie_watcher() +{ + self endon( "disconnect" ); + + func = getFunction( "maps/_zombiemode_weap_zombie_shield", "shield_bowie_watcher" ); + disableDetourOnce( func ); + self [[func]](); +} + +noop() +{ +} diff --git a/scripts/sp/zm_spawn_fix.gsc b/scripts/sp/zm_spawn_fix.gsc new file mode 100644 index 0000000..87d62ee --- /dev/null +++ b/scripts/sp/zm_spawn_fix.gsc @@ -0,0 +1,455 @@ +#include maps\_utility; +#include common_scripts\utility; + +main() +{ + if ( GetDvarInt( "scr_disableHotJoinFixes" ) ) + return; + + level.endGameInCommonZombiemode = []; + level.endGameInCommonZombiemode["nazi_zombie_sumpf"] = true; + + if ( isDedicated() ) + { + // we are always in coop mode for dedis + is_coop = getFunction( "maps/_utility", "is_coop" ); + + if ( isDefined( is_coop ) ) + replaceFunc( is_coop, ::alwaysTrue ); + + + // make lowest player num the host + get_host = getFunction( "maps/_utility", "get_host" ); + + if ( isDefined( get_host ) ) + replaceFunc( get_host, ::getHostDedi ); + + + // no force Ending + forceEnd = getFunction( "maps/_cooplogic", "forceend" ); + + if ( isDefined( forceEnd ) ) + replaceFunc( forceEnd, ::noop ); + + + // fix this gsc thread leak in the vanilla game + ammo_dialog_timer = getFunction( "maps/_zombiemode", "ammo_dialog_timer" ); + + if ( isDefined( ammo_dialog_timer ) ) + replaceFunc( ammo_dialog_timer, ::ammo_dialog_timer_func ); + + + // add a timeout for all_players_connected + all_players_connected = getFunction( "maps/_load", "all_players_connected" ); + + if ( isDefined( all_players_connected ) ) + replaceFunc( all_players_connected, ::all_players_connected_func ); + } +} + +init() +{ + if ( GetDvarInt( "scr_disableHotJoinFixes" ) ) + return; + + // do prints, handle hotjoining and leavers + level thread onPlayerConnect(); + + // lets be the last to setup func ptrs + for ( i = 0; i < 10; i++ ) + waittillframeend; + + if ( !isDefined( level.script ) ) + level.script = Tolower( GetDvar( "mapname" ) ); + + // setup hot joining + level.oldSpawnClient = level.spawnClient; + level.spawnClient = ::spawnClientOverride; + + if ( !isDefined( level.hotJoinPlayer ) ) + level.hotJoinPlayer = ::hotJoin; + + // setup how endgame + if ( !isDefined( level.endGame ) ) + { + if ( level.script == "nazi_zombie_prototype" ) + level.endGame = ::endGamePrototype; + else if ( level.script == "nazi_zombie_asylum" ) + level.endGame = ::endGameAsylum; + else if ( isDefined( level.endGameInCommonZombiemode[level.script] ) ) + level.endGame = ::endGameCommonZombiemodeScript; + else if ( isZombieMode() ) + level.endGame = ::endGameNotify; + else + level.endGame = ::endGameSP; + } + + if ( !isDefined( level.isPlayerDead ) ) + level.isPlayerDead = ::checkIsPlayerDead; + + // make dead players into spectators + if ( isZombieMode() ) + { + level.oldOverridePlayerKilled = level.overridePlayerKilled; + level.overridePlayerKilled = ::playerKilledOverride; + + // setup this callback + zmb_spawnSpectator = GetFunction( "maps/_callbackglobal", "spawnspectator" ); + + if ( isDefined( zmb_spawnSpectator ) && level.spawnSpectator == zmb_spawnSpectator ) + { + if ( level.script == "nazi_zombie_prototype" ) + { + zmb_spawnSpectator = GetFunction( "maps/_zombiemode_prototype", "spawnspectator" ); + + if ( isDefined( zmb_spawnSpectator ) ) + level.spawnSpectator = zmb_spawnSpectator; + } + else if ( level.script == "nazi_zombie_asylum" ) + { + zmb_spawnSpectator = GetFunction( "maps/_zombiemode_asylum", "spawnspectator" ); + + if ( isDefined( zmb_spawnSpectator ) ) + level.spawnSpectator = zmb_spawnSpectator; + } + else + { + zmb_spawnSpectator = GetFunction( "maps/_zombiemode", "spawnspectator" ); + + if ( isDefined( zmb_spawnSpectator ) ) + level.spawnSpectator = zmb_spawnSpectator; + } + } + } +} + +getHostDedi() +{ + return get_players()[0]; +} + +alwaysTrue() +{ + return true; +} + +noop() +{ +} + +all_players_connected_func() +{ + timeout_started = false; + timeout_point = 0; + + while ( 1 ) + { + num_con = getnumconnectedplayers(); + num_exp = getnumexpectedplayers(); + + if ( num_con == num_exp && ( num_exp != 0 ) ) + break; + + if ( num_con > 0 ) + { + if ( !timeout_started ) + { + timeout_started = true; + timeout_point = getDvarFloat( "sv_connecttimeout" ) * 1000 + getTime(); + } + + if ( getTime() > timeout_point ) + break; + } + else + timeout_started = false; + + wait( 0.05 ); + } + + flag_set( "all_players_connected" ); + // CODER_MOD: GMJ (08/28/08): Setting dvar for use by code + SetDvar( "all_players_are_connected", "1" ); +} + +ammo_dialog_timer_func() +{ + level notify( "ammo_out" ); + + func = getFunction( "maps/_zombiemode", "ammo_dialog_timer" ); + + if ( !isDefined( func ) ) + return; + + disableDetourOnce( func ); + self [[func]](); +} + +isZombieMode() +{ + return ( isDefined( level.is_zombie_level ) && level.is_zombie_level ); +} + +endGamePrototype() +{ + func = getFunction( "maps/_zombiemode_prototype", "end_game" ); + + if ( isDefined( func ) ) + level thread [[func]](); +} + +endGameAsylum() +{ + func = getFunction( "maps/_zombiemode_asylum", "end_game" ); + + if ( isDefined( func ) ) + level thread [[func]](); +} + +endGameCommonZombiemodeScript() +{ + func = getFunction( "maps/_zombiemode", "end_game" ); + + if ( isDefined( func ) ) + level thread [[func]](); +} + +endGameNotify() +{ + level notify( "end_game" ); +} + +endGameSP() +{ + if ( get_players().size <= 0 ) + cmdexec( "map_restart" ); + else + missionfailed(); +} + +checkIsPlayerDead( player ) +{ + in_laststand_func = GetFunction( "maps/_laststand", "player_is_in_laststand" ); + + return ( player.sessionstate == "spectator" || ( isDefined( in_laststand_func ) && player [[in_laststand_func]]() ) || ( isDefined( player.is_zombie ) && player.is_zombie ) ); +} + +playerKilledOverride() +{ + self [[level.player_becomes_zombie]](); + checkForAllDead( self ); + self [[level.oldOverridePlayerKilled]](); +} + +spawnClientOverride() +{ + if ( flag( "all_players_spawned" ) ) + self thread [[level.hotJoinPlayer]](); + else + self thread [[level.oldSpawnClient]](); +} + +getHotJoinPlayer() +{ + players = get_players(); + + for ( i = 0; i < players.size; i++ ) + { + player = players[i]; + + if ( !isDefined( player ) || !isDefined( player.sessionstate ) ) + continue; + + if ( player == self ) + continue; + + if ( player.sessionstate == "spectator" ) + continue; + + if ( isDefined( player.is_zombie ) && player.is_zombie ) + continue; + + return player; + } + + return undefined; +} + +getHotJoinAi( team ) +{ + ais = GetAiArray( team ); + ai = undefined; + + if ( ais.size ) + ai = ais[randomint( ais.size )]; + + return ai; +} + +getHotJoinInitSpawn() +{ + structs = getstructarray( "initial_spawn_points", "targetname" ); + players = get_players(); + i = 0; + + for ( i = 0; i < players.size; i++ ) + { + if ( !isDefined( players[i] ) ) + continue; + + if ( self == players[i] ) + break; + } + + spawn_obj = structs[i]; + + if ( !isDefined( spawn_obj ) ) + spawn_obj = structs[0]; + + return spawn_obj; +} + +hotJoin() +{ + self endon( "disconnect" ); + self endon( "end_respawn" ); + + // quik hax: prevent spectators_respawn from spawning us + self.sessionstate = "playing"; + waittillframeend; + self.sessionstate = "spectator"; + + player = self getHotJoinPlayer(); + ally = self getHotJoinAi( "allies" ); + enemy = self getHotJoinAi( "axis" ); + spawn_pt = self getHotJoinInitSpawn(); + + spawn_obj = spawnStruct(); + + if ( isDefined( spawn_pt ) ) + { + spawn_obj = spawn_pt; + } + else if ( isDefined( player ) ) + { + spawn_obj.origin = player getOrigin(); + spawn_obj.angles = player.angles; + } + else if ( isDefined( ally ) ) + { + spawn_obj.origin = ally getOrigin(); + spawn_obj.angles = ally.angles; + } + else if ( isDefined( enemy ) ) + { + spawn_obj.origin = enemy getOrigin(); + spawn_obj.angles = enemy.angles; + } + else + { + spawn_obj.origin = ( 0, 0, 0 ); + spawn_obj.angles = ( 0, 0, 0 ); + } + + // check if custom logic for hotjoining + if ( isDefined( level.customHotJoinPlayer ) ) + { + temp_obj = self [[level.customHotJoinPlayer]]( spawn_obj ); + + // check if theres a spawn obj + if ( isDefined( temp_obj ) ) + { + // check if we should cancel spawning this player (maybe its already done) + if ( isDefined( temp_obj.cancel ) && temp_obj.cancel ) + return; + + // set our spawn location + spawn_obj = temp_obj; + } + } + + // set spawn params + self setorigin( spawn_obj.origin ); + self setplayerangles( spawn_obj.angles ); + self.spectator_respawn = spawn_obj; + self.respawn_point = spawn_obj; + + // do the spawn + println( "*************************Client hotjoin***" ); + + self unlink(); + + if ( isdefined( self.spectate_cam ) ) + self.spectate_cam delete (); + + if ( ( !isZombieMode() && !level.otherPlayersSpectate && ( !isDefined( spawn_obj.force_spectator ) || !spawn_obj.force_spectator ) ) || + ( isDefined( spawn_obj.force_spawn ) && spawn_obj.force_spawn ) ) + self thread [[level.spawnPlayer]](); + else + { + self thread [[level.spawnSpectator]](); + checkForAllDead( self ); + } +} + +onDisconnect() +{ + lpselfnum = self getentitynumber(); + lpguid = self getguid(); + name = self.playername; + + self waittill( "disconnect" ); + + logprint( "Q;" + lpguid + ";" + lpselfnum + ";" + name + "\n" ); + + // check if we need to end the game cause last person left alive left the game + checkForAllDead( self ); +} + +onConnect() +{ + self endon( "disconnect" ); + + logprint( "J;" + self getguid() + ";" + self getentitynumber() + ";" + self.playername + "\n" ); +} + +onPlayerConnect() +{ + for ( ;; ) + { + level waittill( "connected", player ); + + iprintln( player.playername + " connected." ); + + player thread onDisconnect(); + player thread onConnect(); + } +} + +checkForAllDead( excluded_player ) +{ + players = get_players(); + count = 0; + + for ( i = 0; i < players.size; i++ ) + { + player = players[ i ]; + + if ( !isDefined( player ) || !isDefined( player.sessionstate ) ) + continue; + + if ( isDefined( excluded_player ) && excluded_player == player ) + continue; + + if ( [[level.isPlayerDead]]( player ) ) + continue; + + count++; + } + + if ( count == 0 ) + { + PrintConsole( "Ending game as no players are left alive..." ); + level thread [[level.endGame]](); + } +}