diff --git a/README.md b/README.md index 89f91f2f..d6303953 100644 --- a/README.md +++ b/README.md @@ -423,6 +423,7 @@ ### Tranzit * Any door that requires a Turbine to open is automatically open whenever the power is on +* Increased bus speed by 100% * Players can sprint and go prone on the bus * Lava in starting area activates after the power is on * Lava destroys grenades instantly diff --git a/scripts/zm/replaced/zm_transit_bus.gsc b/scripts/zm/replaced/zm_transit_bus.gsc index 67de88f3..56c3d022 100644 --- a/scripts/zm/replaced/zm_transit_bus.gsc +++ b/scripts/zm/replaced/zm_transit_bus.gsc @@ -21,6 +21,426 @@ #include maps\mp\zombies\_zm_audio; #include maps\mp\zm_transit_bus; +#using_animtree("zombie_bus"); + +bussetup() +{ + flag_init( "ladder_attached" ); + flag_init( "catcher_attached" ); + flag_init( "hatch_attached" ); + self.immediatespeed = 0; + self.currentspeed = 0; + self.targetspeed = 0; + self.ismoving = 0; + self.isstopping = 0; + self.gas = 100; + self.accel = 20; + self.decel = 60; + self.radius = 88; + self.height = 240; + self.frontdist = 340; + self.backdist = 55; + self.floor = 36; + self.frontlocal = ( self.frontdist - self.radius / 2.0, 0, 0 ); + self.backlocal = ( self.backdist * -1 + self.radius / 2.0, 0, 0 ); + self.drivepath = 0; + self.zone = "zone_pri"; + self.roadzone = self.zone; + self.zombiesinside = 0; + self.zombiesatwindow = 0; + self.zombiesonroof = 0; + self.numplayers = 0; + self.numplayerson = 0; + self.numplayersonroof = 0; + self.numplayersinsidebus = 0; + self.numplayersnear = 0; + self.numaliveplayersridingbus = 0; + self.numflattires = 0; + self.doorsclosed = 1; + self.doorsdisabledfortime = 0; + self.stalled = 0; + self.issafe = 1; + self.waittimeatdestination = 0; + self.gracetimeatdestination = 10; + self.path_blocking = 0; + self.chase_pos = self.origin; + self.chase_pos_time = 0; + self.istouchingignorewindowsvolume = 0; + level.zm_mantle_over_40_move_speed_override = ::zm_mantle_over_40_move_speed_override; + self setmovingplatformenabled( 1 ); + self.supportsanimscripted = 1; + self setvehmaxspeed( 50 ); + self useanimtree( #animtree ); + level.callbackactordamage = ::transit_actor_damage_override_wrapper; + self maps\mp\zm_transit_automaton::main(); + maps\mp\zm_transit_cling::initializecling(); + self maps\mp\zm_transit_openings::main(); + self bus_upgrades(); + self thread busplowsetup(); + self buslightssetup(); + self busdoorssetup(); + self buspathblockersetup(); + self bussetupbounds(); + self bus_roof_watch(); + self bus_set_nodes(); + self bus_set_exit_triggers(); + self thread bus_audio_setup(); + level thread init_bus_door_anims(); + level thread init_bus_props_anims(); + self thread bususeanimtree(); + self thread bususedoor( 0 ); + self thread busidledoor(); + self thread play_lava_audio(); + self thread busthink(); + self thread busopeningscene(); + busschedule(); + self thread busschedulethink(); + self thread bus_bridge_speedcontrol(); + self.door_nodes_linked = 1; + self thread bussetdoornodes( 0 ); +} + +busscheduleadd( stopname, isambush, maxwaittimebeforeleaving, busspeedleaving, gasusage ) +{ + assert( isdefined( stopname ) ); + assert( isdefined( isambush ) ); + assert( isdefined( maxwaittimebeforeleaving ) ); + assert( isdefined( busspeedleaving ) ); + destinationindex = self.destinations.size; + self.destinations[destinationindex] = spawnstruct(); + self.destinations[destinationindex].name = stopname; + self.destinations[destinationindex].isambush = isambush; + self.destinations[destinationindex].maxwaittimebeforeleaving = maxwaittimebeforeleaving; + self.destinations[destinationindex].busspeedleaving = busspeedleaving * 2; + self.destinations[destinationindex].gasusage = gasusage; +} + +busschedulethink() +{ + self endon( "death" ); + + while ( true ) + { + self waittill( "noteworthy", noteworthy, noteworthynode ); + + zoneisempty = 1; + shouldremovegas = 0; + destinationindex = level.busschedule busschedulegetdestinationindex( noteworthy ); + + if ( !isdefined( destinationindex ) || !isdefined( noteworthynode ) ) + { + continue; + } + + self.destinationindex = destinationindex; + self.waittimeatdestination = level.busschedule busschedulegetmaxwaittimebeforeleaving( self.destinationindex ); + self.currentnode = noteworthynode; + targetspeed = level.busschedule busschedulegetbusspeedleaving( self.destinationindex ); + + foreach ( zone in level.zones ) + { + if ( !isdefined( zone.volumes ) || zone.volumes.size == 0 ) + continue; + + zonename = zone.volumes[0].targetname; + + if ( self maps\mp\zombies\_zm_zonemgr::entity_in_zone( zonename ) ) + { + self.zone = zonename; + zonestocheck = []; + zonestocheck[zonestocheck.size] = zonename; + + switch ( zonename ) + { + case "zone_station_ext": + zonestocheck[zonestocheck.size] = "zone_trans_1"; + zonestocheck[zonestocheck.size] = "zone_pri"; + zonestocheck[zonestocheck.size] = "zone_pri2"; + zonestocheck[zonestocheck.size] = "zone_amb_bridge"; + zonestocheck[zonestocheck.size] = "zone_trans_2b"; + break; + case "zone_gas": + zonestocheck[zonestocheck.size] = "zone_trans_2"; + zonestocheck[zonestocheck.size] = "zone_amb_tunnel"; + zonestocheck[zonestocheck.size] = "zone_gar"; + zonestocheck[zonestocheck.size] = "zone_trans_diner"; + zonestocheck[zonestocheck.size] = "zone_trans_diner2"; + zonestocheck[zonestocheck.size] = "zone_diner_roof"; + zonestocheck[zonestocheck.size] = "zone_din"; + zonestocheck[zonestocheck.size] = "zone_roadside_west"; + zonestocheck[zonestocheck.size] = "zone_roadside_east"; + zonestocheck[zonestocheck.size] = "zone_trans_3"; + break; + case "zone_far": + zonestocheck[zonestocheck.size] = "zone_amb_forest"; + zonestocheck[zonestocheck.size] = "zone_far_ext"; + zonestocheck[zonestocheck.size] = "zone_farm_house"; + zonestocheck[zonestocheck.size] = "zone_brn"; + zonestocheck[zonestocheck.size] = "zone_trans_5"; + zonestocheck[zonestocheck.size] = "zone_trans_6"; + break; + case "zone_pow": + zonestocheck[zonestocheck.size] = "zone_trans_6"; + zonestocheck[zonestocheck.size] = "zone_amb_cornfield"; + zonestocheck[zonestocheck.size] = "zone_trans_7"; + zonestocheck[zonestocheck.size] = "zone_pow_ext1"; + zonestocheck[zonestocheck.size] = "zone_prr"; + zonestocheck[zonestocheck.size] = "zone_pcr"; + zonestocheck[zonestocheck.size] = "zone_pow_warehouse"; + break; + case "zone_town_north": + zonestocheck[zonestocheck.size] = "zone_trans_8"; + zonestocheck[zonestocheck.size] = "zone_amb_power2town"; + zonestocheck[zonestocheck.size] = "zone_tbu"; + zonestocheck[zonestocheck.size] = "zone_town_church"; + zonestocheck[zonestocheck.size] = "zone_bar"; + zonestocheck[zonestocheck.size] = "zone_town_east"; + zonestocheck[zonestocheck.size] = "zone_tow"; + zonestocheck[zonestocheck.size] = "zone_ban"; + zonestocheck[zonestocheck.size] = "zone_ban_vault"; + zonestocheck[zonestocheck.size] = "zone_town_west"; + zonestocheck[zonestocheck.size] = "zone_town_west2"; + zonestocheck[zonestocheck.size] = "zone_town_barber"; + zonestocheck[zonestocheck.size] = "zone_town_south"; + zonestocheck[zonestocheck.size] = "zone_trans_9"; + break; + } + + foreach ( zone in zonestocheck ) + { + if ( !( isdefined( zoneisempty ) && zoneisempty ) ) + continue; + + if ( maps\mp\zombies\_zm_zonemgr::player_in_zone( zone ) ) + { + zoneisempty = 0; + } + } + + if ( isdefined( zoneisempty ) && zoneisempty ) + { + continue; + } + } + } + + if ( isdefined( shouldremovegas ) && shouldremovegas ) + self busgasremove( level.busschedule busschedulegetbusgasusage( self.destinationindex ) ); + + if ( isdefined( zoneisempty ) && zoneisempty ) + { + self busstartmoving( targetspeed ); + continue; + } + + if ( isdefined( self.skip_next_destination ) && self.skip_next_destination ) + { + self notify( "skipping_destination" ); + self busstartmoving( targetspeed ); + continue; + } + + if ( level.busschedule busschedulegetisambushstop( self.destinationindex ) ) + { + if ( maps\mp\zm_transit_ambush::shouldstartambushround() && self.numplayersinsidebus != 0 ) + { + self busstopmoving( 1 ); + level.nml_zone_name = "zone_amb_" + noteworthy; + thread maps\mp\zm_transit_ambush::ambushstartround(); + thread automatonspeak( "inform", "out_of_gas" ); + flag_waitopen( "ambush_round" ); + shouldremovegas = 1; + thread automatonspeak( "inform", "refueled_gas" ); + } + else + { + continue; + } + } + else + { + self notify( "reached_destination" ); + shouldremovegas = 1; + thread do_automaton_arrival_vox( noteworthy ); + + if ( noteworthy == "diner" || noteworthy == "town" || noteworthy == "power" ) + { + self busstopmoving( 1 ); + + if ( noteworthy == "diner" ) + self bussetdineropenings( 0 ); + else if ( noteworthy == "power" ) + self bussetpoweropenings( 0 ); + else if ( noteworthy == "town" ) + self bussettownopenings( 0 ); + } + else + self busstopmoving(); + + self thread busscheduledepartearly(); + } + + waittimeatdestination = self.waittimeatdestination; + + self waittill_any_timeout( waittimeatdestination, "depart_early" ); + + self notify( "ready_to_depart" ); + self thread buslightsflash(); + self thread buslightsignal( "turn_signal_left" ); + thread automatonspeak( "inform", "leaving_warning" ); + self thread play_bus_audio( "grace" ); + wait( self.gracetimeatdestination ); + thread automatonspeak( "inform", "leaving" ); + self.accel = 2; + self busstartmoving( targetspeed ); + self notify( "departing" ); + self setclientfield( "bus_flashing_lights", 0 ); + } +} + +bus_bridge_speedcontrol() +{ + while ( true ) + { + self waittill( "reached_node", nextpoint ); + + if ( isdefined( nextpoint.script_string ) ) + { + if (nextpoint.script_string == "map_out_tunnel" || nextpoint.script_string == "map_out_1forest" || nextpoint.script_string == "map_out_corn" || nextpoint.script_string == "map_out_2forest" || nextpoint.script_string == "map_out_bridge") + { + self setspeed( self.targetspeed / 2, 10, 10 ); + } + } + + if ( isdefined( nextpoint.script_string ) ) + { + if ( nextpoint.script_string == "arrival_slowdown" ) + self thread start_stopping_bus(); + + if ( nextpoint.script_string == "arrival_slowdown_fast" ) + self thread start_stopping_bus( 1 ); + } + + if ( isdefined( nextpoint.script_noteworthy ) ) + { + if ( nextpoint.script_noteworthy == "slow_down" ) + { + self.targetspeed = 20; + + if ( isdefined( nextpoint.script_float ) ) + { + self.targetspeed = nextpoint.script_float * 2; + } + + self setspeed( self.targetspeed, 160, 10 ); + } + else if ( nextpoint.script_noteworthy == "turn_signal_left" || nextpoint.script_noteworthy == "turn_signal_right" ) + self thread buslightsignal( nextpoint.script_noteworthy ); + else if ( nextpoint.script_noteworthy == "resume_speed" ) + { + self.targetspeed = 24; + + if ( isdefined( nextpoint.script_float ) ) + { + self.targetspeed = nextpoint.script_float * 2; + } + + self setspeed( self.targetspeed, 120, 120 ); + } + else if ( nextpoint.script_noteworthy == "emp_stop_point" ) + self notify( "reached_emp_stop_point" ); + else if ( nextpoint.script_noteworthy == "start_lava" ) + playfxontag( level._effect["bus_lava_driving"], self, "tag_origin" ); + else if ( nextpoint.script_noteworthy == "stop_lava" ) + { + + } + else if ( nextpoint.script_noteworthy == "bus_scrape" ) + self playsound( "zmb_bus_car_scrape" ); + else if ( nextpoint.script_noteworthy == "arriving" ) + { + self thread begin_arrival_slowdown(); + self thread play_bus_audio( "arriving" ); + level thread do_player_bus_zombie_vox( "bus_stop", 10 ); + self thread buslightsignal( "turn_signal_right" ); + } + else if ( nextpoint.script_noteworthy == "enter_transition" ) + playfxontag( level._effect["fx_zbus_trans_fog"], self, "tag_headlights" ); + else if ( nextpoint.script_noteworthy == "bridge" ) + { + level thread do_automaton_arrival_vox( "bridge" ); + player_near = 0; + node = getvehiclenode( "bridge_accel_point", "script_noteworthy" ); + + if ( isdefined( node ) ) + { + players = get_players(); + + foreach ( player in players ) + { + if ( player.isonbus ) + continue; + + if ( distancesquared( player.origin, node.origin ) < 6760000 ) + player_near = 1; + } + } + + if ( player_near ) + { + trig = getent( "bridge_trig", "targetname" ); + trig notify( "trigger" ); + } + } + else if ( nextpoint.script_noteworthy == "depot" ) + { + volume = getent( "depot_lava_pit", "targetname" ); + traverse_volume = getent( "depot_pit_traverse", "targetname" ); + + if ( isdefined( volume ) ) + { + zombies = getaiarray( level.zombie_team ); + + for ( i = 0; i < zombies.size; i++ ) + { + if ( isdefined( zombies[i].depot_lava_pit ) ) + { + if ( zombies[i] istouching( volume ) ) + zombies[i] thread [[ zombies[i].depot_lava_pit ]](); + + continue; + } + + if ( zombies[i] istouching( volume ) ) + { + zombies[i] dodamage( zombies[i].health + 100, zombies[i].origin ); + continue; + } + + if ( zombies[i] istouching( traverse_volume ) ) + zombies[i] dodamage( zombies[i].health + 100, zombies[i].origin ); + } + } + } + } + + waittillframeend; + } +} + +start_stopping_bus( stop_fast ) +{ + if ( isdefined( stop_fast ) && stop_fast ) + self setspeed( 4, 30 ); + else + self setspeed( 4, 10 ); +} + +begin_arrival_slowdown() +{ + self setspeed( 10, 10, 10 ); +} + busupdateplayers() { level endon( "end_game" ); diff --git a/scripts/zm/zm_transit/zm_transit_reimagined.gsc b/scripts/zm/zm_transit/zm_transit_reimagined.gsc index cfaedb35..d4b6b810 100644 --- a/scripts/zm/zm_transit/zm_transit_reimagined.gsc +++ b/scripts/zm/zm_transit/zm_transit_reimagined.gsc @@ -21,6 +21,8 @@ main() replaceFunc(maps\mp\zm_transit::lava_damage_depot, scripts\zm\replaced\zm_transit::lava_damage_depot); replaceFunc(maps\mp\zm_transit_gamemodes::init, scripts\zm\replaced\zm_transit_gamemodes::init); replaceFunc(maps\mp\zm_transit_utility::solo_tombstone_removal, scripts\zm\replaced\zm_transit_utility::solo_tombstone_removal); + replaceFunc(maps\mp\zm_transit_bus::bussetup, scripts\zm\replaced\zm_transit_bus::bussetup); + replaceFunc(maps\mp\zm_transit_bus::busscheduleadd, scripts\zm\replaced\zm_transit_bus::busscheduleadd); replaceFunc(maps\mp\zm_transit_bus::busupdateplayers, scripts\zm\replaced\zm_transit_bus::busupdateplayers); replaceFunc(maps\mp\zombies\_zm_ai_screecher::screecher_detach, scripts\zm\replaced\_zm_ai_screecher::screecher_detach); replaceFunc(maps\mp\zombies\_zm_ai_screecher::screecher_cleanup, scripts\zm\replaced\_zm_ai_screecher::screecher_cleanup);