[ZM][RELEASE] Moon Spawn Cancel fix
BO1 Modding Releases & Resources
1
Posts
1
Posters
130
Views
1
Watching
-
Special thanks to TTS4life's video and 5and5's comment
I replaced the RotateTo to ForceTeleport as 5and5 suggested in the video's comments, I also called the
zombie_faller_death_wait() Method again in the method to ensure we always check for deaths correctly.
Also created a custom watcher that makes sure to enable the spawn again, as I was unable to make the spawns work correctly by replacing the moveTo with a ForceTeleport.
How I tested it:
I went in a solo game and spammed the raygun and wavegun at the ceiling spawn, I never managed to cancel the spawn. Removed the patch to be sure, and I was indeed able to cancel the spawn without the patch.
#include maps\_utility; #include common_scripts\utility; #include maps\_zombiemode_utility; main() { if ( GetDvar( #"zombiemode" ) == "1" ) { level thread onPlayerConnect(); replacefunc(maps\_zombiemode_ai_faller::do_zombie_fall, ::custom_do_zombie_fall); } } custom_do_zombie_fall() { self endon("death"); self thread maps\_zombiemode_ai_faller::setup_deathfunc(); // don't drop powerups until we are on the ground self.no_powerups = true; self.in_the_ceiling = true; self.anchor = spawn("script_origin", self.origin); self.anchor.angles = self.angles; self linkto(self.anchor); if ( !IsDefined( self.zone_name ) ) { self.zone_name = self get_current_zone(); } spots = maps\_zombiemode_ai_faller::get_available_fall_locations(); if( spots.size < 1 ) { self unlink(); self.anchor delete(); //IPrintLnBold("deleting zombie faller - no available fall locations"); //can't delete if we're in the middle of spawning, so wait a frame self Hide();//hide so we're not visible for one frame while waiting to delete self delayThread( 0.1, maps\_zombiemode_ai_faller::zombie_faller_delete ); return; } else if ( GetDvarInt(#"zombie_fall_test") ) { // use the spot closest to the first player always player = GetPlayers()[0]; spot = undefined; bestDist = 0.0; for ( i = 0; i < spots.size; i++ ) { checkDist = DistanceSquared(spots[i].origin, player.origin); if ( !IsDefined(spot) || checkDist < bestDist ) { spot = spots[i]; bestDist = checkDist; } } } else { spot = random(spots); } self.zombie_faller_location = spot; //NOTE: multiple zombie fallers could be waiting in the same spot now, need to have spawners detect this // and not use the spot again until the previous zombie has died or dropped down self.zombie_faller_location.is_enabled = false; self thread maps\_zombiemode_ai_faller::zombie_faller_death_wait(); self.zombie_faller_location maps\_zombiemode_ai_faller::parse_script_parameters(); // Start a monitor that will ensure the spot gets re-enabled if this zombie dies early or gets stuck. // This is defensive: it will re-enable on death or after a timeout. self thread zombie_faller_spot_monitor(self, spot); if( !isDefined( spot.angles ) ) { spot.angles = (0, 0, 0); } //Patch begin anim_org = spot.origin; anim_ang = spot.angles; self Hide(); self.anchor moveto(anim_org, .05); self.anchor waittill("movedone"); // face goal target_org = maps\_zombiemode_spawner::get_desired_origin(); if (IsDefined(target_org)) { anim_ang = VectorToAngles(target_org - self.origin); current_pos = self.anchor.origin; // Instantly rotate the anchor instead of waiting for RotateTo self.anchor ForceTeleport(current_pos, (0, anim_ang[1], 0), false, false); } self unlink(); self.anchor delete(); self thread maps\_zombiemode_ai_faller::hide_pop(); // hack to hide the pop when the zombie gets to the start position before the anim starts level thread maps\_zombiemode_ai_faller::zombie_fall_death(self, spot); spot thread maps\_zombiemode_ai_faller::zombie_fall_fx(self); self thread maps\_zombiemode_ai_faller::zombie_faller_death_wait(); //need to thread off the rest because we're apparently still in the middle of our init! self thread maps\_zombiemode_ai_faller::zombie_faller_do_fall(); } zombie_faller_spot_monitor(zombie, spot) { // sanity if ( !IsDefined(spot) ) return; // If the zombie dies cleanly, we re-enable the spot immediately. zombie waittill("death"); // At this point the zombie is dead (or the entity has been freed). if ( IsDefined(spot) ) { spot.is_enabled = true; } // Safety: also ensure we don't leave the spot disabled in pathological cases. wait(0.25); if ( IsDefined(spot) ) spot.is_enabled = true; } onPlayerConnect() { for(;;) { level waittill ("connecting", player); player thread onPlayerSpawned(); } } onPlayerSpawned() { for(;;) { self waittill("spawned_player"); self SetClientDvars( "player_backSpeedScale", "1", "player_strafeSpeedScale", "1"); self iPrintLn("Spawn cancel fix by AlexInZombies"); } }