/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /****************************************************************************** * * FILE * MissionDemo.cpp * * DESCRIPTION * Mission Demo Specific Scripts * * PROGRAMMER * Rich Donnelly * * VERSION INFO * $Author: Byon_g $ * $Revision: 7 $ * $Modtime: 11/29/01 11:05a $ * $Archive: /Commando/Code/Scripts/MissionDemo.cpp $ * ******************************************************************************/ #include "scripts.h" #include "toolkit.h" // Predefined Constants #define M02_OBJCONTROLLER 1111112 #define M02_AREACOUNT 26 // Mission Objective Controller and Initializer DECLARE_SCRIPT(MDD_Objective_Controller, "") { int convoy_trucks; REGISTER_VARIABLES() { SAVE_VARIABLE( convoy_trucks, 1 ); } void Created(GameObject * obj) { //DEMO Commands->Enable_HUD (false); GameObject * camera = Commands->Create_Object("Invisible_Object", Vector3(0,0,0)); if (camera) { Commands->Attach_Script(camera, "Test_Cinematic", "XG_DemoCam.txt"); } int id = Commands->Create_Conversation("Demo_Intro"); Commands->Join_Conversation(NULL, id); Commands->Join_Conversation(STAR, id); Commands->Start_Conversation(id); //DEMO // Set up the expected number of convoy trucks for the objective. convoy_trucks = 3; // Prevent the Objective Controller from hibernating Commands->Enable_Hibernation(obj, false); // Turn on the first primary objective (Locate the Missing Scientists) // Turn on the tertiary objectives (if any) //DEMO Commands->Add_Objective(201, OBJECTIVE_TYPE_PRIMARY, OBJECTIVE_STATUS_PENDING, IDS_M02_OBJECTIVE_01); //DEMO Commands->Add_Objective(222, OBJECTIVE_TYPE_TERTIARY, OBJECTIVE_STATUS_HIDDEN, IDS_M02_OBJECTIVE_22); //DEMO Commands->Add_Objective(223, OBJECTIVE_TYPE_TERTIARY, OBJECTIVE_STATUS_HIDDEN, IDS_M02_OBJECTIVE_23); } // This custom receives requests to activate and deactivate objectives // Type = Objective ID // Param 0 = Activate this objective (Pending) // Param 1 = Complete this objective (Accomplished) // Param 2 = Fail this objective (Failed) // Param 3 = Convoy truck special - counting }; DECLARE_SCRIPT (MDD_Respawn_Controller, "") { bool active_area [M02_AREACOUNT]; bool area_spawn_heli_drop_01_active [M02_AREACOUNT]; bool area_spawn_heli_drop_02_active [M02_AREACOUNT]; bool area_spawn_parachute_active [M02_AREACOUNT]; char area_unit_count [M02_AREACOUNT]; char area_unit_max [M02_AREACOUNT]; int area_officer [M02_AREACOUNT]; int spawner_rotator; int replacement_vehicle; int destroyed_sam; int destroyed_silo; REGISTER_VARIABLES() { SAVE_VARIABLE( active_area, 1); SAVE_VARIABLE( area_spawn_heli_drop_01_active, 2); SAVE_VARIABLE( area_spawn_heli_drop_02_active, 3); SAVE_VARIABLE( area_spawn_parachute_active, 4); SAVE_VARIABLE( area_unit_count, 5); SAVE_VARIABLE( area_unit_max, 6); SAVE_VARIABLE( area_officer, 7); SAVE_VARIABLE( spawner_rotator, 8); SAVE_VARIABLE( replacement_vehicle, 9); SAVE_VARIABLE( destroyed_sam, 10); SAVE_VARIABLE( destroyed_silo, 11); } void Created (GameObject *obj) { int counter; counter = 0; spawner_rotator = 0; replacement_vehicle = -1; destroyed_sam = 0; destroyed_silo = 0; while (counter < ARRAY_ELEMENT_COUNT(active_area)) { active_area [counter] = false; area_unit_count [counter] = 0; area_officer [counter] = 0; area_unit_max [counter] = 4; area_spawn_heli_drop_01_active [counter] = false; area_spawn_heli_drop_02_active [counter] = false; area_spawn_parachute_active [counter] = false; // Turning the actives to true in here means they do not occur in the area // provided you don't turn them off later on in the mission. counter++; } // Drop the first Humm-Vee into the start area. //DEMO Call_GDI_HummVee (0); // Wake up the A25 units. //DEMO Commands->Send_Custom_Event(obj, Commands->Find_Object(400985), 0, 0); //DEMO Turn on A25 GameObject * object = Commands->Find_Object(M02_OBJCONTROLLER); if (object) { Commands->Send_Custom_Event(obj, object, 104, 25); Commands->Send_Custom_Event(obj, Commands->Find_Object(401741), 0, 0); } // Call the ORCA strike intro. //DEMO GameObject * chinook_obj1 = Commands->Create_Object("Invisible_Object", Vector3(0,0,0)); /*if (chinook_obj1) { Commands->Attach_Script(chinook_obj1, "Test_Cinematic", "X2A_OrcaStrike.txt"); }*/ Commands->Start_Timer(obj, this, 3.0f, 2); //DEMO Commands->Start_Timer(obj, this, 10.0f, 99); Commands->Start_Timer(obj, this, 5.0f, 100); Commands->Start_Timer(obj, this, 60.0f, 101); //DEMO } void Call_GDI_HummVee (int area_id) { Vector3 drop_loc = Vector3(-87.2f,-13.1f,-40.1f); float facing = 102.9f; GameObject * chinook_obj1 = Commands->Create_Object("Invisible_Object", drop_loc); if (chinook_obj1) { Commands->Set_Facing(chinook_obj1, facing); Commands->Attach_Script(chinook_obj1, "Test_Cinematic", "X2I_GDI_Drop_HummVee.txt"); } } void Call_GDI_PowerUp (int area_id) { Vector3 drop_loc = Vector3(511.3f,680.3f,-21.2f); float facing = 146.6f; GameObject * chinook_obj1 = Commands->Create_Object("Invisible_Object", drop_loc); if (chinook_obj1) { Commands->Set_Facing(chinook_obj1, facing); Commands->Attach_Script(chinook_obj1, "Test_Cinematic", "X2I_GDI_Drop_PowerUp.txt"); } } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 2) { // Count through each area, check if it is active. int counter; counter = 0; while (counter < ARRAY_ELEMENT_COUNT(active_area)) { if (active_area[counter]) { // Check if the area still has an officer associated. if (area_officer[counter]) { GameObject* officer = Commands->Find_Object(area_officer[counter]); if (officer) { Check_Respawns (counter); } } } counter++; } Commands->Debug_Message (">>>>>>>>>>>>>>>> UNIT COUNT = %i, UNIT MAX = %i.\n",area_unit_count[25],area_unit_max[25]); int players_difficulty = Commands->Get_Difficulty_Level(); float timer_length = 25 - (10 * (players_difficulty)); Commands->Start_Timer(obj, this, timer_length, 2); } //DEMO else if (timer_id == 99) { GameObject *buggy = Commands->Create_Object ("GDI_Orca", Vector3(506.590f,470.752f,-40.590f)); if (buggy) { Commands->Attach_Script (buggy, "MDD_Flying_Vehicle", "0"); } } else if (timer_id == 100) { GameObject *buggy = Commands->Create_Object ("Nod_Apache", Vector3(587.296f,504.567f,-44.034f)); if (buggy) { Commands->Attach_Script (buggy, "MDD_Flying_Vehicle", "1"); } } else if (timer_id == 101) { area_unit_count [25] = 0; Commands->Start_Timer(obj, this, 60.0f, 101); } //DEMO } void Check_Respawns (int area_id) { // Can this particular area handle respawns? // Count through the spawn sequence until all units have been accounted for. int counter; int stop_point; bool stopped_counter; int spawner_buffer = 0; stopped_counter = false; counter = Get_Int_Random(0,2); stop_point = counter; int tempcount = area_unit_count[area_id]; while (tempcount < area_unit_max [area_id]) { if (!stopped_counter) { // Check which respawn type I can use. switch (counter) { case (0): { if (!area_spawn_heli_drop_01_active[area_id]) { if ((area_unit_max[area_id] - tempcount) > 2) { area_spawn_heli_drop_01_active[area_id] = true; tempcount += 3; Use_Heli_Drop_01(area_id); } } break; } case (1): { if (!area_spawn_heli_drop_02_active[area_id]) { if ((area_unit_max[area_id] - tempcount) > 1) { area_spawn_heli_drop_02_active[area_id] = true; tempcount += 2; Use_Heli_Drop_02(area_id); } } break; } case (2): { if (!area_spawn_parachute_active[area_id]) { if ((area_unit_max[area_id] - tempcount) > 2) { area_spawn_parachute_active[area_id] = true; Use_Parachute_Drop(area_id); tempcount += 3; } } break; } } } else { spawner_buffer++; if (spawner_buffer < 3) { tempcount ++; Use_Spawners (area_id); } else { tempcount = area_unit_max[area_id]; } } if (!stopped_counter) { counter++; if (counter > 2) { counter = 0; } if (counter == stop_point) { stopped_counter = true; } } } } // This uses a helicopter to drop three units. void Use_Heli_Drop_01 (int area_id) { Vector3 drop_location; float facing; const char* cinematic; const char* textfile; const char* parameters; cinematic = "Test_Cinematic"; parameters = "25,107"; textfile = "X2I_Drop03_Area25.txt"; drop_location = Vector3(546.5f,274.5f,-45.0f); facing = 30.0f; GameObject * chinook_obj1 = Commands->Create_Object("Invisible_Object", drop_location); if (chinook_obj1) { Commands->Set_Facing(chinook_obj1, facing); Commands->Attach_Script(chinook_obj1, "M02_Reset_Spawn", parameters); Commands->Attach_Script(chinook_obj1, cinematic, textfile); } } // This uses a different helicopter route to drop two units. void Use_Heli_Drop_02 (int area_id) { Vector3 drop_location; float facing; const char* cinematic; const char* textfile; const char* parameters; cinematic = "Test_Cinematic"; parameters = "25,108"; textfile = "X2I_Drop02_Area25.txt"; drop_location = Vector3(558.6f,381.7f,-51.1f); facing = -75.6f; GameObject * chinook_obj2 = Commands->Create_Object("Invisible_Object", drop_location); if (chinook_obj2) { Commands->Set_Facing(chinook_obj2, facing); Commands->Attach_Script(chinook_obj2, "M02_Reset_Spawn", parameters); Commands->Attach_Script(chinook_obj2, cinematic, textfile); } } // This uses a cargo plane parachute drop to drop three units. void Use_Parachute_Drop (int area_id) { Vector3 drop_location; float facing; const char* cinematic; const char* textfile; const char* parameters; cinematic = "Test_Cinematic"; textfile = "X2I_Para03_Area25.txt"; parameters = "25,109"; drop_location = Vector3(598.7f,342.2f,-62.7f); facing = 173.9f; GameObject * plane_obj = Commands->Create_Object("Invisible_Object", drop_location); if (plane_obj) { Commands->Set_Facing(plane_obj, facing); Commands->Attach_Script(plane_obj, "M02_Reset_Spawn", parameters); Commands->Attach_Script(plane_obj, cinematic, textfile); } } // This uses the regular spawners to generate one unit. bool Use_Spawners (int area_id) { int spawner_id; const char *spawner_params; spawner_id = 0; spawner_params = "0,0,-1"; spawner_rotator++; if (spawner_rotator > 2) { spawner_rotator = 0; } switch (spawner_rotator) { case (0): { spawner_id = 401462; break; } case (1): { spawner_id = 401463; break; } default: { spawner_id = 401464; break; } } spawner_params = "25,0,-1"; GameObject * spawn1 = Commands->Trigger_Spawner(spawner_id); if (spawn1) { Commands->Attach_Script(spawn1, "MDD_Nod_Soldier", spawner_params); return true; } else { return false; } } void Custom (GameObject *obj, int type, int param, GameObject *sender) { if (type == 101) { // A unit has died, subtract him from his area (param). area_unit_count [param]--; if (area_unit_count [param] < 0) { area_unit_count [param] = 0; } } else if (type == 102) { // A specific area is requesting a forced spawn if possible. Check_Respawns (param); } else if (type == 103) { // A unit is registering with the area unit count. area_unit_count [param]++; } else if (type == 104) { // An area is being activated. Turn on the area. active_area [param] = true; } else if (type == 105) { // An area is being deactivated. active_area [param] = false; } else if (type == 106) { // An officer is registering with his area. if (sender) { area_officer[param] = Commands->Get_ID(sender); } } else if (type == 107) { // A Heli_01 spawner type is attempting to reset itself. area_spawn_heli_drop_01_active[param] = false; } else if (type == 108) { // A Heli_02 spawner type is attempting to reset itself. area_spawn_heli_drop_02_active[param] = false; } else if (type == 109) { // A Parachute spawner type is attempting to reset itself. area_spawn_parachute_active[param] = false; } else if (type == 111) { // A request to spawn a new vehicle for the commando has been made. Replacement_Vehicle (obj, param); } else if (type == 112) { // A player controlled vehicle has been destroyed, turn on the ability to make a new one replacement_vehicle = param; } else if (type == 113) { // A request has been made to call in a GDI power-up drop. Call_GDI_PowerUp (3); } else if (type == 114) { // Reset the unit area count to zero. area_unit_count [param] = 0; } else if (type == 115) { // Destroyed SAM on the bridge - add to count, determine if both are destroyed. destroyed_sam++; if (destroyed_sam > 1) { // Drop a Medium Tank on the bridge. replacement_vehicle = 6; Replacement_Vehicle (obj, 6); } } else if (type == 116) { // Destroyed Tiberium Silo - add to count, determine if both are destroyed. destroyed_silo++; if (destroyed_silo > 1) { // Complete this mission objective. Commands->Send_Custom_Event (obj, obj, 222, 1); } } //DEMO else if (type == 180) { Commands->Start_Timer(obj, this, 20.0f, 99); } else if (type == 181) { Commands->Start_Timer(obj, this, 20.0f, 100); } } // When a player controlled vehicle is destroyed, it sends a custom to this controller // to turn on the ability to create a new vehicle in a certain area. // Another object then sends a custom to check for new vehicle creation. If the flag for // creating a new vehicle for this area is active, it is reset and the vehicle is delivered. void Replacement_Vehicle (GameObject *obj, int area_id) { Vector3 drop_loc = Vector3(0.0f,0.0f,0.0f); float facing = 0.0f; const char* textfile = "X2I_GDI_Drop_HummVee.txt"; bool nocinematic = false; switch (area_id) { case (0): { drop_loc = Vector3(161.6f,27.6f,-18.0f); facing = 115.4f; textfile = "X2I_GDI_Drop_HummVee.txt"; break; } case (1): { drop_loc = Vector3(494.652f,128.786f,-56.159f); facing = 90.0f; GameObject *buggy = Commands->Create_Object ("Nod_Buggy", drop_loc); if (buggy) { Commands->Set_Facing (buggy, facing); Commands->Attach_Script (buggy, "M02_Player_Vehicle", "3"); } nocinematic = true; break; } case (2): { drop_loc = Vector3(471.4f,716.0f,-17.1f); facing = -30.0f; textfile = "X2I_GDI_Drop_MediumTank.txt"; break; } case (4): { drop_loc = Vector3(429.672f, 894.045f, 4.354f); facing = -25.0f; GameObject *buggy = Commands->Create_Object ("Nod_Light_Tank", drop_loc); if (buggy) { Commands->Set_Facing (buggy, facing); Commands->Attach_Script (buggy, "M02_Player_Vehicle", "5"); } nocinematic = true; break; } case (5): { drop_loc = Vector3(611.1f, 1164.9f, 4.6f); facing = -39.7f; GameObject *buggy = Commands->Create_Object ("Nod_Recon_Bike", drop_loc); if (buggy) { Commands->Set_Facing (buggy, facing); Commands->Attach_Script (buggy, "M02_Player_Vehicle", "6"); } nocinematic = true; break; } case (6): { drop_loc = Vector3(785.3f,893.9f,21.8f); facing = -42.0f; textfile = "X2I_GDI_Drop_MediumTank.txt"; break; } case (14): { drop_loc = Vector3(1229.37f, 742.89f, 27.03f); facing = 85.0f; GameObject *buggy = Commands->Create_Object ("Nod_Recon_Bike", drop_loc); if (buggy) { Commands->Set_Facing (buggy, facing); Commands->Attach_Script (buggy, "M02_Player_Vehicle", "14"); } nocinematic = true; break; } } if (!nocinematic) { GameObject * chinook_obj1 = Commands->Create_Object("Invisible_Object", drop_loc); if (chinook_obj1) { Commands->Set_Facing(chinook_obj1, facing); Commands->Attach_Script(chinook_obj1, "Test_Cinematic", textfile); } } } }; DECLARE_SCRIPT (MDD_Nod_Soldier, "Area_Number:int,Area_Officer:int,Pre_Placed:int") { Vector3 my_home_point; bool no_return_home; int officeranimcounter; bool initial_damage; float initial_health; bool enemy_seen; REGISTER_VARIABLES() { SAVE_VARIABLE( my_home_point, 1); SAVE_VARIABLE( no_return_home, 2); SAVE_VARIABLE( officeranimcounter, 3); } void Created (GameObject *obj) { officeranimcounter = 0; no_return_home = false; enemy_seen = false; initial_damage = false; initial_health = 0.0f; // Set the unit's home point, save the value. Vector3 my_home_point = Commands->Get_Position(obj); Commands->Set_Innate_Soldier_Home_Location(obj, my_home_point, 20.0f); // Turn hibernation off for a moment. Commands->Enable_Hibernation (obj, false); // Start the timer to register with the controller. Commands->Start_Timer(obj, this, 1.0f, 1); //DEMO Commands->Start_Timer(obj, this, 10.0f, 8); //DEMO // If the unit is spawned, do not disturb it. // If the unit is preplaced, turn of actions. // If the unit is flown in, order it to move to the commando. int preplaced = Get_Int_Parameter("Pre_Placed"); if (!preplaced) { // Give spawned units a green key for the Hand of Nod. Commands->Grant_Key (obj, 1, true); //DEMOGameObject *starobj = Commands->Get_A_Star (my_home_point); GameObject *starobj = Commands->Find_Object(403063); //DEMO if (starobj) { ActionParamsStruct params; params.Set_Basic(this, 71, 0); params.Set_Movement(starobj, RUN, 5.0f, 0); Commands->Action_Goto(obj, params); } } else { if (preplaced > 0) { // Turn off all actions for preplaced soldiers. Commands->Innate_Disable (obj); } } } void Enemy_Seen (GameObject * obj, GameObject * enemy) { enemy_seen = true; } void Sound_Heard (GameObject * obj, const CombatSound & sound) { // If an objective shouts, respond to it, letting it know the area is not cleared. if (sound.Type == 1000) { if (sound.Creator) { Commands->Send_Custom_Event(obj, sound.Creator, 100, 1); } } // If a zone shouts to return to home points, do so. else if ((sound.Type > 1049) && (sound.Type < 1100) && (!no_return_home)) { int area_id = (sound.Type - 1050); int area_num = Get_Int_Parameter("Area_Number"); if (area_num == area_id) { // Tell this unit to return to its home point, conserving unit counts. ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Movement(my_home_point, RUN, 20.0f, false); Commands->Modify_Action (obj, 0, params, true, false); } } } void Timer_Expired (GameObject *obj, int timer_id) { if (timer_id == 1) { // Register with the respawn controller - send my area number. int officer = Get_Int_Parameter("Area_Officer"); int preplaced = Get_Int_Parameter("Pre_Placed"); int param = Get_Int_Parameter("Area_Number"); GameObject * object = Commands->Find_Object(M02_OBJCONTROLLER); if (object) { // Register with the respawn controller. Commands->Send_Custom_Event(obj, object, 103, param); if (officer) { // Unit is a preplaced officer. Register as an officer and hibernate. Commands->Set_Innate_Take_Cover_Probability (obj, 100.0f); Commands->Send_Custom_Event(obj, object, 106, param); } else { if (preplaced > 0) { // SPECIAL CASE SETUP: Force fire routine for Rocket Soldiers. if (preplaced == 4) { if ((param == 0) || (param == 3) || (param == 6) || (param == 10) || (param == 16) || (param == 21)) { no_return_home = true; Commands->Start_Timer(obj, this, 15.0f, 4); } } // Soldiers in start cinematic begin self-destruct. if ((preplaced == 2) && (param == 99)) { ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Attack(STAR, 150.0f, 0.0f, true); Commands->Action_Attack(obj, params); Commands->Start_Timer(obj, this, 5.0, 6); } } else { // Unit is not pre-placed, activate cleanup code and do not hibernate if not in the interior areas. Commands->Start_Timer(obj, this, 15.0f, 2); } } } //DEMO Commands->Enable_Hibernation (obj, 1); } else if (timer_id == 2) { // Cleanup code - find the nearest star, check distance, then check visibility Vector3 myloc = Commands->Get_Position(obj); //DEMO GameObject *star_obj = Commands->Get_A_Star(myloc); GameObject *star_obj = Commands->Find_Object(403063); //DEMO if (star_obj) { Vector3 starloc = Commands->Get_Position(star_obj); float distance = Commands->Get_Distance (myloc, starloc); //DEMOif (distance > 70.0f) if (distance > 300.0f) { bool visibility = Commands->Is_Object_Visible(star_obj, obj); if (!visibility) { Commands->Apply_Damage(obj, 10000.0f, "Blamokiller"); } else { Force_Move (obj); } } else { Force_Move (obj); } } Commands->Start_Timer(obj, this, 15.0f, 2); } else if (timer_id == 3) { // Force movement code to prevent irregular activity. Force_Move (obj); Commands->Start_Timer(obj, this, 15.0f, 3); } else if (timer_id == 4) { // Force fire at star code to prevent irregular activity. Vector3 myloc; myloc = Commands->Get_Position(obj); GameObject* starobj = Commands->Get_A_Star(myloc); if (starobj) { Vector3 starloc; float distance; starloc = Commands->Get_Position(starobj); distance = Commands->Get_Distance(myloc, starloc); if (distance < 150.0f) { ActionParamsStruct params; params.Set_Basic(this, 90, 0); params.Set_Attack(starobj, 150.0f, 0.0f, true); Commands->Action_Attack(obj, params); } } Commands->Start_Timer(obj, this, 15.0f, 4); } else if (timer_id == 5) { // An officer is trying to play an animation. Vector3 playerloc = Commands->Get_Position (STAR); Vector3 myloc = Commands->Get_Position(obj); float distance = Commands->Get_Distance(myloc, playerloc); if (distance > 10.0f) { officeranimcounter++; if (officeranimcounter > 2) { officeranimcounter = 0; } switch (officeranimcounter) { case (0): { GameObject *nearsoldier = Commands->Find_Closest_Soldier (myloc, 1.0f, 50.0f); if ((nearsoldier) && (nearsoldier != STAR)) { ActionParamsStruct params; params.Set_Basic(this, 99, 0); Vector3 soldierloc = Commands->Get_Position (nearsoldier); params.Set_Animation ("H_A_J18C", false); params.Set_Face_Location (soldierloc, 4.0f); Commands->Action_Play_Animation (obj, params); } break; } case (1): { if (STAR) { ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Animation ("H_A_J23C", false); params.Set_Face_Location (playerloc, 4.0f); Commands->Action_Play_Animation (obj, params); } break; } default: { if (STAR) { ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Animation ("H_A_J27C", false); params.Set_Face_Location (playerloc, 4.0f); Commands->Action_Play_Animation (obj, params); } break; } } } Commands->Start_Timer(obj, this, 10.0f, 5); } else if (timer_id == 6) { Commands->Apply_Damage(obj, 10000.0f, "Blamokiller"); } else if (timer_id == 7) { if (!enemy_seen) { // Time to move the chem-warrior. Pick a new location. Vector3 newloc; int rndnum = (Get_Int_Random(0.0f,1.0f) * 5); switch (rndnum) { case (0): { newloc = Vector3(1301.55f,617.89f,19.66f); break; } case (1): { newloc = Vector3(1340.65f,655.04f,19.51f); break; } case (2): { newloc = Vector3(1310.67f,694.74f,19.71f); break; } default: { newloc = Vector3(1242.26f,646.04f,19.65f); break; } } ActionParamsStruct params; params.Set_Basic(this, 31, 0); params.Set_Movement(newloc, WALK, 10.0f, false); Commands->Action_Goto(obj, params); } else { Force_Move (obj); } Commands->Start_Timer(obj, this, 30.0f, 7); } //DEMO else if (timer_id == 8) { Vector3 mydemopos = Commands->Get_Position (obj); GameObject* starobj = Commands->Find_Object(403063); if (starobj) { Commands->Send_Custom_Event (obj, starobj, 100, 0); } Commands->Start_Timer(obj, this, 10.0f, 8); } //DEMO } void Force_Move (GameObject* obj) { Vector3 mypos = Commands->Get_Position(obj); //DEMO GameObject *starobj = Commands->Get_A_Star (mypos); GameObject *starobj = Commands->Find_Object(403063); //DEMO if (starobj) { ActionParamsStruct params; params.Set_Basic(this, 90, 0); params.Set_Movement(starobj, RUN, 10.0f, 0); params.Set_Attack(starobj, 150.0f, 0.0f, true); Commands->Action_Attack(obj, params); } } void Killed (GameObject *obj, GameObject *killer) { // Tell the respawn controller I am dead. int param; param = Get_Int_Parameter("Area_Number"); GameObject * object = Commands->Find_Object(M02_OBJCONTROLLER); if (object) { Commands->Send_Custom_Event (obj, object, 101, param); } if (param == 3) { int officer = Get_Int_Parameter("Area_Officer"); if (officer) { // If a Medium Tank is needed for A03, drop it. Commands->Send_Custom_Event (obj, object, 111, 2); } } } void Custom (GameObject *obj, int type, int param, GameObject *sender) { if ((type == 0) && (param == 0)) { Commands->Innate_Enable (obj); // If the unit is a preplaced minigunner, forced movement code is activated for this unit. int preplaced = Get_Int_Parameter("Pre_Placed"); if (preplaced == 2) { int myid = Commands->Get_ID(obj); if ((myid != 400512) || (myid != 400513)) { Commands->Start_Timer(obj, this, 1.0f, 3); } } else if (preplaced == 1) { // Unit is an officer, start the animation timer. Commands->Start_Timer(obj, this, 10.0f, 5); } else if (preplaced == 6) { // Unit is a chem-warrior, start low priority wandering. Commands->Start_Timer(obj, this, 1.0f, 7); } else if (preplaced == 5) { int areanum = Get_Int_Parameter("Area_Number"); if (areanum == 19) { // Unit is a technician, who plays an animation in front of a terminal. ActionParamsStruct params; params.Set_Basic(this, 31, 100); params.Set_Animation ("H_A_CON2", true); Commands->Action_Play_Animation (obj, params); } } } if (type == 99) { if (param == 214) { // An Objective or Building is asking to be repaired. ActionParamsStruct params; params.Set_Basic(this, 99, 214); params.Set_Movement(sender, RUN, 10.0f, 0); Vector3 senderpos = Commands->Get_Position(sender); senderpos.Z -= 1.0f; params.Set_Attack(senderpos, 10.0f, 0.0f, false); Commands->Action_Attack(obj, params); } else if (param == 202) { ActionParamsStruct params; params.Set_Basic(this, 50, 214); params.Set_Movement(Vector3(1113.61f,877.4f,17.15f), RUN, 10.0f, 0); params.Set_Attack(Vector3(1113.61f,877.4f,17.15f), 10.0f, 0.0f, false); Commands->Action_Attack(obj, params); } else if (param == 217) { ActionParamsStruct params; params.Set_Basic(this, 50, 214); params.Set_Movement(Vector3(1062.24f,978.38f,-16.85f), RUN, 10.0f, 0); params.Set_Attack(Vector3(1062.24f,978.38f,-16.85f), 10.0f, 0.0f, false); Commands->Action_Attack(obj, params); } } if (!initial_damage) { if (type == CUSTOM_EVENT_FALLING_DAMAGE) { initial_health = Commands->Get_Health(obj); } } } void Damaged( GameObject * obj, GameObject *damager, float amount) { if (!initial_damage && damager == NULL) { initial_damage = true; Commands->Set_Health(obj, initial_health); } } }; // SOLDIER TYPE PARAMETERS FOR GDI // 1 = Rocket Soldier // 2 = Minigunner Officer // 3 = Minigunner Enlisted // 4 = Grenadier Enlisted DECLARE_SCRIPT (MDD_GDI_Soldier, "Area_ID:int, Soldier_Type=0:int") { bool stop_following; //DEMO Vector3 startloc; //DEMO REGISTER_VARIABLES() { SAVE_VARIABLE( stop_following, 1); } void Created(GameObject* obj) { //DEMO Commands->Enable_Hibernation(obj, false); startloc = Commands->Get_Position(obj); //DEMO stop_following = false; // Special case checks for preplaced soldiers - A01 currently, others to come. int area_id = Get_Int_Parameter("Area_ID"); if (area_id == 1) { Commands->Innate_Disable (obj); } else { // Default spawned following unit - Give orders to stay near the commando on a timer. Commands->Start_Timer(obj, this, 1.0f, 1); } } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { int type = Get_Int_Parameter("Soldier_Type"); if (type < 12) { Commands->Apply_Damage(obj, 10000.0f, "Blamokiller"); } if (!stop_following) { // Follow the commando. //Start this check timer again. Vector3 mypos = Commands->Get_Position(obj); //DEMO GameObject *starobj = Commands->Get_A_Star (mypos); GameObject *starobj = Commands->Find_Object(403063); //DEMO if (starobj) { ActionParamsStruct params; params.Set_Basic(this, 71, 0); params.Set_Movement(starobj, 1.0f, 10.0f, 0); Commands->Action_Goto(obj, params); } else { stop_following = true; } //DEBUG good time to make a quip or comment. } Commands->Start_Timer(obj, this, 10.0f, 1); } } void Sound_Heard (GameObject * obj, const CombatSound & sound) { if ((sound.Type > 1099) && (sound.Type < 1199)) { // Make sure this is the sound this unit is supposed to react to. int area_id = Get_Int_Parameter("Area_ID"); if ((sound.Type - 1100) == area_id) { stop_following = true; switch (area_id) { case (0): { Vector3 guard_tower_loc = Vector3(128.3f,22.3f,-9.6f); ActionParamsStruct params; params.Set_Basic(this, 81, 0); params.Set_Movement(guard_tower_loc, WALK, 1.0f, 0); Commands->Action_Goto(obj, params); //DEBUG say something to the commando here indicating a position hold. break; } case (2): { Vector3 house_loc = Vector3(648.77f,300.74f,-59.99f); ActionParamsStruct params; params.Set_Basic(this, 81, 0); params.Set_Movement(house_loc, WALK, 1.0f, 0); Commands->Action_Goto(obj, params); //DEBUG say something to the commando here indicating a position hold. break; } } } } } void Custom (GameObject *obj, int type, int param, GameObject *sender) { if ((type == 0) && (param == 0)) { // A zone is trying to enable actions for this soldier. Commands->Innate_Enable (obj); } } //DEMO void Destroyed (GameObject* obj) { int type = Get_Int_Parameter("Soldier_Type"); switch (type) { case (12): { GameObject * soldier = Commands->Create_Object("GDI_Grenadier_2SF", startloc); if (soldier) { Commands->Attach_Script(soldier, "MDD_GDI_Soldier", "25, 12"); } break; } case (13): { GameObject * soldier = Commands->Create_Object("GDI_MiniGunner_2SF", startloc); if (soldier) { Commands->Attach_Script(soldier, "MDD_GDI_Soldier", "25, 13"); } break; } case (14): { GameObject * soldier = Commands->Create_Object("GDI_RocketSoldier_2SF", startloc); if (soldier) { Commands->Attach_Script(soldier, "MDD_GDI_Soldier", "25, 14"); } break; } } } //DEMO }; DECLARE_SCRIPT (MDD_Stationary_Vehicle,"Area_ID:int") { void Created (GameObject* obj) { //DEMO Commands->Set_Shield_Type (obj, "Blamo"); Commands->Enable_Enemy_Seen (obj, true); //DEMO int area_id; area_id = Get_Int_Parameter("Area_ID"); // Area One is a conflict area, other stationary vehicles in conflict areas must be paused as well //DEMO Commands->Enable_Enemy_Seen (obj, false); if (area_id == 99) { Commands->Start_Timer(obj, this, 6.0f, 1); } } void Enemy_Seen (GameObject * obj, GameObject * enemy) { ActionParamsStruct params; params.Set_Basic(this, 90, 0); params.Set_Attack(enemy, 300.0f, 0.0f, true); params.AttackCheckBlocked = false; Commands->Action_Attack(obj, params); Commands->Start_Timer(obj, this, 5.0f, 2); } void Sound_Heard (GameObject * obj, const CombatSound & sound) { // If an objective shouts, respond to it, letting it know the area is not cleared. if (sound.Type == 1000) { if (sound.Creator) { int player_type = Commands->Get_Player_Type (obj); if (player_type == SCRIPT_PLAYERTYPE_NOD) { Commands->Send_Custom_Event(obj, sound.Creator, 100, 1); } } } } void Custom (GameObject *obj, int type, int param, GameObject *sender) { if ((type == 0) && (param == 0)) { // A zone is trying to enable actions for this vehicle. Commands->Enable_Enemy_Seen (obj, true); } } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { Commands->Apply_Damage (obj, 10000.0f, "Blamokiller"); } else if (timer_id == 2) { Commands->Action_Reset (obj, 100); } } }; DECLARE_SCRIPT (MDD_Nod_Apache, "Area_ID:int") { int waypath_id; REGISTER_VARIABLES() { SAVE_VARIABLE( waypath_id, 1); } void Created (GameObject* obj) { int area_id = Get_Int_Parameter("Area_ID"); float timer_len = 1.0f; //First waypath means area for looping Apaches, it is set when timer expires, and then uses real IDs. switch (area_id) { case (0): { waypath_id = 0; timer_len = 8.0f; break; } case (15): { waypath_id = 1; timer_len = 15.0f; break; } case (24): { waypath_id = 24; break; } } Commands->Enable_Engine(obj, true); Commands->Disable_Physical_Collisions(obj); Commands->Start_Timer(obj, this, timer_len, 1); Commands->Start_Timer(obj, this, 15.0f, 3); } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { // Delayed initial action. switch (waypath_id) { case (0): // Area 0 Apache delay timer expired, start movement { waypath_id = 400296; break; } case (1): // Area 15 Apache delay timer expired, start movement. { waypath_id = 401169; break; } case (24): { waypath_id = 400544; break; } case (400296): { waypath_id = 400304; break; } case (400304): { waypath_id = 400310; break; } case (400310): { waypath_id = 400304; break; } case (400544): { waypath_id = -1; break; } case (401169): { waypath_id = 401173; break; } case (401173): { waypath_id = 401180; break; } case (401180): { waypath_id = 401173; break; } } if (waypath_id != -1) { ActionParamsStruct params; params.Set_Basic(this, 90, 0); params.Set_Movement(Vector3(0,0,0), 0.2 + (0.1 * DIFFICULTY), 5.0f); params.WaypathID = waypath_id; params.WaypathSplined = true; params.Set_Attack(STAR, 200.0f, 0.0f, true); params.AttackCheckBlocked = false; params.AttackActive = false; Commands->Action_Attack(obj, params); } Commands->Start_Timer(obj, this, 5.0f, 2); } else if (timer_id == 2) { // Time to start firing, and move again in a second. Vector3 myloc = Commands->Get_Position(obj); //DEMO GameObject* target = Commands->Find_Object(403063); //DEMO ActionParamsStruct params; params.Set_Basic(this, 90, 0); params.Set_Movement(myloc, 0.0, 5.0f); //DEMO params.Set_Attack(STAR, 200.0f, 0.0f, true); params.Set_Attack(target, 200.0f, 0.0f, true); //DEMO params.AttackCheckBlocked = false; params.AttackActive = true; Commands->Action_Attack(obj, params); Commands->Start_Timer(obj, this, 5.0f, 1); } else if (timer_id == 3) { // Cleanup code - find the nearest star, check distance. float distance; Vector3 myloc; Vector3 starloc; myloc = Commands->Get_Position(obj); GameObject *star_obj = Commands->Get_A_Star(myloc); if (star_obj) { starloc = Commands->Get_Position(star_obj); distance = Commands->Get_Distance (myloc, starloc); //DEMO if (distance > 300.0f) if (distance > 3000.0f) //DEMO { Commands->Apply_Damage(obj, 10000.0f, "Blamokiller"); } } Commands->Start_Timer(obj, this, 15.0f, 3); } } // If an objective shouts, respond to it, letting it know the area is not cleared. void Sound_Heard (GameObject * obj, const CombatSound & sound) { if (sound.Type == 1000) { if (sound.Creator) { Commands->Send_Custom_Event(obj, sound.Creator, 100, 1); } } } }; DECLARE_SCRIPT (MDD_Nod_Stealth, "") { bool nofiring; void Created (GameObject* obj) { Commands->Enable_Hibernation(obj, false); nofiring = true; Commands->Enable_Enemy_Seen (obj, true); ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Movement(Vector3(0,0,0), 2.5f, 1.0f); params.WaypathID = 401465; Commands->Action_Goto(obj, params); Commands->Start_Timer(obj, this, 10.0f, 1); Commands->Start_Timer(obj, this, 2.0f, 3); } void Enemy_Seen (GameObject * obj, GameObject * enemy) { if (!nofiring) { nofiring = true; ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Attack(enemy, 200.0f, 0.0f, true); params.AttackActive = true; Commands->Action_Attack (obj, params); Commands->Start_Timer(obj, this, 10.0f, 2); } } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { nofiring = false; } else if (timer_id == 2) { ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Movement(Vector3(0,0,0), 2.5f, 1.0f); params.WaypathID = 401465; Commands->Action_Goto(obj, params); Commands->Start_Timer(obj, this, 10.0f, 1); } else if (timer_id == 3) { Vector3 myloc = Commands->Get_Position (obj); Commands->Create_Logical_Sound (obj, 1999, myloc, 10.0f); Commands->Start_Timer(obj, this, 2.0f, 3); } } void Destroyed (GameObject* obj) { GameObject * nodtank = Commands->Create_Object("Nod_Stealth_Tank", Vector3(598.777f,479.691f,-55.824f)); if (nodtank) { Commands->Set_Facing(nodtank, -100.0f); Commands->Attach_Script(nodtank, "MDD_Nod_Stealth", ""); } } }; DECLARE_SCRIPT (MDD_Flying_Vehicle, "Unit_ID:int") { void Created (GameObject* obj) { Commands->Enable_Hibernation(obj, false); Commands->Enable_Enemy_Seen (obj, true); int unit_id = Get_Int_Parameter ("Unit_ID"); int waypath_id = 0; if (unit_id) { waypath_id = 402786; } else { waypath_id = 402768; } Commands->Enable_Engine(obj, true); Commands->Disable_Physical_Collisions(obj); ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Movement(Vector3(0,0,0), 2.5f, 1.0f); params.WaypathID = waypath_id; params.WaypathSplined = true; Commands->Action_Goto(obj, params); Commands->Start_Timer(obj, this, 15.0f, 1); } void Enemy_Seen (GameObject * obj, GameObject * enemy) { ActionParamsStruct params; params.Set_Basic(this, 92, 2); params.AttackCheckBlocked = false; params.Set_Attack(enemy, 300.0f, 0.0f, true); Commands->Action_Attack(obj, params); } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { Vector3 myloc = Commands->Get_Position(obj); ActionParamsStruct params; params.Set_Basic(this, 99, 1); params.Set_Movement(myloc, 0.0, 5.0f); Commands->Action_Goto(obj, params); Commands->Start_Timer(obj, this, 10.0f, 2); } else if (timer_id == 2) { int waypath_id = 0; ActionParamsStruct params; params.Set_Basic(this, 99, 0); params.Set_Movement(Vector3(0,0,0), 2.5f, 1.0f); int unit_id = Get_Int_Parameter ("Unit_ID"); if (unit_id) { waypath_id = 402798; } else { waypath_id = 402777; } params.WaypathID = waypath_id; params.WaypathSplined = true; Commands->Action_Goto(obj, params); Commands->Start_Timer(obj, this, 15.0f, 3); } else { Commands->Apply_Damage(obj, 10000.0f, "Blamokiller"); } } void Destroyed (GameObject* obj) { GameObject * object = Commands->Find_Object(M02_OBJCONTROLLER); if (object) { int unit_id = Get_Int_Parameter ("Unit_ID"); if (!unit_id) { Commands->Send_Custom_Event(obj, object, 180, 0); } else { Commands->Send_Custom_Event(obj, object, 181, 0); } } } }; DECLARE_SCRIPT (MDD_Commando, "") { void Created (GameObject* obj) { Commands->Control_Enable (obj, false); Commands->Set_Shield_Type (obj, "Blamo"); } }; DECLARE_SCRIPT (MDD_Havoc_Unit, "") { bool forcemove; void Created (GameObject* obj) { Commands->Enable_Hibernation(obj, false); forcemove = true; Commands->Set_Shield_Type (obj, "Blamo"); Commands->Set_Shield_Strength (obj, 100.0f); Commands->Start_Timer(obj, this, 5.0f, 1); // move to the center of the field ActionParamsStruct params; params.Set_Basic(this, 99, 1); params.Set_Movement(Vector3(544.119f,339.562f,-60.75f), 1.0, 20.0f); Commands->Action_Goto(obj, params); } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if ((type == 100) && (param == 0)) { if (forcemove) { forcemove = false; ActionParamsStruct params; params.Set_Basic(this, 70, 1); params.Set_Movement(sender, 1.0, 1.0f); Commands->Action_Goto(obj, params); } } } void Timer_Expired(GameObject * obj, int timer_id) { if (timer_id == 1) { forcemove = true; Commands->Start_Timer(obj, this, 10.0f, 1); } } void Sound_Heard (GameObject * obj, const CombatSound & sound) { if (sound.Type == 1999) { if (sound.Creator) { ActionParamsStruct params; params.Set_Basic(this, 99, 1); params.Set_Movement(Vector3(544.119f,339.562f,-60.75f), 1.0, 20.0f); Commands->Action_Goto(obj, params); } } } };