This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/Scripts/MissionDemo.cpp

1855 lines
No EOL
43 KiB
C++

/*
** 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 <http://www.gnu.org/licenses/>.
*/
/******************************************************************************
*
* 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);
}
}
}
};