/* ** 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_Actions.cpp * * DESCRIPTION * Designer Toolkit for Mission Construction - Actions Subset * * PROGRAMMER * Design Team * * VERSION INFO * $Author: Ryan_v $ * $Revision: 10 $ * $Modtime: 11/03/00 2:25p $ * $Archive: /Commando/Code/Scripts/Toolkit_Actions.cpp $ * ******************************************************************************/ #include "toolkit.h" /*Editor Script - M00_Action Animations are not handled with this script - they are handled separately. Parameters: _Move_Target_ID = The Target ID to move towards. _Move_Following = Whether this unit should follow the Target ID or not. _Move_Destination = The Vector3 location of the movement destination. _Move_Waypath_ID = The ID of a waypath to follow. _Move_Waypath_Start_ID = The starting point to use on the waypath. _Move_Waypath_End_ID = The ending point to use on the waypath. _Move_Waypath_Splined = Whether to use splined movement or not on waypaths. _Move_Waypath_Looping = If the unit should circle on the waypath. _Move_Patrol_Radius = A radius to use if patrolling an area. _Move_Patrol_Loiter_Time = How long to wait at each point until patrolling again. _Move_Arrive_Distance = The distance to close to with the destination. _Move_Speed = The speed at which the unit moves. _Move_Crouch = Whether to move crouched or not. _Move_Backwards = Whether to move backwards or not. _Move_Pathfind = Whether to use pathfinding data for movement or not. _Attack_Target_ID = The attack target's ID. _Attack_Location = The location of the attack (if no target). _Attack_Range = The maximum effective range of the attack. _Attack_Deviation = The deviation of the attack. _Attack_Primary = Whether to use the primary weapon or not. _Attack_Crouched = Whether to crouch when firing or not. */ DECLARE_SCRIPT(M00_Action, "Start_Now=0:int, Receive_Type=14:int, Receive_Param_On=1:int, Receive_Param_Off=0:int, Action_Priority=99:int, Action_ID=0:int, _Move_Target_ID=0:int, _Move_Following=0:int, _Move_Destination:vector3, _Move_Waypath_ID=0:int, _Move_Waypath_Start_ID=0:int, _Move_Waypath_End_ID:int, _Move_Waypath_Splined=0:int, _Move_Arrive_Distance=1.0:float, _Move_Speed=1.0:float, _Move_Crouch=0:int, _Move_Backwards=0:int, _Move_Pathfind=1:int, _Attack_Target_ID=0:int, _Attack_Location:vector3, _Attack_Range=100.0:float, _Attack_Deviation=0.0:float, _Attack_Primary=1:int, _Attack_Crouched=0:int, Debug_Mode=0:int") { bool debug_mode; bool script_active; bool attacking; bool primary_weapon; Vector3 current_position; Vector3 current_fire_position; Vector3 current_attack_location; Vector3 empty_vector; void Created(GameObject* obj) { ActionParamsStruct params; script_active = false; attacking = false; debug_mode = (Get_Int_Parameter("Debug_Mode") == 1) ? true : false; GameObject* move_target; GameObject* attack_target; move_target = Commands->Find_Object(Get_Int_Parameter("_Move_Target_ID")); attack_target = Commands->Find_Object(Get_Int_Parameter("_Attack_Target_ID")); primary_weapon = (Get_Int_Parameter("_Attack_Primary") == 1) ? true : false; current_attack_location = Get_Vector3_Parameter("_Attack_Location"); empty_vector = Vector3(0.0f,0.0f,0.0f); params.Set_Basic(this, Get_Int_Parameter("Action_Priority"), Get_Int_Parameter("Action_ID")); params.Set_Movement(Get_Vector3_Parameter("_Move_Destination"), Get_Float_Parameter("_Move_Speed"), Get_Float_Parameter("_Move_Arrive_Distance")); params.Set_Attack(Get_Vector3_Parameter("_Attack_Location"), Get_Float_Parameter("_Attack_Range"), Get_Float_Parameter("_Attack_Deviation"), primary_weapon); params.MoveBackup = (Get_Int_Parameter("_Move_Backwards") == 1) ? true : false; params.MoveFollow = (Get_Int_Parameter("_Move_Following") == 1) ? true : false; params.MoveCrouched = (Get_Int_Parameter("_Move_Crouch") == 1) ? true : false; params.MovePathfind = (Get_Int_Parameter("_Move_Pathfind") == 1) ? true : false; params.AttackCrouched = (Get_Int_Parameter("_Attack_Crouched") == 1) ? true : false; params.WaypathID = Get_Int_Parameter("_Move_Waypath_ID"); params.WaypointStartID = Get_Int_Parameter("_Move_Waypath_Start_ID"); params.WaypointEndID = Get_Int_Parameter("_Move_Waypath_End_ID"); params.WaypathSplined = (Get_Int_Parameter("_Move_Waypath_Splined") == 1) ? true : false; if (attack_target) { // Attacking a target, override the attack location values params.Set_Attack(attack_target, Get_Float_Parameter("_Attack_Range"), Get_Float_Parameter("_Attack_Deviation"), primary_weapon); attacking = true; } if (current_attack_location != empty_vector) { // Attacking a location, be sure to turn on attacking bool attacking = true; } if (move_target) { // Moving toward a target, override other movement values params.Set_Movement(move_target, Get_Float_Parameter("_Move_Speed"), Get_Float_Parameter("_Move_Arrive_Distance")); params.WaypathID = 0; params.WaypointStartID = 0; params.WaypointEndID = 0; params.WaypathSplined = false; } if (params.MoveLocation != empty_vector) { // Moving to a location, override other movement values params.WaypathID = 0; params.WaypointStartID = 0; params.WaypointEndID = 0; params.WaypathSplined = false; } if (Get_Int_Parameter("Start_Now")) { SCRIPT_DEBUG_MESSAGE(("M00_Action ACTIVATED.\n")); script_active = true; if (script_active) { // Check if we are firing and moving, or just moving. if (attacking) { SCRIPT_DEBUG_MESSAGE(("M00_Action is moving and attacking.\n")); Commands->Action_Attack(obj, params); } else { SCRIPT_DEBUG_MESSAGE(("M00_Action is moving only - no attack.\n")); Commands->Action_Goto(obj, params); } } } } void Custom(GameObject * obj, int type, int param, GameObject * sender) { SCRIPT_DEBUG_MESSAGE(("M00_Action received custom type %d, param %d.\n", type, param)); if (type == Get_Int_Parameter("Receive_Type")) { if (param == Get_Int_Parameter("Receive_Param_On")) { GameObject* move_target; GameObject* attack_target; move_target = Commands->Find_Object(Get_Int_Parameter("_Move_Target_ID")); attack_target = Commands->Find_Object(Get_Int_Parameter("_Attack_Target_ID")); ActionParamsStruct params; params.Set_Basic(this, Get_Int_Parameter("Action_Priority"), Get_Int_Parameter("Action_ID")); params.Set_Movement(Get_Vector3_Parameter("_Move_Destination"), Get_Float_Parameter("_Move_Speed"), Get_Float_Parameter("_Move_Arrive_Distance")); params.Set_Attack(Get_Vector3_Parameter("_Attack_Location"), Get_Float_Parameter("_Attack_Range"), Get_Float_Parameter("_Attack_Deviation"), primary_weapon); params.MoveBackup = (Get_Int_Parameter("_Move_Backwards") == 1) ? true : false; params.MoveFollow = (Get_Int_Parameter("_Move_Following") == 1) ? true : false; params.MoveCrouched = (Get_Int_Parameter("_Move_Crouch") == 1) ? true : false; params.MovePathfind = (Get_Int_Parameter("_Move_Pathfind") == 1) ? true : false; params.AttackCrouched = (Get_Int_Parameter("_Attack_Crouched") == 1) ? true : false; params.WaypathID = Get_Int_Parameter("_Move_Waypath_ID"); params.WaypointStartID = Get_Int_Parameter("_Move_Waypath_Start_ID"); params.WaypointEndID = Get_Int_Parameter("_Move_Waypath_End_ID"); params.WaypathSplined = (Get_Int_Parameter("_Move_Waypath_Splined") == 1) ? true : false; SCRIPT_DEBUG_MESSAGE(("M00_Action ACTIVATED.\n")); if (attack_target) { // Attacking a target, override the attack location values params.Set_Attack(attack_target, Get_Float_Parameter("_Attack_Range"), Get_Float_Parameter("_Attack_Deviation"), primary_weapon); attacking = true; } if (current_attack_location != empty_vector) { // Attacking a location, be sure to turn on attacking bool attacking = true; } if (move_target) { // Moving toward a target, override other movement values params.Set_Movement(move_target, Get_Float_Parameter("_Move_Speed"), Get_Float_Parameter("_Move_Arrive_Distance")); params.WaypathID = 0; params.WaypointStartID = 0; params.WaypointEndID = 0; params.WaypathSplined = false; } if (params.MoveLocation != empty_vector) { // Moving to a location, override other movement values params.WaypathID = 0; params.WaypointStartID = 0; params.WaypointEndID = 0; params.WaypathSplined = false; } if (script_active) { // Check if we are firing and moving, or just moving. if (attacking) { SCRIPT_DEBUG_MESSAGE(("M00_Action is moving and attacking.\n")); Commands->Action_Attack(obj, params); } else { SCRIPT_DEBUG_MESSAGE(("M00_Action is moving only - no attack.\n")); Commands->Action_Goto(obj, params); } } } if (param == Get_Int_Parameter("Receive_Param_Off")) { SCRIPT_DEBUG_MESSAGE(("M00_Action DEACTIVATED.\n")); script_active = false; Commands->Action_Reset(obj, Get_Int_Parameter("Action_Priority")+1); } } } void Action_Complete(GameObject * obj, int action_id, ActionCompleteReason reason) { if (script_active) { if (action_id == Get_Int_Parameter("Action_ID")) { switch (reason) { case (ACTION_COMPLETE_LOW_PRIORITY): { SCRIPT_DEBUG_MESSAGE(("M00_Action returned a Low Priority Warning.\n")); break; } case (ACTION_COMPLETE_PATH_BAD_START): { SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Action returned a Path Bad Start Error!\n")); break; } case (ACTION_COMPLETE_PATH_BAD_DEST): { SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Action returned a Path Bad Destination Error!\n")); break; } case (ACTION_COMPLETE_MOVE_NO_PROGRESS_MADE): { SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Action returned a No Progress Made Error!\n")); break; } case (ACTION_COMPLETE_ATTACK_OUT_OF_RANGE): { SCRIPT_DEBUG_MESSAGE(("ERROR - M00_Action returned an Attack Out Of Range Error!\n")); break; } case (MOVEMENT_COMPLETE_ARRIVED): { SCRIPT_DEBUG_MESSAGE(("M00_Action returned a Movement Complete Arrived.\n")); break; } default: { SCRIPT_DEBUG_MESSAGE(("M00_Action returned with default success.\n")); break; } } } } } }; DECLARE_SCRIPT(M00_Action_Set_Home_Location, "Start_Now=1:int, Receive_Type:int, Receive_Param_On:int, Home_Location:vector3, Wander_Distance=99999.0:float") { void Created(GameObject* obj) { if (Get_Int_Parameter("Start_Now")) { Set_Innate_Position (obj); } } 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")) { Set_Innate_Position (obj); } } } void Set_Innate_Position (GameObject* obj) { Commands->Set_Innate_Soldier_Home_Location(obj, Get_Vector3_Parameter("Home_Location"), Get_Float_Parameter("Wander_Distance")); } }; DECLARE_SCRIPT (M00_Action_Innate_Follow_Waypath, "Waypath_ID:int") { void Created (GameObject* obj) { Perform_Action (obj); } void Action_Complete(GameObject * obj, int action_id, ActionCompleteReason complete_reason) { //Commands->Start_Timer (obj, this, 3.0f, 32); } void Timer_Expired (GameObject * obj, int timer_id) { if (timer_id == 32) { Perform_Action (obj); } } void Perform_Action (GameObject* obj) { /* ActionParamsStruct params; params.Set_Basic(this, 29, 11); params.Set_Movement(Vector3(0.0f,0.0f,0.0f), 0.5f, 1.0f); params.WaypathID = Get_Int_Parameter("Waypath_ID"); Commands->Action_Goto (obj, params); */ } }; DECLARE_SCRIPT (M00_Action_Innate_Follow_Player, "") { void Created (GameObject* obj) { Commands->Start_Timer (obj, this, 1.0f, 33); } void Timer_Expired (GameObject* obj, int timer_id) { if (timer_id == 33) { Vector3 my_loc = Commands->Get_Position(obj); GameObject * nearest = Commands->Get_A_Star (my_loc); if (nearest) { ActionParamsStruct params; params.Set_Basic(this, 39, 11); params.Set_Movement(nearest, 1.0f, 3.0f); Commands->Action_Goto (nearest, params); Commands->Start_Timer (obj, this, 10.0f, 33); } } } };