| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- /*
- ** 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
- *
- * DESCRIPTION
- *
- * PROGRAMMER
- * Denzil E. Long, Jr.
- *
- * VERSION INFO
- * $Author: Byon_g $
- * $Revision: 85 $
- * $Modtime: 7/05/01 12:12p $
- * $Archive: /Commando/Code/Scripts/scripts.cpp $
- *
- ******************************************************************************/
- #include "scripts.h"
- #include "scriptfactory.h"
- #include "dprint.h"
- #include "strtrim.h"
- #include <string.h>
- #include <stdio.h>
- #define CHUNKID_SCRIPTHEADER 'shdr'
- #define CHUNKID_SCRIPTDATA 'sdat'
- #define CHUNKID_SCRIPT_AUTO_VARIABLES 'csav'
- enum {
- DATAID_PARAMETER_STRING = 1,
- DATAID_OWNERPTR,
- };
- // Script commands
- ScriptCommands* Commands = NULL;
- void (*ScriptImpClass::Request_Destroy_Script)(ScriptClass*) = NULL;
- void ScriptImpClass::Set_Request_Destroy_Func(void (*function)(ScriptClass*))
- {
- Request_Destroy_Script = function;
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::ScriptImpClass
- *
- * DESCRIPTION
- * Constructor for concrete script implementation class
- *
- * INPUTS
- * NONE
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- ScriptImpClass::ScriptImpClass()
- : mOwner(NULL),
- mArgC(0),
- mArgV(NULL),
- AutoVariableList( NULL )
- {
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::~ScriptImpClass
- *
- * DESCRIPTION
- * Destructor
- *
- * INPUTS
- * NONE
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- ScriptImpClass::~ScriptImpClass()
- {
- #ifdef _DEBUG
- if (Commands != NULL) {
- DebugPrint("Script '%s' for object '%d' deleted.\n",
- Get_Name(), ((mOwner != NULL) ? Commands->Get_ID(mOwner) : 0 ));
- }
- #endif
- Clear_Parameters();
- // Delete the auto variables
- while ( AutoVariableList != NULL ) {
- ScriptVariableClass * next = AutoVariableList->Get_Next();
- delete AutoVariableList;
- AutoVariableList = next;
- }
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Name
- *
- * DESCRIPTION
- * Retrieve name of script
- *
- * INPUTS
- * NONE
- *
- * RESULTS
- * Name - Script name string.
- *
- ******************************************************************************/
- const char* ScriptImpClass::Get_Name(void)
- {
- return mFactory->GetName();
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Destroy
- *
- * DESCRIPTION
- * Destroy script
- *
- * INPUTS
- * NONE
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Destroy_Script(void)
- {
- if (Request_Destroy_Script != NULL) {
- Request_Destroy_Script(this);
- }
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Attach
- *
- * DESCRIPTION
- * Handle attachment of script to an object
- *
- * INPUTS
- * Object - Object script is attaching to.
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Attach(GameObject* obj)
- {
- #ifdef _DEBUG
- if (Commands != NULL) {
- DebugPrint("Attaching script '%s' to object %d\n",
- Get_Name(), Commands->Get_ID(obj));
- }
- #endif
- mOwner = obj;
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Detach
- *
- * DESCRIPTION
- * Handle detachment of script from an object.
- *
- * INPUTS
- * Object - Object script is detaching from.
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Detach(GameObject* obj)
- {
- mOwner = NULL;
- Destroy_Script();
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Set_Parameters_String
- *
- * DESCRIPTION
- * Set script parameters.
- *
- * INPUTS
- * Params - Parameter string
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Set_Parameters_String(const char* params)
- {
- if ((params == NULL) || (strlen(params) == 0)) {
- return;
- }
- DebugPrint("Setting parameters for script '%s', params = '%s'\n",
- Get_Name(), params);
- char* working = strdup(params);
- if ( strlen( working ) && working[ strlen( working ) - 1 ] == '\n' ) {
- working[ strlen( working ) - 1 ] = 0;
- }
- // Count the parameters
- int count = 0;
- char * param_ptr = working;
- if ( *param_ptr ) count++;
- for ( param_ptr = working; *param_ptr; param_ptr++ ) {
- if ( *param_ptr == ',' ) count++;
- }
- if (count == 0) {
- return;
- }
- // Release old argument vector
- Clear_Parameters();
- // Create new argument vector
- mArgC = count;
- mArgV = new char*[count];
- assert(mArgV != NULL);
- memset(mArgV, 0, (sizeof(char*) * count));
- // Copy the parameters
- strcpy(working, params);
- count = 0;
- param_ptr = working;
- while ( *param_ptr ) {
- // Find where this parameter ends
- char * next = param_ptr;
- while ( *next && *next != ',' ) next++;
- if ( *next ) *next++ = 0;
- // Set param
- Set_Parameter(count++, param_ptr);
- param_ptr = next;
- }
- if (count == mArgC - 1) {
- Set_Parameter(count, "");
- }
- free(working);
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Parameters_String
- *
- * DESCRIPTION
- * Retrieve a copy of the scripts parameters string.
- *
- * INPUTS
- * Buffer - Buffer to copy parameter string into.
- * Size - Size of buffer.
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Get_Parameters_String(char* buffer, unsigned int size)
- {
- assert(buffer != NULL);
- buffer[0] = '\0';
- // Build parameter string (comma seperated)
- int count = Get_Parameter_Count();
- int i = 0;
- unsigned int stringLen = 0;
- while ((i < count) && (stringLen < size)) {
- if (i > 0) {
- stringLen++;
- strcat(buffer, ",");
- }
- const char* param = Get_Parameter(i);
- stringLen += strlen(param);
- if (stringLen <= size) {
- strcat(buffer, param);
- i++;
- }
- }
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Clear_Parameters
- *
- * DESCRIPTION
- * Release script parameters
- *
- * INPUTS
- * NONE
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Clear_Parameters(void)
- {
- if (mArgV != NULL) {
- while (mArgC--) {
- if (mArgV[mArgC] != NULL) {
- free((void*)mArgV[mArgC]);
- }
- }
- delete (void*)mArgV;
- }
- mArgC = 0;
- mArgV = NULL;
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Set_Parameter
- *
- * DESCRIPTION
- * Set a script parameter
- *
- * INPUTS
- * Index - Ordinal position of parameter
- * Param - Parameter string
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Set_Parameter(int index, const char* str)
- {
- // Release old parameter
- if (mArgV[index] != NULL) {
- free((void*)mArgV[index]);
- }
- mArgV[index] = strdup(str);
- assert(mArgV[index] != NULL);
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Parameter
- *
- * DESCRIPTION
- * Retrieve paramter by name
- *
- * INPUTS
- * Name - Paramter name
- *
- * RESULTS
- * Param - Parameter
- *
- ******************************************************************************/
- const char* ScriptImpClass::Get_Parameter(const char* name)
- {
- int index = Get_Parameter_Index(name);
- return Get_Parameter(index);
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Parameter
- *
- * DESCRIPTION
- * Retrieve parameter at specified index.
- *
- * INPUTS
- * Index - Ordinal position of paramater
- *
- * RESULTS
- * Param - Parameter string.
- *
- ******************************************************************************/
- const char* ScriptImpClass::Get_Parameter(int index)
- {
- if ((index < 0) || (index >= mArgC)) {
- return "";
- }
- return mArgV[index];
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Int_Parameter
- *
- * DESCRIPTION
- * Retrieve parameter as an integer.
- *
- * INPUTS
- * Name - Name of parameter
- *
- * RESULTS
- * Value - Integer value.
- *
- ******************************************************************************/
- int ScriptImpClass::Get_Int_Parameter(const char* parameterName)
- {
- int index = Get_Parameter_Index(parameterName);
- return Get_Int_Parameter(index);
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Float_Parameter
- *
- * DESCRIPTION
- * Retrieve parameter as a floating point number.
- *
- * INPUTS
- * Name - Name of parameter
- *
- * RESULTS
- * Value - Floating point value
- *
- ******************************************************************************/
- float ScriptImpClass::Get_Float_Parameter(const char* parameterName)
- {
- int index = Get_Parameter_Index(parameterName);
- return Get_Float_Parameter(index);
- }
- /******************************************************************************
- **
- ******************************************************************************/
- Vector3 ScriptImpClass::Get_Vector3_Parameter( int index )
- {
- float x,y,z;
- ::sscanf( Get_Parameter( index ), "%f %f %f", &x, &y, &z );
- return Vector3( x,y,z );
- }
- Vector3 ScriptImpClass::Get_Vector3_Parameter(const char* parameterName)
- {
- int index = Get_Parameter_Index(parameterName);
- return Get_Vector3_Parameter(index);
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Get_Parameter_Index
- *
- * DESCRIPTION
- * Obtain index of parameter with specified name.
- *
- * INPUTS
- * Name - Name of parameter
- *
- * RESULTS
- * Index - Ordinal position of parameter
- *
- ******************************************************************************/
- int ScriptImpClass::Get_Parameter_Index(const char* parameterName)
- {
- const char* paramDesc = mFactory->GetParamDescription();
- // Make copy of parameter description string to work with.
- char string[512];
- strncpy(string, paramDesc, (sizeof(string) - 1));
- string[sizeof(string)-1] = '\0';
- // Search for the specified parameter
- int index = 0;
- char * param_ptr = string;
- while ( *param_ptr ) {
- // Find where this parameter ends
- char * next = param_ptr;
- while ( *next && *next != ',' ) next++;
- if ( *next ) *next++ = 0;
- // Strip the name portion from the parameter definition
- char* tokenEnd = strpbrk(param_ptr, "=:\n");
- if (tokenEnd != NULL) {
- *tokenEnd = '\0';
- }
- // Check for specified parameter
- strtrim(param_ptr);
- if (stricmp(param_ptr, parameterName) == 0) {
- return index;
- }
- // Advance to next parameter definition
- index++;
- param_ptr = next;
- }
- return -1;
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Save
- *
- * DESCRIPTION
- * Save script data
- *
- * INPUTS
- * ScriptSaver& saver
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Save(ScriptSaver& saver)
- {
- /* Commands->Begin_Chunk(saver, CHUNKID_SCRIPTDATA);
- Save_Data(saver);
- Commands->End_Chunk(saver);
- */
- ScriptVariableClass * var = AutoVariableList;
- if ( var != NULL ) {
- Commands->Begin_Chunk(saver, CHUNKID_SCRIPT_AUTO_VARIABLES);
- while ( var != NULL ) {
- Commands->Save_Data(saver, var->Get_ID(), var->Get_Data_Size(), var->Get_Data_Ptr() );
- var = var->Get_Next();
- }
- Commands->End_Chunk(saver);
- }
- }
- /******************************************************************************
- *
- * NAME
- * ScriptImpClass::Load
- *
- * DESCRIPTION
- * Load script data
- *
- * INPUTS
- * ScriptLoader& loader
- *
- * RESULTS
- * NONE
- *
- ******************************************************************************/
- void ScriptImpClass::Load(ScriptLoader& loader)
- {
- unsigned int chunkID;
- while (Commands->Open_Chunk(loader, &chunkID)) {
- switch (chunkID) {
- /* case CHUNKID_SCRIPTDATA:
- DebugPrint("Encountered data chunk.\n");
- Load_Data(loader);
- break;
- */
- case CHUNKID_SCRIPT_AUTO_VARIABLES:
- {
- int id;
- while (Commands->Load_Begin(loader, &id)) {
- // If we find this ID, load it
- ScriptVariableClass * var = AutoVariableList;
- while ( var != NULL ) {
- if ( var->Get_ID() == id ) {
- Commands->Load_Data(loader, var->Get_Data_Size(), var->Get_Data_Ptr() );
- }
- var = var->Get_Next();
- }
- Commands->Load_End(loader);
- }
- }
- break;
- default:
- DebugPrint("***** ScriptImpClass::Load() - Unrecognized chunk %0x!\n", chunkID);
- break;
- }
- Commands->Close_Chunk(loader);
- }
- }
- /*
- **
- */
- void ScriptImpClass::Auto_Save_Variable( void * data_ptr, int data_size, int id )
- {
- if ( ( id < 0 ) || ( id > 255 ) ) {
- DebugPrint("***** ScriptImpClass::Auto_Save_Variable Bad ID %d\n", id );
- return;
- }
- // First be sure we don't already have this ID
- ScriptVariableClass * var = AutoVariableList;
- while ( var != NULL ) {
- if ( var->Get_ID() == id ) {
- DebugPrint("***** ScriptImpClass::Auto_Save_Variable Dupe ID %d\n", id );
- return;
- }
- var = var->Get_Next();
- }
- // Never save more than 250 bytes
- if ( data_size > 250 ) {
- DebugPrint("***** ScriptImpClass::Too Much Save Data on ID %d\n", id );
- return;
- }
- // Then create and add the variable;
- AutoVariableList = new ScriptVariableClass( data_ptr, data_size, id, AutoVariableList );
- }
|