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/Test_Cinematic.cpp

1089 lines
31 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
*
* DESCRIPTION
*
* PROGRAMMER
* Byon Garrabrant
*
* VERSION INFO
* $Author: Greg_h $
* $Revision: 51 $
* $Modtime: 12/13/01 10:37a $
* $Archive: /Commando/Code/Scripts/Test_Cinematic.cpp $
*
******************************************************************************/
#include "scripts.h"
#include "toolkit.h"
#include <stdio.h>
#include <string.h>
#define LAST_VALID_TIMESTAMP 999000.0f
DECLARE_SCRIPT (M00_Cinematic_Attack_Command_DLS, "AttackDuration=1.0:float")
{
void Created( GameObject * obj )
{
float facing = Commands->Get_Facing(Owner());
Vector3 target = Commands->Get_Position(Owner());
target.X += cos(DEG_TO_RADF(facing)) * 10.0f;
target.Y += sin(DEG_TO_RADF(facing)) * 10.0f;
target.Z += 2.0f;
ActionParamsStruct params;
params.Set_Basic( this, 99, 1 );
params.Set_Attack( target, 100.0f, 0.0f, true );
params.AttackForceFire = true;
Commands->Action_Attack( obj, params );
Commands->Send_Custom_Event( obj, obj, 1, 1, Get_Float_Parameter("AttackDuration") );
}
void Custom( GameObject * obj, int type, int param, GameObject * sender )
{
Commands->Action_Reset( obj, 100 );
}
};
DECLARE_SCRIPT(Test_Cinematic_Primary_Killed, "CallbackID=:int")
{
bool custom_sent;
// Register variables to be Auto-Saved
// All variables must have a unique ID, less than 256, that never changes
REGISTER_VARIABLES()
{
SAVE_VARIABLE( custom_sent, 1 );
}
virtual void Created (GameObject *game_obj)
{
custom_sent = false;
}
virtual void Killed( GameObject * obj, GameObject * killer )
{
if (!custom_sent)
{
custom_sent = true;
Commands->Debug_Message( "Cinematic Primary Killed\n" );
int id = Get_Int_Parameter( "CallbackID" );
GameObject * callback = Commands->Find_Object( id );
if ( callback ) {
Commands->Send_Custom_Event( obj, callback, M00_CUSTOM_CINEMATIC_PRIMARY_KILLED, 0 );
}
}
}
virtual void Destroyed( GameObject * obj )
{
if (!custom_sent)
{
custom_sent = true;
Commands->Debug_Message( "Cinematic Primary Destroyed\n" );
int id = Get_Int_Parameter( "CallbackID" );
GameObject * callback = Commands->Find_Object( id );
if ( callback ) {
Commands->Send_Custom_Event( obj, callback, M00_CUSTOM_CINEMATIC_PRIMARY_KILLED, 0 );
}
}
}
};
DECLARE_SCRIPT(Test_Cinematic, "ControlFilename=:string")
{
public:
/*
** Object Slots
*/
#define NUM_SLOTS 40
int ObjectSlots[ NUM_SLOTS ];
int MyID; // doesn't need to be saved
/*
** Timing
*/
unsigned int LastSyncTime;
float Time;
float FrameSync;
bool PrimaryKilled;
bool IsCameraCinematic;
/*
** Parameters
*/
char * NextParameter;
/*
** Control Lines
*/
struct ControlLine {
float Time;
char * Command;
ControlLine * Next;
};
ControlLine * Controls;
void Add_Control_Line( float time, const char * command )
{
ControlLine * control = new ControlLine;
control->Time = time;
control->Command = strdup( command );
control->Next = NULL;
if ( Controls == NULL || Controls->Time > time ) {
control->Next = Controls;
Controls = control;
} else {
ControlLine * node = Controls;
while ( (node->Next != NULL) && (node->Next->Time <= time) ) {
node = node->Next;
}
control->Next = node->Next;
node->Next = control;
}
}
void Remove_Head_Control_Line( void )
{
if ( Controls != NULL ) {
ControlLine * control = Controls;
Controls = Controls->Next;
free( control->Command );
delete control;
}
}
void Display_Control_Lines( void )
{
for ( ControlLine * node = Controls; node != NULL; node = node->Next ) {
// Commands->Debug_Message( "%3.2f \"%s\"\n", node->Time, node->Command );
}
}
/*
** Loading the control file, line-by-line
*/
void Load_Control_File( const char * filename )
{
Commands->Debug_Message( "Loading Control File %s\n", (int)filename );
char full_filename[80];
sprintf( full_filename, "DATA\\%s", filename );
// FILE * in = fopen( full_filename, "rt" );
int handle = Commands->Text_File_Open( filename );
if ( handle == 0 ) {
Commands->Debug_Message( "Failed to open %s\n", (int)full_filename );
return;
}
char *line,line_data[200];
while ( Commands->Text_File_Get_String( handle, line_data, sizeof( line_data )-1 ) != NULL ) {
line = line_data;
// Convert tabs to spaces
for ( char * l = line; *l; l++ ) {
if ( *l == 9 ) *l = ' ';
}
// Remove leading and trailing white space
while ( *line && *line <= ' ' ) line++;
int length = ::strlen( line );
while ( (length != 0) && (line[length-1] <= ' ') ) {
line[--length] = 0;
}
if ( *line && *line != ';' ) { // ignore comments
float time;
time = atof( line );
if ( time < 0 ) { // handle frame numbers
time = -time / 30.f;
}
while ( *line && *line > ' ' ) line++;
while ( *line && *line <= ' ' ) line++;
if ( *line ) {
Add_Control_Line( time, line );
}
}
}
// fclose( in );
Commands->Text_File_Close( handle );
}
/*
**
*/
char * Get_Command_Parameter( char * string = NULL )
{
if ( string != NULL ) {
NextParameter = string;
}
if ( NextParameter == NULL || *NextParameter == 0 ) return "";
// Start at this parameter;
char * parameter = NextParameter;
// Skip leading whitespace
while ( *parameter != 0 && *parameter <= ' ' ) parameter++;
// if starting with quote, find end quote
if ( *parameter == '\"' ) {
parameter++;
NextParameter = parameter;
while ( *NextParameter && *NextParameter != '\"' ) {
NextParameter++;
}
}
// Find next parameter end
while ( *NextParameter && *NextParameter != ',' ) {
NextParameter++;
}
// Terminate
if ( *NextParameter ) {
*NextParameter++ = 0;
}
// Remove trailing whitespace
int length = ::strlen( parameter );
while ( length && parameter[ length-1 ] <= ' ' ) {
parameter[ --length ] = 0;
}
// Remove end quote
if ( length && parameter[ length-1 ] == '\"' ) {
parameter[ --length ] = 0;
}
return parameter;
}
#define CHUNKID_VARIABLES 1000
#define CHUNKID_OBJECT_SLOTS 1001
#define CHUNKID_CONTROL_LINES 1002
#define CHUNKID_VARIABLE_SYNC_DIFF 1
#define CHUNKID_VARIABLE_TIME 2
#define CHUNKID_CONTROL_TIME 4
#define CHUNKID_CONTROL_COMMAND_SIZE 5
#define CHUNKID_CONTROL_COMMAND 6
#define CHUNKID_PRIMARY_KILLED 7
/*
**
*/
void Save(ScriptSaver& saver)
{
// Commands->Debug_Message( "Cinematic Saving\n" );
// Commands->Debug_Message("Sync time is %d.\n", Commands->Get_Sync_Time());
// Save the Variables
Commands->Begin_Chunk(saver, CHUNKID_VARIABLES);
int sync_diff = Commands->Get_Sync_Time() - LastSyncTime;
Commands->Save_Data(saver, CHUNKID_VARIABLE_SYNC_DIFF, sizeof( sync_diff ), &sync_diff );
//Commands->Debug_Message( "Saving sync_diff %d\n", sync_diff );
Commands->Save_Data(saver, CHUNKID_VARIABLE_TIME, sizeof( Time ), &Time );
//Commands->Debug_Message( "Saving Time %f\n", Time );
Commands->Save_Data(saver, CHUNKID_PRIMARY_KILLED, sizeof( PrimaryKilled ), &PrimaryKilled );
Commands->End_Chunk(saver);
// Save the Object Slots
Commands->Begin_Chunk(saver, CHUNKID_OBJECT_SLOTS);
for ( int i = 0; i < NUM_SLOTS; i++ ) {
if ( ObjectSlots[i] != 0 ) {
Commands->Save_Data(saver, i, sizeof( ObjectSlots[i] ), &ObjectSlots[ i ] );
//Commands->Debug_Message( "Saving Slot %d as %d\n", i, ObjectSlots[ i ] );
}
}
Commands->End_Chunk(saver);
// Save Control Lines
Commands->Begin_Chunk(saver, CHUNKID_CONTROL_LINES);
ControlLine * controls = Controls;
while ( controls != NULL ) {
Commands->Save_Data(saver, CHUNKID_CONTROL_TIME, sizeof( controls->Time ), &controls->Time );
int len = strlen( controls->Command ) + 1;
Commands->Save_Data(saver, CHUNKID_CONTROL_COMMAND_SIZE, sizeof( len ), &len );
Commands->Save_Data(saver, CHUNKID_CONTROL_COMMAND, len, controls->Command );
//Commands->Debug_Message( "Saving Command %f %s\n", controls->Time, controls->Command );
controls = controls->Next;
}
Commands->End_Chunk(saver);
}
void Load(ScriptLoader& loader)
{
Controls = NULL;
NextParameter = NULL;
for ( int i = 0; i < NUM_SLOTS; i++ ) {
ObjectSlots[i] =0;
}
// Commands->Debug_Message( "Cinematic Loading\n" );
// Commands->Debug_Message("Sync time is %d.\n", Commands->Get_Sync_Time());
unsigned int chunkID;
while (Commands->Open_Chunk(loader, &chunkID)) {
switch (chunkID) {
case CHUNKID_VARIABLES:
{
int id;
int sync_diff;
while (Commands->Load_Begin(loader, &id)) {
switch ( id ) {
case CHUNKID_VARIABLE_SYNC_DIFF:
Commands->Load_Data(loader, sizeof( sync_diff ), &sync_diff );
//Commands->Debug_Message( "Loading sync_diff %d\n", sync_diff );
LastSyncTime = Commands->Get_Sync_Time() - sync_diff;
break;
case CHUNKID_VARIABLE_TIME:
Commands->Load_Data(loader, sizeof( Time ), &Time );
//Commands->Debug_Message( "Loading Time %f\n", Time );
break;
case CHUNKID_PRIMARY_KILLED:
Commands->Load_Data(loader, sizeof( PrimaryKilled ), &PrimaryKilled );
//Commands->Debug_Message( "Loading Time %f\n", Time );
break;
}
Commands->Load_End(loader);
}
}
break;
case CHUNKID_OBJECT_SLOTS:
{
int id;
while (Commands->Load_Begin(loader, &id)) {
if ( id >= 0 && id < NUM_SLOTS ) {
Commands->Load_Data(loader, sizeof( ObjectSlots[id] ), &ObjectSlots[id] );
//Commands->Debug_Message( "Loading Slot %d as %d\n", id, ObjectSlots[ id ] );
}
Commands->Load_End(loader);
}
}
break;
case CHUNKID_CONTROL_LINES:
{
int id;
float time = 0;
int len = 0;
while (Commands->Load_Begin(loader, &id)) {
if ( id == CHUNKID_CONTROL_TIME ) {
Commands->Load_Data(loader, sizeof( time ), &time );
}
if ( id == CHUNKID_CONTROL_COMMAND_SIZE ) {
Commands->Load_Data(loader, sizeof( len ), &len );
}
if ( id == CHUNKID_CONTROL_COMMAND ) {
#define MAX_COMMAND_LOAD_SIZE 200
char load_command[MAX_COMMAND_LOAD_SIZE+1];
if ( len < MAX_COMMAND_LOAD_SIZE ) {
Commands->Load_Data(loader, len, &load_command[0] );
Add_Control_Line( time, load_command );
//Commands->Debug_Message( "Loading Command %f %s\n", time, load_command );
}
}
Commands->Load_End(loader);
}
}
break;
default:
DebugPrint("***** Cinematic Script::Load() - Unrecognized chunk %0x!\n", chunkID);
break;
}
Commands->Close_Chunk(loader);
}
}
char * Get_First_Parameter( char * str ) { return Get_Command_Parameter( str ); }
char * Get_Next_Parameter( void ) { return Get_Command_Parameter(); }
/*
**
*/
void Command_Create_Object( char * params )
{
// Commands->Debug_Message_2( "Creating Object %s\n", (int)params );
int slot = atoi( Get_First_Parameter( params ) );
char * model_name = Get_Next_Parameter();
if ( (slot < 0) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 && ObjectSlots[ slot ] != 0 ) {
// Commands->Debug_Message( "Used Slot number %d\n", slot );
// Commands->Debug_Message( "Slot used by %d\n", ObjectSlots[ slot ] );
}
// Create a decoration cinematic object, then set it's model
GameObject * obj = Commands->Create_Object( "Generic_Cinematic", Commands->Get_Position( Owner() ) );
Commands->Enable_Hibernation( obj, false );
if ( obj ) {
Commands->Add_To_Dirty_Cull_List(obj);
Commands->Set_Model( obj, model_name );
Commands->Set_Facing( obj, Commands->Get_Facing( Owner() ) );
if ( slot != -1 ) {
ObjectSlots[ slot ] = Commands->Get_ID( obj );
}
if ( IsCameraCinematic ) {
Commands->Enable_Cinematic_Freeze( obj, false );
Commands->Enable_Hibernation(obj, false);
}
} else {
// Commands->Debug_Message( "Failed to create %s\n", (int)model_name );
}
}
/*
**
*/
void Command_Create_Real_Object( char * params )
{
// Commands->Debug_Message_2( "Creating Real Object %s\n", (int)params );
int slot = atoi( Get_First_Parameter( params ) );
char * preset_name = Get_Next_Parameter();
char * host_slot_name = Get_Next_Parameter();
char * host_bone_name = Get_Next_Parameter();
if ( (slot < 0) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 && ObjectSlots[ slot ] != 0 ) {
// Commands->Debug_Message( "Used Slot number %d\n", slot );
// Commands->Debug_Message( "Slot used by %d\n", ObjectSlots[ slot ] );
}
GameObject * obj = NULL;
if (( host_slot_name != NULL ) && ( *host_slot_name != 0 ) ) {
int host_slot = atoi( host_slot_name );
GameObject * host_obj = Commands->Find_Object( ObjectSlots[ host_slot ] );
obj = Commands->Create_Object_At_Bone( host_obj, preset_name, host_bone_name );
} else {
obj = Commands->Create_Object( preset_name, Commands->Get_Position( Owner() ) );
Commands->Set_Facing( obj, Commands->Get_Facing( Owner() ) );
}
if ( obj ) {
Commands->Enable_Engine( obj, true );
Commands->Add_To_Dirty_Cull_List(obj);
// Commands->Enable_Hibernation( obj, false );
if ( slot != -1 ) {
ObjectSlots[ slot ] = Commands->Get_ID( obj );
}
if ( IsCameraCinematic ) {
Commands->Enable_Cinematic_Freeze( obj, false );
Commands->Enable_Hibernation(obj, false);
}
} else {
// Commands->Debug_Message( "Failed to create real %s\n", (int)preset_name );
}
}
/*
**
*/
void Command_Create_Explosion( char * params )
{
// Commands->Debug_Message_2( "Creating Explosion %s\n", (int)params );
char * preset_name = Get_First_Parameter( params );
int host_slot = atoi( Get_Next_Parameter() );
char * host_bone_name = Get_Next_Parameter();
GameObject * host_obj = Commands->Find_Object( ObjectSlots[ host_slot ] );
Commands->Create_Explosion_At_Bone( preset_name, host_obj, host_bone_name );
}
void Command_Destroy_Object( char * params )
{
// Commands->Debug_Message_2( "Destroying Object %s\n", (int)params );
int slot = atoi( Get_First_Parameter( params ) );
if ( (slot < 0) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 ) {
if ( ObjectSlots[ slot ] == 0 ) {
// Commands->Debug_Message( "Empty Slot number %d\n", slot );
} else {
int id = ObjectSlots[ slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Destroy_Object( obj );
}
}
}
}
void Command_Play_Animation( char * params )
{
// Commands->Debug_Message( "Playing Animation %s\n", (int)params );
int slot = atoi( Get_First_Parameter( params ) );
char * name = Get_Next_Parameter();
bool looping = atoi( Get_Next_Parameter() ) != 0;
char * sub_obj_name = Get_Next_Parameter();
bool is_blended = atoi( Get_Next_Parameter() ) == 1;
if ( (slot < 0) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 ) {
int id = ObjectSlots[ slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Set_Animation( obj, name, looping, sub_obj_name, FrameSync, -1.0F, is_blended );
// Anyone that plays an animation in a camera cine, doesn't get innate
if ( IsCameraCinematic ) {
Commands->Innate_Disable( obj );
}
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", slot );
}
}
}
void Command_Play_Audio( char * params )
{
// Commands->Debug_Message( "Playing Audio %s\n", (int)params );
char * preset_name = Get_First_Parameter( params );
char * slot_name = Get_Next_Parameter();
char * bone_name = Get_Next_Parameter();
int slot = -1;
if (( slot_name != NULL ) && ( *slot_name != 0 ) ) {
slot = atoi( slot_name );
}
if ( (slot < 0) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 ) {
int id = ObjectSlots[ slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Create_3D_Sound_At_Bone( preset_name, obj, bone_name );
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", slot );
}
} else {
Commands->Create_2D_Sound( preset_name );
}
}
void Command_Control_Camera( char * params )
{
// Commands->Debug_Message_2( "Controlling the camera %s\n", (int)params );
int slot = atoi( Get_First_Parameter( params ) );
if ( (slot < -1) || ( slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", slot );
slot = -1;
}
if ( slot != -1 ) {
int id = ObjectSlots[ slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Set_Camera_Host( obj );
Commands->Control_Enable( Commands->Get_The_Star(), false );
Commands->Enable_HUD(0);
IsCameraCinematic = true;
Commands->Enable_Cinematic_Freeze( obj, false );
Commands->Enable_Hibernation(obj, false);
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", slot );
}
} else {
Commands->Set_Camera_Host( NULL );
Commands->Control_Enable( Commands->Get_The_Star(), true );
Commands->Enable_HUD(1);
}
}
void Command_Send_Custom( char * params )
{
// Commands->Debug_Message_2( "Send Custom %s\n", (int)params );
char * to_id_name = Get_First_Parameter( params );
int type = atoi( Get_Next_Parameter() );
char * parameter_name = Get_Next_Parameter();
int to_id = -1;
if ( ::strchr( to_id_name, '#' ) != NULL ) {
int to_slot = atoi( ::strchr( to_id_name, '#' ) + 1 );
if ( (to_slot < 0) || ( to_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", to_slot );
} else {
to_id = ObjectSlots[ to_slot ];
}
} else {
to_id = atoi( to_id_name );
}
int parameter = 0;
if ( ::strchr( parameter_name, '#' ) != NULL ) {
int parameter_slot = atoi( ::strchr( parameter_name, '#' ) + 1 );
if ( (parameter_slot < 0) || ( parameter_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Slot Number %d\n", parameter_slot );
} else {
parameter = ObjectSlots[ parameter_slot ];
}
} else {
parameter = atoi( parameter_name );
}
GameObject * to = Commands->Find_Object( to_id );
if ( to ) {
Commands->Send_Custom_Event( Owner(), to, type, parameter );
} else {
// Commands->Debug_Message( "Send Custom Target not found %d\n", to_id );
}
}
void Command_Attach_To_Bone( char * params )
{
// Commands->Debug_Message_2( "Attach_To_Bone %s\n", (int)params );
int obj_slot = atoi( Get_First_Parameter( params ) );
int host_slot = atoi( Get_Next_Parameter() );
char * bone_name = Get_Next_Parameter();
if ( (obj_slot < 0) || ( obj_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Obj Slot Number %d\n", obj_slot );
obj_slot = -1;
}
if ( (host_slot < 0) || ( host_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Host Slot Number %d\n", host_slot );
host_slot = -1;
}
if ( obj_slot != -1 ) {
int id = ObjectSlots[ obj_slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
if ( host_slot != -1 ) {
int id = ObjectSlots[ host_slot ];
GameObject * host = Commands->Find_Object( id );
if ( host ) {
Commands->Attach_To_Object_Bone( obj, host, bone_name );
} else {
// Commands->Debug_Message( "Host Object not found %d\n", host_slot );
}
} else {
Commands->Attach_To_Object_Bone( obj, NULL, NULL );
}
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", obj_slot );
}
}
}
void Command_Attach_Script( char * params )
{
// Commands->Debug_Message_2( "Attach_Script %s\n", (int)params );
int obj_slot = atoi( Get_First_Parameter( params ) );
char * script_name = Get_Next_Parameter();
char * script_parameters = Get_Next_Parameter();
if ( (obj_slot < 0) || ( obj_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Obj Slot Number %d\n", obj_slot );
obj_slot = -1;
}
if ( obj_slot != -1 ) {
int id = ObjectSlots[ obj_slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
// Commands->Debug_Message( "Attaching Script %s \"%s\"\n", script_name, script_parameters );
Commands->Attach_Script( obj, script_name, script_parameters );
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", obj_slot );
}
}
}
void Command_Set_Primary( char * params )
{
// Commands->Debug_Message_2( "Set_Primary %s\n", (int)params );
int obj_slot = atoi( Get_First_Parameter( params ) );
if ( (obj_slot < 0) || ( obj_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Obj Slot Number %d\n", obj_slot );
obj_slot = -1;
}
if ( obj_slot != -1 ) {
int id = ObjectSlots[ obj_slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Enable_Hibernation( obj, false );
char id[10];
sprintf( id, "%d", MyID );
Commands->Attach_Script( obj, "Test_Cinematic_Primary_Killed", id );
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", obj_slot );
}
}
}
void Command_Move_Slot( char * params )
{
int new_slot = atoi( Get_First_Parameter( params ) );
int old_slot = atoi( Get_Next_Parameter() );
if ( (new_slot < 0) || ( new_slot >= NUM_SLOTS ) ) {
new_slot = -1;
}
if ( (old_slot < 0) || ( old_slot >= NUM_SLOTS ) ) {
old_slot = -1;
}
if ( new_slot != -1 && old_slot != -1 && new_slot != old_slot ) {
ObjectSlots[ new_slot ] = ObjectSlots[ old_slot ];
ObjectSlots[ old_slot ] = 0;
}
}
void Command_Sniper_Control( char * params )
{
int enabled = atoi( Get_First_Parameter( params ) );
float zoom = atof( Get_Next_Parameter() );
Commands->Cinematic_Sniper_Control( enabled != 0, zoom );
}
void Command_Shake_Camera( char * params )
{
int obj_slot = atoi( Get_First_Parameter( params ) );
float intensity = atof( Get_Next_Parameter() );
float duration = atof( Get_Next_Parameter() );
if ( (obj_slot < 0) || ( obj_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Obj Slot Number %d\n", obj_slot );
obj_slot = -1;
}
if ( obj_slot != -1 ) {
int id = ObjectSlots[ obj_slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Vector3 pos = Commands->Get_Bone_Position( obj, "Camera" );
Commands->Shake_Camera( pos, 100, intensity, duration );
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", obj_slot );
}
}
}
void Command_Enable_Shadow( char * params )
{
int obj_slot = atoi( Get_First_Parameter( params ) );
int onoff = atoi( Get_Next_Parameter() );
if ( (obj_slot < 0) || ( obj_slot >= NUM_SLOTS ) ) {
// Commands->Debug_Message( "Bad Obj Slot Number %d\n", obj_slot );
obj_slot = -1;
}
if ( obj_slot != -1 ) {
int id = ObjectSlots[ obj_slot ];
GameObject * obj = Commands->Find_Object( id );
if ( obj ) {
Commands->Enable_Shadow(obj,(onoff != 0));
} else {
// Commands->Debug_Message( "Slot Object not found %d\n", obj_slot );
}
}
}
void Command_Enable_Letterbox( char * params )
{
int onoff = atoi( Get_First_Parameter( params ) );
float time = atof( Get_Next_Parameter() );
Commands->Enable_Letterbox(!!onoff,time);
}
void Command_Set_Screen_Fade_Color( char * params )
{
float r = atof( Get_First_Parameter( params ) );
float g = atof( Get_Next_Parameter() );
float b = atof( Get_Next_Parameter() );
float time = atof( Get_Next_Parameter() );
Commands->Set_Screen_Fade_Color(r,g,b,time);
}
void Command_Set_Screen_Fade_Opacity( char * params )
{
float opacity = atof( Get_First_Parameter( params ) );
float time = atof( Get_Next_Parameter() );
Commands->Set_Screen_Fade_Opacity(opacity,time);
}
/*
**
*/
bool Title_Match( char * * command, char * title )
{
if ( ::strnicmp( *command, title, strlen( title ) ) == 0 ) {
*command += strlen( title );
while ( **command && **command != ',' ) {
(*command)++;
}
if ( **command == ',' ) {
(*command)++;
}
return true;
}
return false;
}
void Parse_Command( char *command )
{
// Commands->Debug_Message( "Parse %s\n", (int)command );
if ( Title_Match( &command, "Create_Object" ) ) Command_Create_Object( command );
else if ( Title_Match( &command, "Create_Real_Object" ) ) Command_Create_Real_Object( command );
else if ( Title_Match( &command, "Create_Explosion" ) ) Command_Create_Explosion( command );
else if ( Title_Match( &command, "Destroy_Object" ) ) Command_Destroy_Object( command );
else if ( Title_Match( &command, "Play_Animation" ) ) Command_Play_Animation( command );
else if ( Title_Match( &command, "Play_Audio" ) ) Command_Play_Audio( command );
else if ( Title_Match( &command, "Control_Camera" ) ) Command_Control_Camera( command );
else if ( Title_Match( &command, "Send_Custom" ) ) Command_Send_Custom( command );
else if ( Title_Match( &command, "Attach_To_Bone" ) ) Command_Attach_To_Bone( command );
else if ( Title_Match( &command, "Attach_Script" ) ) Command_Attach_Script( command );
else if ( Title_Match( &command, "Set_Primary" ) ) Command_Set_Primary( command );
else if ( Title_Match( &command, "Move_Slot" ) ) Command_Move_Slot( command );
else if ( Title_Match( &command, "Sniper_Control" ) ) Command_Sniper_Control( command );
else if ( Title_Match( &command, "Shake_Camera" ) ) Command_Shake_Camera( command );
else if ( Title_Match( &command, "Enable_Shadow" ) ) Command_Enable_Shadow( command );
else if ( Title_Match( &command, "Enable_Letterbox" ) ) Command_Enable_Letterbox( command );
else if ( Title_Match( &command, "Set_Screen_Fade_Color" ) ) Command_Set_Screen_Fade_Color( command );
else if ( Title_Match( &command, "Set_Screen_Fade_Opacity" ) ) Command_Set_Screen_Fade_Opacity( command );
else {
// Commands->Debug_Message( "Failed to parse %s\n", (int)command );
}
}
void Parse_Commands( GameObject* obj ) {
unsigned int sync_diff = Commands->Get_Sync_Time() - LastSyncTime;
LastSyncTime += sync_diff;
float bump_time = ((float)sync_diff) / 1000.0f;
Time += bump_time;
MyID = Commands->Get_ID( obj );
// Commands->Debug_Message( "Cinematic Time %1.3f Frame %1.3f Bump Time %1.3f\n", Time, Time * 30.0f, bump_time );
// If Primary Destroyed,
if ( PrimaryKilled ) {
// skip all timestamps < LAST_VALID_TIMESTAMP
while ( Controls != NULL && Controls->Time <= LAST_VALID_TIMESTAMP ) {
Remove_Head_Control_Line();
}
// Run all remaining commands
while ( Controls != NULL ) {
Parse_Command( Controls->Command );
Remove_Head_Control_Line();
}
}
while ( Controls != NULL && Controls->Time <= Time ) {
FrameSync = (Time - Controls->Time) * 30.0f;
Parse_Command( Controls->Command );
Remove_Head_Control_Line();
}
if ( Controls != NULL ) {
// if the next command is > than the LAST_VALID_TIMESTAMP, we are done
if ( Controls->Time >= LAST_VALID_TIMESTAMP ) {
Commands->Destroy_Object( obj );
} else {
float time_diff = Controls->Time - Time;
Commands->Start_Timer( obj, this, time_diff, 0 );
}
} else {
Commands->Destroy_Object( obj );
}
// Make sure we don't sleep
if ( IsCameraCinematic ) {
Commands->Enable_Cinematic_Freeze( obj, false );
}
}
/*
**
*/
void Created(GameObject* obj)
{
Commands->Enable_Hibernation( obj, false );
Controls = NULL;
for ( int i = 0; i < NUM_SLOTS; i++ ) {
ObjectSlots[ i ] = 0;
}
LastSyncTime = Commands->Get_Sync_Time();
Time = 0;
PrimaryKilled = false;
IsCameraCinematic = false;
Load_Control_File( Get_Parameter( "ControlFilename" ) );
Parse_Commands( obj );
}
void Timer_Expired (GameObject* obj, int Timer_ID)
{
// Commands->Debug_Message("In Timer_Expired Get_Sync_Time is %d.\n", Commands->Get_Sync_Time());
Parse_Commands(obj);
}
void Custom( GameObject * obj, int type, int param, GameObject * sender )
{
if ( type == M00_CUSTOM_CINEMATIC_PRIMARY_KILLED ) {
if ( !PrimaryKilled ) { // Prevent loops
Commands->Debug_Message("Cinematic:Primary Killed\n");
PrimaryKilled = true;
Parse_Commands( obj );
}
}
if ( type >= M00_CUSTOM_CINEMATIC_SET_SLOT ) {
int slot = type - M00_CUSTOM_CINEMATIC_SET_SLOT;
if ( slot < NUM_SLOTS ) {
if ( ObjectSlots[ slot ] != 0 ) {
// Commands->Debug_Message( "Slot number %d used by %d\n", slot, ObjectSlots[ slot ] );
} else {
ObjectSlots[ slot ] = param;
// Commands->Debug_Message( "Slot number %d set to %d\n", slot, ObjectSlots[ slot ] );
}
}
}
}
};
#if 0
;_________________________________________
;
; Available Cinematic Script Commands
;
; time/frame Create_Object, id (slot), preset_name, x, y, z, facing, animation
; id can be -1 to mean do not store this object, and do not destroy
; 0 Create_Object, 0, .44 Magnum, 0, 0, 0, 180, "Human.jump"
;
; time/frame Destroy_Object, id (slot)
; 0 Destroy_Object, 0
;
; time/frame Play_Animation, id (slot), animation_name, looping, sub_obj_name
; 0 Play_Animation, 0, "Human.Jump", false
;
; time/frame Control_Camera, id ( slot )
; use id -1 for disabling control;
; note this will also disable star control and disbale the hud
; 0 Control_Camera, 0
;
TIME Create_Object SLOT MODEL_NAME
TIME Create_Real_Object SLOT PRESET_NAME HOST_SLOT HOST_BONE_NAME
TIME Destroy_Object SLOT
TIME Play_Animation SLOT ANIMATION_NAME LOOPING SUB_OBJ_NAME IS_BLENDED
TIME Play_Audio PRESET_NAME HOST_SLOT HOST_BONE_NAME
TIME Control_Camera SLOT
TIME Send_Custon [TO_ID/#TO_SLOT] TYPE [PARAM/#SLOT_PARAM]
TIME Attach_To_Bone SLOT HOST_SLOT HOST_BONE_NAME
TIME Attach_Script SLOT SCRIPT_NAME "SCRIPT_PARAMETERS"
TIME Move_Slot New_Slot, Old_Slot
TIME Sniper_Control ENABLED, ZOOM
TIME Shake_Camera SLOT, INTENSITY, DURATION
TIME Enable_Shadow SLOT, [1/0]
TIME Enable_Letterbox [1/0], TIME_TO_ANIMATE_IN
TIME Set_Screen_Fade_Color RED,GREEN,BLUE,TIME_TO_FADE (all colors floating point 0.0-1.0)
TIME Set_Screen_Fade_Opacity OPACITY,TIME_TO_FADE
To fill a slot, Send_Custom to the controller with
type = M00_CUSTOM_CINEMATIC_SET_SLOT + SLOT_NUMBER
parameter = OBJECT_ID
;_________________________________________
#endif