/* ** 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 * Toolkit_Objects.cpp * * DESCRIPTION * Designer Toolkit for Mission Construction - Object Subset * * PROGRAMMER * Design Team * * VERSION INFO * $Author: Dave_s $ * $Revision: 27 $ * $Modtime: 12/11/01 11:13a $ * $Archive: /Commando/Code/Scripts/Toolkit_Objects.cpp $ * ******************************************************************************/ #include "toolkit.h" /*M00_Object_Create_RMV This script creates an object upon activation. Parameters: Object_To_Create = The object to create. Location = Where to create the object. Facing = What facing to place the object at. */ DECLARE_SCRIPT(M00_Object_Create_RMV, "Start_Now=0:int, Receive_Type:int, Receive_Param_On=1:int, Object_To_Create:string, Location:vector3, Facing=0.00:float, Debug_Mode=0:int") { bool debug_mode; REGISTER_VARIABLES() { SAVE_VARIABLE(debug_mode, 1); } void Created(GameObject* obj) { /* debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false; if (Get_Int_Parameter("Start_Now")) { SCRIPT_DEBUG_MESSAGE(("M00_Object_Create_RMV ACTIVATED.\n")); Create_Object(); } */ } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (type == Get_Int_Parameter("Receive_Type")) { if (param == Get_Int_Parameter("Receive_Param_On")) { SCRIPT_DEBUG_MESSAGE(("M00_Object_Create_RMV ACTIVATED.\n")); Create_Object(); } } } void Create_Object (void) { Vector3 position = Get_Vector3_Parameter("Location"); GameObject *new_object; new_object = Commands->Create_Object(Get_Parameter("Object_To_Create"), position); if (new_object) { Commands->Set_Facing(new_object, Get_Float_Parameter("Facing")); } else { SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Object_Create_RMV failed to create a new object!\n")); } } }; DECLARE_SCRIPT(M00_Object_Destroy_RMV, "Receive_Type_Activate:int, Debug_Mode=0:int") { int r_type; bool debug_mode; REGISTER_VARIABLES() { SAVE_VARIABLE(r_type, 1); SAVE_VARIABLE(debug_mode, 2); } void Created(GameObject * obj) { r_type = Get_Int_Parameter("Receive_Type_Activate"); debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false; } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (debug_mode) Commands->Debug_Message("M00_Destroy_Object_RMV received custom of type %d and param %d.\n", type, param); if (type == r_type) { if (Commands->Find_Object(param) != NULL) { Commands->Destroy_Object(Commands->Find_Object(param)); if (debug_mode) Commands->Debug_Message("M00_Destroy_Object_RMV - Object %d destroyed.\n", param); } else { if (debug_mode) Commands->Debug_Message("M00_Destroy_Object_RMV - Object %d not found!\n", param); } } } }; DECLARE_SCRIPT(M00_Object_Create_Attach_Script_RMV, "Start_Now=0:int, Receive_Type:int, Receive_Param_On=1:int, Object_To_Create:string, Location:vector3, Facing=0.00:float, Debug_Mode=0:int, Script_To_Attach:string, Script_Params:string") { bool debug_mode; void Created(GameObject* obj) { debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false; if (Get_Int_Parameter("Start_Now")) { if (debug_mode) { Commands->Debug_Message("M00_Object_Create_Attach_Script_RMV ACTIVATED.\n"); } Create_Object(); } } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (type == Get_Int_Parameter("Receive_Type")) { if (param == Get_Int_Parameter("Receive_Param_On")) { if (debug_mode) { Commands->Debug_Message("M00_Object_Create_Attach_Script_RMV ACTIVATED.\n"); } Create_Object(); } } } void Create_Object (void) { Vector3 position = Get_Vector3_Parameter("Location"); GameObject *new_object; char *params, fixed_params[255]; params = (char *)Get_Parameter("Script_Params"); Fix_Params(params, fixed_params); new_object = Commands->Create_Object(Get_Parameter("Object_To_Create"), position); if (new_object) { Commands->Set_Facing(new_object, Get_Float_Parameter("Facing")); Commands->Attach_Script(new_object, Get_Parameter("Script_To_Attach"), fixed_params); } else { if (debug_mode) { Commands->Debug_Message("ERROR - M00_Object_Create_Attach_Script_RMV failed to create a new object!\n"); } } } void Fix_Params(const char *input, char * output) { // copy string, converting | to , while ( *input != 0 ) { if ( *input == '|' ) { *output++ = ','; input++; } else { *output++ = *input++; } } *output = 0; // null terminate } }; DECLARE_SCRIPT(M00_Object_Destroy_Self_RMV, "Start_Now=1:int, Receive_Type=3:int, Receive_Param_On=1:int, Receive_Param_Off=0:int, Receive_Param_Activate:int, Debug_Mode=0:int") { bool active, debug_mode; int receive_type, receive_param_on, receive_param_off, receive_param_activate; REGISTER_VARIABLES() { SAVE_VARIABLE(active, 1); SAVE_VARIABLE(debug_mode, 2); SAVE_VARIABLE(receive_type, 3); SAVE_VARIABLE(receive_param_on, 4); SAVE_VARIABLE(receive_param_off, 5); SAVE_VARIABLE(receive_param_activate, 6); } void Created(GameObject * obj) { active = (Get_Int_Parameter("Start_Now") == 1) ? true : false; debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false; receive_type = Get_Int_Parameter("Receive_Type"); receive_param_on = Get_Int_Parameter("Receive_Param_On"); receive_param_off = Get_Int_Parameter("Receive_Param_Off"); receive_param_activate = Get_Int_Parameter("Receive_Param_Activate"); } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (debug_mode) Commands->Debug_Message("M00_Trigger_Destroy_Self_RMV received custom, type %d and param %d.\n", type, param); if (type == receive_type) { if (param == receive_param_on) { active = true; if (debug_mode) Commands->Debug_Message("M00_Trigger_Destroy_Self_RMV on object %d made ACTIVE.\n", Commands->Get_ID(obj)); } if (param == receive_param_off) { active = false; if (debug_mode) Commands->Debug_Message("M00_Trigger_Destroy_Self_RMV on object %d made INACTIVE.\n", Commands->Get_ID(obj)); } if ((param == receive_param_activate) && (active)) { if (debug_mode) Commands->Debug_Message("M00_Trigger_Destroy_Self_RMV activated on object %d, destroying.\n", Commands->Get_ID(obj)); Commands->Destroy_Object(obj); } } } }; /*********************************************************************************************************** * * PowerUp Creation * * - Includes ability to create any preset in the asset database by preset name * - Includes ability to check a random to drop item (Drop_Percentage) * - Arbitrary Create Position (Create_At_Death_Pos) & (Position) * - Provision to Play a "Spawning" Special Effect with Create_Anim_Effect_DAY Script * ***********************************************************************************************************/ DECLARE_SCRIPT(M00_PowerUp_Create_When_Killed_JDG, "Preset_Name:string,Drop_Percentage=100:float,Create_At_Death_Pos=1:int,Position:vector3,Z_Offset=0.75:float,Spawn_Effect=0:int") { void Killed( GameObject * obj, GameObject * killer ) { const char *preset_name; bool create_death_pos_flag; float random; Vector3 create_position; float z_offset; float drop_percentage; bool spawn_effect; preset_name = Get_Parameter( "Preset_Name" ); create_death_pos_flag = (Get_Int_Parameter( "Create_At_Death_Pos" ) == 1 ) ? true : false; z_offset = Get_Float_Parameter( "Z_Offset" ); drop_percentage = Get_Float_Parameter( "Drop_Percentage" ); random = Commands->Get_Random( 0, 1 ); spawn_effect = (Get_Int_Parameter( "Spawn_Effect" ) == 1 ) ? true : false; if ( drop_percentage > random ) { if ( create_death_pos_flag == true ) { create_position = Commands->Get_Position( obj ); } else { create_position = Get_Vector3_Parameter( "Position" ); } if ( z_offset != 0 ) { create_position.Z = create_position.Z + z_offset; } if (spawn_effect == true ) { GameObject *spawn_object; spawn_object = Commands->Create_Object( "Spawner Created Special Effect", create_position ); if ( spawn_object ) { Commands->Attach_Script( spawn_object, "M00_Create_Anim_Effect_DAY", "C4_EX1A.C4_EX1A"); } } Commands->Create_Object( preset_name, create_position ); } } }; /*********************************************************************************************************** * * One Time Special Effect Player * Used with M00_PowerUp_Create_When_Killed_JDG * * - Attach this script to an object that is created through script to play a W3d animation * - (Effect_Model:string) is the name of the animation of the object. * ***********************************************************************************************************/ DECLARE_SCRIPT(M00_Create_Anim_Effect_DAY, "Effect_Model:string") { void Created( GameObject * obj ) { ActionParamsStruct params; params.Set_Basic(this, 99, 1 ); params.Set_Animation( Get_Parameter("Effect_Model"), false ); Commands->Action_Play_Animation( obj, params ); } void Action_Complete(GameObject * obj, int action_id, ActionCompleteReason reason) { if ( obj ) { Commands->Destroy_Object( obj ); } } }; /*********************************************************************************************************** * * One Time Damage Modifier * * - Attach this script to an object that you do not want to recieve falling damage. * Such as from a paradrop. * ***********************************************************************************************************/ DECLARE_SCRIPT(M00_No_Falling_Damage_DME, "") { bool ignore_next_dmg; float initial_health; // Register variables to be Auto-Saved // All variables must have a unique ID, less than 256, that never changes REGISTER_VARIABLES() { SAVE_VARIABLE( ignore_next_dmg, 1 ); SAVE_VARIABLE( initial_health, 2 ); } void Created( GameObject * obj ) { ignore_next_dmg = false; } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (type == CUSTOM_EVENT_FALLING_DAMAGE) { ignore_next_dmg = true; initial_health = Commands->Get_Health(obj); } } void Damaged( GameObject * obj, GameObject *damager, float amount) { if (ignore_next_dmg && damager == NULL) { Commands->Set_Health(obj, initial_health); } ignore_next_dmg = false; } }; /*********************************************************************************************************** * * Permanent Damage Modifier * * - Attach this script to an object that you do not want to recieve falling damage. * ***********************************************************************************************************/ DECLARE_SCRIPT(M00_Permanent_No_Falling_Damage_IML, "") { float initial_health; // Register variables to be Auto-Saved // All variables must have a unique ID, less than 256, that never changes REGISTER_VARIABLES() { SAVE_VARIABLE( initial_health, 1 ); } void Created( GameObject * obj ) { initial_health = Commands->Get_Health(obj); } void Custom(GameObject * obj, int type, int param, GameObject * sender) { if (type == CUSTOM_EVENT_FALLING_DAMAGE) { initial_health = Commands->Get_Health(obj); } } void Damaged( GameObject * obj, GameObject *damager, float amount) { if (damager == NULL) { Commands->Set_Health(obj, initial_health); } } }; DECLARE_SCRIPT (M00_Disable_Transition, "") { void Created (GameObject * obj) { Commands->Enable_Vehicle_Transitions (obj, false); } }; /*********************************************************************************************************** * * Death Script for Fire, Gas and Electric troops. * * - new script for default Fire, Gas and Electric troop deaths. * - Takes preset DeathType:string ("Fire", "Gas", "Electric") and plays appropriate animation * and weapon FX. (1 = flailing and smoke. 2 = Elec Twiching and smoke? 3 = choking and green smoke. ) * ***********************************************************************************************************/ DECLARE_SCRIPT ( M00_Fire_Gas_Elec_Death_DAK, "DeathType=1:int,HealthThreshhold=0.25:float" ) { bool firsttime; // prevents an infinante loop each time obj is damaged by DeathType. void Damaged ( GameObject *obj, GameObject *damager, float amount ) { float bleah = Get_Float_Parameter( "HealthThreshhold" ); // check to see if obj is at 25% or less of its health. if ( Commands->Get_Health ( obj ) <= bleah * Commands->Get_Max_Health ( obj ) ) { // plays animation once. if ( firsttime == true ) { firsttime = false; ActionParamsStruct params; params.Set_Basic( this, 99, 1 ); // set animation based upon DeathType (Gas, Electric or Default to Fire) if ( Get_Int_Parameter( "DeathType" ) == 1 ) { params.Set_Animation( "S_A_HUMAN.H_A_FLMA",0 ); // fire death } else if ( Get_Int_Parameter( "DeathType" ) == 2 ) { params.Set_Animation( "S_A_HUMAN.H_A_6X05",0 ); // electric death } else params.Set_Animation( "S_A_HUMAN.H_A_6X01",0 ); // gas death Commands->Action_Play_Animation( obj, params ); // begin DeathType damage Commands->Apply_Damage( obj, 1.0f, Get_Parameter( "DeathType" ) ); } } } void Killed ( GameObject * obj, GameObject * killer ) { ActionParamsStruct params; params.Set_Basic( this, 99, 1 ); // set animation based upon DeathType (Gas, Electric or Default to Fire) if ( strcmp( Get_Parameter( "DeathType" ), "Fire" ) ) { params.Set_Animation( "S_A_HUMAN.H_A_FLMA",0 ); // Fire Death } else if ( strcmp( Get_Parameter( "DeathType" ), "Gas" ) ) { params.Set_Animation( "S_A_HUMAN.H_A_6X01",0 ); // Gas Death } else params.Set_Animation( "S_A_HUMAN.H_A_6X05",0 ); // Electrocution Commands->Action_Play_Animation( obj, params ); } void Created ( GameObject *obj ) { firsttime = true; } void Action_Complete(GameObject * obj, int action_id, ActionCompleteReason reason) { if((action_id == 1) && (reason == ACTION_COMPLETE_NORMAL)) { // animation is complete. kill obj. Commands->Apply_Damage (obj, 10000.0f, "Blamokiller"); } } }; /*********************************************************************************************************** * * Vehicle Health Regeneration Script for GDI Mammoth Tanks and Tiberium Harvesters. * * - continually checks vehicle's health to see if it needs to be regenerated. * - regenerates vehicle to 50% max health * ***********************************************************************************************************/ DECLARE_SCRIPT(M00_Vehicle_Regen_DAK, "" ) { void Created ( GameObject *obj ) { Commands->Send_Custom_Event ( obj, obj, 0, 0, 0 ); } void Custom (GameObject* obj, int type, int param, GameObject* sender) { if ( type == 0 ) // regenerate health. { // check to see if health needs to be regenerated. if ( Commands->Get_Health ( obj ) < ( Commands->Get_Max_Health ( obj ) ) ) { Commands->Apply_Damage (obj, -2, "RegenHealth", NULL); } // restart the timer Commands->Send_Custom_Event ( obj, obj, 0, 0, 1 ); } } }; DECLARE_SCRIPT(M00_PCT_Pokable_DAK, "" ) { void Created ( GameObject *obj ) { Commands->Enable_HUD_Pokable_Indicator( obj, true ); Commands->Display_Health_Bar( obj, false ); } }; DECLARE_SCRIPT(M00_Send_Object_ID, "Receiver_ID:int, Param=0:int, Delay=1.0f:int") { int r_type; bool debug_mode; REGISTER_VARIABLES() { SAVE_VARIABLE(r_type, 1); SAVE_VARIABLE(debug_mode, 2); } void Created(GameObject * obj) { // Send Custom and Parameter to Receiver object int receiver_id = Get_Int_Parameter("Receiver_ID"); int parameter = Get_Int_Parameter("Param"); float delay = Get_Float_Parameter("Delay"); GameObject * receiver = Commands->Find_Object(receiver_id); if(receiver) { Commands->Send_Custom_Event ( obj, Commands->Find_Object(receiver_id), M00_SEND_OBJECT_ID, parameter, delay ); } else { Commands->Debug_Message("M00_Send_Object_ID on object_id %d Warning! Receiver_ID %d does not exist! /n", Commands->Get_ID(obj), receiver_id); } } };