From 171d2c3c04d08daee8c0b5f15ccf4cc032a122d9 Mon Sep 17 00:00:00 2001 From: Jbleezy Date: Sun, 2 Apr 2023 08:11:50 -0700 Subject: [PATCH] Buried: change Arthur to buyable trap --- README.md | 2 +- scripts/zm/_zm_reimagined.gsc | 3 + scripts/zm/replaced/_zm_ai_sloth.gsc | 314 ++++++++++++++++++ scripts/zm/replaced/zm_buried_buildables.gsc | 31 ++ scripts/zm/zm_buried/zm_buried_reimagined.gsc | 100 ++++++ 5 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 scripts/zm/replaced/_zm_ai_sloth.gsc create mode 100644 scripts/zm/replaced/zm_buried_buildables.gsc diff --git a/README.md b/README.md index 62bc4ebd..4dfe9b70 100644 --- a/README.md +++ b/README.md @@ -550,7 +550,7 @@ * Power automatically on * Removed Turbine * Arthur barricades are buyable debris -* Arthur can no longer be unlocked +* Arthur can be purchased as a trap that runs around and kills zombies for 30 seconds * Ghosts no longer spawn a free perk powerup if any player gets damaged by the ghosts * Fountain portal automatically active * Navcard table automatically crafted diff --git a/scripts/zm/_zm_reimagined.gsc b/scripts/zm/_zm_reimagined.gsc index 611fc934..e7da2584 100644 --- a/scripts/zm/_zm_reimagined.gsc +++ b/scripts/zm/_zm_reimagined.gsc @@ -2564,6 +2564,9 @@ buildbuildables() level.buildables_available = array("subwoofer_zm", "springpad_zm", "headchopper_zm"); removebuildable( "keys_zm" ); + removebuildable( "booze" ); + removebuildable( "candy" ); + removebuildable( "sloth" ); buildbuildable( "turbine" ); buildbuildable( "subwoofer_zm" ); buildbuildable( "springpad_zm" ); diff --git a/scripts/zm/replaced/_zm_ai_sloth.gsc b/scripts/zm/replaced/_zm_ai_sloth.gsc new file mode 100644 index 00000000..ba3d3762 --- /dev/null +++ b/scripts/zm/replaced/_zm_ai_sloth.gsc @@ -0,0 +1,314 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\animscripts\zm_utility; +#include maps\mp\zombies\_zm_ai_sloth_buildables; +#include maps\mp\zombies\_zm_ai_sloth_crawler; +#include maps\mp\zombies\_zm_ai_sloth_magicbox; +#include maps\mp\zombies\_zm_ai_sloth_utility; +#include maps\mp\zombies\_zm_ai_sloth_ffotd; +#include maps\mp\zombies\_zm_ai_sloth; +#include maps\mp\zombies\_zm_zonemgr; +#include maps\mp\zombies\_zm_equipment; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_equip_headchopper; +#include maps\mp\zombies\_zm_spawner; +#include maps\mp\animscripts\zm_shared; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\animscripts\zm_death; +#include maps\mp\animscripts\zm_run; +#include maps\mp\zombies\_zm_powerups; +#include maps\mp\zombies\_zm_weap_slowgun; +#include maps\mp\zombies\_zm_weap_time_bomb; + +sloth_init_start_funcs() +{ + self.start_funcs = []; + self.start_funcs["jail_idle"] = ::start_jail_idle; + self.start_funcs["jail_cower"] = ::start_jail_cower; + self.start_funcs["jail_open"] = ::start_jail_open; + self.start_funcs["jail_run"] = ::start_jail_run; + self.start_funcs["jail_wait"] = ::start_jail_wait; + self.start_funcs["jail_close"] = ::start_jail_close; + self.start_funcs["player_idle"] = ::start_player_idle; + self.start_funcs["roam"] = ::start_roam; + self.start_funcs["follow"] = ::start_follow; + self.start_funcs["mansion"] = ::start_mansion; + self.start_funcs["berserk"] = ::start_berserk; + self.start_funcs["eat"] = ::start_eat; + self.start_funcs["crash"] = ::start_crash; + self.start_funcs["gunshop_run"] = ::start_gunshop_run; + self.start_funcs["gunshop_candy"] = ::start_gunshop_candy; + self.start_funcs["table_eat"] = ::start_table_eat; + self.start_funcs["headbang"] = ::start_headbang; + self.start_funcs["smell"] = ::start_smell; + self.start_funcs["context"] = ::start_context; +} + +sloth_init_update_funcs() +{ + self.update_funcs = []; + self.update_funcs["jail_idle"] = ::update_jail_idle; + self.update_funcs["jail_cower"] = ::update_jail_cower; + self.update_funcs["jail_open"] = ::update_jail_open; + self.update_funcs["jail_run"] = ::update_jail_run; + self.update_funcs["jail_wait"] = ::update_jail_wait; + self.update_funcs["jail_close"] = ::update_jail_close; + self.update_funcs["player_idle"] = ::update_player_idle; + self.update_funcs["roam"] = ::update_roam; + self.update_funcs["follow"] = ::update_follow; + self.update_funcs["mansion"] = ::update_mansion; + self.update_funcs["berserk"] = ::update_berserk; + self.update_funcs["eat"] = ::update_eat; + self.update_funcs["crash"] = ::update_crash; + self.update_funcs["gunshop_run"] = ::update_gunshop_run; + self.update_funcs["gunshop_candy"] = ::update_gunshop_candy; + self.update_funcs["table_eat"] = ::update_table_eat; + self.update_funcs["headbang"] = ::update_headbang; + self.update_funcs["smell"] = ::update_smell; + self.update_funcs["context"] = ::update_context; + self.locomotion_func = ::update_locomotion; +} + +start_jail_run( do_pain ) +{ + if ( self is_jail_state() ) + return false; + + if ( self.state == "berserk" || self.state == "crash" ) + return false; + + if ( self sloth_is_traversing() ) + return false; + + if ( self.state == "gunshop_candy" || self.state == "table_eat" ) + { + if ( isdefined( self.bench ) ) + { + if ( isdefined( level.weapon_bench_reset ) ) + self.bench [[ level.weapon_bench_reset ]](); + } + } + + self stop_action(); + self thread sndchangebreathingstate( "happy" ); + self thread action_jail_run( self.jail_start.origin, do_pain ); + + if ( self.state == "context" ) + { + if ( isdefined( self.context.interrupt ) ) + self [[ self.context.interrupt ]](); + } + + self sloth_init_roam_point(); + thread maps\mp\zombies\_zm_unitrigger::unregister_unitrigger( self.gift_trigger ); + return true; +} + +action_jail_run( pos, do_pain ) +{ + self.needs_action = 0; + + if ( isdefined( self.candy_model ) ) + self.candy_model ghost(); + + if ( isdefined( self.booze_model ) ) + self.booze_model ghost(); + + if ( is_true( do_pain ) ) + { + if ( !self sloth_is_traversing() && !is_true( self.is_pain ) ) + { + self.is_pain = 1; + self setanimstatefromasd( "zm_pain" ); + self.reset_asd = "zm_pain"; + self thread finish_pain(); + maps\mp\animscripts\zm_shared::donotetracks( "pain_anim" ); + self notify( "pain_done" ); + self.is_pain = 0; + } + } + + while ( true ) + { + if ( !self sloth_is_pain() ) + break; + + wait 0.1; + } + + self.reset_asd = undefined; + self animmode( "normal" ); + self set_zombie_run_cycle( "run" ); + self.locomotion = "run"; + self thread sloth_retreat_vo(); + self check_behind_mansion(); + + if ( isdefined( self.mansion_goal ) ) + { + self setgoalpos( self.mansion_goal.origin ); + + self waittill( "goal" ); + + self action_teleport_to_courtyard(); + } + + self.goalradius = 2; + + self setgoalpos( self.jail_start.origin + (0, 128, 0) ); + + self waittill( "goal" ); + + self.goalradius = 16; + + self orientmode( "face angle", self.jail_start.angles[1] ); + + wait 0.5; + + self.needs_action = 1; +} + +start_jail_wait() +{ + self stopanimscripted(); + self action_jail_wait(); + self thread sndchangebreathingstate( "happy" ); + return 1; +} + +action_jail_wait() +{ + self.needs_action = 0; + self setgoalpos( self.origin ); + self.anchor.origin = self.origin; + self.anchor.angles = self.angles; + self linkto( self.anchor ); + self setanimstatefromasd( "zm_idle_protect" ); + self.needs_action = 1; +} + +update_jail_idle() +{ + if ( is_true( self.open_jail ) ) + { + level notify( "cell_open" ); + self.open_jail = 0; + } + + if ( is_true( level.cell_open ) ) + { + self stop_action(); + self sloth_set_state( "jail_idle" ); + } +} + +update_jail_wait() +{ + if (is_true(self.dance_action)) + { + return; + } + + players = get_players(); + + foreach ( player in players ) + { + if ( player maps\mp\zombies\_zm_zonemgr::entity_in_zone( "zone_underground_jail" ) ) + { + return; + } + } + + if ( self.needs_action ) + self sloth_set_state( "jail_close" ); +} + +update_eat() +{ + if ( is_true( self.needs_action ) ) + { + self setclientfield( "sloth_eating", 0 ); + + if ( isdefined( self.candy_model ) ) + self.candy_model ghost(); + + context = self check_contextual_actions(); + + if ( isdefined( context ) ) + { + self sloth_set_state( "context", context ); + return; + } + + self sloth_set_state( "roam" ); + } +} + +sloth_check_ragdolls( ignore_zombie ) +{ + non_ragdoll = 0; + zombies = getaispeciesarray( level.zombie_team, "all" ); + + for ( i = 0; i < zombies.size; i++ ) + { + zombie = zombies[i]; + + if ( is_true( zombie.is_sloth ) ) + continue; + + if ( isdefined( ignore_zombie ) && zombie == ignore_zombie ) + continue; + + if ( isdefined( self.crawler ) && zombie == self.crawler ) + continue; + + if ( self is_facing( zombie ) ) + { + dist = distancesquared( self.origin, zombie.origin ); + + if ( dist < 4096 ) + { + if ( !self sloth_ragdoll_zombie( zombie ) ) + { + if ( !is_true( self.no_gib ) && non_ragdoll % 3 == 0 ) + { + zombie.force_gib = 1; + zombie.a.gib_ref = random( array( "guts", "right_arm", "left_arm", "head" ) ); + zombie thread maps\mp\animscripts\zm_death::do_gib(); + } + + non_ragdoll++; + zombie dodamage( zombie.health * 10, zombie.origin ); + zombie playsound( "zmb_ai_sloth_attack_impact" ); + zombie.noragdoll = 1; + zombie.nodeathragdoll = 1; + } + + if ( isdefined( self.target_zombie ) && self.target_zombie == zombie ) + self.target_zombie = undefined; + } + } + } +} + +sloth_ragdoll_zombie( zombie ) +{ + if ( !isdefined( self.ragdolls ) ) + self.ragdolls = 0; + + if ( self.ragdolls < 4 ) + { + self.ragdolls++; + zombie dodamage( zombie.health * 10, zombie.origin ); + zombie playsound( "zmb_ai_sloth_attack_impact" ); + zombie startragdoll(); + zombie setclientfield( "sloth_ragdoll_zombie", 1 ); + self thread sloth_ragdoll_wait(); + return true; + } + + return false; +} \ No newline at end of file diff --git a/scripts/zm/replaced/zm_buried_buildables.gsc b/scripts/zm/replaced/zm_buried_buildables.gsc new file mode 100644 index 00000000..df85ee61 --- /dev/null +++ b/scripts/zm/replaced/zm_buried_buildables.gsc @@ -0,0 +1,31 @@ +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\zombies\_zm_buildables; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\zombies\_zm_weapons; +#include maps\mp\zombies\_zm_magicbox; +#include maps\mp\zombies\_zm_sidequests; +#include maps\mp\zombies\_zm_buildables_pooled; +#include maps\mp\zombies\_zm_score; +#include maps\mp\zombies\_zm_stats; +#include maps\mp\zombies\_zm_audio; +#include maps\mp\zombies\_zm_melee_weapon; +#include maps\mp\zombies\_zm_weap_claymore; +#include maps\mp\zombies\_zm_unitrigger; +#include maps\mp\zm_buried_buildables; + +watch_cell_open_close( door ) +{ + level.cell_open = 0; + + while ( true ) + { + level waittill( "cell_open" ); + + level.cell_open = 1; + + level waittill( "cell_close" ); + + level.cell_open = 0; + } +} \ No newline at end of file diff --git a/scripts/zm/zm_buried/zm_buried_reimagined.gsc b/scripts/zm/zm_buried/zm_buried_reimagined.gsc index 9cf2d5da..ff98ec8c 100644 --- a/scripts/zm/zm_buried/zm_buried_reimagined.gsc +++ b/scripts/zm/zm_buried/zm_buried_reimagined.gsc @@ -2,9 +2,11 @@ #include common_scripts\utility; #include maps\mp\zombies\_zm_utility; +#include scripts\zm\replaced\zm_buried_buildables; #include scripts\zm\replaced\zm_buried_gamemodes; #include scripts\zm\replaced\zm_buried_ffotd; #include scripts\zm\replaced\zm_buried_fountain; +#include scripts\zm\replaced\_zm_ai_sloth; #include scripts\zm\replaced\_zm_buildables_pooled; #include scripts\zm\replaced\_zm_equip_subwoofer; #include scripts\zm\replaced\_zm_equip_springpad; @@ -18,10 +20,15 @@ main() { replaceFunc(maps\mp\zm_buried_sq::navcomputer_waitfor_navcard, scripts\zm\replaced\_zm_sq::navcomputer_waitfor_navcard); + replaceFunc(maps\mp\zm_buried_buildables::watch_cell_open_close, scripts\zm\replaced\zm_buried_buildables::watch_cell_open_close); replaceFunc(maps\mp\zm_buried_gamemodes::init, scripts\zm\replaced\zm_buried_gamemodes::init); replaceFunc(maps\mp\zm_buried_gamemodes::buildbuildable, scripts\zm\replaced\zm_buried_gamemodes::buildbuildable); replaceFunc(maps\mp\zm_buried_ffotd::spawned_life_triggers, scripts\zm\replaced\zm_buried_ffotd::spawned_life_triggers); replaceFunc(maps\mp\zm_buried_fountain::transport_player_to_start_zone, scripts\zm\replaced\zm_buried_fountain::transport_player_to_start_zone); + replaceFunc(maps\mp\zombies\_zm_ai_sloth::sloth_init_start_funcs, scripts\zm\replaced\_zm_ai_sloth::sloth_init_start_funcs); + replaceFunc(maps\mp\zombies\_zm_ai_sloth::sloth_init_update_funcs, scripts\zm\replaced\_zm_ai_sloth::sloth_init_update_funcs); + replaceFunc(maps\mp\zombies\_zm_ai_sloth::sloth_check_ragdolls, scripts\zm\replaced\_zm_ai_sloth::sloth_check_ragdolls); + replaceFunc(maps\mp\zombies\_zm_ai_sloth::sloth_ragdoll_zombie, scripts\zm\replaced\_zm_ai_sloth::sloth_ragdoll_zombie); replaceFunc(maps\mp\zombies\_zm_buildables_pooled::add_buildable_to_pool, scripts\zm\replaced\_zm_buildables_pooled::add_buildable_to_pool); replaceFunc(maps\mp\zombies\_zm_buildables_pooled::randomize_pooled_buildables, scripts\zm\replaced\_zm_buildables_pooled::randomize_pooled_buildables); replaceFunc(maps\mp\zombies\_zm_equip_subwoofer::startsubwooferdecay, scripts\zm\replaced\_zm_equip_subwoofer::startsubwooferdecay); @@ -60,6 +67,7 @@ init() level thread update_buildable_stubs(); level thread enable_fountain_transport(); level thread disable_ghost_free_perk_on_damage(); + level thread sloth_trap(); } zombie_init_done() @@ -306,4 +314,96 @@ add_jug_collision() collision = spawn( "script_model", origin + anglesToUp(angles) * 64 ); collision.angles = angles; collision setmodel( "collision_wall_128x128x10_standard" ); +} + +sloth_trap() +{ + trig = spawn( "trigger_box_use", level.cell_door.origin, 0, 64, 64, 64 ); + trig.cost = 1000; + trig setcursorhint( "HINT_NOICON" ); + level.sloth_trap_trig = trig; + + flag_wait( "initial_blackscreen_passed" ); + + level.sloth.actor_damage_func = ::sloth_damage_func; + + level.candy_context = []; + maps\mp\zombies\_zm_ai_sloth::register_candy_context( "protect", 100, maps\mp\zombies\_zm_ai_sloth::protect_condition, maps\mp\zombies\_zm_ai_sloth::protect_start, maps\mp\zombies\_zm_ai_sloth::protect_update, maps\mp\zombies\_zm_ai_sloth::protect_action ); + + while (1) + { + trig sethintstring( &"ZM_BURIED_CANDY_GV", " [Cost: " + trig.cost + "]" ); + + trig waittill( "trigger", who ); + + if ( !is_player_valid( who ) ) + { + continue; + } + + if ( who.score < trig.cost ) + { + play_sound_at_pos( "no_purchase", trig.origin ); + who maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "door_deny" ); + continue; + } + + trig sethintstring( "" ); + + who maps\mp\zombies\_zm_score::minus_to_player_score( trig.cost ); + play_sound_at_pos( "purchase", trig.origin ); + + who maps\mp\zombies\_zm_stats::increment_client_stat( "buried_sloth_candy_protect", 0 ); + who maps\mp\zombies\_zm_stats::increment_player_stat( "buried_sloth_candy_protect" ); + who thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "sloth_generic_feed" ); + + who maps\mp\zm_buried_buildables::onuseplantobject_key( who ); + + level.sloth maps\mp\zombies\_zm_ai_sloth::sloth_set_state( "eat", who ); + + wait 30; + + level.sloth maps\mp\zombies\_zm_ai_sloth::sloth_set_state( "jail_run", 0 ); + + while (level.sloth.state == "jail_run") + { + wait 0.05; + } + + level.sloth notify( "stop_action" ); + level.sloth dance_action(); + + level.sloth maps\mp\zombies\_zm_ai_sloth::sloth_set_state( "jail_wait" ); + } +} + +sloth_damage_func() +{ + return 0; +} + +dance_action() +{ + self endon( "death" ); + self endon( "stop_action" ); + self setclientfield( "sloth_vomit", 0 ); + self.dance_end = gettime() + 30000; + level.sloth_protect = 0; + self.dance_action = 1; + + while ( true ) + { + if ( gettime() >= self.dance_end ) + break; + + self animscripted( self.origin, self.jail_start.angles, "zm_dance" ); + maps\mp\animscripts\zm_shared::donotetracks( "dance_anim", maps\mp\zombies\_zm_ai_sloth::vomit_notetrack ); + wait 0.1; + } + + self notify( "stop_dance" ); + self animscripted( self.origin, self.jail_start.angles, "zm_vomit" ); + maps\mp\animscripts\zm_shared::donotetracks( "vomit_anim", maps\mp\zombies\_zm_ai_sloth::vomit_notetrack ); + self.context_done = 1; + self.dance_action = 0; } \ No newline at end of file