mirror of
https://github.com/reaaLx/nx1-gsc-dump.git
synced 2025-10-28 09:06:57 +00:00
aitype
animscripts
animtrees
character
codescripts
common_scripts
maps
animated_models
createart
createfx
mp
gametypes
killstreaks
_ac130.gsc
_airdrop.gsc
_airstrike.gsc
_autosentry.gsc
_blueshell.gsc
_emp.gsc
_exosuit.gsc
_harrier.gsc
_helicopter.gsc
_jet.gsc
_killstreaks.gsc
_lockseekdie.gsc
_nuke.gsc
_reaper.gsc
_remotedog.gsc
_remotemissile.gsc
_rodsofgod.gsc
_spider.gsc
_tank.gsc
_uav.gsc
_weapdrop.gsc
perks
_adrenaline.gsc
_animatedmodels.gsc
_areas.gsc
_art.gsc
_atbr.gsc
_awards.gsc
_compass.gsc
_createfx.gsc
_defcon.gsc
_destructables.gsc
_doorbreach.gsc
_doorswitch.gsc
_entityheadicons.gsc
_events.gsc
_fantasystats.gsc
_flashgrenades.gsc
_gasgrenades.gsc
_global_fx.gsc
_highlights.gsc
_intel.gsc
_javelin.gsc
_killingdoor.gsc
_load.gsc
_matchdata.gsc
_minefields.gsc
_moon_mp.gsc
_mp_trophy_turret.gsc
_radiation.gsc
_remotedog.gsc
_scoreboard.gsc
_shutter.gsc
_skill.gsc
_stinger.gsc
_upgrade.gsc
_utility.gsc
mp_nx_fallout.gsc
mp_nx_fallout_fx.gsc
mp_nx_fallout_precache.gsc
mp_nx_galleria.gsc
mp_nx_galleria_fx.gsc
mp_nx_galleria_precache.gsc
mp_nx_meteor.gsc
mp_nx_meteor_fx.gsc
mp_nx_meteor_precache.gsc
mp_nx_pitstop.gsc
mp_nx_pitstop_fx.gsc
mp_nx_pitstop_precache.gsc
mp_nx_skylab.gsc
mp_nx_skylab_fx.gsc
mp_nx_skylab_precache.gsc
mp_nx_stasis.gsc
mp_nx_stasis_fx.gsc
mp_nx_stasis_precache.gsc
mp_nx_ugvhh.gsc
mp_nx_ugvhh_fx.gsc
mp_nx_ugvhh_precache.gsc
_80s_hatch1.gsc
_80s_sedan1.gsc
_80s_wagon1.gsc
_ac130.gsc
_ac130_amb.gsc
_ac130_snd.gsc
_ambient.gsc
_ambulance.gsc
_anim.gsc
_animatedmodels.gsc
_antonov.gsc
_apache.gsc
_arcademode.gsc
_art.gsc
_atbr.gsc
_attack_heli.gsc
_autosave.gsc
_b2.gsc
_bcs_location_trigs.gsc
_blackhawk.gsc
_bm21.gsc
_bm21_drivable.gsc
_bm21_troops.gsc
_bmp.gsc
_bradley.gsc
_breach.gsc
_briefing.gsc
_btr80.gsc
_bus.gsc
_c130.gsc
_c4.gsc
_cagedchickens.gsc
_camera.gsc
_carry_ai.gsc
_casual_killer.gsc
_chute.gsc
_climb.gsc
_cobra.gsc
_cobra_harbor.gsc
_cobra_player.gsc
_cobrapilot.gsc
_colors.gsc
_compass.gsc
_coop.gsc
_coupe.gsc
_createfx.gsc
_createpath.gsc
_damagefeedback.gsc
_deadbody.gsc
_debug.gsc
_detonategrenades.gsc
_documents.gsc
_drone.gsc
_drone_ai.gsc
_drone_ai_lunar.gsc
_drone_civilian.gsc
_drone_civilian_lunar.gsc
_dynamic_cover.gsc
_ec_lunar_turret.gsc
_empty.gsc
_endmission.gsc
_equalizer.gsc
_escalator.gsc
_f15.gsc
_firetruck.gsc
_flare.gsc
_flashbang.gsc
_float.gsc
_friendlyfire.gsc
_fx.gsc
_gameskill.gsc
_gauntlet.gsc
_global_fx.gsc
_guide.gsc
_hand_signals.gsc
_harrier.gsc
_heli_ride.gsc
_helicopter_ai.gsc
_helicopter_globals.gsc
_helicopter_support.gsc
_hiding_door.gsc
_hiding_door_anims.gsc
_hind.gsc
_hud.gsc
_hud_util.gsc
_hud_weapons.gsc
_hummer_minigun.gsc
_humvee.gsc
_humvee50cal.gsc
_idle.gsc
_intelligence.gsc
_interactive_objects.gsc
_introscreen.gsc
_inventory.gsc
_killstreaks.gsc
_leak.gsc
_leapfrog.gsc
_lights.gsc
_littlebird.gsc
_littlebird_player.gsc
_load.gsc
_loadout.gsc
_locked_combat.gsc
_locked_covertypes_lunar.gsc
_luxurysedan.gsc
_m1a1.gsc
_m1a1_player.gsc
_melee_vignettes.gsc
_menus.gsc
_mg_penetration.gsc
_mgturret.gsc
_mi17.gsc
_mi17_noai.gsc
_mi28.gsc
_mig29.gsc
_minefields.gsc
_minigun.gsc
_minigun_viewmodel.gsc
_money.gsc
_moon.gsc
_moon_actor.gsc
_moon_civilian.gsc
_mortar.gsc
_mortarteam.gsc
_motorcycle.gsc
_names.gsc
_noder.gsc
_nx_blackhawk_armed.gsc
_nx_blackhawk_minigun.gsc
_nx_c102.gsc
_nx_chinese_lgv.gsc
_nx_chinese_skimmer.gsc
_nx_chinese_ugv.gsc
_nx_chinese_vtol.gsc
_nx_chinese_vtol_low.gsc
_nx_exfil_swat_van.gsc
_nx_future_tank.gsc
_nx_infinite_tunnel.gsc
_nx_lapd.gsc
_nx_littlebird.gsc
_nx_lunar_rover.gsc
_nx_miniuav.gsc
_nx_moving_platform.gsc
_nx_moving_platform_vh.gsc
_nx_objective_util.gsc
_nx_osprey.gsc
_nx_parachute.gsc
_nx_policecar.gsc
_nx_president_suburban.gsc
_nx_retreat.gsc
_nx_skyscraper_taxi.gsc
_nx_ugv.gsc
_nx_us_ugv.gsc
_nx_utility.gsc
_nx_vehicle_drive.gsc
_nx_vignette_util.gsc
_objective_routes.gsc
_overheat.gsc
_patrol.gsc
_patrol_anims.gsc
_pavelow.gsc
_pavelow_noai.gsc
_photosource.gsc
_player_stats.gsc
_policecar.gsc
_props.gsc
_quotes.gsc
_radiation.gsc
_rank.gsc
_rappel.gsc
_rappel_util.gsc
_riotshield.gsc
_sa6.gsc
_sea.gsc
_seaknight.gsc
_seaknight_airlift.gsc
_shellshock.gsc
_shutter.gsc
_slamraam.gsc
_slowmo_breach.gsc
_small_hatchback.gsc
_small_wagon.gsc
_snowmobile.gsc
_snowmobile_drive.gsc
_snowmobile_player.gsc
_spawner.gsc
_specialops.gsc
_specialops_battlechatter.gsc
_specialops_code.gsc
_stealth.gsc
_stealth_accuracy_friendly.gsc
_stealth_animation_funcs.gsc
_stealth_anims.gsc
_stealth_behavior_enemy.gsc
_stealth_behavior_friendly.gsc
_stealth_behavior_system.gsc
_stealth_color_friendly.gsc
_stealth_corpse_enemy.gsc
_stealth_corpse_system.gsc
_stealth_event_enemy.gsc
_stealth_shared_utilities.gsc
_stealth_smartstance_friendly.gsc
_stealth_threat_enemy.gsc
_stealth_utility.gsc
_stealth_visibility_enemy.gsc
_stealth_visibility_friendly.gsc
_stealth_visibility_system.gsc
_stretcher.gsc
_stryker.gsc
_stryker50cal.gsc
_stryker50cal_turrettrophy.gsc
_submarine_nuclear.gsc
_submarine_sdv.gsc
_suburban.gsc
_suburban_minigun.gsc
_suitshield.gsc
_swat_van.gsc
_t72.gsc
_tanker.gsc
_technical.gsc
_threatid.gsc
_translation.gsc
_treadfx.gsc
_treeburst.gsc
_trophy_turret.gsc
_truck.gsc
_uaz.gsc
_uaz_ac130.gsc
_ucav.gsc
_utility.gsc
_utility_code.gsc
_van.gsc
_vehicle.gsc
_vehicle_aianim.gsc
_vehicle_missile.gsc
_vehicle_spline.gsc
_vehicledrive.gsc
_vehiclenames.gsc
_viper.gsc
_washfx.gsc
_weather.gsc
_wood.gsc
_zodiac.gsc
_zodiac_player.gsc
_zpu_antiair.gsc
nx_border.gsc
nx_border_amb.gsc
nx_border_anim.gsc
nx_border_audio.gsc
nx_border_border.gsc
nx_border_church.gsc
nx_border_fx.gsc
nx_border_market.gsc
nx_border_precache.gsc
nx_border_streets.gsc
nx_border_util.gsc
nx_crowd_controller.gsc
nx_exfil.gsc
nx_exfil_alley.gsc
nx_exfil_amb.gsc
nx_exfil_anim.gsc
nx_exfil_audio.gsc
nx_exfil_fx.gsc
nx_exfil_intro.gsc
nx_exfil_market.gsc
nx_exfil_precache.gsc
nx_exfil_street.gsc
nx_exfil_util.gsc
nx_harbor.gsc
nx_harbor_amb.gsc
nx_harbor_anim.gsc
nx_harbor_fx.gsc
nx_harbor_precache.gsc
nx_harbor_util.gsc
nx_hithard.gsc
nx_hithard_amb.gsc
nx_hithard_anim.gsc
nx_hithard_audio.gsc
nx_hithard_b.gsc
nx_hithard_b_amb.gsc
nx_hithard_b_anim.gsc
nx_hithard_b_fx.gsc
nx_hithard_b_monorail_station.gsc
nx_hithard_b_on_ramp.gsc
nx_hithard_b_patriot_run.gsc
nx_hithard_b_precache.gsc
nx_hithard_b_util.gsc
nx_hithard_fx.gsc
nx_hithard_motorcade.gsc
nx_hithard_parachute.gsc
nx_hithard_precache.gsc
nx_hithard_rooftop.gsc
nx_hithard_secure.gsc
nx_hithard_util.gsc
nx_hospital.gsc
nx_hospital_amb.gsc
nx_hospital_anim.gsc
nx_hospital_atrium.gsc
nx_hospital_audio.gsc
nx_hospital_exit_corridor.gsc
nx_hospital_fx.gsc
nx_hospital_hall_first_floor.gsc
nx_hospital_hall_second_floor.gsc
nx_hospital_precache.gsc
nx_hospital_util.gsc
nx_lava.gsc
nx_lava_amb.gsc
nx_lava_anim.gsc
nx_lava_audio.gsc
nx_lava_fx.gsc
nx_lava_outpost.gsc
nx_lava_precache.gsc
nx_lava_station_1.gsc
nx_lava_station_2.gsc
nx_lava_train_1.gsc
nx_lava_train_2.gsc
nx_lava_train_derail.gsc
nx_lava_train_interior.gsc
nx_lava_util.gsc
nx_lunar.gsc
nx_lunar_amb.gsc
nx_lunar_anim.gsc
nx_lunar_audio.gsc
nx_lunar_control_room_breach.gsc
nx_lunar_escape_exterior.gsc
nx_lunar_escape_interior.gsc
nx_lunar_fx.gsc
nx_lunar_get_to_the_armory.gsc
nx_lunar_intro.gsc
nx_lunar_precache.gsc
nx_lunar_rover_precache.gsc
nx_lunar_take_back_control.gsc
nx_lunar_util.gsc
nx_rocket.gsc
nx_rocket_amb.gsc
nx_rocket_anim.gsc
nx_rocket_audio.gsc
nx_rocket_fx.gsc
nx_rocket_precache.gsc
nx_rocket_railgun.gsc
nx_rocket_section_base_alpha.gsc
nx_rocket_section_base_delta.gsc
nx_rocket_section_base_echo.gsc
nx_rocket_section_bridge.gsc
nx_rocket_section_crash.gsc
nx_rocket_section_escape.gsc
nx_rocket_section_gantry.gsc
nx_rocket_section_hanging.gsc
nx_rocket_section_intro.gsc
nx_rocket_section_littlebird.gsc
nx_rocket_section_rescue.gsc
nx_rocket_section_turret_base.gsc
nx_rocket_section_turret_control.gsc
nx_rocket_util.gsc
nx_skyscraper.gsc
nx_skyscraper_amb.gsc
nx_skyscraper_anim.gsc
nx_skyscraper_audio.gsc
nx_skyscraper_drive_up.gsc
nx_skyscraper_elevator.gsc
nx_skyscraper_fx.gsc
nx_skyscraper_halon.gsc
nx_skyscraper_hangar.gsc
nx_skyscraper_lab_enter.gsc
nx_skyscraper_lab_exit.gsc
nx_skyscraper_lab_to_vault.gsc
nx_skyscraper_outro.gsc
nx_skyscraper_precache.gsc
nx_skyscraper_rappel.gsc
nx_skyscraper_util.gsc
nx_skyscraper_vault.gsc
nx_skyscraper_vtol.gsc
nx_taser.gsc
ny_hind.gsc
mp
mptype
radiant
scriptdebugger
video
xmodelalias
README.md
816 lines
30 KiB
Plaintext
816 lines
30 KiB
Plaintext
#include maps\mp\_utility;
|
|
#include common_scripts\utility;
|
|
|
|
//****************************************************************************
|
|
// **
|
|
// Confidential - (C) Activision Publishing, Inc. 2010 **
|
|
// **
|
|
//****************************************************************************
|
|
// **
|
|
// Module: Prototype killstreak - Roboturret **
|
|
// Once the killstreak is deployed, it will follow the player **
|
|
// around the map and kill enemies. **
|
|
// **
|
|
// Created: May 31th, 2011 - James Chen **
|
|
// **
|
|
//***************************************************************************/
|
|
|
|
//tagJC<NOTE>: The current implementation consists of three components: one very small joint as vehicle serving as the connecting
|
|
// base for the turret and the legs.
|
|
//tagJC<TODO>: Known Issues (bugs)
|
|
// (1) The animation for the turret is controlled by the another underlying (turret) script. Currently, the turret
|
|
// does not play the proper animation when tracking/shooting enemies.
|
|
// (2) The robo legs is 90 degree from the correct orientation of the vehicle.
|
|
//tagJC<TODO>: Determine a better pathing logic under the current vehicle pathing limitation so the roboturret can really follow
|
|
// the players around the level.
|
|
|
|
init()
|
|
{
|
|
//tagJC<NOTE>: Precache all the assets needed.
|
|
//tagJC<NOTE>: nx_vehicle_roboturret_legs_vehicle is a very small joint which has all the required TAG for a vehicle.
|
|
// It is used so the robo legs and the roboturrets can be attached to it and the game will handle it properly
|
|
// according to the default vehicle animation.
|
|
PrecacheVehicle( "proto_nx_vehicle_roboturret_legs_vehicle" );
|
|
precacheModel( "nx_vehicle_roboturret_legs_vehicle" );
|
|
|
|
//tagJC<NOTE>: nx_vehicle_spider is the robo legs.
|
|
PrecacheVehicle( "nx_spider_mp" );
|
|
precacheModel( "nx_vehicle_spider" );
|
|
|
|
//tagJC<NOTE>: nx_ugv_robo_turret is the robo turret.
|
|
precacheTurret( "ugv_robo_turret_mp" );
|
|
precacheModel( "nx_ugv_robo_turret" );
|
|
|
|
//tagJC<NOTE>: These are the animations for the robo legs.
|
|
precacheMpAnim( "nx_vh_roboturret_run" );
|
|
precacheMpAnim( "nx_vh_roboturret_walk" );
|
|
precacheMpAnim( "nx_vh_roboturret_idle" );
|
|
|
|
//level._spiderSpawners = Vehicle_GetSpawnerArray();
|
|
|
|
//tagJC<NOTE>: This is the killstreak activation callback for the roboturret.
|
|
level._killstreakFuncs["spider"] = ::try_use_killstreak;
|
|
|
|
//tagJC<NOTE>: Use this script to update/initialize players as they connect to the game.
|
|
level thread onPlayerConnect();
|
|
|
|
//tagJC<NOTE>: In order for the roboturret to work correctly, the level needs to have at least one "spidernode".
|
|
level._spiderNodes = getVehicleNodeArray( "spidernode", "script_noteworthy" );
|
|
StartNodeMappingTable();
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Checking whether the level is properly set up for the roboturret killstreak.
|
|
try_use_killstreak( lifeId )
|
|
{
|
|
if ( ! level._spiderNodes.size )
|
|
{
|
|
self iPrintLnBold( "Spider is currently not supported in this level, bug your friendly neighborhood Level Designer, Failed to locate valid spider node." );
|
|
return false;
|
|
}
|
|
|
|
//tagJC<NOTE>: Test script of which any desired testing can be performed before integrated into working prototype.
|
|
//testscript();
|
|
|
|
killstreak_template_use( lifeId );
|
|
|
|
return true;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: This function creates a mapping table for all the start nodes. It uses the coordinate of the start node as the
|
|
// the index for the first dimension of the array. The second dimension of the array stores all the start nodes that
|
|
// the current start node can travel to.
|
|
StartNodeMappingTable()
|
|
{
|
|
println( "StartNodeMappingTable" );
|
|
level._StartNodeMapping = [];
|
|
println( "################################" );
|
|
for ( i = 0; i < level._spiderNodes.size; i++ )
|
|
{
|
|
StartNode = level._spiderNodes[i];
|
|
//tagJC<NOTE>: Getting the end node of the path whose start node is StartNode
|
|
EndNode = GetVehicleNode( StartNode.target, "targetname" );
|
|
//tagJC<NOTE>: Creating the index using the StartNode's coordinate
|
|
index = "X" + StartNode.origin[0] + "Y" + StartNode.origin[1] + "Z" + StartNode.origin[2];
|
|
println( "The index is " + index );
|
|
for ( j = 0; j < level._spiderNodes.size; j++ )
|
|
{
|
|
TargetStartNode = level._spiderNodes[j];
|
|
//tagJC<NOTE>: Store the TargetStartNode into the array if its distance is less than 250 units from the EndNode
|
|
if ( distance( EndNode.origin, TargetStartNode.origin ) < 250 )
|
|
{
|
|
if ( ! IsDefined (level._StartNodeMapping[index]) )
|
|
{
|
|
level._StartNodeMapping[index][0] = TargetStartNode;
|
|
}
|
|
else
|
|
{
|
|
ArraySize = level._StartNodeMapping[index].size;
|
|
level._StartNodeMapping[index][ArraySize] = TargetStartNode;
|
|
}
|
|
}
|
|
}
|
|
//tagJC<NOTE>: Debugging output to look at the array
|
|
println( "There are " + level._StartNodeMapping[index].size + " startnodes connected" );
|
|
for ( r = 0; r < level._StartNodeMapping[index].size; r++)
|
|
{
|
|
println( " The coordinate is " + level._StartNodeMapping[index][r].origin );
|
|
}
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Test script for any desired functionality, such as loading model, playing certain animation etc..
|
|
// This is to make sure things are working properly before they are integrated into the working prototype.
|
|
testscript()
|
|
{
|
|
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
// tagJC<NOTE>: This is the callback that executes when the killstreak is activated by a player pressing on the dpad.
|
|
killstreak_template_use( lifeId )
|
|
{
|
|
assert( isDefined( self ) );
|
|
|
|
//tagJC<NOTE>: spawning the small joint as the vehicle and setting the associated attributes.
|
|
level._spider = spawnVehicle( "nx_vehicle_roboturret_legs_vehicle", "roboturret", "proto_nx_vehicle_roboturret_legs_vehicle", (0, 0, 0), (0, 0, 0) );
|
|
level._spider.health = 3000;
|
|
level._spider.targeting_delay = 1;
|
|
level._spider.team = self.team;
|
|
level._spider.pers["team"] = level._spider.team;
|
|
level._spider.owner = self;
|
|
level._spider setCanDamage( true );
|
|
level._spider.standardSpeed = 10;
|
|
level._spider.evadeSpeed = 50;
|
|
level._spider.dangerSpeed = 15;
|
|
level._spider.miniEngagementSpeed = 15;
|
|
level._spider.engagementSpeed = 15;
|
|
//tagJC<NOTE>: Kill the vehicle if it is dropped for more than 2048 units
|
|
level._spider thread deleteOnZ();
|
|
|
|
//tagJC<NOTE>: Spawning the robo legs
|
|
spiderScriptModel = spawn ( "script_model", level._spider.origin );
|
|
spiderScriptModel setModel ( "nx_vehicle_spider" );
|
|
spiderScriptModel ScriptModelPlayAnim ( "nx_vh_roboturret_idle" );
|
|
level._spiderCurrentAnimation = "nx_vh_roboturret_idle";
|
|
//tagJC<NOTE>: Linking the robo legs to the vehicle.
|
|
spiderScriptModel linkTo ( level._spider, "TAG_ORIGIN" , (0, 0, 0), (0, 0, 0) );
|
|
spiderScriptModel thread loopOnLegs ( level._spider );
|
|
|
|
//tagJC<NOTE>: Spawning the roboturret and setting its attributes.
|
|
spiderTurret = spawnTurret( "misc_turret", level._spider.origin, "ugv_main_turret_mp" );
|
|
//tagJC<NOTE>: Linking the turret to the scripted robo legs model.
|
|
spiderTurret linkTo( spiderScriptModel, "TAG_TURRET", (0,0,0), (0,0,0) );
|
|
spiderTurret setModel( "nx_ugv_robo_turret" );
|
|
spiderTurret.angles = level._spider.angles;
|
|
spiderTurret.owner = level._spider.owner;
|
|
spiderTurret makeTurretInoperable();
|
|
level._spider.mgTurret = spiderTurret;
|
|
level._spider.mgTurret SetDefaultDropPitch( 0 );
|
|
//tagJC<NOTE>: Start the turret to track and shoot enemies.
|
|
level._spider thread tankGetMiniTargets();
|
|
|
|
//tagJC<NOTE>: Finding the spider start node that is closest to the player.
|
|
closest_spidernode = find_closest_spidernode( self, level._spiderNodes );
|
|
|
|
//tagJC<NOTE>: Start moving the roboturret according to player's position.
|
|
level._spider thread move_spider ( self, closest_spidernode );
|
|
|
|
return true;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: There are three animations that the robo legs can play: idel, walk and run
|
|
loopOnLegs ( vehicle )
|
|
{
|
|
timer = 0;
|
|
while ( 1 )
|
|
{
|
|
self.angle = vehicle.angle;
|
|
speed = vehicle Vehicle_GetSpeed();
|
|
|
|
//tagJC<NOTE>: If the vehicle speed is faster than 10 MPH, the legs will run
|
|
if ( speed > 10 )
|
|
{
|
|
timer = 0;
|
|
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_run" )
|
|
{
|
|
self ScriptModelPlayAnim ( "nx_vh_roboturret_run" );
|
|
level._spiderCurrentAnimation = "nx_vh_roboturret_run";
|
|
self stoploopsound("robot_sentry_walk");
|
|
self playloopsound("robot_sentry_run");
|
|
}
|
|
}
|
|
//tagJC<NOTE>: If the vehicle speed is between 10 and 0 MPH, the legs will walk
|
|
else if ( speed < 10 && speed > 0 )
|
|
{
|
|
timer = 0;
|
|
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_walk" )
|
|
{
|
|
self ScriptModelPlayAnim ( "nx_vh_roboturret_walk" );
|
|
level._spiderCurrentAnimation = "nx_vh_roboturret_walk";
|
|
self stoploopsound("robot_sentry_run");
|
|
self playloopsound("robot_sentry_walk");
|
|
}
|
|
}
|
|
//tagJC<NOTE>: If the vehicle speed is 0 MPH, the legs will be idel
|
|
else
|
|
{
|
|
timer = timer + 1;
|
|
//tagJC<NOTE>: If the roboturret has been idle for 15 seconds
|
|
if ( timer == 30 )
|
|
{
|
|
vehicle playsound ( "roboturret_idle_vo" );
|
|
//vehicle playsound ( "roboturret_kill_vo" );
|
|
timer = 0;
|
|
}
|
|
if ( level._spiderCurrentAnimation != "nx_vh_roboturret_idle" )
|
|
{
|
|
self stoploopsound("robot_sentry_run");
|
|
self stoploopsound("robot_sentry_walk");
|
|
self ScriptModelPlayAnim ( "nx_vh_roboturret_idle" );
|
|
level._spiderCurrentAnimation = "nx_vh_roboturret_idle";
|
|
}
|
|
}
|
|
println ( "timer is: " + timer );
|
|
wait ( 0.5 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Currently, in order for this implementation to work, designers would have to place many pairs of bi-directional vehicle nodes
|
|
// in the level. Given the limitation that vehicle seems to be only moving when it is on a vehicle path, the roboturret
|
|
// cannot quite follow the players perfectly yet. Players would have to get close to the roboturret and then guide
|
|
// it to a different position.
|
|
move_spider ( owner, startNode )
|
|
{
|
|
//self playsound( "roboturret_deploy_vo" );
|
|
self Vehicle_SetSpeed( 30, 5, 5 );
|
|
//tagJC<NOTE>: Starting the roboturret along the path where its starting node is the roboturret's spawning node
|
|
self AttachPath( startNode );
|
|
self StartPath( startNode );
|
|
self waittill( "reached_end_node" );
|
|
self playsound( "roboturret_deploy_vo" );
|
|
|
|
prev_node = startNode;
|
|
while ( 1 )
|
|
{
|
|
index = "X" + prev_node.origin[0] + "Y" + prev_node.origin[1] + "Z" + prev_node.origin[2];
|
|
best_node = find_best_spidernode( owner, level._StartNodeMapping[index] );
|
|
//if ( distance ( owner.origin, level._spider.origin ) > 50 )
|
|
if ( isGettingCloserToPlayer ( owner, best_node ) )
|
|
{
|
|
//if ( prev_node != best_node )
|
|
//{
|
|
self StartPath( best_node );
|
|
self waittill( "reached_end_node" );
|
|
prev_node = best_node;
|
|
//println( "This is after subsequent reached_end_node" );
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
wait 0.5;
|
|
}
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: This function checks whether the turret will be moving away from the player or not
|
|
isGettingCloserToPlayer ( owner, StartNode )
|
|
{
|
|
EndNode = GetVehicleNode( StartNode.target, "targetname" );
|
|
if ( distance ( owner.origin, EndNode.origin ) > distance ( owner.origin, StartNode.origin ) )
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: From the ReachableNodeList, determine the node that is will lead the turret to the player
|
|
find_best_spidernode( owner, ReachableNodeList )
|
|
{
|
|
target_vector = VectorNormalize ( owner.origin - level._spider.origin );
|
|
//tagJC<NOTE>: Creating an arbitrary base line using the first node in the node awway
|
|
best_node = ReachableNodeList [0];
|
|
best_dot_product = VectorDot ( VectorNormalize( best_node.origin - level._spider.origin ), target_vector );
|
|
for ( i = 1; i < ReachableNodeList.size; i++)
|
|
{
|
|
//tagJC<NOTE>: If another node in the list can produce a larger dot product, that node is the best node
|
|
dot_product = VectorDot ( VectorNormalize( ReachableNodeList[i].origin - level._spider.origin ), target_vector );
|
|
if ( dot_product > best_dot_product )
|
|
{
|
|
best_node = ReachableNodeList[i];
|
|
}
|
|
}
|
|
return best_node;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
tankGetMiniTargets()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "leaving" );
|
|
miniTargets = [];
|
|
println( "Geting Mini Targets" );
|
|
|
|
for ( ;; )
|
|
{
|
|
miniTargets = [];
|
|
players = level._players;
|
|
|
|
//tagJC<NOTE>: Putting all the players on the oppositing team into a array.
|
|
for (i = 0; i <= players.size; i++)
|
|
{
|
|
if ( isMiniTarget( players[i] ) )
|
|
{
|
|
if( isdefined( players[i] ) )
|
|
miniTargets[miniTargets.size] = players[i];
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
wait( .05 );
|
|
}
|
|
//tagJC<NOTE>: If there is at least one enemy, start acquiring the target
|
|
if ( miniTargets.size > 0 )
|
|
{
|
|
self acquireMiniTarget( miniTargets );
|
|
return;
|
|
}
|
|
else
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: From the potential target list, determine whether there is any target that is feasible/practical for the turret
|
|
// to target.
|
|
isMiniTarget( potentialTarget )
|
|
{
|
|
self endon( "death" );
|
|
|
|
if ( !isalive( potentialTarget ) || potentialTarget.sessionstate != "playing" )
|
|
return false;
|
|
|
|
if ( !isdefined( potentialTarget.pers["team"] ) )
|
|
return false;
|
|
|
|
if ( potentialTarget == self.owner )
|
|
return false;
|
|
|
|
if ( distanceSquared( potentialTarget.origin , self.origin ) > 1024*1024 )
|
|
return false;
|
|
|
|
if ( level._teamBased && potentialTarget.pers["team"] == self.team )
|
|
return false;
|
|
|
|
if ( potentialTarget.pers["team"] == "spectator" )
|
|
return false;
|
|
|
|
if ( isdefined( potentialTarget.spawntime ) && ( gettime() - potentialTarget.spawntime )/1000 <= 5 )
|
|
return false;
|
|
|
|
if ( isDefined( self ) )
|
|
{
|
|
minTurretEye = self.mgTurret.origin + ( 0, 0, 64 );
|
|
minTurretCanSeeTarget = potentialTarget sightConeTrace( minTurretEye, self );
|
|
|
|
if ( minTurretCanSeeTarget < 1 )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: From the target list, determine which one is the best target and shoot it.
|
|
acquireMiniTarget( targets )
|
|
{
|
|
self endon( "death" );
|
|
|
|
//tagJC<NOTE>: If there is only one target in the list, it is the best target.
|
|
if ( targets.size == 1 )
|
|
{
|
|
self.bestMiniTarget = targets[0];
|
|
}
|
|
//tagJC<NOTE>: Else, determine the best target in the list.
|
|
else
|
|
{
|
|
self.bestMiniTarget = self getBestMiniTarget( targets );
|
|
}
|
|
|
|
self notify( "acquiringMiniTarget" );
|
|
//tagJC<NOTE>: Set turret to target the best target.
|
|
self.mgTurret SetTargetEntity( self.bestMiniTarget, ( 0,0,42 ) );
|
|
wait( .15 );
|
|
//tagJC<NOTE>: Set turret to fire at the best target.
|
|
self thread fireMiniOnTarget();
|
|
//tagJC<NOTE>: Abandon the target when it is killed.
|
|
self thread watchMiniTargetDeath( targets );
|
|
self thread watchMiniTargetDistance( targets );
|
|
self thread watchMiniTargetThreat( self.bestMiniTarget );
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Determine the best target from the target list
|
|
getBestMiniTarget( targets )
|
|
{
|
|
self endon( "death" );
|
|
tankOrigin = self.origin;
|
|
|
|
closest = undefined;
|
|
bestTarget = undefined;
|
|
|
|
foreach ( targ in targets )
|
|
{
|
|
curDist = Distance( self.origin, targ.origin );
|
|
|
|
//tagJC<NOTE>: If the target is holding or using explosives, push the target to a higher priority
|
|
curWeaon = targ GetCurrentWeapon();
|
|
if ( isSubStr( curWeaon, "at4" ) || isSubStr( curWeaon, "jav" ) || isSubStr( curWeaon, "c4" ) || isSubStr( curWeaon, "smart" ) || isSubStr( curWeaon, "grenade" ) )
|
|
{
|
|
curDist -= 200;
|
|
}
|
|
if ( !isDefined( closest ) )
|
|
{
|
|
closest = curDist;
|
|
bestTarget = targ;
|
|
}
|
|
else if ( closest > curDist )
|
|
{
|
|
closest = curDist;
|
|
bestTarget = targ;
|
|
}
|
|
}
|
|
return ( bestTarget );
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Firing the turret at the target.
|
|
fireMiniOnTarget()
|
|
{
|
|
self endon( "death" );
|
|
self endon( "abandonedMiniTarget" );
|
|
self endon( "killedMiniTarget" );
|
|
noTargTime = undefined;
|
|
miniAcquiredTime = getTime();
|
|
|
|
if ( !isDefined( self.bestMiniTarget ) )
|
|
{
|
|
println( "No Targ to fire on" );
|
|
return;
|
|
}
|
|
|
|
println( "firing at best target" );
|
|
|
|
while( 1 )
|
|
{
|
|
if ( !isDefined ( self.mgTurret getTurretTarget( true ) ) )
|
|
{
|
|
if ( !isDefined( noTargTime ) )
|
|
{
|
|
noTargTime = getTime();
|
|
}
|
|
|
|
curTime = getTime();
|
|
|
|
//tagJC<NOTE>: If there has been more than 1 milliseconds without a target, abandon the target.
|
|
if ( noTargTime - curTime > 1 )
|
|
{
|
|
noTargTime = undefined;
|
|
self thread explicitAbandonMiniTarget();
|
|
return;
|
|
}
|
|
println("Waiting because the turret doesnt have a target" );
|
|
wait ( .5 );
|
|
continue;
|
|
}
|
|
//tagJC<NOTE>: Firing a random number of shots between 2 to 6.
|
|
numShots = randomIntRange( 2, 6 );
|
|
for ( i = 0; i < numShots; i++ )
|
|
{
|
|
println( "actually shooting turret" );
|
|
self.mgTurret ShootTurret();
|
|
wait ( .25 );
|
|
}
|
|
wait ( randomFloatRange( 0.05, 0.1 ) );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Clearing the current target list for the turret and starting to get more targets.
|
|
explicitAbandonMiniTarget( noNewTarget )
|
|
{
|
|
self notify( "abandonedMiniTarget" );
|
|
println( "ABANDONED MINI TARGET" );
|
|
|
|
self.bestMiniTarget = undefined;
|
|
self.mgTurret ClearTargetEntity();
|
|
|
|
if ( isDefined(noNewTarget) && noNewTarget )
|
|
{
|
|
return;
|
|
}
|
|
|
|
self thread tankGetMiniTargets();
|
|
return;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Wait for the target's death. Once the target is killed, clear the target list and get more targets.
|
|
watchMiniTargetDeath( targets )
|
|
{
|
|
self endon( "abandonedMiniTarget" );
|
|
self endon( "death" );
|
|
if ( ! isDefined( self.bestMiniTarget ) )
|
|
return;
|
|
|
|
self.bestMiniTarget waittill( "death" );
|
|
//self playsound ( "roboturret_idle_vo" );
|
|
self playsound ( "roboturret_kill_vo" );
|
|
|
|
self notify( "killedMiniTarget" );
|
|
println( "Killed Mini Target" );
|
|
|
|
self.bestMiniTarget = undefined;
|
|
self.mgTurret ClearTargetEntity();
|
|
self tankGetMiniTargets();
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: If the target is more than 1024 units away, abandon the target
|
|
watchMiniTargetDistance( targets )
|
|
{
|
|
self endon( "abandonedMiniTarget" );
|
|
self endon( "death" );
|
|
|
|
for ( ;; )
|
|
{
|
|
if (! isDefined( self.bestMiniTarget ) )
|
|
return;
|
|
|
|
trace = BulletTrace( self.mgTurret.origin, self.bestMiniTarget.origin, false, self );
|
|
traceDistance = Distance(self.origin, trace["position"] );
|
|
|
|
if ( traceDistance > 1024 )
|
|
{
|
|
println( "MINI TARGET DIST TOO FAR!!!" );
|
|
self thread explicitAbandonMiniTarget();
|
|
return;
|
|
}
|
|
println( traceDistance );
|
|
wait ( 2 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: If there is a target that is closer to the current target, abandon the curret target
|
|
watchMiniTargetThreat( curTarget )
|
|
{
|
|
self endon( "abandonedMiniTarget" );
|
|
self endon( "death" );
|
|
self endon( "killedMiniTarget" );
|
|
|
|
for ( ;; )
|
|
{
|
|
miniTargets = [];
|
|
players = level._players;
|
|
|
|
for (i = 0; i <= players.size; i++)
|
|
{
|
|
if ( isMiniTarget( players[i] ) )
|
|
{
|
|
if( !isdefined( players[i] ) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if( !isdefined(curTarget) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
traceOldTarg = Distance(self.origin, CurTarget.origin );
|
|
traceNewTarg = Distance(self.origin, players[i].origin );
|
|
|
|
if ( traceNewTarg < traceOldTarg )
|
|
{
|
|
self thread explicitAbandonMiniTarget();
|
|
return;
|
|
}
|
|
}
|
|
wait( .05 );
|
|
}
|
|
wait( .25 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: From the entity_list, return the one that is closest to the entity
|
|
find_closest_spidernode ( target, entity_list )
|
|
{
|
|
//tagJC<NOTE>: Use an arbitrary distance as the base for comparision
|
|
closest_distance = distance( target.origin , entity_list[0].origin );
|
|
closest_entity = entity_list[0];
|
|
for ( i = 1; i < entity_list.size; i++ )
|
|
{
|
|
//tagJC<NOTE>: If another entity on the list results in a shorter distance, update the results accordingly
|
|
if ( distance( target.origin , entity_list[i].origin ) < closest_distance )
|
|
{
|
|
closest_distance = distance( target.origin , entity_list[i].origin );
|
|
closest_entity = entity_list[i];
|
|
}
|
|
}
|
|
return closest_entity;
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: If a vehicle is dropped more than 2048 units, kill it.
|
|
deleteOnZ()
|
|
{
|
|
self endon ( "death" );
|
|
|
|
originalZ = self.origin[2];
|
|
|
|
for ( ;; )
|
|
{
|
|
if ( originalZ - self.origin[2] > 2048 )
|
|
{
|
|
self.health = 0;
|
|
self notify( "death" );
|
|
return;
|
|
}
|
|
wait ( 1.0 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: This function tracks player's movement and put the closest node to the player into a queue
|
|
TrackingPlayers( owner )
|
|
{
|
|
self.PlayerLocations = [];
|
|
while ( 1 )
|
|
{
|
|
close_node = find_closest_spidernode( owner, level._spiderNodes );
|
|
if ( self.PlayerLocations.size == 0 )
|
|
{
|
|
self.PlayerLocations[0] = close_node;
|
|
}
|
|
else
|
|
{
|
|
size = self.PlayerLocations.size;
|
|
Player_last_location = self.PlayerLocations[ size - 1 ];
|
|
if ( close_node != Player_last_location )
|
|
{
|
|
self.PlayerLocations[ size ] = close_node;
|
|
//println ( "========== This is inside Tracking Player ============" );
|
|
//println ( "The location of the node being added is: " + self.PlayerLocations[ size ].origin);
|
|
//println ( "The size of PlayerLocations is: " + self.PlayerLocations.size );
|
|
//println ( "======================================================" );
|
|
}
|
|
}
|
|
wait( 0.5 );
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
//tagJC<NOTE>: Remove the first item in the list by shifting entities in the list forward by one slot in the list
|
|
RemoveFirstItem ( list )
|
|
{
|
|
if ( list.size > 0 )
|
|
{
|
|
for ( i = 0 ; i < list.size - 1 ; i ++ )
|
|
{
|
|
list[ i ] = list[ i + 1 ];
|
|
}
|
|
list[ list.size - 1 ] = undefined;
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
// tagJC<NOTE>: This script is running on the global level object, it monitors players connecting to the game.
|
|
// Its main purpose is to apply the onPlayerSpawned script to each player as they connect to the game.
|
|
onPlayerConnect()
|
|
{
|
|
for(;;)
|
|
{
|
|
level waittill("connected", player);
|
|
player thread onPlayerSpawned();
|
|
}
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
// tagJC<NOTE>: This script is running on each player in the game, it recieves a notification each time the player it is running on spawns in the game
|
|
// Its main purpose is to initialize any per player data, as well as update the player subject to any global killstreak data when that player spawns.
|
|
onPlayerSpawned()
|
|
{
|
|
self endon("disconnect");
|
|
|
|
for(;;)
|
|
{
|
|
self waittill( "spawned_player" );
|
|
println( "player spwaned" );
|
|
|
|
// init/manage any per player killstreak data here
|
|
}
|
|
}
|
|
|
|
main ( vehicle, model )
|
|
{
|
|
|
|
}
|
|
|
|
//*******************************************************************
|
|
// *
|
|
// *
|
|
//*******************************************************************
|
|
|
|
/*
|
|
QUAKED script_vehicle_nx_proto_roboturret (1 0 0) (-16 -16 -24) (16 16 32) USABLE SPAWNER
|
|
|
|
maps\mp\killstreaks\_spider::main( "nx_vehicle_roboturret_legs_vehicle", "proto_nx_vehicle_roboturret_legs_vehicle" );
|
|
|
|
include,prototype_nx_vehicle_roboturret
|
|
|
|
defaultmdl="nx_vehicle_roboturret_legs_vehicle"
|
|
default:"vehicletype" "proto_nx_vehicle_roboturret_legs_vehicle"
|
|
default:"script_team" "allies"
|
|
*/ |