Initial commit of Command & Conquer Renegade source code.

This commit is contained in:
LFeenanEA
2025-02-27 16:39:46 +00:00
parent 74ab8fa5e0
commit 58ed459113
4918 changed files with 1366710 additions and 0 deletions

2487
Code/BandTest/BandTest.cpp Normal file

File diff suppressed because it is too large Load Diff

163
Code/BandTest/BandTest.dsp Normal file
View File

@@ -0,0 +1,163 @@
# Microsoft Developer Studio Project File - Name="BandTest" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=BandTest - Win32 Profile
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "BandTest.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "BandTest.mak" CFG="BandTest - Win32 Profile"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "BandTest - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "BandTest - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "BandTest - Win32 Profile" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/BandTest", PYFEAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "BandTest - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /MT /W4 /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /FD /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib /nologo /dll /pdb:"..\..\Run\BandTest.pdb" /map:"..\..\Run\BandTest.map" /debug /machine:I386 /out:"..\..\Run\BandTest.dll"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Release\BandTest.lib ..\libs\Release\BandTest.lib
# End Special Build Tool
!ELSEIF "$(CFG)" == "BandTest - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /FD /GZ /c
# SUBTRACT CPP /YX /Yc /Yu
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib /nologo /dll /pdb:"..\..\Run\BandTestD.pdb" /map:"..\..\Run\BandTestD.map" /debug /machine:I386 /out:"..\..\Run\BandTestD.dll" /implib:"Debug/BandTest.lib"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Debug\BandTest.lib ..\libs\Debug\BandTest.lib
# End Special Build Tool
!ELSEIF "$(CFG)" == "BandTest - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Ignore_Export_Lib 0
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W4 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /FD /GZ /c
# SUBTRACT BASE CPP /YX /Yc /Yu
# ADD CPP /nologo /MT /W4 /Zi /O2 /Ob2 /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BANDTEST_EXPORTS" /FR /FD /c
# SUBTRACT CPP /WX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib /nologo /dll /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib winmm.lib /nologo /dll /pdb:"..\..\Run\BandTestP.pdb" /map:"..\..\Run\BandTestP.map" /debug /machine:I386 /out:"..\..\Run\BandTestP.dll" /implib:"Profile/BandTest.lib"
# SUBTRACT LINK32 /pdb:none
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Profile\BandTest.lib ..\libs\Profile\BandTest.lib
# End Special Build Tool
!ENDIF
# Begin Target
# Name "BandTest - Win32 Release"
# Name "BandTest - Win32 Debug"
# Name "BandTest - Win32 Profile"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\BandTest.cpp
# End Source File
# Begin Source File
SOURCE=.\bandtest.rc
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\BandTest.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "BandTest"=.\BandTest.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

112
Code/BandTest/BandTest.h Normal file
View File

@@ -0,0 +1,112 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Bandwidth Tester *
* *
* $Archive:: /Commando/Code/BandTest/BandTest.h $*
* *
* $Author:: Steve_t $*
* *
* $Modtime:: 1/28/02 1:50p $*
* *
* $Revision:: 5 $*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* *
*---------------------------------------------------------------------------------------------*
* *
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** The following ifdef block is the standard way of creating macros which make exporting
** from a DLL simpler. All files within this DLL are compiled with the BANDTEST_EXPORTS
** symbol defined on the command line. this symbol should not be defined on any project
** that uses this DLL. This way any other project whose source files include this file see
** BANDTEST_API functions as being imported from a DLL, wheras this DLL sees symbols
** defined with this macro as being exported.
*/
#ifdef BANDTEST_EXPORTS
#define BANDTEST_API __declspec(dllexport)
#else
#define BANDTEST_API __declspec(dllimport)
#endif
/*
** Extended failure codes.
*/
enum {
BANDTEST_OK,
BANDTEST_NO_WINSOCK2,
BANDTEST_NO_RAW_SOCKET_PERMISSION,
BANDTEST_NO_RAW_SOCKET_CREATE,
BANDTEST_NO_UDP_SOCKET_BIND,
BANDTEST_NO_TTL_SET,
BANDTEST_NO_PING_RESPONSE,
BANDTEST_NO_FINAL_PING_TIME,
BANDTEST_NO_EXTERNAL_ROUTER,
BANDTEST_NO_IP_DETECT,
BANDTEST_UNKNOWN_ERROR,
BANDTEST_WRONG_API_VERSION,
BANDTEST_BAD_PARAM,
};
typedef struct tBandtestSettingsStruct {
/*
** Use ICMP packets instead of UDP packets when testing bandwidth.
*/
unsigned int AlwaysICMP : 1;
/*
** Use various values of TTL when testing bandwidth.
*/
unsigned int TTLScatter : 1;
/*
** Max number of packets to send for slow pings.
*/
unsigned int FastPingPackets : 7;
/*
** Max number of packets to send for fast pings.
*/
unsigned int SlowPingPackets : 7;
/*
** Pings over this time in ms use smaller number of packets for bandwidth discovery.
*/
unsigned int FastPingThreshold : 5;
/*
** Tell bandtest.dll to do a ping profile.
*/
unsigned int PingProfile : 1;
} BandtestSettingsStruct;
#define BANDTEST_API_VERSION 0x101
BANDTEST_API unsigned long Detect_Bandwidth(unsigned long server_ip, unsigned long my_ip, int retries, int &failure_code, unsigned long &downstream, unsigned long api_version, BandtestSettingsStruct *settings = NULL, char *regpath = NULL);

2161
Code/BandTest/BandTest.plg Normal file

File diff suppressed because it is too large Load Diff

109
Code/BandTest/BandTest.rc Normal file
View File

@@ -0,0 +1,109 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0
PRODUCTVERSION 1,0,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
#else
FILEFLAGS 0x20L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Westwood Studios\0"
VALUE "FileDescription", "BandTest\0"
VALUE "FileVersion", "1, 0, 0, 0\0"
VALUE "InternalName", "BandTest\0"
VALUE "LegalCopyright", "Copyright <20> 2002\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "BandTest.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "Westwood Studios BandTest\0"
VALUE "ProductVersion", "1, 0, 0, 0\0"
VALUE "SpecialBuild", "xa37dd45ffe100bfffcc9753aabac325f07cb3fa231144fe2e33ae4783feead2b8a73ff021fac326df0ef9753ab9cdf6573ddff0312fab0b0ff39779eaff312x\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
Code/BandTest/resource.h Normal file
View File

@@ -0,0 +1,15 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by bandtest.rc
//
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,358 @@
/*
** 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/>.
*/
#include "binkmovie.h"
#include "dx8wrapper.h"
#include "formconv.h"
#include "render2d.h"
#include "Bink.h"
#include "rect.h"
#include "subtitlemanager.h"
#include "dx8caps.h"
class BINKMovieClass
{
private:
StringClass Filename;
HBINK Bink;
bool FrameChanged;
unsigned TextureCount;
unsigned long TicksPerFrame;
struct TextureInfoStruct {
TextureClass* Texture;
int TextureWidth;
int TextureHeight;
int TextureLocX;
int TextureLocY;
RectClass UV;
RectClass Rect;
};
TextureInfoStruct* TextureInfos;
unsigned char* TempBuffer;
Render2DClass Renderer;
SubTitleManagerClass* SubTitleManager;
public:
BINKMovieClass(const char* filename,const char* subtitlename,FontCharsClass* font);
~BINKMovieClass();
void Update();
void Render();
bool Is_Complete();
};
static BINKMovieClass* CurrentMovie;
void BINKMovie::Play(const char* filename,const char* subtitlename, FontCharsClass* font)
{
if (CurrentMovie) {
delete CurrentMovie;
CurrentMovie = NULL;
}
CurrentMovie = new BINKMovieClass(filename,subtitlename,font);
}
void BINKMovie::Stop()
{
if (CurrentMovie) {
delete CurrentMovie;
CurrentMovie = NULL;
}
}
void BINKMovie::Update()
{
if (CurrentMovie) {
CurrentMovie->Update();
}
}
void BINKMovie::Render()
{
if (CurrentMovie) {
CurrentMovie->Render();
}
}
void BINKMovie::Init()
{
BinkSoundUseDirectSound(0);
}
void BINKMovie::Shutdown()
{
Stop();
}
bool BINKMovie::Is_Complete()
{
if (CurrentMovie) {
return CurrentMovie->Is_Complete();
}
return true;
}
// ----------------------------------------------------------------------------
BINKMovieClass::BINKMovieClass(const char* filename, const char* subtitlename, FontCharsClass* font)
:
Filename(filename),
Bink(0),
FrameChanged(true),
TicksPerFrame(0),
SubTitleManager(NULL)
{
Bink = BinkOpen(Filename, 0);
if (Bink == NULL) {
return;
}
TempBuffer = new unsigned char[Bink->Width * Bink->Height*2];
const D3DCAPS8& dx8caps = DX8Wrapper::Get_Current_Caps()->Get_DX8_Caps();
unsigned poweroftwowidth = 1;
while (poweroftwowidth < Bink->Width) {
poweroftwowidth <<= 1;
}
unsigned poweroftwoheight = 1;
while (poweroftwoheight < Bink->Height) {
poweroftwoheight <<= 1;
}
if (poweroftwowidth > dx8caps.MaxTextureWidth) {
poweroftwowidth = dx8caps.MaxTextureWidth;
}
if (poweroftwoheight > dx8caps.MaxTextureHeight) {
poweroftwoheight = dx8caps.MaxTextureHeight;
}
TextureCount = 0;
unsigned max_width = poweroftwowidth;
unsigned max_height = poweroftwoheight;
unsigned x, y;
for (y = 0; y < Bink->Height; y += max_height-2) { // Two pixels are lost due to duplicated edges to prevent bilinear artifacts
for (x = 0; x < Bink->Width; x += max_width-2) {
++TextureCount;
}
}
TextureInfos = new TextureInfoStruct[TextureCount];
unsigned cnt = 0;
for (y = 0; y < Bink->Height; y += max_height-1) {
for (x = 0; x < Bink->Width; x += max_width-1) {
TextureInfos[cnt].Texture = new TextureClass(
max_width, max_height, D3DFormat_To_WW3DFormat(D3DFMT_R5G6B5),
TextureClass::MIP_LEVELS_1, TextureClass::POOL_MANAGED, false);
TextureInfos[cnt].TextureLocX = x;
TextureInfos[cnt].TextureLocY = y;
TextureInfos[cnt].TextureWidth = max_width;
TextureInfos[cnt].UV.Right = float(max_width) / float(max_width);
if ((TextureInfos[cnt].TextureWidth + x) > Bink->Width) {
TextureInfos[cnt].TextureWidth = Bink->Width - x;
TextureInfos[cnt].UV.Right = float(TextureInfos[cnt].TextureWidth - 1) / float(max_width);
}
TextureInfos[cnt].TextureHeight = max_height;
TextureInfos[cnt].UV.Bottom = float(max_height) / float(max_height);
if ((TextureInfos[cnt].TextureHeight + y) > Bink->Height) {
TextureInfos[cnt].TextureHeight = Bink->Height - y;
TextureInfos[cnt].UV.Bottom = float(TextureInfos[cnt].TextureHeight + 1) / float(max_height);
}
TextureInfos[cnt].UV.Left = 1.0f / float(max_width);
TextureInfos[cnt].UV.Top = 1.0f / float(max_height);
TextureInfos[cnt].Rect.Left = float(TextureInfos[cnt].TextureLocX) / float(Bink->Width);
TextureInfos[cnt].Rect.Top = float(TextureInfos[cnt].TextureLocY) / float(Bink->Height);
TextureInfos[cnt].Rect.Right = float(TextureInfos[cnt].TextureLocX + TextureInfos[cnt].TextureWidth) / float(Bink->Width);
TextureInfos[cnt].Rect.Bottom = float(TextureInfos[cnt].TextureLocY + TextureInfos[cnt].TextureHeight) / float(Bink->Height);
++cnt;
}
}
Renderer.Reset();
// Calculate the time per frame of video
unsigned int rate = (Bink->FrameRate / Bink->FrameRateDiv);
TicksPerFrame = (60 / rate);
if (subtitlename && font) {
SubTitleManager = SubTitleManagerClass::Create(filename, subtitlename, font);
}
}
BINKMovieClass::~BINKMovieClass()
{
if (Bink == NULL) {
return;
}
if (Bink) {
BinkClose(Bink);
}
delete[] TempBuffer;
if (TextureInfos) {
for (unsigned t = 0; t < TextureCount; ++t) {
REF_PTR_RELEASE(TextureInfos[t].Texture);
}
delete[] TextureInfos;
}
if (SubTitleManager) {
delete SubTitleManager;
}
}
void BINKMovieClass::Update()
{
if (!Bink) {
return;
}
FrameChanged |= !BinkWait(Bink);
}
static unsigned char* Get_Tex_Address(unsigned char* buffer, int x, int y, int w, int h)
{
if (x < 0) {
x = 0;
} else if (x >= w) {
x = w - 1;
}
if (y < 0) {
y = 0;
} else if (y >= h) {
y = h - 1;
}
return buffer + x * 2 + y * 2 * w;
}
void BINKMovieClass::Render()
{
if (!Bink) {
return;
}
// decompress a frame
if (FrameChanged) {
BinkDoFrame(Bink);
FrameChanged = false;
BinkCopyToBuffer(Bink, TempBuffer, Bink->Width * 2, Bink->Height, 0, 0, BINKSURFACE565|BINKCOPYNOSCALING);
for (unsigned t = 0; t < TextureCount; ++t) {
IDirect3DTexture8* d3d_texture = TextureInfos[t].Texture->Peek_DX8_Texture();
if (d3d_texture) {
unsigned char* cur_tex_ptr = Get_Tex_Address(TempBuffer, TextureInfos[t].TextureLocX,
TextureInfos[t].TextureLocY, Bink->Width, Bink->Height);
unsigned w = TextureInfos[t].TextureWidth;
unsigned h = TextureInfos[t].TextureHeight;
if (w > Bink->Width-TextureInfos[t].TextureLocX) {
w = Bink->Width-TextureInfos[t].TextureLocX;
}
if (h > Bink->Height-TextureInfos[t].TextureLocY) {
h = Bink->Height-TextureInfos[t].TextureLocY;
}
D3DSURFACE_DESC d3d_surf_desc;
D3DLOCKED_RECT locked_rect;
DX8_ErrorCode(d3d_texture->GetLevelDesc(0, &d3d_surf_desc));
RECT rect;
rect.left = 0;
rect.top = 0;
rect.right = w;
rect.bottom = h;
DX8_ErrorCode(d3d_texture->LockRect(0,&locked_rect,&rect,0));
for (unsigned y = 0; y < h; ++y) {
unsigned char* dest = (unsigned char*)locked_rect.pBits + y * locked_rect.Pitch;
memcpy(dest, cur_tex_ptr, w * 2);
cur_tex_ptr += Bink->Width * 2;
}
DX8_ErrorCode(d3d_texture->UnlockRect(0));
}
}
if (Bink->FrameNum < Bink->Frames) // goto the next if not on the last
BinkNextFrame(Bink);
}
for (unsigned t = 0; t < TextureCount; ++t) {
Renderer.Reset();
Renderer.Set_Texture(TextureInfos[t].Texture);
Renderer.Set_Coordinate_Range(RectClass(0.0f, 0.0f, 1.0f, 1.0f));//Bink->Width,Bink->Height));
RectClass rect(TextureInfos[t].TextureLocX, TextureInfos[t].TextureLocY, TextureInfos[t].TextureWidth, TextureInfos[t].TextureHeight);
Renderer.Add_Quad(TextureInfos[t].Rect, TextureInfos[t].UV, 0xffffffff);
Renderer.Render();
}
if (SubTitleManager) {
unsigned long movieTime = (Bink->FrameNum * TicksPerFrame);
SubTitleManager->Process(movieTime);
SubTitleManager->Render();
}
}
bool BINKMovieClass::Is_Complete()
{
if (!Bink) return true;
return (Bink->FrameNum>=Bink->Frames);
}

View File

@@ -0,0 +1,58 @@
/*
** 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/>.
*/
#if defined(_MSV_VER)
#pragma once
#endif
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef BINKMOVIE_H
#define BINKMOVIE_H
#include "always.h"
#include "wwstring.h"
class FontCharsClass;
// ----------------------------------------------------------------------------
//
// BINK movie player. You'll need to have binkw32.dll in the run directory!
//
// To start a movie call Play("movie.bik","subtitle_name");
// To end movie playing call Stop();
//
// In order to change the subtitle properties see SubTitleManagerClass.
//
// ----------------------------------------------------------------------------
class BINKMovie
{
public:
static void Play(const char* filename,const char* subtitlename=NULL, FontCharsClass* font = NULL);
static void Stop();
static void Update();
static void Render();
static void Init();
static void Shutdown();
static bool Is_Complete();
};
#endif

View File

@@ -0,0 +1,157 @@
# Microsoft Developer Studio Project File - Name="BinkMovie" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=BinkMovie - Win32 Profile
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "BinkMovie.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "BinkMovie.mak" CFG="BinkMovie - Win32 Profile"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "BinkMovie - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "BinkMovie - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "BinkMovie - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/BinkMovie", XPFEAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "BinkMovie - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX- /Zi /O2 /Ob2 /I "..\wwmath" /I "..\\" /I "..\ww3d2" /I "..\wwdebug" /I "..\wwlib" /I "..\DirectX\Include" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\Libs\Release\BinkMovie.lib"
!ELSEIF "$(CFG)" == "BinkMovie - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GR- /GX- /ZI /Od /I "..\wwmath" /I "..\\" /I "..\ww3d2" /I "..\wwdebug" /I "..\wwlib" /I "..\DirectX\Include" /D "_DEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\Libs\Debug\BinkMovie.lib"
!ELSEIF "$(CFG)" == "BinkMovie - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MT /W4 /GX- /Zi /O2 /Ob2 /I "..\wwmath" /I "..\\" /I "..\ww3d2" /I "..\wwdebug" /I "..\wwlib" /I "..\DirectX\Include" /D "NDEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"Debug\BinkMovieD.lib"
# ADD LIB32 /nologo /out:"..\Libs\Profile\BinkMovie.lib"
!ENDIF
# Begin Target
# Name "BinkMovie - Win32 Release"
# Name "BinkMovie - Win32 Debug"
# Name "BinkMovie - Win32 Profile"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\BINKMovie.cpp
# End Source File
# Begin Source File
SOURCE=.\subtitle.cpp
# End Source File
# Begin Source File
SOURCE=.\subtitlemanager.cpp
# End Source File
# Begin Source File
SOURCE=.\subtitleparser.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\BINK.H
# End Source File
# Begin Source File
SOURCE=.\BINKMovie.h
# End Source File
# Begin Source File
SOURCE=.\RAD.H
# End Source File
# Begin Source File
SOURCE=.\subtitle.h
# End Source File
# Begin Source File
SOURCE=.\subtitlemanager.h
# End Source File
# Begin Source File
SOURCE=.\subtitleparser.h
# End Source File
# End Group
# End Target
# End Project

Binary file not shown.

Binary file not shown.

Binary file not shown.

156
Code/BinkMovie/subtitle.cpp Normal file
View File

@@ -0,0 +1,156 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitle.cpp $
*
* DESCRIPTION
* Subtitling support.
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Modtime: 1/15/02 8:48p $
* $Revision: 2 $
*
****************************************************************************/
#include "always.h"
#include "subtitle.h"
/******************************************************************************
*
* NAME
* SubTitleClass::SubTitleClass
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleClass::SubTitleClass()
:
mTimeStamp(0),
mDuration(20 * 60),
mRGBColor(0x00FFFFFF),
mLinePosition(15),
mAlignment(Center),
mCaption(NULL)
{
}
/******************************************************************************
*
* NAME
* SubTitleClass::~SubTitleClass
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleClass::~SubTitleClass()
{
if (mCaption != NULL) {
delete[] mCaption;
}
}
/******************************************************************************
*
* NAME
* SubTitleClass::SetRGBColor
*
* DESCRIPTION
* Set the color the subtitle caption should be displayed in.
*
* INPUTS
* unsigned char red
* unsigned char green
* unsigned char blue
*
* RESULTS
* NONE
*
******************************************************************************/
void SubTitleClass::Set_RGB_Color(
unsigned char red,
unsigned char green,
unsigned char blue)
{
// Combine components as 8:8:8
mRGBColor = (
((unsigned long)red << 16) |
((unsigned long)green << 8) |
(unsigned long)blue);
}
/******************************************************************************
*
* NAME
* SubTitleClass::SetCaption
*
* DESCRIPTION
* Set the caption text
*
* INPUTS
* Caption - Caption string
*
* RESULTS
* NONE
*
******************************************************************************/
void SubTitleClass::Set_Caption(wchar_t* string)
{
// Release existing caption
if (mCaption != NULL) {
delete[] mCaption;
mCaption = NULL;
}
// Make a copy of caption
if (string != NULL) {
unsigned int length = wcslen(string);
mCaption = new wchar_t[length + 1];
WWASSERT(mCaption != NULL);
if (mCaption != NULL) {
wcscpy(mCaption, string);
}
}
}

112
Code/BinkMovie/subtitle.h Normal file
View File

@@ -0,0 +1,112 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitle.h $
*
* DESCRIPTION
* Subtitling support.
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Modtime: 1/15/02 8:48p $
* $Revision: 2 $
*
****************************************************************************/
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef _SUBTITLE_H_
#define _SUBTITLE_H_
#include "always.h"
#include "wwdebug.h"
#include <wchar.h>
class SubTitleClass
{
public:
SubTitleClass();
~SubTitleClass();
// Set the time (in milliseconds) at which the subtitle is to be displayed.
void Set_Display_Time(unsigned long time) { mTimeStamp = time; }
// Retrieve the time in ticks (1/60 seconds) this subtitle is to be displayed.
unsigned long Get_Display_Time(void) const { return mTimeStamp; }
// Set the time duration in ticks (1/60 seconds) for the subtitle to remain displayed.
void Set_Display_Duration(unsigned long duration) { mDuration = duration; }
// Retrieve the duration time in ticks (1/60 seconds) for the subtitle.
unsigned long Get_Display_Duration(void) const { return mDuration; }
// Set the color the subtitle caption should be displayed in.
void Set_RGB_Color(unsigned char red, unsigned char green, unsigned char blue);
// Retrieve the color of the subtitle
unsigned long Get_RGB_Color(void) const { return mRGBColor; }
// Set the line position the subtitle should be displayed at.
void Set_Line_Position(int linePos)
{
WWASSERT((linePos >= 1) && (linePos <= 15));
mLinePosition = linePos;
}
// Retrieve the line position to display the subtitle at.
int Get_Line_Position(void) const { return mLinePosition; }
// Caption justifications
typedef enum
{
Left,
Right,
Center,
} Alignment;
// Set the alignment of the subtitle caption
void Set_Alignment(Alignment align)
{mAlignment = align;}
// Retrieve the caption justification
Alignment Get_Alignment(void) const { return mAlignment; }
// Set the caption text
void Set_Caption(wchar_t* string);
// Retrieve the caption text
const wchar_t* Get_Caption(void) const { return mCaption; }
private:
unsigned long mTimeStamp;
unsigned long mDuration;
unsigned long mRGBColor;
int mLinePosition;
Alignment mAlignment;
wchar_t* mCaption;
};
#endif // _SUBTITLE_H_

View File

@@ -0,0 +1,351 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitlemanager.cpp $
*
* DESCRIPTION
* Subtitling manager
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Modtime: 1/24/02 10:11a $
* $Revision: 3 $
*
****************************************************************************/
#include "always.h"
#include "subtitlemanager.h"
#include "subtitleparser.h"
#include "subtitle.h"
#include "xstraw.h"
#include "rawfile.h"
#include "assetmgr.h"
#include "ww3d.h"
#include <stdlib.h>
/******************************************************************************
*
* NAME
* SubTitleManagerClass::Create
*
* DESCRIPTION
* Instantiate a subtitle manager for the specified movie.
*
* INPUTS
* Filename - Name of movie file to create subtitle manager for.
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleManagerClass* SubTitleManagerClass::Create(const char* filename, const char* subtitlefilename, FontCharsClass* font)
{
if ((filename == NULL) || (strlen(filename) == 0)) {
return NULL;
}
if (subtitlefilename && !font) {
return NULL;
}
// Create subtitle manager for the vqa
SubTitleManagerClass* instance = new SubTitleManagerClass();
WWASSERT(instance != NULL);
if (instance != NULL) {
instance->Set_Font(font);
// Retrieve moviename
char fname[_MAX_FNAME];
_splitpath(filename, NULL, NULL, fname, NULL);
bool loaded = instance->Load_Sub_Titles(fname, subtitlefilename);
if (loaded == false) {
delete instance;
return NULL;
}
}
return instance;
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::SubTitleManagerClass
*
* DESCRIPTION
*
* INPUTS
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleManagerClass::SubTitleManagerClass()
:
mSubTitles(NULL),
mSubTitleIndex(0),
mActiveSubTitle(NULL)
{
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::~SubTitleManagerClass
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleManagerClass::~SubTitleManagerClass()
{
// Release subtitle entries
if (mSubTitles != NULL) {
for (int index = 0; index < mSubTitles->Count(); index++) {
delete (*mSubTitles)[index];
}
delete mSubTitles;
}
}
void SubTitleManagerClass::Set_Font(FontCharsClass* font)
{
if (font) {
Renderer.Set_Font(font);
}
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::LoadSubTitles
*
* DESCRIPTION
*
* INPUTS
* Moviename - Pointer to movie name
*
* RESULTS
* Success -
*
******************************************************************************/
bool SubTitleManagerClass::Load_Sub_Titles(const char* moviename, const char* subtitlefilename)
{
if ((moviename == NULL) || (strlen(moviename) == 0)) {
return false;
}
if ((subtitlefilename == NULL) || (strlen(subtitlefilename) == 0)) {
return false;
}
RawFileClass file(subtitlefilename);
if (!file.Is_Available()) {
return false;
}
FileStraw input(file);
SubTitleParserClass parser(input);
mSubTitles = parser.Get_Sub_Titles(moviename);
if (mSubTitles == NULL) {
return false;
}
// TODO: Make sure entries are sorted by time.
return true;
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::Process
*
* DESCRIPTION
* Handle subtitle processing. This must be called each frame advance.
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
bool SubTitleManagerClass::Process(unsigned long movieTime)
{
if (mSubTitles == NULL) {
return false;
}
bool update = false;
for (;;) {
// Terminate if there aren't more subtitles
if (mSubTitleIndex >= mSubTitles->Count()) {
break;
}
// Get the next subtitle
SubTitleClass* subtitle = (*mSubTitles)[mSubTitleIndex];
WWASSERT(subtitle != NULL);
// Check the display time against the current movie time. If it is time
// to display the subtitle then send a subtitle event to the client.
unsigned long displayTime = subtitle->Get_Display_Time();
// If its not time then we are done.
if (displayTime > movieTime) {
break;
} else {
// Make this subtitle the active one
mActiveSubTitle = subtitle;
// Advance to the next subtitle entry
mSubTitleIndex++;
Draw_Sub_Title(subtitle);
update = true;
// WWDEBUG_SAY(("SubTitle: %04d @ %u\n", mSubTitleIndex, movieTime));
}
}
// If the active subtitles duration has expired then remove it as being active.
if (mActiveSubTitle != NULL) {
SubTitleClass* subtitle = mActiveSubTitle;
unsigned long expireTime = subtitle->Get_Display_Time() + subtitle->Get_Display_Duration();
if (movieTime >= expireTime) {
mActiveSubTitle = NULL;
// Erase subtitle
Renderer.Reset();
update = true;
}
}
return update;
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::Reset
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
void SubTitleManagerClass::Reset(void)
{
mSubTitleIndex = 0;
mActiveSubTitle = NULL;
}
/******************************************************************************
*
* NAME
* SubTitleManagerClass::DrawSubTitle
*
* DESCRIPTION
*
* INPUTS
* const SubTitleClass* subtitle
*
* RESULTS
* NONE
*
******************************************************************************/
void SubTitleManagerClass::Draw_Sub_Title(const SubTitleClass* subtitle)
{
WWASSERT(subtitle != NULL);
Renderer.Reset();
unsigned short* string = (unsigned short*)subtitle->Get_Caption();
int w,h,bits;
bool windowed;
WW3D::Get_Device_Resolution(w,h,bits,windowed);
Vector2 extents=Renderer.Get_Text_Extents( string );
// Assume left justification
int xPos = 0;
int yPos = subtitle->Get_Line_Position() * (h/16);
int xSize=extents[0];
SubTitleClass::Alignment align = subtitle->Get_Alignment();
if (align == SubTitleClass::Center) {
xPos = ((w - xSize) / 2);
}
else if (align == SubTitleClass::Right) {
xPos = (w - xSize);
}
Renderer.Set_Location(Vector2(xPos,yPos));
Renderer.Build_Sentence(string);
// Set font color
unsigned long rgbColor = subtitle->Get_RGB_Color()|0xff000000;
Renderer.Draw_Sentence(rgbColor);
}
void SubTitleManagerClass::Render()
{
Renderer.Render();
}

View File

@@ -0,0 +1,87 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitlemanager.h $
*
* DESCRIPTION
* Subtitling manager
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Modtime: 1/15/02 9:13p $
* $Revision: 2 $
*
****************************************************************************/
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef _SUBTITLEMANAGER_H_
#define _SUBTITLEMANAGER_H_
#include "always.h"
#include <wwlib\vector.h>
#include "wwstring.h"
#include <windows.h>
#include "render2dsentence.h"
class SubTitleClass;
class Surface;
class SubTitleManagerClass
{
public:
// Instantiate a subtitle manager
static SubTitleManagerClass* Create(const char* filename, const char* subtitlefilename, FontCharsClass* font);
// Destroy subtitle manager
~SubTitleManagerClass();
// Check if there are subtitles.
bool Has_Sub_Titles(void) const { return (mSubTitles != NULL); }
// Reset subtitles to start
void Reset(void);
// Process subtitles
bool Process(unsigned long movieTime);
void Render();
private:
// Prevent direct creation
SubTitleManagerClass();
void Set_Font(FontCharsClass* font);
bool Load_Sub_Titles(const char* moviename, const char* subtitlefilename);
void Draw_Sub_Title(const SubTitleClass* subtitle);
DynamicVectorClass<class SubTitleClass*>* mSubTitles;
int mSubTitleIndex;
SubTitleClass* mActiveSubTitle;
Render2DSentenceClass Renderer;
};
#endif // _SUBTITLEMANAGER_H_

View File

@@ -0,0 +1,583 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitleparser.cpp $
*
* DESCRIPTION
* Subtitling control file parser
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Denzil_l $
* $Modtime: 1/12/02 9:27p $
* $Revision: 2 $
*
****************************************************************************/
#include "subtitleparser.h"
#include "subtitle.h"
#include "straw.h"
#include "readline.h"
#include "trim.h"
#include <wchar.h>
#include <stdlib.h>
// Subtitle control file parsing tokens
#define BEGINMOVIE_TOKEN L"BeginMovie"
#define ENDMOVIE_TOKEN L"EndMovie"
#define TIMEBIAS_TOKEN L"TimeBias"
#define TIME_TOKEN L"Time"
#define DURATION_TOKEN L"Duration"
#define POSITION_TOKEN L"Position"
#define COLOR_TOKEN L"Color"
#define TEXT_TOKEN L"Text"
unsigned long DecodeTimeString(wchar_t* string);
void Parse_Time(wchar_t* string, SubTitleClass* subTitle);
void Parse_Duration(wchar_t* string, SubTitleClass* subTitle);
void Parse_Position(wchar_t* string, SubTitleClass* subTitle);
void Parse_Color(wchar_t* string, SubTitleClass* subTitle);
void Parse_Text(wchar_t* string, SubTitleClass* subTitle);
SubTitleParserClass::TokenHook SubTitleParserClass::mTokenHooks[] =
{
{TIME_TOKEN, Parse_Time},
{DURATION_TOKEN, Parse_Duration},
{POSITION_TOKEN, Parse_Position},
{COLOR_TOKEN, Parse_Color},
{TEXT_TOKEN, Parse_Text},
{NULL, NULL}
};
/******************************************************************************
*
* NAME
* SubTitleParserClass::SubTitleParserClass
*
* DESCRIPTION
*
* INPUTS
* Input - Control file input stream.
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleParserClass::SubTitleParserClass(Straw& input)
:
mInput(input),
mLineNumber(0)
{
// Check for Unicode byte-order mark.
// All Unicode plaintext files are prefixed with the byte-order mark U+FEFF
// or its mirror U+FFFE. This mark is used to indicate the byte order of a
// text stream.
wchar_t byteOrderMark = 0;
mInput.Get(&byteOrderMark, sizeof(wchar_t));
WWASSERT(byteOrderMark == 0xFEFF);
if (byteOrderMark != 0xFEFF) {
WWDEBUG_SAY(("Error: Subtitle control file is not unicode!\n"));
}
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::~SubTitleParserClass
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
* NONE
*
******************************************************************************/
SubTitleParserClass::~SubTitleParserClass()
{
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::GetSubTitles
*
* DESCRIPTION
*
* INPUTS
* NONE
*
* RESULTS
*
******************************************************************************/
DynamicVectorClass<SubTitleClass*>* SubTitleParserClass::Get_Sub_Titles(const char* moviename)
{
DynamicVectorClass<SubTitleClass*>* subTitleCollection = NULL;
// Find the movie marker
if (Find_Movie_Entry(moviename) == true) {
// Allocate container to hold subtitles
subTitleCollection = new DynamicVectorClass<SubTitleClass*>;
WWASSERT(subTitleCollection != NULL);
if (subTitleCollection != NULL) {
for (;;) {
// Retrieve a line from the control file
wchar_t* string = Get_Next_Line();
if ((string != NULL) && (wcslen(string) > 0)) {
// Check for subtitle entry markers
if ((string[0] == L'<') && (string[wcslen(string) - 1] == L'>')) {
// Trim off markers
string++;
string[wcslen(string) - 1] = 0;
wcstrim(string);
// Ignore empty caption
if (wcslen(string) == 0) {
continue;
}
// Create a new SubTitleClass
SubTitleClass* subTitle = new SubTitleClass();
WWASSERT(subTitle != NULL);
if (subTitle == NULL) {
WWDEBUG_SAY(("***** Failed to create SubTitleClass!\n"));
break;
}
if (Parse_Sub_Title(string, subTitle) == true) {
subTitleCollection->Add(subTitle);
}
else {
delete subTitle;
}
continue;
}
// Terminate if end movie token encountered.
if (wcsnicmp(string, ENDMOVIE_TOKEN, wcslen(ENDMOVIE_TOKEN)) == 0) {
break;
}
}
}
if (subTitleCollection->Count() == 0) {
delete subTitleCollection;
subTitleCollection = NULL;
}
}
}
return subTitleCollection;
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::FindMovieEntry
*
* DESCRIPTION
* No description provided,
*
* INPUTS
* Moviename - Pointer to name of movie to find subtitles for.
*
* RESULTS
* Success - True if movie entry found; False if unable to find movie entry.
*
******************************************************************************/
bool SubTitleParserClass::Find_Movie_Entry(const char* moviename)
{
// Convert the moviename into Unicode
WWASSERT(moviename != NULL);
wchar_t wideName[32];
mbstowcs(wideName, moviename, 32);
do {
// Retrieve line of text
wchar_t* string = Get_Next_Line();
// Terminate if no string read.
if (string == NULL) {
break;
}
// Look for begin movie token
if (wcsnicmp(string, BEGINMOVIE_TOKEN, wcslen(BEGINMOVIE_TOKEN)) == 0) {
// Get moviename following the token
wchar_t* ptr = wcschr(string, L' ');
// Check for matching moviename
if (ptr != NULL) {
wcstrim(ptr);
if (wcsicmp(ptr, wideName) == 0) {
WWDEBUG_SAY(("Found movie entry %s\n", moviename));
return true;
}
}
}
} while (true);
return false;
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::ParseSubTitle
*
* DESCRIPTION
*
* INPUTS
* wchar_t* string
* SubTitleClass* subTitle
*
* RESULTS
* bool
*
******************************************************************************/
bool SubTitleParserClass::Parse_Sub_Title(wchar_t* string, SubTitleClass* subTitle)
{
// Parameter check
WWASSERT(string != NULL);
WWASSERT(subTitle != NULL);
for (;;) {
// Find token separator
wchar_t* separator = wcschr(string, L'=');
if (separator == NULL) {
WWDEBUG_SAY(("Error on line %d: syntax error\n", Get_Line_Number()));
return false;
}
// NULL terminate token part
*separator++ = 0;
// Tokens are to the left of the separator
wchar_t* token = string;
wcstrim(token);
// Parameters are to the right of the separator
wchar_t* param = separator;
wcstrim(param);
// Quoted parameters are treated as literals (ignore contents)
if (param[0] == L'"') {
// Skip leading quote
param++;
// Use next quote to mark end of parameter
separator = wcschr(param, L'"');
if (separator == NULL) {
WWDEBUG_SAY(("Error on line %d: mismatched quotes\n", Get_Line_Number()));
return false;
}
// NULL terminate parameter
*separator++ = 0;
// Skip any comma following a literal string since we used the trailing
// quote to terminate the tokens parameters
wcstrim(separator);
if (*separator == L',') {
separator++;
}
// Advance string past quoted parameter
string = separator;
}
else {
// Look for separator to next token
separator = wcspbrk(param, L", ");
if (separator != NULL) {
*separator++ = 0;
string = separator;
}
else {
string = L"";
}
}
// Error on empty tokens
if (wcslen(token) == 0) {
WWDEBUG_SAY(("Error on line %d: missing token\n", Get_Line_Number()));
return false;
}
// Parse current token
Parse_Token(token, param, subTitle);
// Prepare for next token
wcstrim(string);
if (wcslen(string) == 0) {
break;
}
}
return true;
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::ParseToken
*
* DESCRIPTION
*
* INPUTS
* wchar_t* token
* wchar_t* param
* SubTitleClass* subTitle
*
* RESULTS
* NONE
*
******************************************************************************/
void SubTitleParserClass::Parse_Token(wchar_t* token, wchar_t* param, SubTitleClass* subTitle)
{
// Parameter check
WWASSERT(token != NULL);
WWASSERT(subTitle != NULL);
if (token != NULL) {
int index = 0;
while (mTokenHooks[index].Token != NULL) {
TokenHook& hook = mTokenHooks[index];
if (wcsicmp(hook.Token, token) == 0) {
WWASSERT(subTitle != NULL);
hook.Handler(param, subTitle);
return;
}
index++;
}
}
}
/******************************************************************************
*
* NAME
* SubTitleParserClass::GetNextLine
*
* DESCRIPTION
* Retrieve the next line of text from the control file.
*
* INPUTS
* NONE
*
* RESULTS
* String - Pointer to next line of text. NULL if error or EOF.
*
******************************************************************************/
wchar_t* SubTitleParserClass::Get_Next_Line(void)
{
bool eof = false;
while (eof == false) {
// Read in a line of text
Read_Line(mInput, mBuffer, LINE_MAX, eof);
mLineNumber++;
// Remove whitespace
wchar_t* string = wcstrim(mBuffer);
// Skip comments and blank lines
if ((wcslen(string) > 0) && (string[0] != L';')) {
return string;
}
}
return NULL;
}
// Convert a time string in the format hh:mm:ss:tt into 1/60 second ticks.
unsigned long Decode_Time_String(wchar_t* string)
{
#define TICKS_PER_SECOND 60
#define TICKS_PER_MINUTE (60 * TICKS_PER_SECOND)
#define TICKS_PER_HOUR (60 * TICKS_PER_MINUTE)
WWASSERT(string != NULL);
wchar_t buffer[12];
wcsncpy(buffer, string, 12);
buffer[11] = 0;
wchar_t* ptr = &buffer[0];
// Isolate hours part
wchar_t* separator = wcschr(ptr, L':');
WWASSERT(separator != NULL);
*separator++ = 0;
unsigned long hours = wcstoul(ptr, NULL, 10);
// Isolate minutes part
ptr = separator;
separator = wcschr(ptr, L':');
WWASSERT(separator != NULL);
*separator++ = 0;
unsigned long minutes = wcstoul(ptr, NULL, 10);
// Isolate seconds part
ptr = separator;
separator = wcschr(ptr, L':');
WWASSERT(separator != NULL);
*separator++ = 0;
unsigned long seconds = wcstoul(ptr, NULL, 10);
// Isolate hundredth part (1/100th of a second)
ptr = separator;
unsigned long hundredth = wcstoul(ptr, NULL, 10);
unsigned long time = (hours * TICKS_PER_HOUR);
time += (minutes * TICKS_PER_MINUTE);
time += (seconds * TICKS_PER_SECOND);
time += ((hundredth * TICKS_PER_SECOND) / 100);
return time;
}
void Parse_Time(wchar_t* param, SubTitleClass* subTitle)
{
WWASSERT(param != NULL);
WWASSERT(subTitle != NULL);
unsigned long time = Decode_Time_String(param);
subTitle->Set_Display_Time(time);
}
void Parse_Duration(wchar_t* param, SubTitleClass* subTitle)
{
WWASSERT(param != NULL);
WWASSERT(subTitle != NULL);
unsigned long time = Decode_Time_String(param);
if (time > 0) {
subTitle->Set_Display_Duration(time);
}
}
void Parse_Position(wchar_t* param, SubTitleClass* subTitle)
{
static struct
{
const wchar_t* Name;
SubTitleClass::Alignment Align;
} _alignLookup[] = {
{L"Left", SubTitleClass::Left},
{L"Right", SubTitleClass::Right},
{L"Center", SubTitleClass::Center},
{NULL, SubTitleClass::Center}
};
WWASSERT(subTitle != NULL);
WWASSERT(param != NULL);
wchar_t* ptr = param;
// Line position
wchar_t* separator = wcschr(ptr, L':');
if (separator != NULL) {
*separator++ = 0;
int linePos = wcstol(ptr, NULL, 0);
subTitle->Set_Line_Position(linePos);
ptr = separator;
}
// Justification
SubTitleClass::Alignment align = SubTitleClass::Center;
int index = 0;
while (_alignLookup[index].Name != NULL) {
if (wcsicmp(ptr, _alignLookup[index].Name) == 0) {
align = _alignLookup[index].Align;
break;
}
index++;
}
subTitle->Set_Alignment(align);
}
void Parse_Color(wchar_t* param, SubTitleClass* subTitle)
{
WWASSERT(param != NULL);
WWASSERT(subTitle != NULL);
wchar_t* ptr = param;
wchar_t* separator = wcschr(ptr, L':');
*separator++ = 0;
unsigned char red = (unsigned char)wcstoul(ptr, NULL, 10);
ptr = separator;
separator = wcschr(ptr, L':');
*separator++ = 0;
unsigned char green = (unsigned char)wcstoul(ptr, NULL, 10);
ptr = separator;
unsigned char blue = (unsigned char)wcstoul(ptr, NULL, 10);
subTitle->Set_RGB_Color(red, green, blue);
}
void Parse_Text(wchar_t* param, SubTitleClass* subTitle)
{
WWASSERT(param != NULL);
WWASSERT(subTitle != NULL);
subTitle->Set_Caption(param);
}

View File

@@ -0,0 +1,84 @@
/*
** 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
* $Archive: /Commando/Code/BinkMovie/subtitleparser.h $
*
* DESCRIPTION
* Subtitling control file parser
*
* PROGRAMMER
* Denzil E. Long, Jr.
*
* VERSION INFO
* $Author: Ian_l $
* $Modtime: 8/24/01 2:36p $
* $Revision: 1 $
*
****************************************************************************/
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef _SUBTITLEPARSER_H_
#define _SUBTITLEPARSER_H_
#include "always.h"
#include <wwlib\vector.h>
#include <stddef.h>
class Straw;
class SubTitleClass;
class SubTitleParserClass
{
public:
SubTitleParserClass(Straw& input);
~SubTitleParserClass();
DynamicVectorClass<SubTitleClass*>* Get_Sub_Titles(const char* moviename);
private:
enum {LINE_MAX = 1024};
typedef struct tagTokenHook
{
const wchar_t* Token;
void (*Handler)(wchar_t* param, SubTitleClass* subTitle);
} TokenHook;
// Prevent copy construction
SubTitleParserClass(const SubTitleParserClass&);
const SubTitleParserClass operator=(const SubTitleParserClass&);
bool Find_Movie_Entry(const char* moviename);
bool Parse_Sub_Title(wchar_t* string, SubTitleClass* subTitle);
void Parse_Token(wchar_t* token, wchar_t* param, SubTitleClass* subTitle);
wchar_t* Get_Next_Line(void);
unsigned int Get_Line_Number(void) const {return mLineNumber;}
static TokenHook mTokenHooks[];
Straw& mInput;
wchar_t mBuffer[LINE_MAX];
unsigned int mLineNumber;
};
#endif // _SUBTITLEPARSER_H_

View File

@@ -0,0 +1,582 @@
/*
** 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/>.
*/
#include "CNCModeSettings.h"
#include "CombatChunkID.h"
#include "PersistFactory.h"
#include "DefinitionFactory.h"
#include "SimpleDefinitionFactory.h"
#include "PlayerType.h"
#include "WWHack.h"
#include "Debug.h"
DECLARE_FORCE_LINK(CNCModeSettings)
CNCModeSettingsDef* CNCModeSettingsDef::_mInstance = NULL;
// Factories
SimplePersistFactoryClass<CNCModeSettingsDef, CHUNKID_GLOBAL_SETTINGS_DEF_CNCMODE> _CNCModeSettingsDefPersistFactory;
DECLARE_DEFINITION_FACTORY(CNCModeSettingsDef, CLASSID_GLOBAL_SETTINGS_DEF_CNCMODE, "C&C Mode Settings") _CNCModeSettingsDefDefFactory;
CNCModeSettingsDef::CNCModeSettingsDef(void) :
AnnouncementInterval(30)
{
//WWASSERT(_mInstance == NULL);
_mInstance = this;
for (int team = 0; team < NUM_TEAMS; ++team)
{
mPowerOfflineID[team] = 0;
mPurchaseCanceledID[team] = 0;
mInsufficientFundsID[team] = 0;
mConstructingID[team] = 0;
mUnitReadyID[team] = 0;
mIonBeaconDeployedID[team] = 0;
mIonBeaconDisarmedID[team] = 0;
mIonBeaconWarningID[team] = 0;
mNukeBeaconDeployedID[team] = 0;
mNukeBeaconDisarmedID[team] = 0;
mNukeBeaconWarningID[team] = 0;
}
memset(mRadioCmds, 0, sizeof(mRadioCmds));
EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_INT, AnnouncementInterval);
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mPowerOfflineID[0], "Nod power offline");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mPowerOfflineID[1], "GDI power offline");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mPurchaseCanceledID[0], "Nod purchase canceled");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mPurchaseCanceledID[1], "GDI purchase canceled");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mInsufficientFundsID[0], "Nod inssufficient funds");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mInsufficientFundsID[1], "GDI inssufficient funds");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mUnitReadyID[0], "Nod unit ready");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mUnitReadyID[1], "GDI unit ready");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconDeployedID[0], "Nod Ion Cannon Deployed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconDeployedID[1], "GDI Ion Cannon Deployed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconDisarmedID[0], "Nod Ion Cannon Disarmed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconDisarmedID[1], "GDI Ion Cannon Disarmed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconWarningID[0], "Nod Ion Cannon Warning");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mIonBeaconWarningID[1], "GDI Ion Cannon Disarmed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconDeployedID[0], "Nod Nuke Deployed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconDeployedID[1], "GDI Nuke Deployed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconDisarmedID[0], "Nod Nuke Disarmed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconDisarmedID[1], "GDI Nuke Disarmed");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconWarningID[0], "Nod Nuke Warning");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mNukeBeaconWarningID[1], "GDI Nuke Warning");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[0], "Radio Command 1 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[1], "Radio Command 2 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[2], "Radio Command 3 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[3], "Radio Command 4 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[4], "Radio Command 5 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[5], "Radio Command 6 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[6], "Radio Command 7 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[7], "Radio Command 8 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[8], "Radio Command 9 (CTRL");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[9], "Radio Command 10 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[10], "Radio Command 11 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[11], "Radio Command 12 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[12], "Radio Command 13 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[13], "Radio Command 14 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[14], "Radio Command 15 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[15], "Radio Command 16 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[16], "Radio Command 17 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[17], "Radio Command 18 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[18], "Radio Command 19 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[19], "Radio Command 20 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[20], "Radio Command 21 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[21], "Radio Command 22 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[22], "Radio Command 23 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[23], "Radio Command 24 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[24], "Radio Command 25 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[25], "Radio Command 26 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[26], "Radio Command 27 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[27], "Radio Command 28 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[28], "Radio Command 29 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_STRINGSDB_ID, mRadioCmds[29], "Radio Command 30 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[0], "Radio EmotIcon 1 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[1], "Radio EmotIcon 2 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[2], "Radio EmotIcon 3 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[3], "Radio EmotIcon 4 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[4], "Radio EmotIcon 5 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[5], "Radio EmotIcon 6 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[6], "Radio EmotIcon 7 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[7], "Radio EmotIcon 8 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[8], "Radio EmotIcon 9 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[9], "Radio EmotIcon 10 (CTRL)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[10], "Radio EmotIcon 11 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[11], "Radio EmotIcon 12 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[12], "Radio EmotIcon 13 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[13], "Radio EmotIcon 14 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[14], "Radio EmotIcon 15 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[15], "Radio EmotIcon 16 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[16], "Radio EmotIcon 17 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[17], "Radio EmotIcon 18 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[18], "Radio EmotIcon 19 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[19], "Radio EmotIcon 20 (ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[20], "Radio EmotIcon 21 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[21], "Radio EmotIcon 22 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[22], "Radio EmotIcon 23 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[23], "Radio EmotIcon 24 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[24], "Radio EmotIcon 25 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[25], "Radio EmotIcon 26 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[26], "Radio EmotIcon 27 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[27], "Radio EmotIcon 28 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[28], "Radio EmotIcon 29 (CTRL + ALT)");
NAMED_EDITABLE_PARAM(CNCModeSettingsDef, ParameterClass::TYPE_FILENAME, mRadioCmdIcons[29], "Radio EmotIcon 30 (CTRL + ALT)");
}
CNCModeSettingsDef::~CNCModeSettingsDef(void)
{
_mInstance = NULL;
}
uint32 CNCModeSettingsDef::Get_Class_ID(void) const
{
return CLASSID_GLOBAL_SETTINGS_DEF_CNCMODE;
}
const PersistFactoryClass& CNCModeSettingsDef::Get_Factory(void) const
{
return _CNCModeSettingsDefPersistFactory;
}
PersistClass* CNCModeSettingsDef::Create(void) const
{
WWASSERT (0);
return NULL;
}
// Save/load constants
enum
{
CHUNKID_PARENT = 803001812,
CHUNKID_VARIABLES,
VARID_DEF_ANNOUNCEMENT_INTERVAL = 1,
VARID_DEF_NOD_POWER_OFFLINE_ID,
VARID_DEF_GDI_POWER_OFFLINE_ID,
VARID_DEF_NOD_PURCHASE_CANCELED_ID,
VARID_DEF_GDI_PURCHASE_CANCELED_ID,
VARID_DEF_NOD_INSUFFICIENT_FUNDS_ID,
VARID_DEF_GDI_INSUFFICIENT_FUNDS_ID,
VARID_DEF_NOD_UNIT_READY_ID,
VARID_DEF_GDI_UNIT_READY_ID,
VARID_DEF_RADIO_CMD_01,
VARID_DEF_RADIO_CMD_02,
VARID_DEF_RADIO_CMD_03,
VARID_DEF_RADIO_CMD_04,
VARID_DEF_RADIO_CMD_05,
VARID_DEF_RADIO_CMD_06,
VARID_DEF_RADIO_CMD_07,
VARID_DEF_RADIO_CMD_08,
VARID_DEF_RADIO_CMD_09,
VARID_DEF_RADIO_CMD_10,
VARID_DEF_RADIO_CMD_11,
VARID_DEF_RADIO_CMD_12,
VARID_DEF_RADIO_CMD_13,
VARID_DEF_RADIO_CMD_14,
VARID_DEF_RADIO_CMD_15,
VARID_DEF_RADIO_CMD_16,
VARID_DEF_RADIO_CMD_17,
VARID_DEF_RADIO_CMD_18,
VARID_DEF_RADIO_CMD_19,
VARID_DEF_RADIO_CMD_20,
VARID_DEF_RADIO_CMD_21,
VARID_DEF_RADIO_CMD_22,
VARID_DEF_RADIO_CMD_23,
VARID_DEF_RADIO_CMD_24,
VARID_DEF_RADIO_CMD_25,
VARID_DEF_RADIO_CMD_26,
VARID_DEF_RADIO_CMD_27,
VARID_DEF_RADIO_CMD_28,
VARID_DEF_RADIO_CMD_29,
VARID_DEF_RADIO_CMD_30,
VARID_DEF_NOD_ION_BEACON_DEPLOYED_ID,
VARID_DEF_GDI_ION_BEACON_DEPLOYED_ID,
VARID_DEF_NOD_ION_BEACON_DISARMED_ID,
VARID_DEF_GDI_ION_BEACON_DISARMED_ID,
VARID_DEF_NOD_ION_BEACON_WARNING_ID,
VARID_DEF_GDI_ION_BEACON_WARNING_ID,
VARID_DEF_NOD_NUKE_BEACON_DEPLOYED_ID,
VARID_DEF_GDI_NUKE_BEACON_DEPLOYED_ID,
VARID_DEF_NOD_NUKE_BEACON_DISARMED_ID,
VARID_DEF_GDI_NUKE_BEACON_DISARMED_ID,
VARID_DEF_NOD_NUKE_BEACON_WARNING_ID,
VARID_DEF_GDI_NUKE_BEACON_WARNING_ID,
VARID_DEF_RADIO_ICON_01,
VARID_DEF_RADIO_ICON_02,
VARID_DEF_RADIO_ICON_03,
VARID_DEF_RADIO_ICON_04,
VARID_DEF_RADIO_ICON_05,
VARID_DEF_RADIO_ICON_06,
VARID_DEF_RADIO_ICON_07,
VARID_DEF_RADIO_ICON_08,
VARID_DEF_RADIO_ICON_09,
VARID_DEF_RADIO_ICON_10,
VARID_DEF_RADIO_ICON_11,
VARID_DEF_RADIO_ICON_12,
VARID_DEF_RADIO_ICON_13,
VARID_DEF_RADIO_ICON_14,
VARID_DEF_RADIO_ICON_15,
VARID_DEF_RADIO_ICON_16,
VARID_DEF_RADIO_ICON_17,
VARID_DEF_RADIO_ICON_18,
VARID_DEF_RADIO_ICON_19,
VARID_DEF_RADIO_ICON_20,
VARID_DEF_RADIO_ICON_21,
VARID_DEF_RADIO_ICON_22,
VARID_DEF_RADIO_ICON_23,
VARID_DEF_RADIO_ICON_24,
VARID_DEF_RADIO_ICON_25,
VARID_DEF_RADIO_ICON_26,
VARID_DEF_RADIO_ICON_27,
VARID_DEF_RADIO_ICON_28,
VARID_DEF_RADIO_ICON_29,
VARID_DEF_RADIO_ICON_30,
};
bool CNCModeSettingsDef::Save(ChunkSaveClass& csave)
{
csave.Begin_Chunk(CHUNKID_PARENT);
DefinitionClass::Save(csave);
csave.End_Chunk();
csave.Begin_Chunk(CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK(csave, VARID_DEF_ANNOUNCEMENT_INTERVAL, AnnouncementInterval);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_POWER_OFFLINE_ID, mPowerOfflineID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_POWER_OFFLINE_ID, mPowerOfflineID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_PURCHASE_CANCELED_ID, mPurchaseCanceledID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_PURCHASE_CANCELED_ID, mPurchaseCanceledID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_INSUFFICIENT_FUNDS_ID, mInsufficientFundsID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_INSUFFICIENT_FUNDS_ID, mInsufficientFundsID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_UNIT_READY_ID, mUnitReadyID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_UNIT_READY_ID, mUnitReadyID[1]);
for (int radioIndex = 0; radioIndex < 30; ++radioIndex)
{
WRITE_MICRO_CHUNK(csave, VARID_DEF_RADIO_CMD_01 + radioIndex, mRadioCmds[radioIndex]);
WRITE_MICRO_CHUNK_WWSTRING(csave, VARID_DEF_RADIO_ICON_01 + radioIndex, mRadioCmdIcons[radioIndex]);
}
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_ION_BEACON_DEPLOYED_ID, mIonBeaconDeployedID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_ION_BEACON_DEPLOYED_ID, mIonBeaconDeployedID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_ION_BEACON_DISARMED_ID, mIonBeaconDisarmedID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_ION_BEACON_DISARMED_ID, mIonBeaconDisarmedID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_ION_BEACON_WARNING_ID, mIonBeaconWarningID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_ION_BEACON_WARNING_ID, mIonBeaconWarningID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_NUKE_BEACON_DEPLOYED_ID, mNukeBeaconDeployedID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_NUKE_BEACON_DEPLOYED_ID, mNukeBeaconDeployedID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_NUKE_BEACON_DISARMED_ID, mNukeBeaconDisarmedID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_NUKE_BEACON_DISARMED_ID, mNukeBeaconDisarmedID[1]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_NOD_NUKE_BEACON_WARNING_ID, mNukeBeaconWarningID[0]);
WRITE_MICRO_CHUNK(csave, VARID_DEF_GDI_NUKE_BEACON_WARNING_ID, mNukeBeaconWarningID[1]);
csave.End_Chunk();
return true;
}
bool CNCModeSettingsDef::Load(ChunkLoadClass& cload)
{
while (cload.Open_Chunk())
{
switch (cload.Cur_Chunk_ID())
{
case CHUNKID_PARENT:
DefinitionClass::Load(cload);
break;
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk())
{
switch (cload.Cur_Micro_Chunk_ID())
{
READ_MICRO_CHUNK(cload, VARID_DEF_ANNOUNCEMENT_INTERVAL, AnnouncementInterval);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_POWER_OFFLINE_ID, mPowerOfflineID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_POWER_OFFLINE_ID, mPowerOfflineID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_PURCHASE_CANCELED_ID, mPurchaseCanceledID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_PURCHASE_CANCELED_ID, mPurchaseCanceledID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_INSUFFICIENT_FUNDS_ID, mInsufficientFundsID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_INSUFFICIENT_FUNDS_ID, mInsufficientFundsID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_UNIT_READY_ID, mUnitReadyID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_UNIT_READY_ID, mUnitReadyID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_01, mRadioCmds[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_02, mRadioCmds[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_03, mRadioCmds[2]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_04, mRadioCmds[3]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_05, mRadioCmds[4]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_06, mRadioCmds[5]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_07, mRadioCmds[6]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_08, mRadioCmds[7]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_09, mRadioCmds[8]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_10, mRadioCmds[9]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_11, mRadioCmds[10]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_12, mRadioCmds[11]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_13, mRadioCmds[12]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_14, mRadioCmds[13]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_15, mRadioCmds[14]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_16, mRadioCmds[15]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_17, mRadioCmds[16]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_18, mRadioCmds[17]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_19, mRadioCmds[18]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_20, mRadioCmds[19]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_21, mRadioCmds[20]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_22, mRadioCmds[21]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_23, mRadioCmds[22]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_24, mRadioCmds[23]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_25, mRadioCmds[24]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_26, mRadioCmds[25]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_27, mRadioCmds[26]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_28, mRadioCmds[27]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_29, mRadioCmds[28]);
READ_MICRO_CHUNK(cload, VARID_DEF_RADIO_CMD_30, mRadioCmds[29]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_01, mRadioCmdIcons[0]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_02, mRadioCmdIcons[1]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_03, mRadioCmdIcons[2]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_04, mRadioCmdIcons[3]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_05, mRadioCmdIcons[4]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_06, mRadioCmdIcons[5]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_07, mRadioCmdIcons[6]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_08, mRadioCmdIcons[7]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_09, mRadioCmdIcons[8]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_10, mRadioCmdIcons[9]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_11, mRadioCmdIcons[10]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_12, mRadioCmdIcons[11]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_13, mRadioCmdIcons[12]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_14, mRadioCmdIcons[13]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_15, mRadioCmdIcons[14]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_16, mRadioCmdIcons[15]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_17, mRadioCmdIcons[16]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_18, mRadioCmdIcons[17]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_19, mRadioCmdIcons[18]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_20, mRadioCmdIcons[19]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_21, mRadioCmdIcons[20]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_22, mRadioCmdIcons[21]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_23, mRadioCmdIcons[22]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_24, mRadioCmdIcons[23]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_25, mRadioCmdIcons[24]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_26, mRadioCmdIcons[25]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_27, mRadioCmdIcons[26]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_28, mRadioCmdIcons[27]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_29, mRadioCmdIcons[28]);
READ_MICRO_CHUNK_WWSTRING(cload, VARID_DEF_RADIO_ICON_30, mRadioCmdIcons[29]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_ION_BEACON_DEPLOYED_ID, mIonBeaconDeployedID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_ION_BEACON_DEPLOYED_ID, mIonBeaconDeployedID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_ION_BEACON_DISARMED_ID, mIonBeaconDisarmedID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_ION_BEACON_DISARMED_ID, mIonBeaconDisarmedID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_ION_BEACON_WARNING_ID, mIonBeaconWarningID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_ION_BEACON_WARNING_ID, mIonBeaconWarningID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_NUKE_BEACON_DEPLOYED_ID, mNukeBeaconDeployedID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_NUKE_BEACON_DEPLOYED_ID, mNukeBeaconDeployedID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_NUKE_BEACON_DISARMED_ID, mNukeBeaconDisarmedID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_NUKE_BEACON_DISARMED_ID, mNukeBeaconDisarmedID[1]);
READ_MICRO_CHUNK(cload, VARID_DEF_NOD_NUKE_BEACON_WARNING_ID, mNukeBeaconWarningID[0]);
READ_MICRO_CHUNK(cload, VARID_DEF_GDI_NUKE_BEACON_WARNING_ID, mNukeBeaconWarningID[1]);
default:
Debug_Say(("Unhandled Micro Chunk:%d File:%s Line:%d\r\n",cload.Cur_Micro_Chunk_ID (),__FILE__,__LINE__));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Chunk();
}
return true;
}
int CNCModeSettingsDef::Get_Power_Offline_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mPowerOfflineID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Purchase_Canceled_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mPurchaseCanceledID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Insufficient_Funds_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mInsufficientFundsID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Constructing_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mConstructingID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Unit_Ready_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mUnitReadyID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Ion_Beacon_Deployed_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mIonBeaconDeployedID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Ion_Beacon_Disarmed_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mIonBeaconDisarmedID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Ion_Beacon_Warning_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mIonBeaconWarningID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Nuke_Beacon_Deployed_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mNukeBeaconDeployedID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Nuke_Beacon_Disarmed_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mNukeBeaconDisarmedID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Nuke_Beacon_Warning_Report(int team) const
{
if (team >= 0 && team < NUM_TEAMS)
{
return mNukeBeaconWarningID[team];
}
return 0;
}
int CNCModeSettingsDef::Get_Radio_Command(int num) const
{
return mRadioCmds[num];
}
const char *CNCModeSettingsDef::Get_Radio_Command_Emot_Icon(int num) const
{
const char *retval = NULL;
if (num >= 0 && num < 30)
{
retval = mRadioCmdIcons[num];
}
return retval;
}

View File

@@ -0,0 +1,110 @@
/*
** 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
* $Archive: /Commando/Code/Combat/CNCModeSettings.h $
*
* DESCRIPTION
* Settings for CNC Multiplayer mode.
*
* PROGRAMMER
* Denzil E. Long, Jr.
* $Author: Patrick $
*
* VERSION INFO
* $Revision: 5 $
* $Modtime: 11/28/01 2:22p $
*
******************************************************************************/
#ifndef __CNCMODESETTINGS_H__
#define __CNCMODESETTINGS_H__
#include "Always.h"
#include "Definition.h"
class CNCModeSettingsDef :
public DefinitionClass
{
public:
enum {NUM_TEAMS = 2};
CNCModeSettingsDef(void);
virtual ~CNCModeSettingsDef(void);
virtual uint32 Get_Class_ID(void) const;
virtual PersistClass* Create(void) const;
virtual bool Save(ChunkSaveClass& csave);
virtual bool Load(ChunkLoadClass& cload);
virtual const PersistFactoryClass& Get_Factory(void) const;
static CNCModeSettingsDef* Get_Instance(void)
{return _mInstance;}
int Get_Announcement_Interval(void) const
{return AnnouncementInterval;}
int Get_Power_Offline_Report(int team) const;
int Get_Purchase_Canceled_Report(int team) const;
int Get_Insufficient_Funds_Report(int team) const;
int Get_Constructing_Report(int team) const;
int Get_Unit_Ready_Report(int team) const;
int Get_Ion_Beacon_Deployed_Report(int team) const;
int Get_Ion_Beacon_Disarmed_Report(int team) const;
int Get_Ion_Beacon_Warning_Report(int team) const;
int Get_Nuke_Beacon_Deployed_Report(int team) const;
int Get_Nuke_Beacon_Disarmed_Report(int team) const;
int Get_Nuke_Beacon_Warning_Report(int team) const;
int Get_Radio_Command(int num) const;
const char *Get_Radio_Command_Emot_Icon(int num) const;
// Editable support
DECLARE_EDITABLE(CNCModeSettingsDef, DefinitionClass);
protected:
static CNCModeSettingsDef* _mInstance;
int AnnouncementInterval;
int mPowerOfflineID[NUM_TEAMS];
int mPurchaseCanceledID[NUM_TEAMS];
int mInsufficientFundsID[NUM_TEAMS];
int mConstructingID[NUM_TEAMS];
int mUnitReadyID[NUM_TEAMS];
int mIonBeaconDeployedID[NUM_TEAMS];
int mIonBeaconDisarmedID[NUM_TEAMS];
int mIonBeaconWarningID[NUM_TEAMS];
int mNukeBeaconDeployedID[NUM_TEAMS];
int mNukeBeaconDisarmedID[NUM_TEAMS];
int mNukeBeaconWarningID[NUM_TEAMS];
int mRadioCmds[30];
StringClass mRadioCmdIcons[30];
};
#endif // __CNCMODESETTINGS_H__

1259
Code/Combat/Combat.dsp Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,170 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/SoundEnvironment.cpp $*
* *
* Author:: Ian Leslie *
* *
* $Modtime:: 5/21/01 2:16p $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Includes.
#include "soundenvironment.h"
#include "camera.h"
#include "combat.h"
#include "gameobjmanager.h"
#include "phys.h"
#include "physcoltest.h"
#include "pscene.h"
/***********************************************************************************************
* SoundEnvironmentClass::SoundEnvironmentClass -- *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/16/01 IML : Created. *
*=============================================================================================*/
SoundEnvironmentClass::SoundEnvironmentClass()
: UserCount (0)
{
// Initialize the amplitude mixing buffer.
AmplitudeBuffer = new float [AMPLITUDE_BUFFER_SIZE];
WWASSERT (AmplitudeBuffer != NULL);
Reset();
}
/***********************************************************************************************
* SoundEnvironmentClass::Reset -- *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/16/01 IML : Created. *
*=============================================================================================*/
void SoundEnvironmentClass::Reset()
{
// Clear the amplitude buffer.
AmplitudeIndex = 0;
AmplitudeSum = 0.0f;
for (unsigned i = 0; i < AMPLITUDE_BUFFER_SIZE; i++) {
AmplitudeBuffer [i] = 0.0f;
}
}
/***********************************************************************************************
* SoundEnvironmentClass::~SoundEnvironmentClass -- *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/20/01 PDS : Created. *
*=============================================================================================*/
SoundEnvironmentClass::~SoundEnvironmentClass()
{
delete [] AmplitudeBuffer;
}
/***********************************************************************************************
* SoundEnvironmentClass::Update -- *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 04/16/01 IML : Created. *
*=============================================================================================*/
void SoundEnvironmentClass::Update (PhysicsSceneClass *scene, CameraClass *camera)
{
// Optimization: only update if this object is being used.
if (UserCount > 0) {
Vector3 cameraposition;
Vector3 scenemin, scenemax;
float amplitude;
cameraposition = camera->Get_Position();
// Get the highest point in the scene.
scene->Get_Level_Extents (scenemin, scenemax);
// Expand the bounding box by a small amount so that we can distinguish between collisions with geometry and
// collisions with the bounding box.
scenemin.Z -= 1.0f;
scenemax.Z += 1.0f;
// Cast a ray from the camera position upwards.
{
Vector3 raycastendpoint (cameraposition.X, cameraposition.Y, scenemax.Z);
LineSegClass raycast (cameraposition, raycastendpoint);
CastResultStruct rayresult;
PhysRayCollisionTestClass raytest (raycast, &rayresult, TERRAIN_ONLY_COLLISION_GROUP, COLLISION_TYPE_PROJECTILE);
scene->Cast_Ray (raytest);
// Did the ray hit an object?
if (raytest.Result->Fraction < 1.0f) {
// Is the camera in an environment zone (in which case environmental sounds should not be heard)?
if (GameObjManager::Is_In_Environment_Zone (cameraposition)) {
amplitude = 0.0f;
} else {
amplitude = 0.5f;
}
} else {
amplitude = 1.0f;
}
}
AmplitudeSum -= AmplitudeBuffer [AmplitudeIndex];
AmplitudeBuffer [AmplitudeIndex] = amplitude;
AmplitudeSum += amplitude;
AmplitudeIndex++;
if (AmplitudeIndex >= AMPLITUDE_BUFFER_SIZE) AmplitudeIndex = 0;
}
}

View File

@@ -0,0 +1,81 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/SoundEnvironment.h $*
* *
* Author:: Ian Leslie *
* *
* $Modtime:: 4/20/01 7:01p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef SOUNDENVIRONMENT_H
#define SOUNDENVIRONMENT_H
// Includes.
#include "refcount.h"
// Class declarations.
class CameraClass;
class PhysicsSceneClass;
// A simple class that, upon each update, will determine of there is an object vertically
// above the camera (at any height). If so then an amplitude value is attenuated. If, the
// camera is also in an environment zone, then the amplitude is attenuated further. Amplitude
// values are in the range 0..1. This class also uses a small mixing buffer so that amplitude
// changes occur smoothly over time.
class SoundEnvironmentClass : public RefCountClass
{
public:
SoundEnvironmentClass();
~SoundEnvironmentClass();
void Reset();
void Update (PhysicsSceneClass *scene, CameraClass *camera);
float Get_Amplitude() {return (AmplitudeSum / AMPLITUDE_BUFFER_SIZE);}
void Add_User() {UserCount++;} // Call to indicate that you want to start using this object.
void Remove_User() {UserCount--;} // Call to indicate that you no longer need this object.
protected:
enum {
AMPLITUDE_BUFFER_SIZE = 8
};
unsigned UserCount;
unsigned AmplitudeIndex;
float AmplitudeSum;
float *AmplitudeBuffer;
};
#endif // SOUNDENVIRONMENT_H

2378
Code/Combat/WeatherMgr.cpp Normal file

File diff suppressed because it is too large Load Diff

452
Code/Combat/WeatherMgr.h Normal file
View File

@@ -0,0 +1,452 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/WeatherMgr.h $*
* *
* Author:: Ian Leslie *
* *
* $Modtime:: 1/15/02 7:26p $*
* *
* $Revision:: 16 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef WEATHERMGR_H
#define WEATHERMGR_H
// Code controlling defines.
#define WEATHER_PARTICLE_SORT 0
// Includes.
#include "combatchunkid.h"
#include "pointgr.h"
#include "mempool.h"
#include "networkobject.h"
#include "random.h"
#include "rendobj.h"
#include "saveloadsubsystem.h"
#include "soundenvironment.h"
#include "texture.h"
#include "vector.h"
#include "vector2.h"
#include "vector3.h"
#include "wwdebug.h"
// Class declarations.
class ChunkLoadClass;
class ChunkSaveClass;
class PhysicsSceneClass;
#if WEATHER_PARTICLE_SORT
class SortingIndexBufferClass;
#else
class DX8IndexBufferClass;
#endif
class AudibleSoundClass;
class WindClass
{
public:
WindClass (float heading, float speed, float variability, SoundEnvironmentClass *soundenvironment);
~WindClass();
Vector2 Get_Velocity() {return (Velocity);}
void Set (float heading, float speed, float variability);
bool Update();
protected:
enum {
OCTAVE_COUNT = 2
};
SoundEnvironmentClass *SoundEnvironment;
float Heading;
float Speed;
float Variability;
double Theta [OCTAVE_COUNT];
Vector2 Velocity;
AudibleSoundClass *Sound;
};
class WeatherSystemClass : public RenderObjClass
{
public:
enum {
GROWTH_STEP = 256
};
enum RenderModeEnum {
RENDER_MODE_AXIS_ALIGNED, // Render particle oriented about the particle's velocity vector (suitable for rain, for example).
RENDER_MODE_CAMERA_ALIGNED, // Render particle aligned with the camera direction (suitable for snow, for example).
RENDER_MODE_SURFACE_ALIGNED // Render particle such that it looks attached to the surface of an object.
};
WeatherSystemClass (PhysicsSceneClass *scene,
float emittersize,
float emitterheight,
float particledensity,
float particlesperunitlength,
float particlewidth,
float particleheight,
float particlespeed,
const Vector2 &pageoffset,
const Vector2 &pagesize,
unsigned pagecount,
bool staticpageexists,
float minstatictime,
float maxstatictime,
RenderModeEnum rendermode,
bool decayaftercollision,
bool prime);
~WeatherSystemClass();
RenderObjClass *Clone() const
{
WWASSERT (false);
return (0);
}
void Set_Density (float density);
void Render (RenderInfoClass &rinfo);
void Get_Obj_Space_Bounding_Sphere (SphereClass &sphere) const;
void Get_Obj_Space_Bounding_Box (AABoxClass &box) const;
virtual bool Update (WindClass *wind, const Vector3 &cameraposition);
protected:
enum {
VERTICES_PER_TRIANGLE = 3,
MAX_IB_PARTICLE_COUNT = 2048,
MAX_AGE = 1000000
};
struct RayStruct : public AutoPoolClass <RayStruct, GROWTH_STEP>
{
public:
RayStruct *Next; // Next ray in list.
bool Initialized; // Has the ray been defined?
bool RayCast; // Does this ray need to be relocated in the emitter (and therefore needs to be raycast).
Vector3 ParticleVelocity; // Velocity of all particles spawned by this ray.
Vector2 StartPosition; // Start position of ray inside emitter.
Vector3 EndPosition; // Point of collision of ray with environment.
bool ValidSurfaceNormal; // Does the ray intersect a phyical object?
Vector3 SurfaceNormal; // Normal of surface ray intersects (if any).
};
struct ParticleStruct : public AutoPoolClass <ParticleStruct, GROWTH_STEP>
{
public:
ParticleStruct *Prev; // Previous particle in list.
ParticleStruct *Next; // Next particle in list.
float CollisionTime; // Time when particle hits something (in seconds).
float LifeTime; // Lifetime of particle (in seconds).
float ElapsedTime; // Time elapsed since birth of particle (in seconds).
Vector3 Velocity; // Velocity of particle (in metres per second).
Vector2 UnitZVelocity; // Velocity / Velocity.Z (precomputed for optimization purposes).
Vector3 CollisionPosition; // Position of collision.
Vector3 CurrentPosition; // Current position of particle (in world space).
Vector3 SurfaceNormal; // Normal of surface particle collides with (if any).
unsigned char Page; // Texture page for this particle.
unsigned char RenderMode;
unsigned char Pad [2]; // Pad structure to 4-byte multiple.
};
// Utility functions.
float Spawn_Count (float time) {return (ParticleDensity * EmitterSize * EmitterSize * time);}
bool Can_Spawn (const RayStruct *rayptr) {return (rayptr->EndPosition.Z < EmitterPosition.Z);}
bool Spawn (RayStruct *suppliedrayptr = NULL);
void Kill (ParticleStruct *particleptr);
PhysicsSceneClass *Scene; // The scene that contains the weather system.
float Age; // Age of this weather system (in seconds).
float EmitterSize; // Size of square emitter (area of emitter = size * size).
float EmitterHeight; // Height of emitter (relative to camera).
Vector3 EmitterPosition; // Centroid of emitter (in world space).
float ParticleDensity; // Density of particles (over area of emitter).
float ParticlesPerUnitLength;
float ParticleSpeed;
Vector3 ParticleVelocity; // Dominant velocity vector of particles.
float HalfParticleWidth;
float HalfParticleHeight;
RayStruct *RayHead;
unsigned RayCount;
RayStruct *RaySpawnPtr;
RayStruct *RayUpdatePtr;
float MinRayEndZ; // Current lowest Z-value of end of any ray (used to determine a bounding box around this render object).
float SpawnCountFraction; // Cumulative fractional spawn counts (for improved accuracy).
Vector3 SceneMin, SceneMax; // Bounding box around the scene that the particle system lives in.
Vector3 ObjectMin, ObjectMax; // Bounding box around this render object (for culling purposes).
ParticleStruct *ParticleHead; // Head of list of particles in system.
unsigned ParticleCount; // No. of particles in system.
#if WEATHER_PARTICLE_SORT
SortingIndexBufferClass *IndexBuffer;
#else
DX8IndexBufferClass *IndexBuffer;
#endif
VertexMaterialClass *Material;
ShaderClass Shader;
TextureClass *Texture;
Vector2 *TextureArray;
RenderModeEnum RenderMode;
bool DecayAfterCollision;
unsigned PageCount;
bool StaticPageExists;
float MinStaticTime;
float MaxStaticTime;
Vector3 CameraPosition;
bool CameraPositionValid;
static Random2Class _RandomNumber; // Random no. generator.
static unsigned _GlobalParticleCount; // Total no. of particles over all weather systems.
};
class RainSystemClass : public WeatherSystemClass
{
public:
RainSystemClass (PhysicsSceneClass *scene, float particledensity, WindClass *wind, SoundEnvironmentClass *soundenvironment, bool prime);
virtual ~RainSystemClass();
bool Update (WindClass *wind, const Vector3 &cameraposition);
protected:
enum {
PAGE_COUNT = 4
};
AudibleSoundClass *Sound; // Sound effect for rainfall.
SoundEnvironmentClass *SoundEnvironment;
};
class SnowSystemClass : public WeatherSystemClass
{
public:
SnowSystemClass (PhysicsSceneClass *scene, float particledensity, WindClass *wind, bool prime);
bool Update (WindClass *wind, const Vector3 &cameraposition);
protected:
enum {
PAGE_COUNT = 4
};
};
class AshSystemClass : public WeatherSystemClass
{
public:
AshSystemClass (PhysicsSceneClass *scene, float particledensity, WindClass *wind, bool prime);
bool Update (WindClass *wind, const Vector3 &cameraposition);
protected:
enum {
PAGE_COUNT = 4
};
};
class WeatherParameterClass
{
public:
void Initialize();
void Set (float targetvalue, float ramptime, bool override);
void Set (float overrideramptime) {OverrideDuration = overrideramptime;}
float Value() {return (CurrentValue);}
bool Update (float time, bool override);
void Update (float &value, float &target, float &duration, float time);
private:
float CurrentValue;
float NormalValue;
float NormalTarget;
float NormalDuration;
float OverrideTarget;
float OverrideDuration;
friend class WeatherMgrClass;
};
class WeatherMgrClass : public SaveLoadSubSystemClass, public NetworkObjectClass
{
public:
enum PrecipitationEnum {
PRECIPITATION_FIRST,
PRECIPITATION_RAIN = PRECIPITATION_FIRST,
PRECIPITATION_SNOW,
PRECIPITATION_ASH,
PRECIPITATION_COUNT
};
WeatherMgrClass();
~WeatherMgrClass() {}
uint32 Chunk_ID() const {return (CHUNKID_WEATHER_MGR);}
const char *Name() const {return ("WeatherMgrClass");}
void Delete (void) {}
virtual void Set_Delete_Pending (void) {};
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
bool Load_Micro_Chunks (ChunkLoadClass &cload);
void Export_Rare (BitStreamClass &packet);
void Import_Rare (BitStreamClass &packet);
static void Init (SoundEnvironmentClass *soundenvironment);
static void Reset();
static void Shutdown();
static bool Save_Dynamic (ChunkSaveClass &csave);
static bool Load_Dynamic (ChunkLoadClass &cload);
static bool Load_Dynamic_Micro_Chunks (ChunkLoadClass &cload);
static bool Set_Wind (float heading, float speed, float variability, float ramptime = 0.0f);
static bool Override_Wind (float heading, float speed, float variability, float ramptime = 0.0f);
static void Get_Wind (float &heading, float &speed, float &variability);
static void Restore_Wind (float ramptime);
static bool Set_Precipitation (PrecipitationEnum precipitation, float density, float ramptime = 0.0f);
static bool Override_Precipitation (PrecipitationEnum precipitation, float density, float ramptime = 0.0f);
static void Get_Precipitation (PrecipitationEnum precipitation, float &density);
static void Restore_Precipitation (float ramptime);
static void Set_Fog_Enable (bool enabled)
{
_FogEnabled = enabled;
Set_Dirty();
}
static bool Get_Fog_Enable()
{
return (_FogEnabled);
}
static bool Set_Fog_Range (float startdistance, float enddistance, float ramptime = 0.0f);
static void Get_Fog_Range (float &startdistance, float &enddistance);
static void Update (PhysicsSceneClass *scene, CameraClass *camera);
static void Render (const CameraClass *camera);
private:
#define VARID_PARAMETER(varname) \
VARID_ ## varname ## _CURRENT_VALUE, \
VARID_ ## varname ## _NORMAL_VALUE, \
VARID_ ## varname ## _NORMAL_TARGET, \
VARID_ ## varname ## _NORMAL_DURATION, \
VARID_ ## varname ## _OVERRIDE_TARGET, \
VARID_ ## varname ## _OVERRIDE_DURATION
// Constants.
enum {
CHUNKID_MICRO_CHUNKS = 0x03020113,
CHUNKID_DYNAMIC_MICRO_CHUNKS = 0x11020245
};
enum {
VARID_DUMMY = 0x09,
VARID_PARAMETER (WIND_HEADING),
VARID_PARAMETER (WIND_SPEED),
VARID_PARAMETER (WIND_VARIABILITY),
VARID_PARAMETER (RAIN_DENSITY),
VARID_PARAMETER (SNOW_DENSITY),
VARID_PARAMETER (ASH_DENSITY),
VARID_WIND_OVERRIDE_COUNT,
VARID_PRECIPITATION_OVERRIDE_COUNT,
VARID_FOG_ENABLED,
VARID_PARAMETER (FOG_START_DISTANCE),
VARID_PARAMETER (FOG_END_DISTANCE)
};
#undef VARID_PARAMETER
enum {
PARAMETER_WIND_HEADING,
PARAMETER_WIND_SPEED,
PARAMETER_WIND_VARIABILITY,
PARAMETER_RAIN_DENSITY,
PARAMETER_SNOW_DENSITY,
PARAMETER_ASH_DENSITY,
PARAMETER_FOG_START_DISTANCE,
PARAMETER_FOG_END_DISTANCE,
PARAMETER_COUNT
};
static bool Set_Wind (float heading, float speed, float variability, float ramptime, bool override);
static bool Set_Precipitation (PrecipitationEnum precipitation, float density, float ramptime, bool override);
static bool Is_Dirty() {return (_Dirty);}
static void Set_Dirty (bool dirty = true) {_Dirty = dirty;}
static SoundEnvironmentClass *_SoundEnvironment;
static WeatherParameterClass _Parameters [PARAMETER_COUNT];
static bool _Prime;
static bool _Imported;
static unsigned _WindOverrideCount;
static unsigned _PrecipitationOverrideCount;
static WindClass *_Wind;
static WeatherSystemClass *_Precipitation [PRECIPITATION_COUNT];
static bool _FogEnabled;
static bool _Dirty;
};
// Externals.
extern WeatherMgrClass _TheWeatherMgr;
#endif // WEATHERMGR_H

3389
Code/Combat/action.cpp Normal file

File diff suppressed because it is too large Load Diff

147
Code/Combat/action.h Normal file
View File

@@ -0,0 +1,147 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/action.h $*
* *
* $Author:: Patrick $*
* *
* $Modtime:: 10/09/01 2:15p $*
* *
* $Revision:: 47 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ACTION_H
#define ACTION_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef VECTOR3_H
#include "vector3.h"
#endif
#ifndef GAMEOBJREF_H
#include "gameobjref.h"
#endif
#ifndef WWSTRING_H
#include "wwstring.h"
#endif
#ifndef ACTIONPARAMS_H
#include "actionparams.h"
#endif
/*
**
*/
class ActionCodeClass;
class SmartGameObj;
/*
**
*/
class SafeActionParamsStruct : public ActionParamsStruct {
public:
SafeActionParamsStruct & operator = (const ActionParamsStruct & src); // Assignment operator.
bool Save( ChunkSaveClass & csave );
bool Load( ChunkLoadClass & cload );
GameObjReference MoveObjectRef;
GameObjReference AttackObjectRef;
GameObjReference LookObjectRef;
StringClass SafeAnimationName;
StringClass SafeConversationName;
};
/*
**
*/
class ActionClass {
public:
ActionClass( SmartGameObj *obj );
virtual ~ActionClass( void );
bool Save( ChunkSaveClass & csave );
bool Load( ChunkLoadClass & cload );
SmartGameObj * Get_Action_Obj( void ) { return ActionObj; }
SafeActionParamsStruct & Get_Parameters( void ) { return Parameters; }
bool Is_Acting( void );
bool Is_Animating( void );
void Begin_Hibernation( void );
void End_Hibernation( void );
bool Reset( float priority );
bool Follow_Input( const ActionParamsStruct & parameters );
bool Stand( const ActionParamsStruct & parameters );
bool Play_Animation( const ActionParamsStruct & parameters );
bool Goto( const ActionParamsStruct & parameters );
bool Enter_Exit( const ActionParamsStruct & parameters );
bool Dive( const ActionParamsStruct & parameters );
bool Attack( const ActionParamsStruct & parameters );
bool Face_Location( const ActionParamsStruct & parameters );
bool Have_Conversation( const ActionParamsStruct & parameters );
bool Dock_Vehicle( const ActionParamsStruct & parameters );
bool Modify( const ActionParamsStruct & parameters, bool modify_move, bool modify_attack );
void Act( void );
unsigned int Get_Act_Count( void ) { return ActCount; }
bool Is_Active( void );
bool Is_Busy( void );
bool Is_Paused( void ) const { return IsPaused; }
void Pause( bool onoff) { IsPaused = onoff; }
void Done( int reason ); // Notify the obserever
protected:
void Notify_Completed( int observer_id, int action_id, int reason ); // Notify the obserever
bool Request_Action( ActionCodeClass * action, const ActionParamsStruct & parameters );
SmartGameObj * ActionObj;
ActionCodeClass * ActionCode;
SafeActionParamsStruct Parameters;
bool IsPaused;
unsigned int ActCount; // TSS - diagnostic
void Set_Action_Code( ActionCodeClass * code );
};
// Debugging
void Toggle_Display_Findpaths( void );
#endif // ACTION_H

228
Code/Combat/actionparams.h Normal file
View File

@@ -0,0 +1,228 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/actionparams.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 3/19/02 11:31a $*
* *
* $Revision:: 30 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ACTIONPARAMS_H
#define ACTIONPARAMS_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef VECTOR3_H
#include "vector3.h"
#endif
#ifndef GAMEOBJOBSERVER_H
#include "gameobjobserver.h"
#endif
/*
**
*/
class ScriptableGameObj;
typedef ScriptableGameObj GameObject;
/*
**
*/
typedef enum {
NO_AI_STATE_CHANGE = -1,
AI_STATE_IDLE = 0,
AI_STATE_SECONDARY_IDLE,
AI_STATE_SEARCH,
AI_STATE_COMBAT
} SoldierAIState;
/*
**
*/
const float DONT_MOVE_ARRIVED_DIST = 1000.0F;
/*
**
*/
class ActionParamsStruct {
public:
ActionParamsStruct( void );
void Set_Basic( GameObjObserverClass * script, float priority, int action_id, SoldierAIState ai_state = NO_AI_STATE_CHANGE ) { ObserverID = script->Get_ID(); Priority = priority; ActionID = action_id; AIState = ai_state; }
void Set_Basic( long observer_id, float priority, int action_id, SoldierAIState ai_state = NO_AI_STATE_CHANGE ) { ObserverID = observer_id; Priority = priority; ActionID = action_id; AIState = ai_state; }
void Set_Look( const Vector3 & location, float duration ) { LookLocation = location; LookDuration = duration; }
void Set_Look( GameObject * object, float duration ) { LookObject = object; LookDuration = duration; }
void Set_Look( const Vector3 & obj_pos, float angle, float duration );
void Set_Movement( const Vector3 & location, float speed, float arrived_distance, bool crouched = false ) { MoveLocation = location; MoveSpeed = speed; MoveArrivedDistance = arrived_distance; MoveCrouched = crouched; }
void Set_Movement( GameObject * object, float speed, float arrived_distance, bool crouched = false ) { MoveObject = object; MoveSpeed = speed; MoveArrivedDistance = arrived_distance; MoveCrouched = crouched; }
void Set_Attack( const Vector3 & location, float range, float error, bool primary_fire ) { AttackLocation = location; AttackRange = range; AttackError = error; AttackPrimaryFire = primary_fire; }
void Set_Attack( GameObject * object, float range, float error, bool primary_fire ) { AttackObject = object; AttackRange = range; AttackError = error; AttackPrimaryFire = primary_fire; }
void Set_Animation( const char * name, bool looping ) { AnimationName = name; AnimationLooping = looping; }
void Set_Face_Location( const Vector3 &location, float duration ) { FaceLocation = location; FaceDuration = duration; }
void Set_Face_Location( const Vector3 & obj_pos, float angle, float duration );
void Join_Conversation( int active_conversation_id ) { ActiveConversationID = active_conversation_id; }
void Start_Conversation( const char * name ) { ConversationName = name; }
void Dock_Vehicle( const Vector3 &dock_location, const Vector3 &dock_entrance ) { DockLocation = dock_location; DockEntrance = dock_entrance; }
//protected:
// Note: all of these must be saved in SafeActionParamsStruct::Save
int Priority;
int ActionID;
long ObserverID;
Vector3 LookLocation;
GameObject * LookObject;
float LookDuration;
Vector3 MoveLocation;
GameObject * MoveObject;
Vector3 MoveObjectOffset;
float MoveSpeed;
float MoveArrivedDistance;
bool MoveBackup;
bool MoveFollow;
bool MoveCrouched;
bool MovePathfind;
bool ShutdownEngineOnArrival;
float AttackRange;
float AttackError;
bool AttackErrorOverride;
GameObject * AttackObject;
bool AttackPrimaryFire;
bool AttackCrouched;
Vector3 AttackLocation;
bool AttackCheckBlocked;
bool AttackActive;
bool AttackWanderAllowed;
bool AttackFaceTarget; // (gth) control over whether VTOL vehicles face their target when attacking
bool AttackForceFire;
bool ForceFacing;
Vector3 FaceLocation;
float FaceDuration;
bool IgnoreFacing;
int WaypathID;
int WaypointStartID;
int WaypointEndID;
bool WaypathSplined;
const char * AnimationName;
bool AnimationLooping;
int ActiveConversationID;
const char * ConversationName;
SoldierAIState AIState;
Vector3 DockLocation;
Vector3 DockEntrance;
};
inline ActionParamsStruct::ActionParamsStruct( void ) :
Priority( 0 ),
ActionID( 0 ),
ObserverID( 0 ),
LookLocation( 0,0,0 ),
LookObject( NULL ),
LookDuration( 0 ),
MoveLocation( 0,0,0 ),
MoveObject( NULL ),
MoveObjectOffset( 0,0,0 ),
MoveSpeed( 1 ),
MoveArrivedDistance( DONT_MOVE_ARRIVED_DIST ),
MoveBackup( false ),
MoveFollow( false ),
MoveCrouched( false ),
MovePathfind( true ),
ShutdownEngineOnArrival( false ),
AttackRange( 20 ),
AttackError( 0 ),
AttackErrorOverride( false ),
AttackObject( NULL ),
AttackPrimaryFire( true ),
AttackCrouched( false ),
AttackLocation( 0,0,0 ),
AttackCheckBlocked( true ),
AttackActive( true ),
AttackWanderAllowed( false ),
AttackFaceTarget( true ),
AttackForceFire( false ),
ForceFacing( false ),
IgnoreFacing( false ),
FaceLocation( 0, 0, 0 ),
FaceDuration( 2.0F ),
WaypathID( 0 ),
WaypointStartID( 0 ),
WaypointEndID( 0 ),
WaypathSplined( false ),
AnimationName( NULL ),
AnimationLooping( false ),
ActiveConversationID( 0 ),
ConversationName( NULL ),
AIState( NO_AI_STATE_CHANGE ),
DockLocation( 0,0,0 ),
DockEntrance( 0,0,0 )
{
}
void inline ActionParamsStruct::Set_Face_Location( const Vector3 &obj_pos, float angle, float duration )
{
FaceLocation = obj_pos;
FaceLocation.X += ::cos( angle );
FaceLocation.Y += ::sin( angle );
FaceDuration = duration;
return ;
}
void inline ActionParamsStruct::Set_Look( const Vector3 &obj_pos, float angle, float duration )
{
LookLocation = obj_pos;
LookLocation.X += ::cos( angle );
LookLocation.Y += ::sin( angle );
LookDuration = duration;
return ;
}
#endif // ACTIONPARAMS_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,210 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/activeconversation.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/05/01 1:46p $*
* *
* $Revision:: 14 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __ACTIVE_CONVERSATION_H
#define __ACTIVE_CONVERSATION_H
#include "refcount.h"
#include "conversation.h"
#include "vector.h"
#include "vector3.h"
#include "gameobjref.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class ChunkSaveClass;
class ChunkLoadClass;
class PhysicalGameObj;
class OratorClass;
////////////////////////////////////////////////////////////////
//
// ActiveConversationClass
//
////////////////////////////////////////////////////////////////
class ActiveConversationClass : public RefCountClass
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
ActiveConversationClass (void);
virtual ~ActiveConversationClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Save/load methods
//
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
//
// Identification
//
int Get_ID (void) const { return ID; }
void Set_ID (int id) { ID = id; }
//
// Conversation methods
//
ConversationClass * Peek_Conversation (void) const;
void Set_Conversation (ConversationClass *conversation);
//
// Conversation flow control
//
void Start_Conversation (void);
void Stop_Conversation (ActionCompleteReason reason = ACTION_COMPLETE_CONVERSATION_ENDED);
void Think (void);
bool Is_Finished (void) { return bool(State == STATE_FINISHED); }
//
// State evaluation methods
//
bool Get_Orator_Location (PhysicalGameObj *orator, Vector3 *position);
bool Get_Current_Orator_Location (Vector3 *position);
PhysicalGameObj * Get_Current_Orator (void);
void Get_Conversation_Center (Vector3 *position);
void Set_Orator_Arrived (PhysicalGameObj *orator, bool has_arrived);
void Control_Orator (SoldierGameObj *orator);
//
// Orator methods
//
OratorClass * Add_Orator (PhysicalGameObj *orator);
OratorClass * Get_Orator_Information (PhysicalGameObj *orator);
//
// Monitor support
//
void Register_Monitor (ScriptableGameObj *game_obj);
void Unregister_Monitor (ScriptableGameObj *game_obj);
void Set_Action_ID (int id) { ActionID = id; }
//
// Misc accessors
//
int Get_Priority (void) const { return Priority; }
void Set_Priority (int priority) { Priority = priority; }
float Get_Max_Dist (void) const { return MaxDist; }
void Set_Max_Dist (float max_dist) { MaxDist = max_dist; }
bool Is_Interruptable (void) const { return IsInterruptable; }
void Set_Is_Interruptable (bool onoff) { IsInterruptable = onoff; }
//
// Time estimation
//
float Get_Conversation_Time (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Load_Variables (ChunkLoadClass &cload);
void Free_Orator_List (void);
bool Is_Audience_In_Place (void);
void Check_For_Audience (void);
void Say_Next_Remark (void);
void Stop_Current_Sound (void);
void Notify_Monitors_On_End (ActionCompleteReason id);
void Notify_Monitors (int custom_event_id, int param);
////////////////////////////////////////////////////////////////
// Protected data types
////////////////////////////////////////////////////////////////
enum
{
STATE_INITIALIZING = 0,
STATE_WAITING_FOR_AUDIENCE,
STATE_TALKING,
STATE_FINISHED,
STATE_INTERRUPTED = STATE_FINISHED
};
enum
{
MAX_MONITORS = 10,
};
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
int ID;
ConversationClass * Conversation;
int CurrentRemark;
float NextRemarkTimer;
DynamicVectorClass<OratorClass *> OratorList;
int ActionID;
int OratorSpokenBitmask;
Vector3 CentralPos;
GameObjReference MonitorArray[MAX_MONITORS];
AudibleSoundClass * CurrentSound;
int State;
float InitializingTimeLeft;
int Priority;
float MaxDist;
bool IsInterruptable;
};
////////////////////////////////////////////////////////////////
// Peek_Conversation
////////////////////////////////////////////////////////////////
inline ConversationClass *
ActiveConversationClass::Peek_Conversation (void) const
{
return Conversation;
}
#endif //__ACTIVE_CONVERSATION_H

View File

@@ -0,0 +1,572 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/airstripgameobj.cpp $Author:: Patrick $*
* *
* $Modtime:: 2/24/02 2:06p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "airstripgameobj.h"
#include "basecontroller.h"
#include "vehicle.h"
#include "wwhack.h"
#include "simpledefinitionfactory.h"
#include "persistfactory.h"
#include "definitionmgr.h"
#include "combatchunkid.h"
#include "debug.h"
#include "scriptzone.h"
#include "wwprofile.h"
#include "basecontroller.h"
#include "combatchunkid.h"
#include "objlibrary.h"
#include "cinematicgameobj.h"
#include "combat.h"
////////////////////////////////////////////////////////////////
// Hacks
////////////////////////////////////////////////////////////////
DECLARE_FORCE_LINK (AirStrip)
////////////////////////////////////////////////////////////////
// Editable and persist factories
////////////////////////////////////////////////////////////////
SimplePersistFactoryClass <AirStripGameObjDef, CHUNKID_GAME_OBJECT_DEF_AIRSTRIP> _AirStripGameObjDefPersistFactory;
SimplePersistFactoryClass <AirStripGameObj, CHUNKID_GAME_OBJECT_AIRSTRIP> _AirStripGameObjPersistFactory;
DECLARE_DEFINITION_FACTORY (AirStripGameObjDef, CLASSID_GAME_OBJECT_DEF_AIRSTRIP, "Airstrip") _AirStripGameObjDefDefFactory;
////////////////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////////////////
static const float UNITIALIZED_TIMER = -100.0F;
static const float VEHICLE_LOCK_TIME = 30.0f;
////////////////////////////////////////////////////////////////
// Save/Load constants
////////////////////////////////////////////////////////////////
enum
{
CHUNKID_DEF_PARENT = 0x02200638,
CHUNKID_DEF_VARIABLES,
MICROCHUNKID_DEF_CINEMATIC_DEFID = 1,
MICROCHUNKID_DEF_CINEMATIC_LENGTH_TO_DROPOFF,
MICROCHUNKID_DEF_CINEMATIC_SLOT_INDEX,
MICROCHUNKID_DEF_DISPLAY_VEHICLE_TIME
};
enum
{
CHUNKID_PARENT = 0x0219043,
CHUNKID_VARIABLES,
MICROCHUNKID_UNUSED = 1,
};
////////////////////////////////////////////////////////////////
//
// AirStripGameObjDef
//
////////////////////////////////////////////////////////////////
AirStripGameObjDef::AirStripGameObjDef (void) :
CinematicLengthToDropOff (0),
CinematicLengthToVehicleDisplay (0),
CinematicDefID (0),
CinematicSlotIndex (0)
{
//
// Editable support
//
EDITABLE_PARAM (AirStripGameObjDef, ParameterClass::TYPE_FLOAT, CinematicLengthToDropOff);
EDITABLE_PARAM (AirStripGameObjDef, ParameterClass::TYPE_INT, CinematicSlotIndex);
EDITABLE_PARAM (AirStripGameObjDef, ParameterClass::TYPE_FLOAT, CinematicLengthToVehicleDisplay);
#ifdef PARAM_EDITING_ON
GenericDefParameterClass *param = new GenericDefParameterClass (&CinematicDefID);
param->Set_Class_ID (CLASSID_GAME_OBJECT_DEF_SIMPLE);
param->Set_Name ("Drop-Off Cinematic");
GENERIC_EDITABLE_PARAM (AirStripGameObjDef, param)
#endif //PARAM_EDITING_ON
return ;
}
////////////////////////////////////////////////////////////////
//
// ~AirStripGameObjDef
//
////////////////////////////////////////////////////////////////
AirStripGameObjDef::~AirStripGameObjDef (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Class_ID
//
////////////////////////////////////////////////////////////////
uint32
AirStripGameObjDef::Get_Class_ID (void) const
{
return CLASSID_GAME_OBJECT_DEF_AIRSTRIP;
}
////////////////////////////////////////////////////////////////
//
// Create
//
////////////////////////////////////////////////////////////////
PersistClass *
AirStripGameObjDef::Create (void) const
{
AirStripGameObj *building = new AirStripGameObj;
building->Init (*this);
return building;
}
////////////////////////////////////////////////////////////////
//
// Create
//
////////////////////////////////////////////////////////////////
bool
AirStripGameObjDef::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_DEF_PARENT);
VehicleFactoryGameObjDef::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_DEF_VARIABLES);
WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_CINEMATIC_LENGTH_TO_DROPOFF, CinematicLengthToDropOff);
WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_CINEMATIC_DEFID, CinematicDefID);
WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_CINEMATIC_SLOT_INDEX, CinematicSlotIndex);
WRITE_MICRO_CHUNK (csave, MICROCHUNKID_DEF_DISPLAY_VEHICLE_TIME, CinematicLengthToVehicleDisplay);
csave.End_Chunk ();
return true;
}
////////////////////////////////////////////////////////////////
//
// Load
//
////////////////////////////////////////////////////////////////
bool
AirStripGameObjDef::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ())
{
switch (cload.Cur_Chunk_ID ())
{
case CHUNKID_DEF_PARENT:
VehicleFactoryGameObjDef::Load (cload);
break;
case CHUNKID_DEF_VARIABLES:
Load_Variables (cload);
break;
default:
Debug_Say (("Unrecognized AirStrip Def chunkID\n"));
break;
}
cload.Close_Chunk ();
}
return true;
}
////////////////////////////////////////////////////////////////
//
// Load_Variables
//
////////////////////////////////////////////////////////////////
void
AirStripGameObjDef::Load_Variables (ChunkLoadClass &cload)
{
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ())
{
READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_CINEMATIC_LENGTH_TO_DROPOFF, CinematicLengthToDropOff);
READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_CINEMATIC_DEFID, CinematicDefID);
READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_CINEMATIC_SLOT_INDEX, CinematicSlotIndex);
READ_MICRO_CHUNK (cload, MICROCHUNKID_DEF_DISPLAY_VEHICLE_TIME, CinematicLengthToVehicleDisplay);
default:
Debug_Say (("Unrecognized AirStrip Def Variable chunkID\n"));
break;
}
cload.Close_Micro_Chunk();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Factory
//
////////////////////////////////////////////////////////////////
const PersistFactoryClass &
AirStripGameObjDef::Get_Factory (void) const
{
return _AirStripGameObjDefPersistFactory;
}
////////////////////////////////////////////////////////////////
//
// AirStripGameObj
//
////////////////////////////////////////////////////////////////
AirStripGameObj::AirStripGameObj (void) :
CinematicStartTimer (0),
ClearDropoffZoneTimer (UNITIALIZED_TIMER),
DisplayVehicleTimer (UNITIALIZED_TIMER),
IsCinematicStarted (false),
CinematicObject (NULL)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// ~AirStripGameObj
//
////////////////////////////////////////////////////////////////
AirStripGameObj::~AirStripGameObj (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Factory
//
////////////////////////////////////////////////////////////////
const PersistFactoryClass &
AirStripGameObj::Get_Factory (void) const
{
return _AirStripGameObjPersistFactory;
}
////////////////////////////////////////////////////////////////
//
// Init
//
////////////////////////////////////////////////////////////////
void AirStripGameObj::Init( void )
{
Init( Get_Definition() );
}
////////////////////////////////////////////////////////////////
//
// Init
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::Init (const AirStripGameObjDef &definition)
{
VehicleFactoryGameObj::Init (definition);
return ;
}
////////////////////////////////////////////////////////////////
//
// Get_Definition
//
////////////////////////////////////////////////////////////////
const AirStripGameObjDef &
AirStripGameObj::Get_Definition (void) const
{
return (const AirStripGameObjDef &)BaseGameObj::Get_Definition ();
}
////////////////////////////////////////////////////////////////
//
// Save
//
////////////////////////////////////////////////////////////////
bool
AirStripGameObj::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_PARENT);
VehicleFactoryGameObj::Save (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_VARIABLES);
csave.End_Chunk ();
return true;
}
////////////////////////////////////////////////////////////////
//
// Load
//
////////////////////////////////////////////////////////////////
bool
AirStripGameObj::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_PARENT:
VehicleFactoryGameObj::Load (cload);
break;
case CHUNKID_VARIABLES:
Load_Variables (cload);
break;
default:
Debug_Say (("Unrecognized AirStrip chunkID\n"));
break;
}
cload.Close_Chunk();
}
return true;
}
////////////////////////////////////////////////////////////////
//
// Load_Variables
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::Load_Variables (ChunkLoadClass &cload)
{
while (cload.Open_Micro_Chunk ()) {
/*switch (cload.Cur_Micro_Chunk_ID ())
{
default:
Debug_Say (("Unrecognized AirStrip Variable chunkID\n"));
break;
}*/
cload.Close_Micro_Chunk();
}
return ;
}
////////////////////////////////////////////////////////////////
//
// CnC_Initialize
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::CnC_Initialize (BaseControllerClass *base)
{
VehicleFactoryGameObj::CnC_Initialize (base);
return ;
}
////////////////////////////////////////////////////////////////
//
// Think
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::Think (void)
{
WWPROFILE ("AirStrip Think");
//
// Begin the cinematic if necessary
//
if (IsDestroyed == false && GeneratingVehicleID != 0) {
//
// Start the cinematic (if necessary)
//
if (IsCinematicStarted == false) {
CinematicStartTimer -= TimeManager::Get_Frame_Seconds ();
if (CinematicStartTimer <= 0) {
Start_Cinematic ();
ClearDropoffZoneTimer = 0.8f * Get_Definition().CinematicLengthToDropOff;
}
}
}
if ((GeneratingVehicleID != 0) && (IsCinematicStarted)) {
//
// Check to see if its time to display the object or not
//
if (DisplayVehicleTimer > UNITIALIZED_TIMER) {
DisplayVehicleTimer -= TimeManager::Get_Frame_Seconds ();
if (DisplayVehicleTimer < 0) {
//
// Display the vehicle
//
if (Vehicle != NULL) {
PhysicalGameObj *physical_obj = Vehicle.Get_Ptr ()->As_PhysicalGameObj ();
physical_obj->Peek_Model ()->Set_Hidden (false);
physical_obj->Set_Object_Dirty_Bit (NetworkObjectClass::BIT_RARE, true);
}
DisplayVehicleTimer = UNITIALIZED_TIMER;
// Tell the vehicle to drive to one of the delivery points
Deliver_Vehicle();
}
}
//
// Check if we need to clear the dropoff zone
//
if (ClearDropoffZoneTimer > UNITIALIZED_TIMER) {
ClearDropoffZoneTimer -= TimeManager::Get_Frame_Seconds ();
if (ClearDropoffZoneTimer < 0) {
Destroy_Blocking_Objects ();
ClearDropoffZoneTimer = UNITIALIZED_TIMER;
}
}
}
VehicleFactoryGameObj::Think ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Begin_Generation
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::Begin_Generation (void)
{
CinematicStartTimer = GenerationTime - Get_Definition ().CinematicLengthToDropOff;
IsCinematicStarted = false;
return ;
}
////////////////////////////////////////////////////////////////
//
// Start_Cinematic
//
////////////////////////////////////////////////////////////////
void
AirStripGameObj::Start_Cinematic (void)
{
if (CombatManager::I_Am_Server () == false) {
return ;
}
//
// Create the vehicle
//
VehicleGameObj *vehicle = Create_Vehicle ();
if (vehicle != NULL) {
//
// Hide the vehicle until later
//
if (vehicle->Peek_Model () != NULL) {
vehicle->Peek_Model ()->Set_Hidden (true);
vehicle->Set_Object_Dirty_Bit (NetworkObjectClass::BIT_RARE, true);
}
//
// Lock the vehicle
//
if (Purchaser != NULL) {
vehicle->Lock_Vehicle(Purchaser,VEHICLE_LOCK_TIME);
}
//
// Create the cinematic controller
//
CinematicObject = ObjectLibraryManager::Create_Object (Get_Definition ().CinematicDefID);
if (CinematicObject != NULL) {
CinematicObject->Start_Observers ();
//
// Position the cinematic controller in the world
//
Matrix3D test_tm = CreationTM;
CinematicObject->Set_Transform (test_tm);
//
// Try to find the script parser so we can communicate with it
//
const GameObjObserverList &script_list = CinematicObject->Get_Observers ();
for (int index = 0; index < script_list.Count (); index ++) {
GameObjObserverClass *script = script_list[index];
if (::lstrcmpi (script->Get_Name (), "Test_Cinematic") == 0) {
//
// Attach the vehicle to the given slot in the cinematic
//
int slot = 10000 + Get_Definition ().CinematicSlotIndex;
script->Custom (this, slot, vehicle->Get_ID (), this);
break;
}
}
}
}
IsCinematicStarted = true;
DisplayVehicleTimer = Get_Definition ().CinematicLengthToVehicleDisplay;
return ;
}

View File

@@ -0,0 +1,174 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/airstripgameobj.h $Author:: Patrick $*
* *
* $Modtime:: 10/01/01 3:44p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __AIRSTRIPGAMEOBJ_H
#define __AIRSTRIPGAMEOBJ_H
#include "always.h"
#include "vehiclefactorygameobj.h"
////////////////////////////////////////////////////////////////
// Forward delcarations
////////////////////////////////////////////////////////////////
class BaseControllerClass;
////////////////////////////////////////////////////////////////
//
// AirStripGameObjDef
//
////////////////////////////////////////////////////////////////
class AirStripGameObjDef : public VehicleFactoryGameObjDef
{
public:
////////////////////////////////////////////////////////////////
// Friends
////////////////////////////////////////////////////////////////
friend class AirStripGameObj;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
AirStripGameObjDef (void);
~AirStripGameObjDef (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
uint32 Get_Class_ID (void) const;
PersistClass * Create (void) const;
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
const PersistFactoryClass & Get_Factory (void) const;
////////////////////////////////////////////////////////////////
// Editable support
////////////////////////////////////////////////////////////////
DECLARE_EDITABLE (AirStripGameObjDef, VehicleFactoryGameObjDef);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Load_Variables (ChunkLoadClass &cload);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
int CinematicDefID;
int CinematicSlotIndex;
float CinematicLengthToDropOff;
float CinematicLengthToVehicleDisplay;
};
////////////////////////////////////////////////////////////////
//
// AirStripGameObj
//
////////////////////////////////////////////////////////////////
class AirStripGameObj : public VehicleFactoryGameObj
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
AirStripGameObj (void);
~AirStripGameObj (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Definition support
//
virtual void Init( void );
void Init (const AirStripGameObjDef & definition);
const AirStripGameObjDef & Get_Definition (void) const;
//
// RTTI
//
AirStripGameObj * As_AirStripGameObj (void) { return this; }
//
// Persist support
//
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
const PersistFactoryClass & Get_Factory (void) const;
//
// From BuildingGameObj
//
void CnC_Initialize (BaseControllerClass *base);
//
// GameObj methods
//
void Think (void);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Load_Variables (ChunkLoadClass &cload);
void Begin_Generation (void);
void Start_Cinematic (void);
void Attach_Vehicle (void);
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
float CinematicStartTimer;
float EndTimer;
float DisplayVehicleTimer;
float ClearDropoffZoneTimer;
bool IsCinematicStarted;
PhysicalGameObj * CinematicObject;
};
#endif // __AIRSTRIPGAMEOBJ_H

921
Code/Combat/animcontrol.cpp Normal file
View File

@@ -0,0 +1,921 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/animcontrol.cpp $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 1/04/02 10:26a $*
* *
* $Revision:: 53 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "animcontrol.h"
#include "assets.h"
#include "debug.h"
#include "rendobj.h"
#include "chunkio.h"
#include "saveload.h"
#include "htree.h"
/*
**
*/
enum {
XXXCHUNKID_LEGS = 910991512,
XXXCHUNKID_TORSO,
CHUNKID_CHANNEL,
CHUNKID_VARIABLES,
CHUNKID_OLD,
CHUNKID_NEW,
CHUNKID_PARENT,
CHUNKID_CHANNEL1,
CHUNKID_CHANNEL2,
MICROCHUNKID_BLEND_TIMER = 1,
MICROCHUNKID_BLEND_TOTAL,
MICROCHUNKID_FRAME,
XXXMICROCHUNKID_WEIGHT,
MICROCHUNKID_MODE,
MICROCHUNKID_ANIMATION_NAME,
MICROCHUNKID_MODEL_PTR,
MICROCHUNKID_CHANNEL2_RATIO,
MICROCHUNKID_TARGET_FRAME,
MICROCHUNKID_SKELETON,
};
/*
** AnimChannelClass
*/
AnimChannelClass::AnimChannelClass( void ) :
Animation( NULL ),
Frame( 0.0f ),
NumFrames( 1 ),
TargetFrame( 0.0f ),
Mode( ANIM_MODE_ONCE )
{
}
AnimChannelClass::~AnimChannelClass( void )
{
if ( Animation ) {
Animation->Release_Ref();
Animation = NULL;
}
}
AnimChannelClass & AnimChannelClass::operator = (const AnimChannelClass & src)
{
if (Animation != NULL) {
Animation->Release_Ref();
}
Animation = src.Animation;
if (Animation != NULL) {
Animation->Add_Ref();
}
Frame = src.Frame;
NumFrames = src.NumFrames;
Mode = src.Mode;
TargetFrame = src.TargetFrame;
return *this;
}
bool AnimChannelClass::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_VARIABLES );
// save the anim first, because the load will stomp the frame & weight
if ( Animation ) {
csave.Begin_Micro_Chunk( MICROCHUNKID_ANIMATION_NAME );
const char * anim_name = Animation->Get_Name();
csave.Write( anim_name, strlen( anim_name ) + 1);
csave.End_Micro_Chunk();
}
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_FRAME, Frame );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_MODE, Mode );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TARGET_FRAME, TargetFrame );
csave.End_Chunk();
return true;
}
bool AnimChannelClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_FRAME, Frame );
READ_MICRO_CHUNK( cload, MICROCHUNKID_MODE, Mode );
READ_MICRO_CHUNK( cload, MICROCHUNKID_TARGET_FRAME, TargetFrame );
case MICROCHUNKID_ANIMATION_NAME:
{
char anim_name[80];
cload.Read( anim_name, cload.Cur_Micro_Chunk_Length() );
Set_Animation( anim_name );
break;
}
default:
Debug_Say(("Unhandled Micro Chunk:%d File:%s Line:%d\r\n",cload.Cur_Micro_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Chunk();
}
return true;
}
void AnimChannelClass::Set_Animation( const char *name )
{
// If this is our current anim, bail
if ( ( Animation != NULL ) && ( name != NULL ) ) {
if ( stricmp( Animation->Get_Name(), name ) == 0 ) {
return;
}
}
if ( ( Animation == NULL ) && ( name == NULL ) ) {
return;
}
// Release the old anim
if ( Animation ) {
Animation->Release_Ref();
Animation = NULL;
}
// we need to switch anims
if (( name != NULL ) && ( name[0] != 0 ) ) {
Animation = WW3DAssetManager::Get_Instance()->Get_HAnim( name );
}
if ( Animation ) {
SET_REF_OWNER( Animation );
NumFrames = Animation->Get_Num_Frames();
Mode = ANIM_MODE_ONCE;
Frame = 0;
TargetFrame = 0;
}
}
void AnimChannelClass::Set_Animation( const HAnimClass *anim )
{
// If this is our current anim, bail
if ( Animation == anim ) {
return;
}
// Release the old anim
if ( Animation ) {
Animation->Release_Ref();
Animation = NULL;
}
// we need to switch anims
Animation = (HAnimClass *)anim;
if ( Animation ) {
Animation->Add_Ref();
NumFrames = Animation->Get_Num_Frames();
Mode = ANIM_MODE_ONCE;
Frame = 0;
TargetFrame = 0;
}
}
void AnimChannelClass::Set_Mode( AnimMode mode, float frame )
{
Mode = mode;
if ( frame >= 0 ) {
Frame = frame;
}
}
void AnimChannelClass::Update( float dtime )
{
if ( Mode == ANIM_MODE_STOP ) {
return;
}
if ( Animation != NULL ) {
switch ( Mode )
{
case ANIM_MODE_LOOP:
//
// Increment the frame based on the current timeslice
//
Frame += dtime * Animation->Get_Frame_Rate();
//
// Handle wrapping
//
if ( Frame >= NumFrames-1 ) {
Frame -= NumFrames-1;
}
if ( Frame >= NumFrames ) {
Frame = 0;
}
break;
case ANIM_MODE_TARGET:
//
// Which direction are we animating?
//
if ( Frame < TargetFrame ) {
Frame += dtime * Animation->Get_Frame_Rate();
//
// If we overshoot targetframe, snap to targetframe
//
if (Frame >= TargetFrame) {
Frame = TargetFrame;
}
} else if ( Frame > TargetFrame ) {
Frame -= dtime * Animation->Get_Frame_Rate();
//
// If we overshoot targetframe, snap to targetframe
//
if ( Frame <= TargetFrame ) {
Frame = TargetFrame;
}
}
break;
case ANIM_MODE_ONCE:
//
// Increment the frame based on the current timeslice
//
Frame += dtime * Animation->Get_Frame_Rate();
//
// Make sure we don't go past the end
//
if ( Frame > NumFrames-1 ) {
Frame = NumFrames-1;
}
break;
}
#if 0
if ( dtime != 0 ) {
Debug_Say(( "Anim %s frame %1.3f\n", Animation->Get_Name(), Frame ));
}
#endif
}
}
void AnimChannelClass::Get_Animation_Data( AnimationDataList & list, float weight )
{
if ( Animation != NULL && weight > 0 ) {
AnimationDataRecord * record = list.Uninitialized_Add();
WWASSERT( record != NULL );
record->Animation = Animation;
record->Frame = Frame;
record->Weight = weight;
}
}
void AnimChannelClass::Update_Model( RenderObjClass *anim_model )
{
if ( Animation ) {
anim_model->Set_Animation( Animation, Frame );
} else {
anim_model->Set_Animation();
}
}
/*
** BlendableAnimChannelClass
*/
BlendableAnimChannelClass::BlendableAnimChannelClass( void ) :
BlendTimer( 0 ),
BlendTotal( 0 )
{
}
bool BlendableAnimChannelClass::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_NEW );
NewChannel.Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_OLD );
OldChannel.Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_BLEND_TIMER, BlendTimer );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_BLEND_TOTAL, BlendTotal );
csave.End_Chunk();
return true;
}
bool BlendableAnimChannelClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_NEW:
NewChannel.Load( cload );
break;
case CHUNKID_OLD:
OldChannel.Load( cload );
break;
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_BLEND_TIMER, BlendTimer );
READ_MICRO_CHUNK( cload, MICROCHUNKID_BLEND_TOTAL, BlendTotal );
default:
Debug_Say(( "Unrecognized BlendableAnimChannel Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(( "Unrecognized BlendableAnimChannel chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
void BlendableAnimChannelClass::Set_Animation( const char *name, float blendtime, float start_frame )
{
// if setting to our current anim, bail
if ( ( NewChannel.Peek_Animation() == NULL ) && ( name == NULL ) ) {
return;
}
if ( ( NewChannel.Peek_Animation() != NULL ) && ( name != NULL ) ) {
if ( stricmp( NewChannel.Peek_Animation()->Get_Name(), name ) == 0 ) {
return;
}
}
// if no current channel, or no blend, or no new name, don't blend
if ( (NewChannel.Peek_Animation() == NULL) || (blendtime == 0) || (name == NULL) ) {
BlendTotal = 0.0f;
BlendTimer = 0.0f;
} else if ( BlendTotal == 0.0 ) { //if not currently blending
OldChannel = NewChannel;
BlendTimer = 0.0f;
BlendTotal = blendtime;
#if 0
} else if ( OldChannel.Peek_Animation() == new_anim.Peek_Animation() ) { // if old anim is the new one
OldChannel.Copy_From( NewChannel );
BlendTimer = (1.0f - (BlendTimer / BlendTotal)) * blendtime;
BlendTotal = blendtime;
#endif
} else if ( (BlendTimer / BlendTotal) > 0.5 ) { // if more than halfway through the old blend
OldChannel = NewChannel;
BlendTimer = (1.0f - (BlendTimer / BlendTotal)) * blendtime;
BlendTotal = blendtime;
} else {
BlendTimer = (BlendTimer / BlendTotal) * blendtime;
BlendTotal = blendtime;
}
NewChannel.Set_Animation( name );
if ( NewChannel.Peek_Animation() != NULL ) {
NewChannel.Set_Frame( start_frame );
}
if ( name == NULL ) {
OldChannel.Set_Animation( (const char *)NULL );
}
}
void BlendableAnimChannelClass::Set_Animation( const HAnimClass * anim, float blendtime, float start_frame )
{
// if setting to our current anim, bail
if ( ( NewChannel.Peek_Animation() == NULL ) && ( anim == NULL ) ) {
return;
}
if ( ( NewChannel.Peek_Animation() != NULL ) && ( anim != NULL ) ) {
if ( NewChannel.Peek_Animation() == anim ) {
return;
}
}
// if no current channel, or no blend, or no new name, don't blend
if ( (NewChannel.Peek_Animation() == NULL) || (blendtime == 0) || (anim == NULL) ) {
BlendTotal = 0.0f;
BlendTimer = 0.0f;
} else if ( BlendTotal == 0.0 ) { //if not currently blending
OldChannel = NewChannel;
BlendTimer = 0.0f;
BlendTotal = blendtime;
#if 0
} else if ( OldChannel.Peek_Animation() == new_anim.Peek_Animation() ) { // if old anim is the new one
OldChannel.Copy_From( NewChannel );
BlendTimer = (1.0f - (BlendTimer / BlendTotal)) * blendtime;
BlendTotal = blendtime;
#endif
} else if ( (BlendTimer / BlendTotal) > 0.5 ) { // if more than halfway through the old blend
OldChannel = NewChannel;
BlendTimer = (1.0f - (BlendTimer / BlendTotal)) * blendtime;
BlendTotal = blendtime;
} else {
BlendTimer = (BlendTimer / BlendTotal) * blendtime;
BlendTotal = blendtime;
}
NewChannel.Set_Animation( anim );
if ( NewChannel.Peek_Animation() != NULL ) {
NewChannel.Set_Frame( start_frame );
}
if ( anim == NULL ) {
OldChannel.Set_Animation( (const HAnimClass *)NULL );
}
}
void BlendableAnimChannelClass::Update( float dtime )
{
if ( BlendTotal != 0.0f ) { // if blending between two animations
BlendTimer += dtime; // Bump blend timer forward
if ( BlendTimer >= BlendTotal ) // blend complete, remove oldanim
{
BlendTotal = 0.0f;
BlendTimer = 0.0f;
OldChannel.Set_Animation( (const char *)NULL );
}
}
// Calculate which frame we are on in each of the animations
NewChannel.Update( dtime );
OldChannel.Update( dtime );
}
void BlendableAnimChannelClass::Get_Animation_Data( AnimationDataList & list, float weight )
{
float blend_ratio = 1.0f; // assume no blending
if ( BlendTotal != 0.0f ) { // if blending between two animations
// Calculate the blend percentage between the two animations.
// This starts at 0.0 (all OldAnimation) and proceeds to 1.0 (all Animation)
blend_ratio = WWMath::Clamp( BlendTimer / BlendTotal, 0, 1 );
}
NewChannel.Get_Animation_Data( list, weight * blend_ratio );
OldChannel.Get_Animation_Data( list, weight * ( 1 - blend_ratio ) );
}
void BlendableAnimChannelClass::Update_Model( RenderObjClass *anim_model )
{
float blend_ratio = 1.0f; // assume no blending
if ( BlendTotal != 0.0f ) { // if blending between two animations
// Calculate the blend percentage between the two animations.
// This starts at 0.0 (all OldAnimation) and proceeds to 1.0 (all Animation)
blend_ratio = WWMath::Clamp( BlendTimer / BlendTotal, 0, 1 );
}
if ( OldChannel.Peek_Animation() ) {
anim_model->Set_Animation( OldChannel.Peek_Animation(), OldChannel.Get_Frame(),
NewChannel.Peek_Animation(), NewChannel.Get_Frame(),
blend_ratio );
} else if ( NewChannel.Peek_Animation() ) {
anim_model->Set_Animation( NewChannel.Peek_Animation(), NewChannel.Get_Frame() );
} else {
anim_model->Set_Animation();
}
}
/*
** AnimControlClass
*/
AnimControlClass::AnimControlClass( void ) :
Model( NULL )
{
}
AnimControlClass::~AnimControlClass( void )
{
REF_PTR_RELEASE( Model );
}
bool AnimControlClass::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_MODEL_PTR, Model );
csave.End_Chunk();
return true;
}
bool AnimControlClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_VARIABLES:
WWASSERT( Model == NULL );
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_MODEL_PTR, Model );
default:
Debug_Say(( "Unrecognized AnimControl Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
if ( Model != NULL ) {
REQUEST_REF_COUNTED_POINTER_REMAP( (RefCountClass **)&Model );
} else {
Debug_Say(( "Loaded NULL model\n" ));
}
break;
default:
Debug_Say(( "Unrecognized AnimControl chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
void AnimControlClass::Set_Model( RenderObjClass *anim_model )
{
REF_PTR_SET( Model, anim_model );
}
/*
** SimpleAnimControlClass
*/
SimpleAnimControlClass::SimpleAnimControlClass( void )
{
}
SimpleAnimControlClass::~SimpleAnimControlClass( void )
{
}
bool SimpleAnimControlClass::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_PARENT );
AnimControlClass::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_CHANNEL );
Channel.Save( csave );
csave.End_Chunk();
return true;
}
bool SimpleAnimControlClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_PARENT:
AnimControlClass::Load( cload );
break;
case CHUNKID_CHANNEL:
Channel.Load( cload );
break;
default:
Debug_Say(( "Unrecognized HumanAnimControl chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
void SimpleAnimControlClass::Set_Animation( const char *name, float blendtime, float start_frame )
{
Channel.Set_Animation( name, blendtime, start_frame );
}
void SimpleAnimControlClass::Set_Animation( const HAnimClass * anim, float blendtime, float start_frame )
{
Channel.Set_Animation( anim, blendtime, start_frame );
}
void SimpleAnimControlClass::Update( float dtime )
{
Channel.Update( dtime );
// Setup the model for the current frame(s)
assert( Model != NULL );
Channel.Update_Model( Model );
}
/*
** HumanAnimControlClass
*/
HumanAnimControlClass::HumanAnimControlClass( void ) :
AnimCombo( 2 ),
Channel2Ratio( 0 ),
Skeleton( 'A' ),
AnimSpeedScale( 1 )
{
}
HumanAnimControlClass::~HumanAnimControlClass( void )
{
}
bool HumanAnimControlClass::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_PARENT );
AnimControlClass::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_CHANNEL2_RATIO, Channel2Ratio );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_SKELETON, Skeleton );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_CHANNEL1 );
Channel1.Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_CHANNEL2 );
Channel2.Save( csave );
csave.End_Chunk();
// Don't need to save the animcombo
return true;
}
bool HumanAnimControlClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_PARENT:
AnimControlClass::Load( cload );
break;
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_CHANNEL2_RATIO, Channel2Ratio );
READ_MICRO_CHUNK( cload, MICROCHUNKID_SKELETON, Skeleton );
default:
Debug_Say(( "Unrecognized HumanAnimControl Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
case CHUNKID_CHANNEL1:
Channel1.Load( cload );
break;
case CHUNKID_CHANNEL2:
Channel2.Load( cload );
break;
default:
Debug_Say(( "Unrecognized HumanAnimControl chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
void HumanAnimControlClass::Build_Skeleton_Anim_Name( StringClass& new_name, const char * name )
{
if (name == NULL) return;
if (*name == NULL) {
Debug_Say(( "No name in Build_Skeleton_Anim_Name\n" ));
return;
}
new_name = name;
if ( Skeleton == 'V' ) { // Special case for visceroids
return;
}
// If the anim doesn't start with "S_A_HUMAN.", add it
if ( ::strnicmp( name, "S_", 2 ) != 0 ) {
new_name.Format( "S_%c_HUMAN.%s", Skeleton, name );
}
// If the anim name is "S_A_HUMAN.H_A_*", and the Skeleton is not 'A', use
// the other skeleton anim, if found
if ( new_name.Get_Length() > 14 && Skeleton != 'A' && ::strnicmp( new_name, "S_A_HUMAN.H_A_", 14 ) == 0 ) {
StringClass mod_name(new_name,true);
mod_name[2] = Skeleton;
mod_name[12] = Skeleton;
// can we find the anim name?
HAnimClass * anim = WW3DAssetManager::Get_Instance()->Get_HAnim( mod_name );
if ( anim != NULL ) {
anim->Release_Ref();
new_name=mod_name;
}
}
}
void HumanAnimControlClass::Set_Animation( const char *name, float blendtime, float start_frame )
{
StringClass new_name(0,true);
Build_Skeleton_Anim_Name( new_name, name );
Channel1.Set_Animation( new_name, blendtime, start_frame );
Channel2.Set_Animation( (const char *)NULL );
Channel2Ratio = 0;
}
void HumanAnimControlClass::Set_Animation( const HAnimClass * anim, float blendtime, float start_frame )
{
if ( anim != NULL ) {
Set_Animation( anim->Get_Name(), blendtime, start_frame );
} else {
Set_Animation( (const char *)NULL, blendtime, start_frame );
}
}
void HumanAnimControlClass::Set_Animation( const char *name1, const char * name2, float ratio, float blendtime )
{
StringClass new_name1(0,true);
Build_Skeleton_Anim_Name( new_name1, name1 );
StringClass new_name2(0,true);
Build_Skeleton_Anim_Name( new_name2, name2 );
if ( ratio == 0 ) {
Set_Animation( new_name1, blendtime );
return;
}
if ( Channel2Ratio == 0 ) {
Channel2 = Channel1;
}
Channel1.Set_Animation( new_name1, blendtime );
Channel2.Set_Animation( new_name2, blendtime );
Channel2Ratio = ratio;
}
void HumanAnimControlClass::Set_Mode( AnimMode mode, float frame )
{
Channel1.Set_Mode( mode, frame );
Channel2.Set_Mode( mode, frame );
}
void HumanAnimControlClass::Set_Model( RenderObjClass *anim_model )
{
AnimControlClass::Set_Model( anim_model );
// Update the skeleton
if( anim_model != NULL ) {
const HTreeClass * tree = anim_model->Get_HTree();
if ( tree != NULL ) {
const char * name = tree->Get_Name();
Skeleton = name[2];
}
}
}
/*
**
*/
StringClass _MonitorAnimDescription;
HumanAnimControlClass * _Monitor = NULL;
void HumanAnimControlClass::Update( float dtime )
{
// Update channels
Channel1.Update( dtime * AnimSpeedScale );
Channel2.Update( dtime * AnimSpeedScale );
if ( Model != NULL ) {
// Get Animation data
DataList.Reset_Active();
Channel1.Get_Animation_Data( DataList, (1 - Channel2Ratio) );
Channel2.Get_Animation_Data( DataList, Channel2Ratio );
// Use the cheapest anim method possible
int total_animations = DataList.Count();
if ( total_animations == 0 ) {
// Debug_Say(( "No animations to display!\n" ));
Model->Set_Animation();
} else if ( total_animations == 1 ) {
// Debug_Say(( "1 animation to display!\n" ));
Model->Set_Animation( DataList[0].Animation, DataList[0].Frame );
} else if ( total_animations == 2 ) {
// Debug_Say(( "2 animation to display!\n" ));
float percent = DataList[1].Weight / (DataList[0].Weight + DataList[1].Weight);
Model->Set_Animation( DataList[0].Animation, DataList[0].Frame,
DataList[1].Animation, DataList[1].Frame, percent );
} else {
// Debug_Say(( ">2 animation to display!\n" ));
// set up anim combo
AnimCombo.Reset();
for ( int i = 0; i < total_animations; i++ ) {
HAnimComboDataClass * anim_data = new HAnimComboDataClass();
anim_data->Set_HAnim( DataList[i].Animation );
anim_data->Set_Frame( DataList[i].Frame );
anim_data->Set_Weight( DataList[i].Weight );
AnimCombo.Append_Anim_Combo_Data( anim_data );
}
// Setup the model for the current frame(s)
Model->Set_Animation( &AnimCombo );
}
if ( _Monitor == this ) {
for ( int i = 0; i < total_animations; i++ ) {
if ( i == 0 ) {
_MonitorAnimDescription = "";
}
StringClass a(0,true);
a.Format( "%s %1.0f%% %1.0f\n", DataList[i].Animation->Get_Name()+10, DataList[i].Weight*100, DataList[i].Frame );
_MonitorAnimDescription += a;
}
}
}
}
/*
**
*/
void HumanAnimControlClass::Get_Information( StringClass & string )
{
_Monitor = this;
string += _MonitorAnimDescription;
}

310
Code/Combat/animcontrol.h Normal file
View File

@@ -0,0 +1,310 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/animcontrol.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 1/04/02 10:33a $*
* *
* $Revision:: 36 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ANIMCONTROL_H
#define ANIMCONTROL_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef HANIM_H
#include "hanim.h"
#endif
#ifndef VECTOR_H
#include "vector.h"
#endif
#include "wwstring.h"
/*
**
*/
class RenderObjClass;
typedef enum {
ANIM_MODE_ONCE,
ANIM_MODE_LOOP,
ANIM_MODE_STOP,
ANIM_MODE_TARGET
} AnimMode;
/*
** AnimationDataRecord
*/
struct AnimationDataRecord {
HAnimClass *Animation;
float Frame;
float Weight;
bool operator == (AnimationDataRecord const & rec) const { return false; }
bool operator != (AnimationDataRecord const & rec) const { return true; }
};
typedef DynamicVectorClass<AnimationDataRecord> AnimationDataList;
/*
** AnimChannelClass
*/
class AnimChannelClass {
public:
// Constructor and Destructor
AnimChannelClass( void );
AnimChannelClass(const AnimChannelClass &);
AnimChannelClass & operator = (const AnimChannelClass &);
~AnimChannelClass(void);
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
// Set Animation
void Set_Animation( const char *name );
void Set_Animation( const HAnimClass *anim );
HAnimClass *Peek_Animation( void ) { return Animation; }
// Set Mode
void Set_Mode( AnimMode mode, float frame = -1 );
AnimMode Get_Mode( void ) { return Mode; }
bool Is_Complete( void ) { return (Animation == NULL) || ((Mode == ANIM_MODE_ONCE) && (Frame == NumFrames-1)) || ((Mode == ANIM_MODE_TARGET) && (Frame == TargetFrame)); }
const char *Get_Animation_Name( void ) { return Animation ? Animation->Get_Name() : ""; }
// Frame
void Set_Frame( float frame ) { Frame = frame; }
float Get_Frame( void ) { return Frame; }
float Get_Progress( void ) { return NumFrames ? Frame / NumFrames : 0; }
void Set_Target_Frame( float frame ) { TargetFrame = frame; }
float Get_Target_Frame( void ) { return TargetFrame; }
// Update the animation
void Update( float dtime );
// Get Animation Data
void Get_Animation_Data( AnimationDataList & list, float weight = 1.0f );
// Update Model
void Update_Model( RenderObjClass *anim_model );
private:
HAnimClass * Animation;
float Frame;
float NumFrames;
float TargetFrame;
AnimMode Mode;
};
/*
** BlendableAnimChannelClass
*/
class BlendableAnimChannelClass {
public:
// Constructor
BlendableAnimChannelClass( void );
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
// Set Animation
void Set_Animation( const char *name, float blendtime = 0.0f, float start_frame = 0.0f );
void Set_Animation( const HAnimClass * anim, float blendtime = 0.0f, float start_frame = 0.0f );
void Set_Mode( AnimMode mode, float frame = -1 ) { NewChannel.Set_Mode( mode, frame ); }
AnimMode Get_Mode( void ) { return NewChannel.Get_Mode(); }
bool Is_Complete( void ) { return NewChannel.Is_Complete(); }
const char *Get_Animation_Name( void ) { return NewChannel.Get_Animation_Name(); }
void Set_Target_Frame( float frame ) { NewChannel.Set_Target_Frame ( frame ); }
float Get_Target_Frame( void ) { return NewChannel.Get_Target_Frame(); }
HAnimClass *Peek_Animation( void ) { return NewChannel.Peek_Animation (); }
// Update the animation
void Update( float dtime );
// Get Animation Data
void Get_Animation_Data( AnimationDataList & list, float weight = 1.0f );
// Update Model
void Update_Model( RenderObjClass *anim_model );
// Data Access
float Get_Frame( void ) { return NewChannel.Get_Frame(); }
float Get_Progress( void ) { return NewChannel.Get_Progress(); }
private:
AnimChannelClass NewChannel;
AnimChannelClass OldChannel;
float BlendTimer; // in seconds
float BlendTotal; // in seconds
};
/*
** AnimControlClass
*/
class AnimControlClass {
public:
// Constructor and Destructor
AnimControlClass( void );
virtual ~AnimControlClass( void );
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
// Set Model
virtual void Set_Model( RenderObjClass *anim_model );
virtual RenderObjClass *Peek_Model( void ) { return Model; }
// Set Animation
virtual void Set_Animation( const char *name, float blendtime = 0.0f, float start_frame = 0.0f ) = 0;
virtual void Set_Animation( const HAnimClass * anim, float blendtime = 0.0f, float start_frame = 0.0f ) = 0;
virtual void Set_Mode( AnimMode mode, float frame = -1 ) = 0;
virtual AnimMode Get_Mode( void ) = 0;
virtual bool Is_Complete( void ) = 0;
virtual const char *Get_Animation_Name( void ) = 0;
virtual void Set_Target_Frame( float frame ) = 0;
virtual float Get_Target_Frame( void ) = 0;
virtual float Get_Current_Frame( void ) = 0;
virtual HAnimClass * Peek_Animation( void ) { return NULL; }
// Update the animation
virtual void Update( float dtime ) = 0;
protected:
RenderObjClass *Model;
};
/*
** SimpleAnimControlClass
*/
class SimpleAnimControlClass : public AnimControlClass {
public:
// Constructor and Destructor
SimpleAnimControlClass( void );
~SimpleAnimControlClass( void );
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
// Set Animation
virtual void Set_Animation( const char *name, float blendtime = 0.0f, float start_frame = 0.0f );
virtual void Set_Animation( const HAnimClass * anim, float blendtime = 0.0f, float start_frame = 0.0f );
virtual void Set_Mode( AnimMode mode, float frame = -1 ) { Channel.Set_Mode( mode, frame ); }
virtual AnimMode Get_Mode( void ) { return Channel.Get_Mode(); }
virtual bool Is_Complete( void ) { return Channel.Is_Complete(); }
virtual const char *Get_Animation_Name( void ) { return Channel.Get_Animation_Name(); }
virtual void Set_Target_Frame( float frame ) { Channel.Set_Target_Frame( frame ); }
virtual float Get_Target_Frame( void ) { return Channel.Get_Target_Frame(); }
virtual float Get_Current_Frame( void ) { return Channel.Get_Frame(); }
// Update the animation
virtual void Update( float dtime );
private:
BlendableAnimChannelClass Channel;
};
/*
** HumanAnimControlClass
*/
class HumanAnimControlClass : public AnimControlClass {
public:
// Constructor and Destructor
HumanAnimControlClass( void );
~HumanAnimControlClass( void );
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual void Set_Model( RenderObjClass *anim_model );
// Set Animation
virtual void Set_Animation( const char *name, float blendtime = 0.0f, float start_frame = 0.0f );
virtual void Set_Animation( const HAnimClass * anim, float blendtime = 0.0f, float start_frame = 0.0f );
virtual void Set_Animation( const char *name1, const char * name2, float ratio, float blendtime = 0.0f );
virtual void Set_Mode( AnimMode mode, float frame = -1 );
virtual AnimMode Get_Mode( void ) { return Channel1.Get_Mode(); }
virtual bool Is_Complete( void ) { return Channel1.Is_Complete(); }
virtual const char *Get_Animation_Name( void ) { return Channel1.Get_Animation_Name(); }
virtual float Get_Frame( void ) { return Channel1.Get_Frame(); }
virtual float Get_Progress( void ) { return Channel1.Get_Progress(); }
virtual void Set_Target_Frame( float frame ) { Channel1.Set_Target_Frame( frame ); }
virtual float Get_Target_Frame( void ) { return Channel1.Get_Target_Frame(); }
virtual float Get_Current_Frame( void ) { return Channel1.Get_Frame(); }
virtual void Set_Anim_Speed_Scale( float speed ) { AnimSpeedScale = speed; }
virtual void Update( float dtime );
virtual HAnimClass * Peek_Animation( void ) { return Channel1.Peek_Animation(); }
void Get_Information( StringClass & string );
char Get_Skeleton( void ) { return Skeleton; }
private:
BlendableAnimChannelClass Channel1;
BlendableAnimChannelClass Channel2;
float Channel2Ratio;
float AnimSpeedScale;
AnimationDataList DataList;
HAnimComboClass AnimCombo;
char Skeleton;
void Build_Skeleton_Anim_Name( StringClass& new_name, const char * name );
};
#endif // ANIMCONTROL_H

View File

@@ -0,0 +1,138 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/apppackettypes.h $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 2/21/02 3:01p $*
* *
* $Revision:: 21 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __APPPACKETTYPES_H__
#define __APPPACKETTYPES_H__
//-----------------------------------------------------------------------------
//
// Leaf node net object types
// N.B. If you add to this list you must also add in cAppPacketStats::Interpret_Type.
//
enum
{
//
// S->C
//
APPPACKETTYPE_UNKNOWN,
APPPACKETTYPE_SIMPLE,
APPPACKETTYPE_SOLDIER,
APPPACKETTYPE_VEHICLE,
APPPACKETTYPE_TURRET,
APPPACKETTYPE_BUILDING,
APPPACKETTYPE_PLAYER,
APPPACKETTYPE_TEAM,
APPPACKETTYPE_GAMEOPTIONSEVENT,
APPPACKETTYPE_PLAYERKILLEVENT,
APPPACKETTYPE_PURCHASERESPONSEEVENT,
APPPACKETTYPE_SCTEXTOBJ,
APPPACKETTYPE_SVRGOODBYEEVENT,
APPPACKETTYPE_WINEVENT,
APPPACKETTYPE_POWERUP,
APPPACKETTYPE_STATIC,
APPPACKETTYPE_DOOR,
APPPACKETTYPE_ELEVATOR,
APPPACKETTYPE_DSAPO,
APPPACKETTYPE_SERVERFPS,
APPPACKETTYPE_CONSOLECOMMANDEVENT,
APPPACKETTYPE_RESETWINSEVENT,
APPPACKETTYPE_EVICTIONEVENT,
APPPACKETTYPE_NETWEATHER,
APPPACKETTYPE_GAMEDATAUPDATEEVENT,
APPPACKETTYPE_SCPINGRESPONSEEVENT,
APPPACKETTYPE_BASECONTROLLER,
APPPACKETTYPE_CINEMATIC,
APPPACKETTYPE_C4,
APPPACKETTYPE_BEACON,
APPPACKETTYPE_SCEXPLOSIONEVENT,
APPPACKETTYPE_SCOBELISKEVENT,
APPPACKETTYPE_SCANNOUNCEMENT,
APPPACKETTYPE_NETBACKGROUND,
APPPACKETTYPE_GAMESPYSCCHALLENGEEVENT,
//
// C->S
//
APPPACKETTYPE_CLIENTCONTROL,
APPPACKETTYPE_CSTEXTOBJ,
APPPACKETTYPE_SUICIDEEVENT,
APPPACKETTYPE_CHANGETEAMEVENT,
APPPACKETTYPE_MONEYEVENT,
APPPACKETTYPE_WARPEVENT,
APPPACKETTYPE_PURCHASEREQUESTEVENT,
APPPACKETTYPE_CLIENTGOODBYEEVENT,
APPPACKETTYPE_BIOEVENT,
APPPACKETTYPE_LOADINGEVENT,
APPPACKETTYPE_GODMODEEVENT,
APPPACKETTYPE_VIPMODEEVENT,
APPPACKETTYPE_SCOREEVENT,
APPPACKETTYPE_CLIENTBBOEVENT,
APPPACKETTYPE_CLIENTFPS,
APPPACKETTYPE_CSPINGREQUESTEVENT,
APPPACKETTYPE_CSDAMAGEEVENT,
APPPACKETTYPE_REQUESTKILLEVENT,
APPPACKETTYPE_CSCONSOLECOMMANDEVENT,
APPPACKETTYPE_CSHINT,
APPPACKETTYPE_CSANNOUNCEMENT,
APPPACKETTYPE_DONATEEVENT,
APPPACKETTYPE_GAMESPYCSCHALLENGERESPONSEEVENT,
//
// Summation
//
APPPACKETTYPE_ALL,
APPPACKETTYPE_COUNT,
};
//-----------------------------------------------------------------------------
#endif //__APPPACKETTYPES_H__
//APPPACKETTYPE_FLAGCAPEVENT,
//APPPACKETTYPE_STEALTHEVENT,

View File

@@ -0,0 +1,530 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/armedgameobj.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 12/20/01 7:10p $*
* *
* $Revision:: 38 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** Includes
*/
#include "armedgameobj.h"
#include "debug.h"
#include "weaponbag.h"
#include "weapons.h"
#include "rendobj.h"
#include "bitpackids.h"
#include "wwprofile.h"
#include "smartgameobj.h"
/*
** ArmedGameObjDef
*/
ArmedGameObjDef::ArmedGameObjDef( void ) :
WeaponTiltRate( 1.0f ),
WeaponTiltMin( -10000.0f ),
WeaponTiltMax( 10000.0f ),
WeaponTurnRate( 1.0f ),
WeaponTurnMin( -10000.0f ),
WeaponTurnMax( 10000.0f ),
WeaponError( 0 ),
WeaponDefID( 0 ),
SecondaryWeaponDefID( 0 ),
WeaponRounds( -1 )
{
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTiltRate );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTiltMin );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTiltMax );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTurnRate );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTurnMin );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponTurnMax );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_ANGLE, WeaponError );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_WEAPONOBJDEFINITIONID, WeaponDefID );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_INT, WeaponRounds );
EDITABLE_PARAM( ArmedGameObjDef, ParameterClass::TYPE_WEAPONOBJDEFINITIONID, SecondaryWeaponDefID );
}
enum {
CHUNKID_DEF_PARENT = 418001829,
CHUNKID_DEF_VARIABLES,
MICROCHUNKID_DEF_WEAPON_TILT_RATE = 1,
MICROCHUNKID_DEF_WEAPON_TILT_MIN,
MICROCHUNKID_DEF_WEAPON_TILT_MAX,
MICROCHUNKID_DEF_WEAPON_TURN_RATE,
MICROCHUNKID_DEF_WEAPON_TURN_MIN,
MICROCHUNKID_DEF_WEAPON_TURN_MAX,
XXXMICROCHUNKID_DEF_PRIMARY_ROUNDS,
XXXMICROCHUNKID_DEF_PRIMARY_AMMO_WEAPON_DEF_ID,
XXXMICROCHUNKID_DEF_SECONDARY_AMMO_WEAPON_DEF_ID,
XXXMICROCHUNKID_DEF_SECONDARY_ROUNDS,
MICROCHUNKID_DEF_WEAPON_DEF_ID,
MICROCHUNKID_DEF_WEAPON_ROUNDS,
MICROCHUNKID_DEF_WEAPON_ERROR,
MICROCHUNKID_DEF_SECONDARY_WEAPON_DEF_ID,
};
bool ArmedGameObjDef::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_DEF_PARENT );
PhysicalGameObjDef::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TILT_RATE, WeaponTiltRate );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TILT_MIN, WeaponTiltMin );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TILT_MAX, WeaponTiltMax );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TURN_RATE, WeaponTurnRate );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TURN_MIN, WeaponTurnMin );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_TURN_MAX, WeaponTurnMax );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_DEF_ID, WeaponDefID );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_SECONDARY_WEAPON_DEF_ID, SecondaryWeaponDefID );
WRITE_SAFE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_ROUNDS, WeaponRounds, int );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_WEAPON_ERROR, WeaponError );
csave.End_Chunk();
return true;
}
bool ArmedGameObjDef::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_DEF_PARENT:
PhysicalGameObjDef::Load( cload );
break;
case CHUNKID_DEF_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TILT_RATE, WeaponTiltRate );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TILT_MIN, WeaponTiltMin );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TILT_MAX, WeaponTiltMax );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TURN_RATE, WeaponTurnRate );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TURN_MIN, WeaponTurnMin );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_TURN_MAX, WeaponTurnMax );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_DEF_ID, WeaponDefID );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_SECONDARY_WEAPON_DEF_ID, SecondaryWeaponDefID );
READ_SAFE_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_ROUNDS, WeaponRounds, int );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_WEAPON_ERROR, WeaponError );
default:
Debug_Say(( "Unrecognized ArmedDef Variable chunkID %d\n", cload.Cur_Micro_Chunk_ID() ));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(( "Unrecognized ArmedDef chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
/*
** ArmedGameObj
*/
ArmedGameObj::ArmedGameObj( void ) :
MuzzleA0Bone( 0 ),
MuzzleA1Bone( 0 ),
MuzzleB0Bone( 0 ),
MuzzleB1Bone( 0 ),
TargetingPos(0,0,0)
{
WeaponBag = new WeaponBagClass( this );
}
ArmedGameObj::~ArmedGameObj( void )
{
delete WeaponBag;
}
/*
**
*/
void ArmedGameObj::Init( const ArmedGameObjDef & definition )
{
PhysicalGameObj::Init( definition );
Copy_Settings( definition );
return ;
}
/*
**
*/
void ArmedGameObj::Copy_Settings( const ArmedGameObjDef & definition )
{
WeaponClass * weapon = NULL;
if ( definition.WeaponDefID != 0 ) {
weapon = WeaponBag->Add_Weapon( definition.WeaponDefID, definition.WeaponRounds );
}
if ( definition.SecondaryWeaponDefID != 0 ) {
WeaponClass * s_weapon = WeaponBag->Add_Weapon( definition.SecondaryWeaponDefID, definition.WeaponRounds );
if ( weapon == NULL ) {
weapon = s_weapon;
}
}
if ( weapon != NULL ) {
WeaponBag->Select_Weapon( weapon );
}
Init_Muzzle_Bones();
return ;
}
/*
**
*/
void ArmedGameObj::Re_Init( const ArmedGameObjDef & definition )
{
PhysicalGameObj::Re_Init( definition );
//
// Remove all non-beacon entries from the weapon bag...
//
WeaponBagClass *old_bag = WeaponBag;
if ( WeaponBag != NULL ) {
//
// Loop over all the weapons in the bag
//
int weapon_index = WeaponBag->Get_Count();
while (weapon_index --) {
WeaponClass *weapon = WeaponBag->Peek_Weapon( weapon_index );
//
// If this isn't a beacon, then remove it
//
if (weapon != NULL && weapon->Get_Definition ()->Style != WEAPON_HOLD_STYLE_BEACON) {
WeaponBag->Remove_Weapon( weapon_index );
}
}
WeaponBag = NULL;
}
//
// Re-initialize the weapon bag
//
WeaponBag = new WeaponBagClass( this );
//
// Copy any internal settings from the definition
//
Copy_Settings( definition );
//
// Now add any beacons back into the weapon bag
//
if ( old_bag != NULL ) {
WeaponBag->Move_Contents( old_bag );
delete old_bag;
}
return ;
}
const ArmedGameObjDef & ArmedGameObj::Get_Definition( void ) const
{
return (const ArmedGameObjDef &)BaseGameObj::Get_Definition();
}
/*
** ArmedGameObj Save and Load
*/
enum {
CHUNKID_PARENT = 418001841,
CHUNKID_VARIABLES,
CHUNKID_WEAPONBAG,
MICROCHUNKID_TARGETING_POS = 1,
};
bool ArmedGameObj::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_PARENT );
PhysicalGameObj::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TARGETING_POS, TargetingPos );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_WEAPONBAG );
WeaponBag->Save( csave );
csave.End_Chunk();
return true;
}
bool ArmedGameObj::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_PARENT:
PhysicalGameObj::Load( cload );
break;
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_TARGETING_POS, TargetingPos );
default:
Debug_Say(( "Unrecognized ArmedGameObj Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
case CHUNKID_WEAPONBAG:
WeaponBag->Load( cload );
break;
default:
Debug_Say(( "Unrecognized ArmedGameObj chunkID\n" ));
break;
}
cload.Close_Chunk();
}
SaveLoadSystemClass::Register_Post_Load_Callback(this);
return true;
}
void ArmedGameObj::On_Post_Load( void )
{
PhysicalGameObj::On_Post_Load();
Init_Muzzle_Bones();
}
//-----------------------------------------------------------------------------
void ArmedGameObj::Import_Frequent(BitStreamClass & packet)
{
PhysicalGameObj::Import_Frequent( packet );
Vector3 targeting_pos;
packet.Get(targeting_pos.X, BITPACK_WORLD_POSITION_X);
packet.Get(targeting_pos.Y, BITPACK_WORLD_POSITION_Y);
packet.Get(targeting_pos.Z, BITPACK_WORLD_POSITION_Z);
//
// Don't force the targetting if the object is controlled
// by this player
//
SmartGameObj *smart_game_obj = As_SmartGameObj ();
if (smart_game_obj == NULL || smart_game_obj->Is_Controlled_By_Me() == false) {
Set_Targeting(targeting_pos);
}
return ;
}
//-----------------------------------------------------------------------------
void ArmedGameObj::Export_Frequent(BitStreamClass & packet)
{
PhysicalGameObj::Export_Frequent( packet );
packet.Add(TargetingPos.X, BITPACK_WORLD_POSITION_X);
packet.Add(TargetingPos.Y, BITPACK_WORLD_POSITION_Y);
packet.Add(TargetingPos.Z, BITPACK_WORLD_POSITION_Z);
}
//-----------------------------------------------------------------------------
void ArmedGameObj::Export_State_Cs(BitStreamClass & packet)
{
#if 1
Vector3 my_pos;
Get_Position( &my_pos );
Vector3 rel_target = TargetingPos - my_pos;
packet.Add(rel_target.X, BITPACK_WORLD_POSITION_X);
packet.Add(rel_target.Y, BITPACK_WORLD_POSITION_Y);
packet.Add(rel_target.Z, BITPACK_WORLD_POSITION_Z);
#else
packet.Add(TargetingPos.X, BITPACK_WORLD_POSITION_X);
packet.Add(TargetingPos.Y, BITPACK_WORLD_POSITION_Y);
packet.Add(TargetingPos.Z, BITPACK_WORLD_POSITION_Z);
#endif
}
//-----------------------------------------------------------------------------
void ArmedGameObj::Import_State_Cs(BitStreamClass & packet)
{
#if 1
Vector3 rel_target;
packet.Get(rel_target.X, BITPACK_WORLD_POSITION_X);
packet.Get(rel_target.Y, BITPACK_WORLD_POSITION_Y);
packet.Get(rel_target.Z, BITPACK_WORLD_POSITION_Z);
Vector3 my_pos;
Get_Position( &my_pos );
Vector3 targeting_pos = rel_target + my_pos;
Set_Targeting(targeting_pos);
#else
Vector3 targeting_pos;
packet.Get(targeting_pos.X, BITPACK_WORLD_POSITION_X);
packet.Get(targeting_pos.Y, BITPACK_WORLD_POSITION_Y);
packet.Get(targeting_pos.Z, BITPACK_WORLD_POSITION_Z);
Set_Targeting(targeting_pos);
#endif
}
void ArmedGameObj::Post_Think( void )
{
PhysicalGameObj::Post_Think();
WWPROFILE( "Armed PostThink" );
if ( Is_Delete_Pending() ) { // don't update if destroying... (so we don't create a new laser!)
return;
}
if ( Get_Weapon() != NULL ) { // Update the weapon after the commands and update_human_animation
Get_Weapon()->Update();
}
// allow any recoil animation to progress
if (Peek_Model() != NULL) {
for (int i=0; i<MAX_MUZZLES; i++) {
MuzzleRecoilController[i].Update(Peek_Model());
}
}
}
/*
** Weapons
*/
WeaponClass * ArmedGameObj::Get_Weapon( void )
{
return WeaponBag->Get_Weapon();
}
void ArmedGameObj::Init_Muzzle_Bones( void )
{
MuzzleA0Bone = Peek_Model()->Get_Bone_Index( "muzzlea0" );
MuzzleA1Bone = Peek_Model()->Get_Bone_Index( "muzzlea1" );
MuzzleB0Bone = Peek_Model()->Get_Bone_Index( "muzzleb0" );
MuzzleB1Bone = Peek_Model()->Get_Bone_Index( "muzzleb1" );
if (MuzzleA1Bone == 0) {
MuzzleA1Bone = MuzzleA0Bone;
}
if (MuzzleB0Bone == 0) {
MuzzleB0Bone = MuzzleA0Bone;
}
if (MuzzleB1Bone == 0) {
MuzzleB1Bone = MuzzleB0Bone;
}
MuzzleRecoilController[0].Init(MuzzleA0Bone);
MuzzleRecoilController[1].Init(MuzzleA1Bone);
MuzzleRecoilController[2].Init(MuzzleB0Bone);
MuzzleRecoilController[3].Init(MuzzleB1Bone);
// Let the weapon learn about muzzle flashes
if ( Get_Weapon() ) {
Get_Weapon()->Set_Model( Peek_Model() );
}
}
bool ArmedGameObj::Set_Targeting( const Vector3 & pos, bool do_tilt )
{
TargetingPos = pos;
// Move the turret to match the target
return true;
}
const Matrix3D & ArmedGameObj::Get_Muzzle( int index )
{
RenderObjClass * model = Peek_Model();
if ( index == 3 && MuzzleB1Bone != 0 ) {
return model->Get_Bone_Transform( MuzzleB1Bone );
}
if ( index >= 2 && MuzzleB0Bone != 0 ) {
return model->Get_Bone_Transform( MuzzleB0Bone );
}
if ( index == 1 && MuzzleA1Bone != 0 ) {
return model->Get_Bone_Transform( MuzzleA1Bone );
}
if ( MuzzleA0Bone != 0 ) {
return model->Get_Bone_Transform( MuzzleA0Bone );
}
return Get_Transform();
}
bool ArmedGameObj::Muzzle_Exists( int index )
{
if ( index == 0 ) {
return MuzzleA0Bone != 0;
}
if ( index == 1 ) {
return MuzzleA1Bone != 0;
}
if ( index == 2 ) {
return MuzzleB0Bone != 0;
}
if ( index == 3 ) {
return MuzzleB1Bone != 0;
}
return false;
}
void ArmedGameObj::Start_Recoil( int muzzle_index,float recoil_scale,float recoil_time )
{
WWASSERT(muzzle_index >= 0);
WWASSERT(muzzle_index < MAX_MUZZLES);
MuzzleRecoilController[muzzle_index].Start_Recoil(recoil_scale,recoil_time);
}

157
Code/Combat/armedgameobj.h Normal file
View File

@@ -0,0 +1,157 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/armedgameobj.h $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/17/01 4:18p $*
* *
* $Revision:: 23 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ARMEDGAMEOBJ_H
#define ARMEDGAMEOBJ_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef PHYSICALGAMEOBJ_H
#include "physicalgameobj.h"
#endif
#ifndef MUZZLERECOIL_H
#include "muzzlerecoil.h"
#endif
/*
**
*/
class WeaponClass;
class WeaponBagClass;
/*
** ArmedGameObjDef - Defintion class for a ArmedGameObj
*/
class ArmedGameObjDef : public PhysicalGameObjDef
{
public:
ArmedGameObjDef( void );
// virtual uint32 Get_Class_ID( void ) const;
// virtual PersistClass * Create( void ) const ;
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
// virtual const PersistFactoryClass & Get_Factory( void ) const;
DECLARE_EDITABLE( ArmedGameObjDef, PhysicalGameObjDef );
protected:
float WeaponTiltRate;
float WeaponTiltMin;
float WeaponTiltMax;
float WeaponTurnRate;
float WeaponTurnMin;
float WeaponTurnMax;
float WeaponError;
int WeaponDefID;
int SecondaryWeaponDefID;
safe_int WeaponRounds;
friend class ArmedGameObj;
};
/*
**
*/
class ArmedGameObj : public PhysicalGameObj {
public:
// Constructor and Destructor
ArmedGameObj( void );
virtual ~ArmedGameObj( void );
// Definitions
void Init( const ArmedGameObjDef & definition );
void Copy_Settings( const ArmedGameObjDef & definition );
void Re_Init( const ArmedGameObjDef & definition );
const ArmedGameObjDef & Get_Definition( void ) const ;
// Save / Load
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual void On_Post_Load( void );
// State import/export
virtual void Import_Frequent( BitStreamClass & packet );
virtual void Export_Frequent( BitStreamClass & packet );
virtual void Import_State_Cs( BitStreamClass & packet );
virtual void Export_State_Cs( BitStreamClass & packet );
// Thinking
virtual void Post_Think();
// Weapon
WeaponClass * Get_Weapon( void );
WeaponBagClass * Get_Weapon_Bag( void ) { return WeaponBag; }
bool Muzzle_Exists( int index = 0 );
virtual const Matrix3D &Get_Muzzle( int index = 0 );
void Start_Recoil( int muzzle_index,float recoil_scale,float recoil_time );
float Get_Weapon_Error( void ) { return Get_Definition().WeaponError; }
// Targeting
Vector3 Get_Targeting_Pos( void ) { return TargetingPos; }
virtual bool Set_Targeting( const Vector3 & pos, bool do_tilt = true );
// Type identification
virtual ArmedGameObj *As_ArmedGameObj( void ) { return this; }
protected:
WeaponBagClass * WeaponBag; // Weapon & Ammo collection
private:
Vector3 TargetingPos;
int MuzzleA0Bone; // YUCK!!!
int MuzzleA1Bone;
int MuzzleB0Bone;
int MuzzleB1Bone;
enum { MAX_MUZZLES = 4 };
MuzzleRecoilClass MuzzleRecoilController[MAX_MUZZLES];
void Init_Muzzle_Bones( void );
};
#endif // ARMEDGAMEOBJ_H

341
Code/Combat/assetdep.cpp Normal file
View File

@@ -0,0 +1,341 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/assetdep.cpp $*
* *
* $Author:: Jani_p $*
* *
* $Modtime:: 11/29/01 9:48p $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "assetdep.h"
#include "chunkio.h"
#include "wwstring.h"
#include "assetmgr.h"
#include "ffactory.h"
#include "saveloadstatus.h"
#include "wwprofile.h"
///////////////////////////////////////////////////////////////////////
// Local prototypes
///////////////////////////////////////////////////////////////////////
static void Asset_Name_From_Filename (StringClass& new_name, const char *filename);
static void Get_Filename_From_Path (StringClass& new_name, const char *filename);
///////////////////////////////////////////////////////////////////////
// Constants
///////////////////////////////////////////////////////////////////////
static const char * ALWAYS_FILENAME = "always.dep";
static const char * DEP_EXTENSION = ".dep";
enum
{
CHUNKID_FILE_LIST = 0x04020527,
VARID_ASSET_FILENAME = 0x01,
};
///////////////////////////////////////////////////////////////////////
//
// Save_Always_Dependencies
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Save_Always_Dependencies (const char *path, ASSET_LIST &asset_list)
{
//
// Get a pointer to the file object
//
StringClass filename(path + StringClass ("\\") + StringClass (ALWAYS_FILENAME),true);
FileClass * file = _TheWritingFileFactory->Get_File (filename);
if (file != NULL) {
//
// Open or create the file
//
file->Open (FileClass::WRITE);
//
// Save the asset list to the file
//
ChunkSaveClass csave (file);
Save_Dependencies (csave, asset_list);
//
// Close the file
//
file->Close ();
_TheWritingFileFactory->Return_File (file);
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Save_Level_Dependencies
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Save_Level_Dependencies (const char *full_path, ASSET_LIST &asset_list)
{
//
// Get a pointer to the file object
//
FileClass * file = _TheWritingFileFactory->Get_File (full_path);
if (file != NULL) {
//
// Open or create the file
//
file->Open (FileClass::WRITE);
//
// Save the asset list to the file
//
ChunkSaveClass csave (file);
Save_Dependencies (csave, asset_list);
//
// Close the file
//
file->Close ();
_TheWritingFileFactory->Return_File (file);
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Save_Dependencies
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Save_Dependencies (ChunkSaveClass &csave, ASSET_LIST &asset_list)
{
csave.Begin_Chunk (CHUNKID_FILE_LIST);
//
// Write each filename dependency to a chunk
//
for (int index = 0; index < asset_list.Count (); index ++) {
StringClass &filename = asset_list[index];
WRITE_MICRO_CHUNK_WWSTRING (csave, VARID_ASSET_FILENAME, filename);
}
csave.End_Chunk ();
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Load_Level_Assets
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Load_Level_Assets (const char *level_name)
{
//
// Strip the extension (if necessary)
//
StringClass base_name(level_name,true);
const char *extension = ::strrchr (base_name, '.');
if (extension != NULL && base_name.Get_Length () > 4) {
base_name.Erase (base_name.Get_Length () - 4, 4);
}
//
// Build a filename from the level name, and load the assets from it.
//
StringClass filename(base_name + StringClass (DEP_EXTENSION),true);
Load_Assets (filename);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Load_Always_Assets
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Load_Always_Assets (void)
{
//
// Load the assets from the always file
//
Load_Assets (ALWAYS_FILENAME);
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Load_Assets
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Load_Assets (const char *filename)
{
//
// Get a pointer to the file object
//
FileClass * file = _TheFileFactory->Get_File (filename);
if (file != NULL) {
if ( file->Is_Available() ) {
//
// Open the file
//
file->Open (FileClass::READ);
//
// Load the asset dependencies from the file
//
ChunkLoadClass cload (file);
Load_Assets (cload);
//
// Close the file
//
file->Close ();
} else {
WWDEBUG_SAY(( "Failed to find %s\n", filename ));
}
_TheFileFactory->Return_File (file);
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// Load_Assets
//
///////////////////////////////////////////////////////////////////////
void
AssetDependencyManager::Load_Assets (ChunkLoadClass &cload)
{
WWLOG_PREPARE_TIME_AND_MEMORY("AssetDependencyManager::Load_Assets (ChunkLoadClass &cload)");
cload.Open_Chunk ();
WWASSERT (cload.Cur_Chunk_ID () == CHUNKID_FILE_LIST);
if (cload.Cur_Chunk_ID () == CHUNKID_FILE_LIST) {
//
// Read the filename of each asset from the chunk and
// load its assets into the asset manager.
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ())
{
case VARID_ASSET_FILENAME:
{
//
// Read the filename from the chunk
//
StringClass filename(0,true);
int size = cload.Cur_Micro_Chunk_Length ();
cload.Read (filename.Get_Buffer (size), size);
//
// Determine what the render object name should be from
// the filename.
//
StringClass render_obj_name(0,true);
::Asset_Name_From_Filename (render_obj_name,filename);
INIT_SUB_STATUS(filename);
//
// Load the assets from this file into the asset manager
//
if (WW3DAssetManager::Get_Instance ()->Render_Obj_Exists (render_obj_name) == false) {
WW3DAssetManager::Get_Instance ()->Load_3D_Assets (filename);
}
// WWLOG_INTERMEDIATE(filename);
}
break;
default:
WWDEBUG_SAY (("Unexpected chunk id %d found while preloading assets.\r\n", cload.Cur_Micro_Chunk_ID));
break;
}
cload.Close_Micro_Chunk ();
}
}
cload.Close_Chunk ();
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_Filename_From_Path
//
////////////////////////////////////////////////////////////////////////////
void Get_Filename_From_Path (StringClass& new_filename, const char *path)
{
// Find the last occurance of the directory deliminator
const char *filename = ::strrchr (path, '\\');
if (filename != NULL) {
// Increment past the directory deliminator
filename ++;
} else {
filename = path;
}
new_filename=filename;
}
////////////////////////////////////////////////////////////////////////////
//
// Asset_Name_From_Filename
//
////////////////////////////////////////////////////////////////////////////
void Asset_Name_From_Filename (StringClass& asset_name, const char *filename)
{
// Get the filename from this path
::Get_Filename_From_Path (asset_name, filename);
// Find and strip off the extension (if it exists)
char *extension = ::strrchr (asset_name, '.');
if (extension != NULL) {
extension[0] = 0;
}
}

85
Code/Combat/assetdep.h Normal file
View File

@@ -0,0 +1,85 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/assetdep.h $*
* *
* $Author:: Patrick $*
* *
* $Modtime:: 4/20/00 5:59p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __ASSET_DEP_H
#define __ASSET_DEP_H
#include "vector.h"
///////////////////////////////////////////////////////////////////////
// Forward declarations
///////////////////////////////////////////////////////////////////////
class ChunkSaveClass;
class ChunkLoadClass;
class StringClass;
///////////////////////////////////////////////////////////////////////
//
// AssetDependencyManager
//
///////////////////////////////////////////////////////////////////////
class AssetDependencyManager
{
public:
////////////////////////////////////////////////////////////////////
// Public data types
////////////////////////////////////////////////////////////////////
typedef DynamicVectorClass<StringClass> ASSET_LIST;
////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////
static void Save_Always_Dependencies (const char *path, ASSET_LIST &asset_list);
static void Save_Level_Dependencies (const char *full_path, ASSET_LIST &asset_list);
static void Save_Dependencies (ChunkSaveClass &csave, ASSET_LIST &asset_list);
static void Load_Level_Assets (const char *level_name);
static void Load_Always_Assets (void);
static void Load_Assets (const char *filename);
static void Load_Assets (ChunkLoadClass &cload);
};
#endif //__ASSET_DEP_H

143
Code/Combat/assets.cpp Normal file
View File

@@ -0,0 +1,143 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/assets.cpp $*
* *
* $Author:: Jani_p $*
* *
* $Modtime:: 8/31/01 8:03p $*
* *
* $Revision:: 49 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "assets.h"
#include "wwfile.h"
#include "debug.h"
#include "ffactory.h"
/*
**
*/
INIClass * Get_INI( const char * filename )
{
INIClass * ini = NULL;
FileClass * INIfile = _TheFileFactory->Get_File( filename );
if ( INIfile ) {
if ( INIfile->Is_Available() ) {
ini = new INIClass( *INIfile );
}
_TheFileFactory->Return_File( INIfile );
}
return ini;
}
void Save_INI( INIClass * p_ini, const char * filename )
{
WWASSERT(p_ini != NULL);
WWASSERT(filename != NULL);
FileClass * p_INIfile = _TheWritingFileFactory->Get_File(filename);
if (p_INIfile != NULL && p_INIfile->Is_Available()) {
p_ini->Save(*p_INIfile);
_TheWritingFileFactory->Return_File(p_INIfile);
}
}
void Release_INI( INIClass * ini )
{
WWASSERT( ini );
delete ini;
}
/*
**
*/
void Strip_Path_From_Filename( StringClass& new_name, const char * filename )
{
if ( ::strchr( filename, '\\' ) != 0 ) {
new_name = ::strrchr( filename, '\\' ) + 1;
}
else new_name=filename;
}
/*
** Asset access
*/
void Get_Render_Obj_Name_From_Filename( StringClass& new_name, const char * filename )
{
Strip_Path_From_Filename( new_name, filename );
if ( new_name.Get_Length() > 4 ) {
new_name.Erase( new_name.Get_Length() - 4, 4 );
}
}
RenderObjClass * Create_Render_Obj_From_Filename( const char * filename )
{
StringClass render_obj_name(true);
Strip_Path_From_Filename( render_obj_name, filename );
render_obj_name.Erase( render_obj_name.Get_Length() - 4, 4 );
RenderObjClass *model = WW3DAssetManager::Get_Instance()->Create_Render_Obj( render_obj_name );
if ( model == NULL ) {
Debug_Say(( "Failed to create \"%s\" from \"%s\"\n", (const char *)render_obj_name, filename ));
}
return model;
}
TextureClass * Get_Texture_From_Filename
(
const char * filename,
TextureClass::MipCountType mip_level_count
)
{
StringClass tex_name(true);
Strip_Path_From_Filename( tex_name, filename );
return WW3DAssetManager::Get_Instance()->Get_Texture( tex_name, mip_level_count );
}
/*
** Filenames
*/
void Create_Animation_Name( StringClass& anim_name, const char * anim_filename, const char * model_name )
{
anim_name=anim_filename;
if ( ::strrchr( anim_name, '\\' ) != 0 ) {
StringClass temp(::strrchr( anim_name, '\\' ) + 1,true);
anim_name = temp;
anim_name.Erase( anim_name.Get_Length() - 4, 4 ); // Strip off ".w3d"
}
if ( ::strchr( anim_name, '.' ) == 0 ) { // Add model name
StringClass temp(true);
temp.Format( "%s.%s", model_name, anim_name );
anim_name = temp;
}
}

80
Code/Combat/assets.h Normal file
View File

@@ -0,0 +1,80 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/assets.h $*
* *
* $Author:: Jani_p $*
* *
* $Modtime:: 8/31/01 8:03p $*
* *
* $Revision:: 31 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef ASSETS_H
#define ASSETS_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef ASSETMGR_H
#include "assetmgr.h"
#endif
#ifndef INI_H
#include "ini.h"
#endif
/*
** INI File Access
*/
void Set_INI_Path( const char * path );
INIClass * Get_INI( const char * filename );
void Save_INI( INIClass * p_ini, const char * filename );
void Release_INI( INIClass * ini );
/*
** Path Striping
*/
void Strip_Path_From_Filename( StringClass& new_name, const char * filename );
void Get_Render_Obj_Name_From_Filename( StringClass& new_name, const char * filename );
/*
** Asset access - these functions strips the path off of the filenames; for use
** with filenames that come from preset definitions.
*/
RenderObjClass * Create_Render_Obj_From_Filename( const char * filename );
TextureClass * Get_Texture_From_Filename( const char * filename,
TextureClass::MipCountType mip_level_count=TextureClass::MIP_LEVELS_ALL );
/*
** Filenames
*/
void Create_Animation_Name( StringClass& anim_name, const char * anim_filename, const char * model_name );
#endif // ASSETS_H

File diff suppressed because it is too large Load Diff

651
Code/Combat/backgroundmgr.h Normal file
View File

@@ -0,0 +1,651 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/backgroundmgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/15/02 7:26p $*
* *
* $Revision:: 25 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __BACKGROUNDMGR_H
#define __BACKGROUNDMGR_H
// Includes.
#include "combat.h"
#include "combatchunkid.h"
#include "dx8indexbuffer.h"
#include "networkobject.h"
#include "rendobj.h"
#include "saveloadsubsystem.h"
#include "segline.h"
#include "shader.h"
#include "vector3.h"
#include "vector3i.h"
#include "vertmaterial.h"
#include "wwdebug.h"
// Forward declarations.
class CameraClass;
class DazzleRenderObjClass;
class SimpleSceneClass;
class TextureClass;
class SoundEnvironmentClass;
// Classes.
class VisibilityClass {
public:
VisibilityClass() {Visible = true;}
bool Is_Visible() {return (Visible);}
void Set_Visibility (bool visible) {Visible = visible;}
private :
bool Visible;
};
class HazeClass : public VisibilityClass
{
public:
HazeClass (float radius);
~HazeClass();
void Configure (const Vector3 &blendcolor, const Vector3 &horizoncolor, float intensity);
void Configure (const Vector3 &blendcolor, const Vector3 &horizoncolor);
void Configure (const Vector3 &blendcolor, float intensity);
void Configure (const Vector3 &blendcolor);
Vector3 Get_Horizon_Color() {return (HorizonColor * Intensity);}
void Render();
protected:
enum {
ROW_COUNT = 3,
VERTICES_PER_TRIANGLE = 3
};
void Configure();
Vector3 BlendColor;
Vector3 HorizonColor;
float Intensity;
unsigned RowCount;
unsigned VertexCount;
Vector3 *VertexArray;
unsigned TriangleCount;
DX8IndexBufferClass *IndexBuffer;
unsigned *DiffuseArray;
VertexMaterialClass *Material;
ShaderClass Shader;
};
class StarfieldClass : public VisibilityClass
{
public:
StarfieldClass (float radius, unsigned starcount);
~StarfieldClass();
void Configure (const Vector3 &orientation, float length, float radius, const Vector3 &color0, const Vector3 &color1, float alpha);
void Configure (const Vector3 &orientation, float length, float radius);
void Configure (const Vector3 &color0, const Vector3 &color1, float alpha);
void Render();
protected:
void Configure();
enum {
VERTICES_PER_TRIANGLE = 3
};
Vector3 Orientation;
float Length;
float Radius;
Vector3 Color0, Color1;
float Alpha;
unsigned VertexCount;
Vector3 *VertexArray;
unsigned TriangleCount;
DX8IndexBufferClass *IndexBuffer;
VertexMaterialClass *Material;
ShaderClass Shader;
TextureClass *Texture;
unsigned *DiffuseArray;
unsigned ActiveVertexCount;
unsigned ActiveTriangleCount;
};
class SkyObjectClass : public VisibilityClass
{
public:
SkyObjectClass (ShaderClass shader);
~SkyObjectClass();
void Configure (const Vector3 &direction, float length, float radius, const Vector3 &color);
void Configure (const Vector3 &direction, float length, float width, float height);
void Configure (const Vector3 &direction, float length, float radius);
void Configure (const Vector3 &color);
void Set_Texture (const char *texturename);
Vector3 Get_Color() {return (Color);}
void Render();
protected:
enum {
VERTICES_PER_TRIANGLE = 3
};
void Configure();
Vector3 Direction;
float Length;
float Width;
float Height;
Vector3 Color;
unsigned VertexCount;
Vector3 *VertexArray;
unsigned TriangleCount;
DX8IndexBufferClass *IndexBuffer;
VertexMaterialClass *Material;
ShaderClass Shader;
TextureClass *Texture;
Vector2 *TexCoordArray;
unsigned *DiffuseArray;
};
class CloudLayerClass : public VisibilityClass
{
public:
CloudLayerClass (float maxdistance, const char *texturename, const Vector2 &velocity, float tilefactor, bool rotate);
~CloudLayerClass();
void Configure (const Vector3 &warmcolor, const Vector3 &coldcolor);
void Configure (const Vector3 &warmdirection);
void Configure (const Vector3 &warmcolor, const Vector3 &coldcolor, const Vector3 &warmdirection);
void Configure (float alpha, float cloudintensity, float horizonintensity);
void Render();
protected:
enum {
VERTICES_PER_TRIANGLE = 3
};
void Configure();
Vector3 WarmColor;
Vector3 ColdColor;
Vector3 WarmDirection;
float Alpha;
float CloudIntensity;
float HorizonIntensity;
unsigned RowCount;
unsigned VertexCount;
Vector3 *VertexArray;
unsigned TriangleCount;
DX8IndexBufferClass *IndexBuffer;
VertexMaterialClass *Material;
ShaderClass Shader;
TextureClass *Texture;
Vector2 *TexCoordArray;
Vector2 Velocity;
unsigned *DiffuseArray;
};
class SkyGlowClass : public VisibilityClass
{
public:
SkyGlowClass (float radius);
~SkyGlowClass();
void Configure (const Vector2 &hotdirection, const Vector3 &horizoncolor, float coldintensity);
void Render();
protected:
enum {
ROW_COUNT = 5,
VERTICES_PER_TRIANGLE = 3
};
void Configure();
Vector2 HotDirection;
Vector3 HorizonColor;
float ColdIntensity;
unsigned RowCount;
float Radius;
float MinZ, MaxZ;
unsigned VertexCount;
Vector3 *VertexArray;
unsigned TriangleCount;
DX8IndexBufferClass *IndexBuffer;
unsigned *DiffuseArray;
VertexMaterialClass *Material;
ShaderClass Shader;
};
class LightningBoltClass : public VisibilityClass, public SegmentedLineClass
{
public:
LightningBoltClass::LightningBoltClass (int branchcount, Matrix3D &m, float length, float childlength, float width, float amplitude);
~LightningBoltClass ();
void Configure (Vector3 &color);
virtual void Set_Transform (Matrix3D &t);
virtual void Render (RenderInfoClass &rinfo);
void Set_Visibility (bool visible, bool recurse);
private:
struct BranchStruct {
LightningBoltClass *LightningBolt;
};
BranchStruct *Branches;
int BranchCount;
};
class LightningClass
{
public:
LightningClass (float extent, float startdistance, float enddistance, float heading, float distribution);
~LightningClass();
bool Update (Matrix3D &t, Vector3 &additivecolor, SoundEnvironmentClass *soundenvironment);
void Render (RenderInfoClass &rinfo);
private:
SkyGlowClass *LightningGlow;
LightningBoltClass *LightningBolt;
SkyObjectClass *LightningSource;
Vector2 Direction;
float Distance;
unsigned Time;
unsigned ThunderDelayTime;
Vector3 ThunderPosition;
const char *ThunderSampleName;
bool PlayedThunder;
};
class WarBlitzClass
{
public:
WarBlitzClass (float extent, float startdistance, float enddistance, float heading, float distribution);
~WarBlitzClass();
bool Update (Matrix3D &t, Vector3 &additivecolor);
void Render (RenderInfoClass &rinfo);
private:
SkyGlowClass *WarBlitzGlow;
Vector2 Direction;
float Distance;
unsigned Time;
unsigned SampleDelayTime;
Vector3 SamplePosition;
bool PlayedSample;
};
class SkyClass : public RenderObjClass
{
public:
enum MoonTypeEnum {
MOON_TYPE_FULL,
MOON_TYPE_PART,
MOON_TYPE_COUNT
};
SkyClass (SoundEnvironmentClass *soundenvironment);
~SkyClass();
RenderObjClass *Clone() const
{
WWASSERT (false);
return (0);
}
void Set_Color();
Vector3 Get_Color() {return (Color);}
SkyObjectClass *Get_Sun() {return (Sun);}
void Set_Light_Direction (const Vector3 &sundirection, const Vector3 &moondirection);
void Set_Time_Of_Day (unsigned hours, unsigned minutes);
void Set_Moon_Type (MoonTypeEnum moontype);
void Set_Clouds (float cloudcover, float gloominess);
void Set_Tint_Factor (float tintfactor);
void Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution)
{
LightningIntensity = intensity;
LightningStartDistance = startdistance;
LightningEndDistance = enddistance;
LightningHeading = DEG_TO_RADF (heading);
LightningDistribution = distribution;
}
void Set_War_Blitz (float intensity, float startdistance, float enddistance, float heading, float distribution)
{
WarBlitzIntensity = intensity;
WarBlitzStartDistance = startdistance;
WarBlitzEndDistance = enddistance;
WarBlitzHeading = DEG_TO_RADF (heading);
WarBlitzDistribution = distribution;
}
void Update (SceneClass *mainscene, const Vector3 &cameraposition);
void Render (RenderInfoClass &rinfo);
void Get_Obj_Space_Bounding_Sphere (SphereClass &sphere) const;
void Get_Obj_Space_Bounding_Box (AABoxClass &box) const;
protected:
enum {
LIGHTNING_COUNT = 2
};
Vector3 Interpolate_Color (const unsigned char colortable [][3], unsigned colorcount, float interpolant);
float Interpolate_Scalar (const unsigned char scalartable [], unsigned scalarcount, float interpolant);
unsigned Lightning_Delay();
unsigned War_Blitz_Delay();
float Extent; // Radius of sphere (and half cube width) which contains all sky objects (for clipping purposes).
Vector3 Color;
unsigned Hours, Minutes;
float Gloominess;
float TintFactor;
HazeClass *Haze;
StarfieldClass *Starfield;
SkyObjectClass *Sun;
SkyObjectClass *SunHalo;
SkyObjectClass *Moon;
SkyObjectClass *MoonHalo;
CloudLayerClass *CloudLayer0;
CloudLayerClass *CloudLayer1;
LightningClass *Lightning [LIGHTNING_COUNT];
int LightningCountdown [LIGHTNING_COUNT];
float LightningIntensity;
float LightningStartDistance;
float LightningEndDistance;
float LightningHeading;
float LightningDistribution;
SoundEnvironmentClass *SoundEnvironment;
WarBlitzClass *WarBlitz;
int WarBlitzCountdown;
float WarBlitzIntensity;
float WarBlitzStartDistance;
float WarBlitzEndDistance;
float WarBlitzHeading;
float WarBlitzDistribution;
};
class BackgroundParameterClass
{
public:
void Initialize();
void Set (float targetvalue, float ramptime, bool override);
void Set (float overrideramptime) {OverrideDuration = overrideramptime;}
float Value() {return (CurrentValue);}
bool Update (float time, bool override);
void Update (float &value, float &target, float &duration, float time);
private:
float CurrentValue;
float NormalValue;
float NormalTarget;
float NormalDuration;
float OverrideTarget;
float OverrideDuration;
friend class BackgroundMgrClass;
};
class BackgroundMgrClass : public SaveLoadSubSystemClass, public NetworkObjectClass
{
public:
enum LightSourceTypeEnum {
LIGHT_SOURCE_TYPE_SUN,
LIGHT_SOURCE_TYPE_MOON
};
BackgroundMgrClass();
~BackgroundMgrClass() {}
uint32 Chunk_ID() const {return (CHUNKID_BACKGROUND_MGR);}
const char *Name() const {return ("BackgroundMgrClass");}
void Delete (void) {}
virtual void Set_Delete_Pending (void) {};
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
bool Load_Micro_Chunks (ChunkLoadClass &cload);
void Export_Rare (BitStreamClass &packet);
void Import_Rare (BitStreamClass &packet);
static void Init (SimpleSceneClass *renderscene, SoundEnvironmentClass *soundenvironment, bool render_available = true);
static void Reset();
static void Shutdown();
static bool Save_Dynamic (ChunkSaveClass &csave);
static bool Load_Dynamic (ChunkLoadClass &cload);
static bool Load_Dynamic_Micro_Chunks (ChunkLoadClass &cload);
static Vector3 Get_Clear_Color()
{
if (_Sky != NULL) {
return (_Sky->Get_Color());
} else {
return (Vector3 (0.0f, 0.0f, 0.0f));
}
}
static bool Set_Time_Of_Day (unsigned hours, unsigned minutes)
{
if ((hours >= 0) && (hours <= 23) && (minutes >= 0) && (minutes <= 59)) {
_Hours = hours;
_Minutes = minutes;
Set_Dirty();
return (true);
} else {
return (false);
}
}
static void Get_Time_Of_Day (unsigned &hours, unsigned &minutes)
{
hours = _Hours;
minutes = _Minutes;
}
static void Set_Light_Source_Type (LightSourceTypeEnum lightsourcetype)
{
_LightSourceType = lightsourcetype;
Set_Dirty();
}
static LightSourceTypeEnum Get_Light_Source_Type() {return (_LightSourceType);}
static void Set_Moon_Type (SkyClass::MoonTypeEnum moontype)
{
_MoonType = moontype;
Set_Dirty();
}
static SkyClass::MoonTypeEnum Get_Moon_Type()
{
return (_MoonType);
}
static bool Set_Clouds (float cloudcover, float cloudgloominess, float ramptime = 0.0f);
static bool Override_Clouds (float cloudcover, float cloudgloominess, float ramptime = 0.0f);
static void Get_Clouds (float &cloudcover, float &gloominess);
static void Restore_Clouds (float ramptime);
static bool Set_Sky_Tint (float skytintfactor, float ramptime = 0.0f);
static bool Override_Sky_Tint (float skytintfactor, float ramptime = 0.0f);
static void Restore_Sky_Tint (float ramptime);
static bool Set_Lightning_Intensity (float intensity, float ramptime = 0.0f);
static bool Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f);
static bool Override_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f);
static void Get_Lightning (float &intensity, float &startdistance, float &enddistance, float &heading, float &distribution);
static void Restore_Lightning (float ramptime);
static bool Set_War_Blitz (float intensity, float ramptime = 0.0f);
static bool Set_War_Blitz (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime = 0.0f, bool override = false);
static void Get_War_Blitz (float &intensity, float &startdistance, float &enddistance, float &heading, float &distribution);
static void Update (PhysicsSceneClass *mainscene, CameraClass *camera);
private:
#define VARID_PARAMETER(varname) \
VARID_ ## varname ## _CURRENT_VALUE, \
VARID_ ## varname ## _NORMAL_VALUE, \
VARID_ ## varname ## _NORMAL_TARGET, \
VARID_ ## varname ## _NORMAL_DURATION, \
VARID_ ## varname ## _OVERRIDE_TARGET, \
VARID_ ## varname ## _OVERRIDE_DURATION
// Constants.
enum
{
CHUNKID_MICRO_CHUNKS = 0x11080732,
CHUNKID_DYNAMIC_MICRO_CHUNKS = 0x11020216
};
enum {
VARID_TIME_HOURS = 0x14,
VARID_TIME_MINUTES,
VARID_LIGHT_SOURCE_TYPE,
VARID_MOON_TYPE,
VARID_PARAMETER (CLOUD_COVER),
VARID_PARAMETER (CLOUD_GLOOMINESS),
VARID_PARAMETER (SKY_TINT_FACTOR),
VARID_PARAMETER (LIGHTNING_INTENSITY),
VARID_PARAMETER (LIGHTNING_START_DISTANCE),
VARID_PARAMETER (LIGHTNING_END_DISTANCE),
VARID_PARAMETER (LIGHTNING_HEADING),
VARID_PARAMETER (LIGHTNING_DISTRIBUTION),
VARID_CLOUD_OVERRIDE_COUNT,
VARID_LIGHTNING_OVERRIDE_COUNT,
VARID_PARAMETER (WAR_BLITZ_INTENSITY),
VARID_PARAMETER (WAR_BLITZ_START_DISTANCE),
VARID_PARAMETER (WAR_BLITZ_END_DISTANCE),
VARID_PARAMETER (WAR_BLITZ_HEADING),
VARID_PARAMETER (WAR_BLITZ_DISTRIBUTION),
VARID_SKY_TINT_OVERRIDE_COUNT
};
#undef VARID_PARAMETER
enum {
PARAMETER_CLOUD_COVER,
PARAMETER_CLOUD_GLOOMINESS,
PARAMETER_SKY_TINT_FACTOR,
PARAMETER_LIGHTNING_INTENSITY,
PARAMETER_LIGHTNING_START_DISTANCE,
PARAMETER_LIGHTNING_END_DISTANCE,
PARAMETER_LIGHTNING_HEADING,
PARAMETER_LIGHTNING_DISTRIBUTION,
PARAMETER_WAR_BLITZ_INTENSITY,
PARAMETER_WAR_BLITZ_START_DISTANCE,
PARAMETER_WAR_BLITZ_END_DISTANCE,
PARAMETER_WAR_BLITZ_HEADING,
PARAMETER_WAR_BLITZ_DISTRIBUTION,
PARAMETER_COUNT
};
static bool Set_Clouds (float cloudcover, float cloudgloominess, float ramptime, bool override);
static bool Set_Sky_Tint (float skytintfactor, float ramptime, bool override);
static bool Set_Lightning_Intensity (float intensity, float ramptime, bool override);
static bool Set_Lightning (float intensity, float startdistance, float enddistance, float heading, float distribution, float ramptime, bool override);
static bool Is_Dirty() {return (_Dirty);}
static void Set_Dirty (bool dirty = true) {_Dirty = dirty;}
static unsigned _Hours;
static unsigned _Minutes;
static LightSourceTypeEnum _LightSourceType;
static SkyClass::MoonTypeEnum _MoonType;
static BackgroundParameterClass _Parameters [PARAMETER_COUNT];
static Vector3 _LightVector;
static Vector3 _UnitLightVector;
static unsigned _CloudOverrideCount;
static unsigned _LightningOverrideCount;
static unsigned _SkyTintOverrideCount;
static bool _Dirty;
static bool _FogEnabled;
static SkyClass *_Sky;
static DazzleRenderObjClass *_Dazzle;
};
// Externals.
extern BackgroundMgrClass _TheBackgroundMgr;
#endif // BACKGROUNDMGR_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,255 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/basecontroller.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/15/02 7:18p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BASE_CONTROLLER_H
#define __BASE_CONTROLLER_H
#include "building.h"
#include "obbox.h"
#include "vector.h"
#include "characterclasssettings.h"
#include "networkobject.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class ChunkSaveClass;
class ChunkLoadClass;
class ConversationClass;
class ActiveConversationClass;
class SoldierGameObj;
class BuildingGameObj;
class VehicleGameObj;
class BeaconGameObj;
////////////////////////////////////////////////////////////////
//
// BaseControllerClass
//
////////////////////////////////////////////////////////////////
class BaseControllerClass : public NetworkObjectClass
{
public:
////////////////////////////////////////////////////////////////
// Friends
////////////////////////////////////////////////////////////////
friend class BuildingMonitorClass;
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
BaseControllerClass (void);
virtual ~BaseControllerClass (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Initialization
//
void Initialize ( int player_type );
void Shutdown (void);
void Delete (void) {};
//
// Networking.
//
// Set_Delete_Pending -
//
// The base controllers persist between levels so they should never be marked for deletion. They will be deleted
// when needed by their owner, the game mode
//
virtual void Set_Delete_Pending (void) {};
//
// Building access
//
void Add_Building (BuildingGameObj *building);
//
// Timestep
//
void Think (void);
//
// Power related methods
//
void Set_Base_Powered (bool onoff);
bool Is_Base_Powered (void) const { return BasePowered; }
void Check_Base_Power (void);
void Power_Base (bool onoff);
void Set_Operation_Time_Factor (float factor);
float Get_Operation_Time_Factor (void) { return OperationTimeFactor; }
//
// Harvester support
//
void Request_Harvester (int def_id);
VehicleGameObj * Get_Harvester_Vehicle (void);
//
// State accessors
//
bool Can_Generate_Soldiers (void) const { return CanGenerateSoldiers; }
bool Can_Generate_Vehicles (void) const { return CanGenerateVehicles; }
void Set_Can_Generate_Soldiers (bool onoff);
void Set_Can_Generate_Vehicles (bool onoff);
//
// Data accessors
//
int Get_Player_Type (void) const { return PlayerType; }
//
// Base destruction
//
void Set_Base_Destroyed ( bool onoff );
bool Is_Base_Destroyed (void) const { return IsBaseDestroyed; }
void Destroy_Base (void);
void Set_Beacon_Destroyed_Base ( bool onoff );
bool Did_Beacon_Destroy_Base ( void ) const { return DidBeaconDestroyBase; }
//
// Beacon zone access
//
const OBBoxClass & Get_Beacon_Zone (void) { return BeaconZone; }
//
// Radar support
//
void Check_Radar (void);
bool Is_Radar_Enabled (void) const { return IsRadarEnabled; }
void Play_Announcement(int text_id);
//
// Notifications
//
void On_Building_Damaged (BuildingGameObj *building);
void On_Building_Destroyed (BuildingGameObj *building);
void On_Vehicle_Generated(VehicleGameObj *vehicle);
void On_Vehicle_Delivered(VehicleGameObj *vehicle);
void On_Vehicle_Damaged(VehicleGameObj* vehicle);
void On_Vehicle_Destroyed(VehicleGameObj* vehicle);
void On_Beacon_Armed(BeaconGameObj* beacon);
void On_Beacon_Disarmed(BeaconGameObj* beacon);
void On_Beacon_Warning(BeaconGameObj* beacon);
//
// Fund support
//
//void Deposit_Funds (int funds);
void Distribute_Funds_To_Each_Teammate (int funds);
//
// Network support
//
void Import_Occasional (BitStreamClass &packet);
void Export_Occasional (BitStreamClass &packet);
//
// Component lookup
//
static BaseControllerClass * Find_Base ( int playertype );
static BaseControllerClass * Find_Base_For_Star (void);
BuildingGameObj * Find_Building (BuildingConstants::BuildingType type);
protected:
////////////////////////////////////////////////////////////////
// Protected constants
////////////////////////////////////////////////////////////////
typedef enum
{
BASE_UNDER_ATTACK = 0,
BUILDING_DESTROYED
} Notification;
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Initialize_Building_List (void);
void Reset_Building_List (void);
void Enable_Radar (bool onoff);
//
// Team notification
//
void Notify_Team (Notification event, BuildingConstants::BuildingType type);
private:
////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////
bool Are_All_Buildings_Destroyed (void);
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
float OperationTimeFactor;
int PlayerType; // Team
DynamicVectorClass<BuildingGameObj *> BuildingList;
bool BasePowered;
bool CanGenerateSoldiers;
bool CanGenerateVehicles;
bool IsRadarEnabled;
bool IsBaseDestroyed;
bool DidBeaconDestroyBase;
OBBoxClass BeaconZone;
int AnnounceInterval;
float AnnouncedAlliedBldgDamageTime;
float AnnouncedEnemyBldgDamageTime;
float AnnouncedAlliedVehicleDamageTime;
float AnnouncedEnemyVehicleDamageTime;
static BaseControllerClass * CurrentBases[BuildingConstants::BASE_COUNT];
};
#endif //__BASE_CONTROLLER_H

271
Code/Combat/basegameobj.cpp Normal file
View File

@@ -0,0 +1,271 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/basegameobj.cpp $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 8/23/01 10:52a $*
* *
* $Revision:: 27 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "basegameobj.h"
#include "combat.h"
#include "pscene.h"
#include "gameobjmanager.h"
#include "phys.h"
#include "timemgr.h"
#include "chunkio.h"
#include "debug.h"
#include "assets.h"
#include "matinfo.h"
#include "definitionclassids.h"
#include "networkobjectfactory.h"
//////////////////////////////////////////////////////////////
// NetworkGameObjectFactoryClass
//////////////////////////////////////////////////////////////
class NetworkGameObjectFactoryClass : public NetworkObjectFactoryClass
{
public:
virtual NetworkObjectClass * Create (cPacket &packet) const;
virtual void Prep_Packet (NetworkObjectClass *object, cPacket &packet) const;
virtual uint32 Get_Class_ID (void) const { return NETCLASSID_GAMEOBJ; }
};
//////////////////////////////////////////////////////////////
// Prep_Packet
//////////////////////////////////////////////////////////////
void
NetworkGameObjectFactoryClass::Prep_Packet (NetworkObjectClass *object, cPacket &packet) const
{
WWASSERT (object != NULL);
BaseGameObj *game_obj = (BaseGameObj *)(object);
//
// Add the definition ID of the object to the packet
//
packet.Add (game_obj->Get_Definition ().Get_ID ());
return ;
}
//////////////////////////////////////////////////////////////
// Create
//////////////////////////////////////////////////////////////
NetworkObjectClass *
NetworkGameObjectFactoryClass::Create (cPacket &packet) const
{
int definition_id = packet.Get (definition_id);
//
// Lookup the definition for this object
//
DefinitionClass *definition = DefinitionMgrClass::Find_Definition (definition_id);
WWASSERT (definition != NULL);
//
// Create the new object
//
BaseGameObj *new_game_obj = (BaseGameObj *)definition->Create();
//
// Convert the game object to a network object
//
return static_cast<NetworkObjectClass *> (new_game_obj);
}
//////////////////////////////////////////////////////////////
// Static data
//////////////////////////////////////////////////////////////
static NetworkGameObjectFactoryClass _NetworkGameObjectFactory;
/*
** BaseGameObjDef
*/
enum {
CHUNKID_DEF_PARENT = 1111991123,
};
bool BaseGameObjDef::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_DEF_PARENT );
DefinitionClass::Save( csave );
csave.End_Chunk();
return true;
}
bool BaseGameObjDef::Load( ChunkLoadClass &cload )
{
cload.Open_Chunk();
WWASSERT( cload.Cur_Chunk_ID() == CHUNKID_DEF_PARENT );
DefinitionClass::Load( cload );
cload.Close_Chunk();
return true;
}
/*
**
*/
BaseGameObj::BaseGameObj( void ) :
Definition( NULL ),
//DestroyType( DESTROY_NONE ),
//ID( 0 ),
IsPostThinkAllowed( false ),
EnableCinematicFreeze( true )
{
GameObjManager::Add( this );
Set_Object_Dirty_Bit (NetworkObjectClass::BIT_CREATION, true);
}
/*
**
*/
BaseGameObj::~BaseGameObj( void )
{
GameObjManager::Remove( this );
}
/*
**
*/
void BaseGameObj::Init( const BaseGameObjDef & definition )
{
Definition = &definition;
}
const BaseGameObjDef & BaseGameObj::Get_Definition( void ) const
{
return *Definition;
};
/*
** BaseGameObj Save and Load
*/
enum {
CHUNKID_VARIABLES = 910991407,
XXX_MICROCHUNKID_DESTROY_TYPE = 1,
MICROCHUNKID_DEFINITION_ID,
MICROCHUNKID_INSTANCE_ID,
MICROCHUNKID_IS_PENDING_DELETE,
MICROCHUNKID_ENABLE_CINEMATIC_FREEZE,
};
bool BaseGameObj::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_VARIABLES );
bool is_delete_pending = Is_Delete_Pending ();
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_IS_PENDING_DELETE, is_delete_pending );
int definition_id = Definition->Get_ID();
WWASSERT( SuperClassID_From_ClassID( Definition->Get_Class_ID () ) == CLASSID_GAME_OBJECTS ||
SuperClassID_From_ClassID( Definition->Get_Class_ID () ) == CLASSID_BUILDINGS );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEFINITION_ID, definition_id );
int id = Get_Network_ID ();
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_INSTANCE_ID, id );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENABLE_CINEMATIC_FREEZE, EnableCinematicFreeze );
csave.End_Chunk();
return true;
}
bool BaseGameObj::Load( ChunkLoadClass &cload )
{
int id = 0;
cload.Open_Chunk();
WWASSERT( cload.Cur_Chunk_ID() == CHUNKID_VARIABLES );
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
case MICROCHUNKID_IS_PENDING_DELETE:
{
bool is_delete_pending = false;
LOAD_MICRO_CHUNK( cload, is_delete_pending );
if (is_delete_pending) {
Set_Delete_Pending ();
}
break;
}
case MICROCHUNKID_INSTANCE_ID:
{
LOAD_MICRO_CHUNK( cload, id );
//TSS
//Set_Network_ID( id );
break;
}
case MICROCHUNKID_DEFINITION_ID:
int definition_id;
LOAD_MICRO_CHUNK( cload, definition_id );
WWASSERT( Definition == NULL );
Definition = (const BaseGameObjDef*)DefinitionMgrClass::Find_Definition( definition_id );
if ( Definition == NULL ) {
Debug_Say(( "Definition %d not found\n. Re-Export needed\n", definition_id ));
}
//
// 07/30/01 attempting to load a level with temps will presently assert here.
//
WWASSERT( Definition != NULL );
break;
READ_MICRO_CHUNK( cload, MICROCHUNKID_ENABLE_CINEMATIC_FREEZE, EnableCinematicFreeze );
default:
Debug_Say(( "Unrecognized BaseGameObj Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
cload.Close_Chunk();
//
// Set the ID if necessary
//
if (id == 0) {
id = Get_ID ();
if (id == 0) {
Set_Network_ID (NetworkObjectMgrClass::Get_New_Dynamic_ID ());
} else {
WWASSERT(id >= NETID_DYNAMIC_OBJECT_MIN && id <= NETID_DYNAMIC_OBJECT_MAX);
}
} else {
Set_Network_ID (id);
}
return true;
}

149
Code/Combat/basegameobj.h Normal file
View File

@@ -0,0 +1,149 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/basegameobj.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/15/01 7:48p $*
* *
* $Revision:: 17 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BASEGAMEOBJ_H
#define BASEGAMEOBJ_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef PERSIST_H
#include "persist.h"
#endif
#ifndef DEFINITION_H
#include "definition.h"
#endif
#ifndef __NETWORKOBJECT_H
#include "networkobject.h"
#endif
#include "netclassids.h"
/*
**
*/
class SmartGameObj;
class PhysicalGameObj;
class ScriptableGameObj;
class VehicleGameObj;
/*
** BaseGameObjDef - Defintion class for a BaseGameObj
*/
class BaseGameObjDef : public DefinitionClass
{
public:
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
};
/*
**
*/
class BaseGameObj : public PersistClass, public NetworkObjectClass {
public:
// Constructor and Destructor
BaseGameObj( void );
virtual ~BaseGameObj( void );
// Definitions
virtual void Init( void ) = 0;
void Init( const BaseGameObjDef & definition );
const BaseGameObjDef & Get_Definition( void ) const ;
// Save / Load
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
// Thinking
virtual void Think() { IsPostThinkAllowed = true; }
virtual void Post_Think() {};
// ID
void Set_ID( int id ) { Set_Network_ID (id); }
int Get_ID( void ) const { return Get_Network_ID (); }
// Hibernation
virtual bool Is_Hibernating( void ) { return false; }
// Termination
//virtual void Destroy(bool damaged = false) { DestroyType = damaged ? DESTROY_DAMAGED : DESTROY_CONTROLLED; }
//bool Is_Destroy() { return (DestroyType != DESTROY_NONE); }
//bool Is_Damage_Destroyed() { return (DestroyType == DESTROY_DAMAGED); }
// Type identification
virtual PhysicalGameObj *As_PhysicalGameObj( void ) { return (PhysicalGameObj*)NULL; };
virtual VehicleGameObj *As_VehicleGameObj( void ) { return (VehicleGameObj *)NULL; }
virtual SmartGameObj *As_SmartGameObj( void ) { return (SmartGameObj*)NULL; };
virtual ScriptableGameObj *As_ScriptableGameObj( void ) { return (ScriptableGameObj*)NULL; };
// Network support
virtual uint32 Get_Network_Class_ID( void ) const { return NETCLASSID_GAMEOBJ; }
virtual void Delete (void) { delete this; }
bool Is_Post_Think_Allowed( void ) { return IsPostThinkAllowed; }
void Enable_Cinematic_Freeze( bool enable ) { EnableCinematicFreeze = enable; }
bool Is_Cinematic_Freeze_Enabled( void ) { return EnableCinematicFreeze; }
private:
// Constants
/*enum
{
DESTROY_NONE = 0,
DESTROY_DAMAGED,
DESTROY_CONTROLLED
};*/
// Member data
const BaseGameObjDef * Definition;
//int DestroyType;
//int ID;
// This is used to prevent postthinking before a think call
bool IsPostThinkAllowed;
// This keeps certain object alive during cinematic freeze
bool EnableCinematicFreeze;
};
#endif // BASEGAMEOBJ_H

File diff suppressed because it is too large Load Diff

251
Code/Combat/beacongameobj.h Normal file
View File

@@ -0,0 +1,251 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/beacongameobj.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 1/04/02 2:58p $*
* *
* $Revision:: 16 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BEACONGAMEOBJ_H
#define __BEACONGAMEOBJ_H
#include "always.h"
#include "simplegameobj.h"
#include "timemgr.h"
////////////////////////////////////////////////////////////////
// Forward delcarations
////////////////////////////////////////////////////////////////
class BaseControllerClass;
class WeaponDefinitionClass;
class AudibleSoundClass;
////////////////////////////////////////////////////////////////
//
// BeaconGameObjDef
//
////////////////////////////////////////////////////////////////
class BeaconGameObjDef : public SimpleGameObjDef
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
BeaconGameObjDef (void);
~BeaconGameObjDef (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
virtual uint32 Get_Class_ID (void) const;
virtual PersistClass * Create (void) const;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual const PersistFactoryClass & Get_Factory (void) const;
bool Is_Nuke(void) const {return (IsNuke != 0);}
DECLARE_EDITABLE (BeaconGameObjDef, SimpleGameObjDef);
protected:
////////////////////////////////////////////////////////////////
// Protected methods
////////////////////////////////////////////////////////////////
void Load_Variables (ChunkLoadClass &cload);
////////////////////////////////////////////////////////////////
// Protected friends
////////////////////////////////////////////////////////////////
friend class BeaconGameObj;
////////////////////////////////////////////////////////////////
// Protected member data
////////////////////////////////////////////////////////////////
float BroadcastToAllTime;
float ArmTime;
float DisarmTime;
float PreDetonateCinematicDelay;
float DetonateTime;
float PostDetonateTime;
int ArmedSoundDefID;
int DisarmingTextID;
int DisarmedTextID;
int ArmingTextID;
int ArmingInterruptedTextID;
int DisarmingInterruptedTextID;
int PreDetonateCinematicDefID;
int PostDetonateCinematicDefID;
int ExplosionDefID;
int IsNuke;
StringClass ArmingAnimationName;
};
////////////////////////////////////////////////////////////////
//
// BeaconGameObj
//
////////////////////////////////////////////////////////////////
class BeaconGameObj : public SimpleGameObj
{
public:
////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////
BeaconGameObj (void);
virtual ~BeaconGameObj (void);
////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////
//
// Definition support
//
virtual void Init( void );
void Init (const BeaconGameObjDef & definition);
const BeaconGameObjDef & Get_Definition (void) const;
//
// RTTI
//
virtual BeaconGameObj * As_BeaconGameObj (void) { return this; }
//
// Save / Load / Construction Factory
//
bool Save (ChunkSaveClass & csave);
bool Load (ChunkLoadClass & cload);
const PersistFactoryClass & Get_Factory (void) const;
//
// GameObj methods
//
void Think (void);
void Get_Information (StringClass &string);
//
// Beacon initialization
//
void Init_Beacon (const WeaponDefinitionClass *definiton, SoldierGameObj *owner, const Vector3 &position);
//
// Beacon stuff
//
bool Can_Place_Here (const Vector3 &position);
void On_Arming_Interrupted (void);
void Begin_Arming (void);
void On_Poked (ScriptableGameObj *poker);
virtual void Completely_Damaged( const OffenseObjectClass & damager );
virtual void Export_Rare( BitStreamClass &packet );
virtual void Import_Rare( BitStreamClass &packet );
SoldierGameObj * Get_Owner (void);
private:
////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////
void Load_Variables (ChunkLoadClass &cload);
void Stop_Armed_Sound (void);
void Stop_Current_Message_Sound (void);
void Display_Message (int text_id);
void Start_Owner_Animation (void);
void Stop_Owner_Animation (void);
bool Was_Owner_Interrupted (void);
void Start_Cinematic (int id);
bool Is_In_Enemy_Base( void );
void Create_Explosion (void);
//
// State support
//
void Set_State (int state);
void Update_State (void);
BaseControllerClass * Get_Enemy_Base (void);
////////////////////////////////////////////////////////////////
// Private constants
////////////////////////////////////////////////////////////////
enum
{
STATE_NULL = 0,
STATE_ARMING,
STATE_ARMED,
STATE_DISARMED,
STATE_DETONATING
};
////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////
GameObjReference Owner;
int State;
float StateTimer;
float PreDetonateTimer;
float DetonateTimer;
float WarningTimer;
AudibleSoundClass * ArmedSound;
AudibleSoundClass * MessageSound;
bool IsArmed;
const WeaponDefinitionClass * WeaponDefinition;
GameObjReference CinematicObject;
void * OwnerBackup;
void Restore_Owner( void );
};
#endif // __BEACONGAMEOBJ_H

139
Code/Combat/bones.cpp Normal file
View File

@@ -0,0 +1,139 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/bones.cpp $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 6/14/02 10:41a $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "bones.h"
#include "debug.h"
#include "assets.h"
#include "wwstring.h"
#include "stl.h"
static bool _BonesMangerInitted = false;
/*
**
*/
class BoneDataClass {
public:
BoneDataClass( const char * screen_name, float damage_scale ) :
ScreenName( screen_name ), DamageScale( damage_scale ) {}
StringClass ScreenName;
float DamageScale;
};
typedef std::map< StringClass , BoneDataClass * > BoneMapper;
BoneMapper BoneMap;
/*
** Database Loading
*/
#define BONES_INI_FILENAME "BONES.INI"
#define SECTION_LIST "Bones_List"
#define ENTRY_NAME "Name"
#define ENTRY_SCREEN_NAME "ScreenName"
#define ENTRY_DAMAGE_SCALE "DamageScale"
void Load_Bones( void )
{
INIClass * bonesINI = Get_INI( BONES_INI_FILENAME );
if (bonesINI != NULL) {
WWASSERT( bonesINI && bonesINI->Section_Count() > 0 );
int count = bonesINI->Entry_Count( SECTION_LIST ); // Load gang list
for ( int entry = 0; entry < count; entry++ ) {
char name[80];
char screen_name[80];
char section_name[80];
bonesINI->Get_String( SECTION_LIST, bonesINI->Get_Entry( SECTION_LIST, entry),
"", section_name, sizeof( section_name ) );
bonesINI->Get_String( section_name, ENTRY_NAME, "", name, sizeof( name ) );
bonesINI->Get_String( section_name, ENTRY_SCREEN_NAME, "", screen_name, sizeof( screen_name ) );
float damage_scale = bonesINI->Get_Float( section_name, ENTRY_DAMAGE_SCALE, 1.0 );
BoneMap[ name ] = new BoneDataClass( screen_name, damage_scale );
// Debug_Say(( "Add bone %s %s %f\n", name, screen_name, damage_scale ));
}
Release_INI( bonesINI );
} else {
Debug_Say(("Load_Bones - Unable to load %s\n", BONES_INI_FILENAME));
}
}
/*
**
*/
void BonesManager::Init( void )
{
if (_BonesMangerInitted) {
Shutdown();
}
Load_Bones();
_BonesMangerInitted = true;
}
void BonesManager::Shutdown( void )
{
for(BoneMapper::iterator it = BoneMap.begin(); it != BoneMap.end(); it++) {
delete it->second;
}
BoneMap.clear();
_BonesMangerInitted = false;
}
const char * BonesManager::Get_Bone_Screen_Name( const char * bone_name )
{
BoneMapper::iterator i = BoneMap.find( bone_name );
if ( i != BoneMap.end() ) {
return i->second->ScreenName;
}
return "???";
}
float BonesManager::Get_Bone_Damage_Scale( const char * bone_name )
{
StringClass bone_name_string(bone_name,true);
BoneMapper::iterator i = BoneMap.find( bone_name_string );
if ( i != BoneMap.end() ) {
return i->second->DamageScale;
}
return 1.0f;
}

59
Code/Combat/bones.h Normal file
View File

@@ -0,0 +1,59 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Commando/bones.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 7/28/99 11:58a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BONES_H
#define BONES_H
#ifndef ALWAYS_H
#include "always.h"
#endif
/*
** BONES MANAGER
*/
class BonesManager {
public:
static void Init( void );
static void Shutdown( void );
static const char * Get_Bone_Screen_Name( const char * bone_name );
static float Get_Bone_Damage_Scale( const char * bone_name );
};
#endif

1635
Code/Combat/building.cpp Normal file

File diff suppressed because it is too large Load Diff

327
Code/Combat/building.h Normal file
View File

@@ -0,0 +1,327 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/building.h $*
* *
* $Author:: Patrick $*
* *
* $Modtime:: 1/07/02 3:52p $*
* *
* $Revision:: 42 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef BUILDING_H
#define BUILDING_H
#include "always.h"
#include "damageablegameobj.h"
#include "combatphysobserver.h"
#include "buildingaggregate.h"
#include "lightphys.h"
#include "playertype.h"
/*
** Forward declarations
*/
class AudibleSoundClass;
class BaseControllerClass;
class BuildingMonitorClass;
class PowerPlantGameObj;
class SoldierFactoryGameObj;
class VehicleFactoryGameObj;
class AirStripGameObj;
class WarFactoryGameObj;
class RefineryGameObj;
class ComCenterGameObj;
class RepairBayGameObj;
/**
** BuildingConstants
** Convienent namespace declaration for the constants used with buildings
*/
namespace BuildingConstants
{
typedef enum
{
TYPE_NONE = -1,
TYPE_POWER_PLANT,
TYPE_SOLDIER_FACTORY,
TYPE_VEHICLE_FACTORY,
TYPE_REFINERY,
TYPE_COM_CENTER,
TYPE_REPAIR_BAY,
TYPE_SHRINE,
TYPE_HELIPAD,
TYPE_CONYARD,
TYPE_BASE_DEFENSE,
TYPE_COUNT
} BuildingType;
typedef enum
{
LEGACY_TEAM_GDI = 0,
LEGACY_TEAM_NOD,
} LegacyBuildingTeam;
typedef enum
{
BASE_COUNT = 2,
};
}
/**
** Building Game Obj Def
** This class is an editable definition for a building. It contains all constant data needed to initialize
** a BuildingGameObj.
*/
class BuildingGameObjDef : public DamageableGameObjDef
{
public:
BuildingGameObjDef( void );
virtual uint32 Get_Class_ID( void ) const;
virtual PersistClass * Create( void ) const ;
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
DECLARE_EDITABLE( BuildingGameObjDef, DamageableGameObjDef );
void Set_Type (BuildingConstants::BuildingType type) { Type = type; }
BuildingConstants::BuildingType Get_Type (void) const { return Type; }
const StringClass & Get_Mesh_Prefix (void) const { return MeshPrefix; }
int Get_Damage_Report(int team) const;
int Get_Destroy_Report(int team) const;
protected:
StringClass MeshPrefix;
ArmorType MCTSkin;
BuildingConstants::BuildingType Type;
int GDIDamageReportID;
int NodDamageReportID;
int GDIDestroyReportID;
int NodDestroyReportID;
friend class BuildingGameObj;
};
/*
** Building Game Obj
** This class encapsulates the basic building functionality.
**
** At initialization, the following things need to happen.
** - Collects all of the meshes that are part of the building using proximity, prefix matching
** and the "house" naming convention (# indicates an interior mesh, ^ indicates an exterior mesh).
** - Collect all of the BuildingAggregates that are part of the building using proximity and
** prefix matching.
** - Collect all light sources associated with the building using proximity and prefix matching.
** - Install itself as an observer into each StaticPhysClass (meshes and aggregates) that is part
** of the building.
**
** During gameplay, the building code does the following things:
** - Responds to all bullet collisions and explosions on any of its meshes/aggregates by
** applying damage to the building.
** - When destroyed, applies the alternate materials on its exterior meshes
** - When the power goes out, applies the alternate materials on its interior meshes
** - When the state changes (power on/off, health 100,75,50,25,0) switches the behaviors of
** all aggregates.
**
*/
class BuildingGameObj : public DamageableGameObj, public CombatPhysObserverClass
{
public:
// Constructor and Destructor
BuildingGameObj( void );
virtual ~BuildingGameObj( void );
// Definitions
virtual void Init( void );
void Init( const BuildingGameObjDef & definition );
const BuildingGameObjDef & Get_Definition( void ) const ;
// Save / Load
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
// Type identification
virtual BuildingGameObj * As_BuildingGameObj( void ) { return this; }
virtual DamageableGameObj * As_DamageableGameObj( void ) { return this; }
virtual PowerPlantGameObj * As_PowerPlantGameObj (void) { return NULL; }
virtual SoldierFactoryGameObj * As_SoldierFactoryGameObj (void) { return NULL; }
virtual VehicleFactoryGameObj * As_VehicleFactoryGameObj (void) { return NULL; }
virtual AirStripGameObj * As_AirStripGameObj (void) { return NULL; }
virtual WarFactoryGameObj * As_WarFactoryGameObj (void) { return NULL; }
virtual RefineryGameObj * As_RefineryGameObj (void) { return NULL; }
virtual ComCenterGameObj * As_ComCenterGameObj (void) { return NULL; }
virtual RepairBayGameObj * As_RepairBayGameObj (void) { return NULL; }
/****/
/*
** Position interface, the position of the building controller influences which meshes
** and other components are automatically assigned to this building. When there are two
** BuildingGameObj's that can accept a particular component, the closest one wins.
*/
void Get_Position(Vector3 * pos) const { *pos = Position; }
void Set_Position(const Vector3 & pos) { Position = pos; CollectionSphere.Center = pos; }
/*
** Damage interface, designed to work similarly to a game object
*/
virtual void Apply_Damage( const OffenseObjectClass & damager,
float scale = 1.0f,
int alternate_skin = -1 );
void Apply_Damage_Building( const OffenseObjectClass & offense,
StaticPhysClass * component );
void Apply_Damage_Building( const OffenseObjectClass & offense,
bool mct_damage );
void Set_Normalized_Health (float health);
/*
** Power interface, turn the power on and off
*/
void Enable_Power(bool onoff);
bool Is_Power_Enabled(void) const { return IsPowerOn; }
/*
** Building announcment support
*/
void Play_Announcement( int text_id, bool broadcast );
void Stop_Current_Announcement( void );
/*
** Utility functions for the building mesh naming convention.
** Exterior meshes contain a ^ as the first character following their prefix.
** Interior meshes contain a # as the first character following their prefix.
*/
bool Name_Prefix_Matches_This_Building(const char * name);
static bool Is_Interior_Mesh_Name(const char * name);
static bool Is_Exterior_Mesh_Name(const char * name);
const char * Get_Name_Prefix (void) const { return Get_Definition().MeshPrefix; }
/*
** Building component support
*/
void Collect_Building_Components (void);
void Get_Collection_Sphere (SphereClass *sphere) const { *sphere = CollectionSphere; }
void Set_Collection_Sphere (const SphereClass &sphere) { CollectionSphere = sphere; }
/*
** CnC mode suport
*/
virtual void CnC_Initialize (BaseControllerClass *base);
virtual void On_Destroyed (void);
virtual void On_Damaged (void);
bool Is_Destroyed (void) const { return IsDestroyed; }
/*
** Network support
*/
virtual void Import_Rare (BitStreamClass &packet);
virtual void Export_Rare (BitStreamClass &packet);
virtual void Export_Creation (BitStreamClass &packet);
virtual void Import_Creation (BitStreamClass &packet);
static void Set_Precision (void);
virtual bool Get_World_Position (Vector3 &pos) const { pos = Position; return true; }
//virtual float Compute_Object_Priority (int client_id, const Vector3 &client_pos);
//virtual void Get_Extended_Information( StringClass & description );
virtual void Get_Description( StringClass & description );
virtual bool Is_Tagged(void) { return false; }
/*
**
*/
bool Is_GDI( void ) { return Get_Player_Type() == PLAYERTYPE_GDI; }
bool Is_Nod( void ) { return Get_Player_Type() == PLAYERTYPE_NOD; }
static void Set_Can_Repair_Buildings(bool flag) {CanRepairBuildings = flag;}
static bool Get_Can_Repair_Buildings(void) {return CanRepairBuildings;}
//
// Informational
//
void Find_Closest_Poly (const Vector3 &pos, float *distance2);
protected:
/*
** CnC mode stuff
*/
BuildingMonitorClass * BuildingMonitor;
BaseControllerClass * BaseController;
bool IsDestroyed;
//private:
Vector3 Position;
bool IsPowerOn;
int CurrentState; // derived from the health and IsPowerOn
AudibleSoundClass * CurrentAnnouncement;
SphereClass AnnouncementSphere;
SphereClass CollectionSphere;
RefMultiListClass<StaticPhysClass> InteriorMeshes;
RefMultiListClass<StaticPhysClass> ExteriorMeshes;
RefMultiListClass<BuildingAggregateClass> Aggregates;
RefMultiListClass<LightPhysClass> PowerOnLights;
RefMultiListClass<LightPhysClass> PowerOffLights;
static bool CanRepairBuildings;
void Initialize_Building(void);
void Reset_Components(void);
void Add_Mesh(StaticPhysClass * terrain);
void Remove_Mesh(StaticPhysClass * terrain);
void Add_Aggregate(BuildingAggregateClass * aggregate);
void Remove_Aggregate(BuildingAggregateClass * aggregate);
void Add_Light(LightPhysClass * light);
void Find_Closest_Poly_For_Model (RenderObjClass *model, const Vector3 &pos, float *distance2);
void Update_State(bool force_update = false);
void Enable_Alternate_Materials(RefMultiListClass<StaticPhysClass> & models, bool onoff);
void Enable_Alternate_Materials(RenderObjClass * model,bool onoff);
friend class GameObjManager;
};
#endif // BUILDING_H

View File

@@ -0,0 +1,749 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingaggregate.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Bhayes $*
* *
* $Modtime:: 1/07/03 1:38p $*
* *
* $Revision:: 14 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* BuildingAggregateClass::BuildingAggregateClass -- Constructor *
* BuildingAggregateClass::BuildingAggregateClass -- Constructor *
* BuildingAggregateClass::~BuildingAggregateClass -- Destructor *
* BuildingAggregateClass::Init -- Initialze from a definition *
* BuildingAggregateClass::Get_Current_State -- returns the current state *
* BuildingAggregateClass::Set_Current_State -- Sets the current state *
* BuildingAggregateClass::Is_MCT -- is this aggregate an MCT? *
* BuildingAggregateClass::Save -- Get the persist factory for this clas *
* BuildingAggregateClass::Save -- Save the state of this object *
* BuildingAggregateClass::Load -- Load the state of this object *
* BuildingAggregateClass::On_Post_Load -- post-load processing *
* BuildingAggregateDefClass::BuildingAggregateDefClass -- Constructor *
* BuildingAggregateDefClass::Get_Class_ID -- returns the definition class ID *
* BuildingAggregateDefClass::Create -- creates an instance of a BuildingAggregateClass *
* BuildingAggregateDefClass::Get_Factory -- returns the persist factory *
* BuildingAggregateDefClass::Save -- Saves the contents of this object *
* BuildingAggregateDefClass::Save_State_Animation_Data -- Save the data for one of the buil *
* BuildingAggregateDefClass::Load -- Load the contents of this object *
* BuildingAggregateDefClass::Load_State_Animation_Data -- Load anim data for a building sta *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "buildingaggregate.h"
#include "simpledefinitionfactory.h"
#include "persistfactory.h"
#include "wwphysids.h"
#include "hanim.h"
#include "combat.h"
#include "wwaudio.h"
#include "wwdebug.h"
#include "wwhack.h"
#include "wwprofile.h"
DECLARE_FORCE_LINK( buildingaggregate );
/*************************************************************************************************************
**
** BuildingAggregateClass (BAG) Implementation
**
*************************************************************************************************************/
SimplePersistFactoryClass<BuildingAggregateClass, PHYSICS_CHUNKID_BUILDINGAGGREGATE> _BuildingAggregatePersistFactory;
enum
{
BAG_CHUNK_STATICANIMPHYS = 8281529,
BAG_CHUNK_VARIABLES,
BAG_VARIABLE_CURRENTSTATE = 0,
};
/***********************************************************************************************
* BuildingAggregateClass::BuildingAggregateClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
BuildingAggregateClass::BuildingAggregateClass(void) :
CurrentState(BuildingStateClass::HEALTH100_POWERON)
{
}
/***********************************************************************************************
* BuildingAggregateClass::~BuildingAggregateClass -- Destructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
*=============================================================================================*/
BuildingAggregateClass::~BuildingAggregateClass(void)
{
}
/***********************************************************************************************
* BuildingAggregateClass::Init -- Initialze from a definition *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
void BuildingAggregateClass::Init(const BuildingAggregateDefClass & def)
{
StaticAnimPhysClass::Init(def);
AnimCollisionManagerClass & anim_mgr = Get_Animation_Manager();
anim_mgr.Set_Current_Frame(def.Frame0[CurrentState]);
}
/***********************************************************************************************
* BuildingAggregateClass::Get_Current_State -- returns the current state *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/8/2000 gth : Created. *
*=============================================================================================*/
int BuildingAggregateClass::Get_Current_State(void)
{
return CurrentState;
}
/***********************************************************************************************
* BuildingAggregateClass::Set_Current_State -- Sets the current state *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/8/2000 gth : Created. *
*=============================================================================================*/
void BuildingAggregateClass::Set_Current_State(int new_state,bool force_update)
{
if ((new_state != CurrentState) || (force_update == true)) {
AnimCollisionManagerClass & anim_mgr = Get_Animation_Manager();
const BuildingAggregateDefClass * def = Get_BuildingAggregateDef();
WWASSERT(def != NULL);
switch (def->AnimLogicMode)
{
case BuildingAggregateDefClass::ANIM_LOGIC_LOOP:
{
/*
** Calculate the fractional position in our current loop
*/
float normalized_frame = 0.0f;
float cur_loop_len = def->Frame1[CurrentState] - def->Frame0[CurrentState];
if (cur_loop_len > 0.0f) {
normalized_frame = (anim_mgr.Get_Current_Frame() - def->Frame0[CurrentState]) /
(def->Frame1[CurrentState] - def->Frame0[CurrentState]);
}
/*
** Switch the loop start and end
*/
anim_mgr.Set_Loop_Start(def->Frame0[new_state]);
anim_mgr.Set_Loop_End(def->Frame1[new_state]);
/*
** Jump to the same fractional position in the new loop
*/
anim_mgr.Set_Current_Frame(def->Frame0[new_state] + normalized_frame * (def->Frame1[new_state] - def->Frame0[new_state]));
/*
** If animation is disabled, set the animation mode to manual, otherwise set it to loop
*/
if (def->AnimationEnabled[new_state] == true) {
anim_mgr.Set_Animation_Mode(AnimCollisionManagerClass::ANIMATE_LOOP);
} else {
anim_mgr.Set_Animation_Mode(AnimCollisionManagerClass::ANIMATE_MANUAL);
}
break;
}
case BuildingAggregateDefClass::ANIM_LOGIC_LINEAR:
{
/*
** The new target frame is determined by the new state
*/
anim_mgr.Set_Target_Frame(def->Frame0[new_state]);
anim_mgr.Set_Animation_Mode(AnimCollisionManagerClass::ANIMATE_TARGET);
/*
** If we changed power states or animation is disabled, then we need to warp the current frame
*/
if ( (BuildingStateClass::Is_Power_On(new_state) != BuildingStateClass::Is_Power_On(CurrentState)) ||
(def->AnimationEnabled[new_state] == false))
{
anim_mgr.Set_Current_Frame(def->Frame0[new_state]);
}
break;
}
case BuildingAggregateDefClass::ANIM_LOGIC_SEQUENCE:
{
/*
** The current and target frames are determined by the new state. If the new sequence
** is the same as the previous sequence, don't do anything.
*/
if ((def->Frame0[CurrentState] != def->Frame0[new_state]) || (def->Frame1[CurrentState] != def->Frame1[new_state])) {
anim_mgr.Set_Animation_Mode(AnimCollisionManagerClass::ANIMATE_TARGET);
anim_mgr.Set_Current_Frame(def->Frame0[new_state]);
anim_mgr.Set_Target_Frame(def->Frame1[new_state]);
}
break;
}
}
CurrentState = new_state;
}
}
/***********************************************************************************************
* BuildingAggregateClass::Is_MCT -- is this aggregate an MCT? *
* *
* MCT's are weak points for the building. The building will use an alternate skin type *
* when applying damage that was done to the MCT. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/24/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateClass::Is_MCT(void)
{
return Get_BuildingAggregateDef()->IsMCT;
}
/*
** Save and Load
*/
/***********************************************************************************************
* BuildingAggregateClass::Save -- Get the persist factory for this class *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
const PersistFactoryClass & BuildingAggregateClass::Get_Factory(void) const
{
return _BuildingAggregatePersistFactory;
}
/***********************************************************************************************
* BuildingAggregateClass::Save -- Save the state of this object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateClass::Save(ChunkSaveClass & csave)
{
csave.Begin_Chunk(BAG_CHUNK_STATICANIMPHYS);
StaticAnimPhysClass::Save(csave);
csave.End_Chunk();
csave.Begin_Chunk(BAG_CHUNK_VARIABLES);
WRITE_MICRO_CHUNK(csave, BAG_VARIABLE_CURRENTSTATE, CurrentState );
csave.End_Chunk();
return true;
}
/***********************************************************************************************
* BuildingAggregateClass::Load -- Load the state of this object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case BAG_CHUNK_STATICANIMPHYS:
StaticAnimPhysClass::Load( cload );
break;
case BAG_CHUNK_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK(cload, BAG_VARIABLE_CURRENTSTATE, CurrentState );
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregate Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
WWDEBUG_SAY(("Unrecognized BuildingAggregate Chunk: 0x%x in file %s, line %d\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Chunk();
}
SaveLoadSystemClass::Register_Post_Load_Callback(this);
return true;
}
/***********************************************************************************************
* BuildingAggregateClass::On_Post_Load -- post-load processing *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 9/8/2000 gth : Created. *
*=============================================================================================*/
void BuildingAggregateClass::On_Post_Load(void)
{
StaticAnimPhysClass::On_Post_Load();
Set_Current_State(CurrentState,true);
}
/*
**
*/
void BuildingAggregateClass::Save_State( ChunkSaveClass & csave )
{
csave.Begin_Chunk( BAG_CHUNK_STATICANIMPHYS );
StaticAnimPhysClass::Save_State(csave);
csave.End_Chunk();
csave.Begin_Chunk(BAG_CHUNK_VARIABLES);
WRITE_MICRO_CHUNK(csave, BAG_VARIABLE_CURRENTSTATE, CurrentState );
csave.End_Chunk();
}
/*
**
*/
void BuildingAggregateClass::Load_State( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case BAG_CHUNK_STATICANIMPHYS:
StaticAnimPhysClass::Load_State( cload );
break;
case BAG_CHUNK_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK(cload, BAG_VARIABLE_CURRENTSTATE, CurrentState );
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregate Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregate chunkID\n" ));
break;
}
cload.Close_Chunk();
}
}
/*************************************************************************************************
**
** BuildingAggregateDefClass Implementation
**
*************************************************************************************************/
/*
** Persist Factory for BuildingAggregateDefClass, this makes them save and load.
*/
SimplePersistFactoryClass<BuildingAggregateDefClass, PHYSICS_CHUNKID_BUILDINGAGGREGATEDEF> _BuildingAggregateDefPersistFactory;
/*
** Definition Factory for BuildingAggregateDefClass, this makes them show up in the editor
*/
DECLARE_DEFINITION_FACTORY(BuildingAggregateDefClass, CLASSID_BUILDINGAGGREGATEDEF, "BuildingAggregate") _BuildingAggregateDefDefFactory;
/*
** Chunk ID's used by BuildingAggregateDefClass
*/
enum
{
BAGDEF_CHUNK_STATICANIMPHYS = 8281441,
BAGDEF_CHUNK_VARIABLES,
BAGDEF_CHUNK_HEALTH100_POWERON_VARIABLES,
BAGDEF_CHUNK_HEALTH75_POWERON_VARIABLES,
BAGDEF_CHUNK_HEALTH50_POWERON_VARIABLES,
BAGDEF_CHUNK_HEALTH25_POWERON_VARIABLES,
BAGDEF_CHUNK_DESTROYED_POWERON_VARIABLES,
BAGDEF_CHUNK_HEALTH100_POWEROFF_VARIABLES,
BAGDEF_CHUNK_HEALTH75_POWEROFF_VARIABLES,
BAGDEF_CHUNK_HEALTH50_POWEROFF_VARIABLES,
BAGDEF_CHUNK_HEALTH25_POWEROFF_VARIABLES,
BAGDEF_CHUNK_DESTROYED_POWEROFF_VARIABLES,
BAGDEF_VARIABLE_ANIMLOGICMODE = 0,
BAGDEF_VARIABLE_FRAME0,
BAGDEF_VARIABLE_FRAME1,
BAGDEF_VARIABLE_ANIMATIONENABLED,
BAGDEF_VARIABLE_ISMCT,
};
/***********************************************************************************************
* BuildingAggregateDefClass::BuildingAggregateDefClass -- Constructor *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
BuildingAggregateDefClass::BuildingAggregateDefClass( void ) :
StaticAnimPhysDefClass(),
AnimLogicMode(ANIM_LOGIC_LOOP),
IsMCT(false)
{
int i;
for (i=0; i<BuildingStateClass::STATE_COUNT; i++) {
Frame0[i] = 0;
Frame1[i] = 0;
AnimationEnabled[i] = true;
}
#ifdef PARAM_EDITING_ON
PARAM_SEPARATOR(BuildingAggregateDefClass, "Building Behavior Settings");
EnumParameterClass * anim_logic_param = new EnumParameterClass(&AnimLogicMode);
anim_logic_param->Set_Name ("AnimLogicMode");
anim_logic_param->Add_Value("ANIM_LOGIC_LINEAR",ANIM_LOGIC_LINEAR);
anim_logic_param->Add_Value("ANIM_LOGIC_LOOP",ANIM_LOGIC_LOOP);
anim_logic_param->Add_Value("ANIM_LOGIC_SEQUENCE",ANIM_LOGIC_SEQUENCE);
GENERIC_EDITABLE_PARAM( BuildingAggregateDefClass, anim_logic_param);
EDITABLE_PARAM(BuildingAggregateDefClass, ParameterClass::TYPE_BOOL, IsMCT);
for (i=0; i<BuildingStateClass::STATE_COUNT; i++) {
PARAM_SEPARATOR(BuildingAggregateDefClass, BuildingStateClass::Get_State_Name(i))
NAMED_EDITABLE_PARAM(BuildingAggregateDefClass, ParameterClass::TYPE_INT, Frame0[i], "Frame0");
NAMED_EDITABLE_PARAM(BuildingAggregateDefClass, ParameterClass::TYPE_INT, Frame1[i], "Frame1");
NAMED_EDITABLE_PARAM(BuildingAggregateDefClass, ParameterClass::TYPE_BOOL, AnimationEnabled[i], "AnimationEnabled");
}
#endif
}
/***********************************************************************************************
* BuildingAggregateDefClass::Get_Class_ID -- returns the definition class ID *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
uint32 BuildingAggregateDefClass::Get_Class_ID(void) const
{
return CLASSID_BUILDINGAGGREGATEDEF;
}
bool BuildingAggregateDefClass::Is_Type(const char * type_name)
{
if (stricmp(type_name,BuildingAggregateDefClass::Get_Type_Name()) == 0) {
return true;
} else {
return StaticAnimPhysDefClass::Is_Type(type_name);
}
}
/***********************************************************************************************
* BuildingAggregateDefClass::Create -- creates an instance of a BuildingAggregateClass *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
PersistClass * BuildingAggregateDefClass::Create(void) const
{
BuildingAggregateClass * obj = new BuildingAggregateClass;
obj->Init( *this );
return obj;
}
/*
** Save and Load
*/
/***********************************************************************************************
* BuildingAggregateDefClass::Get_Factory -- returns the persist factory *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
const PersistFactoryClass & BuildingAggregateDefClass::Get_Factory(void) const
{
return _BuildingAggregateDefPersistFactory;
}
/***********************************************************************************************
* BuildingAggregateDefClass::Save -- Saves the contents of this object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateDefClass::Save(ChunkSaveClass & csave)
{
csave.Begin_Chunk( BAGDEF_CHUNK_STATICANIMPHYS );
StaticAnimPhysDefClass::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( BAGDEF_CHUNK_VARIABLES );
WRITE_MICRO_CHUNK( csave, BAGDEF_VARIABLE_ANIMLOGICMODE, AnimLogicMode );
WRITE_MICRO_CHUNK( csave, BAGDEF_VARIABLE_ISMCT, IsMCT );
csave.End_Chunk();
for (int i=0; i<BuildingStateClass::STATE_COUNT; i++) {
Save_State_Animation_Data(csave,i);
}
return true;
}
/***********************************************************************************************
* BuildingAggregateDefClass::Save_State_Animation_Data -- Save the data for one of the buildi *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateDefClass::Save_State_Animation_Data(ChunkSaveClass & csave,int state_index)
{
WWASSERT(state_index >= 0);
WWASSERT(state_index < BuildingStateClass::STATE_COUNT);
csave.Begin_Chunk(BAGDEF_CHUNK_HEALTH100_POWERON_VARIABLES + state_index);
WRITE_MICRO_CHUNK(csave,BAGDEF_VARIABLE_FRAME0,Frame0[state_index]);
WRITE_MICRO_CHUNK(csave,BAGDEF_VARIABLE_FRAME1,Frame1[state_index]);
WRITE_MICRO_CHUNK(csave,BAGDEF_VARIABLE_ANIMATIONENABLED,AnimationEnabled[state_index]);
csave.End_Chunk();
return true;
}
/***********************************************************************************************
* BuildingAggregateDefClass::Load -- Load the contents of this object *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateDefClass::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case BAGDEF_CHUNK_STATICANIMPHYS:
StaticAnimPhysDefClass::Load( cload );
break;
case BAGDEF_CHUNK_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, BAGDEF_VARIABLE_ANIMLOGICMODE,AnimLogicMode );
READ_MICRO_CHUNK( cload, BAGDEF_VARIABLE_ISMCT, IsMCT );
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregateDef Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
case BAGDEF_CHUNK_HEALTH100_POWERON_VARIABLES:
case BAGDEF_CHUNK_HEALTH75_POWERON_VARIABLES:
case BAGDEF_CHUNK_HEALTH50_POWERON_VARIABLES:
case BAGDEF_CHUNK_HEALTH25_POWERON_VARIABLES:
case BAGDEF_CHUNK_DESTROYED_POWERON_VARIABLES:
case BAGDEF_CHUNK_HEALTH100_POWEROFF_VARIABLES:
case BAGDEF_CHUNK_HEALTH75_POWEROFF_VARIABLES:
case BAGDEF_CHUNK_HEALTH50_POWEROFF_VARIABLES:
case BAGDEF_CHUNK_HEALTH25_POWEROFF_VARIABLES:
case BAGDEF_CHUNK_DESTROYED_POWEROFF_VARIABLES:
Load_State_Animation_Data(cload,cload.Cur_Chunk_ID() - BAGDEF_CHUNK_HEALTH100_POWERON_VARIABLES);
break;
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregateDef chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
/***********************************************************************************************
* BuildingAggregateDefClass::Load_State_Animation_Data -- Load anim data for a building state *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 8/29/2000 gth : Created. *
*=============================================================================================*/
bool BuildingAggregateDefClass::Load_State_Animation_Data(ChunkLoadClass & cload,int state_index)
{
WWASSERT(state_index >= 0);
WWASSERT(state_index < BuildingStateClass::STATE_COUNT);
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK(cload,BAGDEF_VARIABLE_FRAME0,Frame0[state_index]);
READ_MICRO_CHUNK(cload,BAGDEF_VARIABLE_FRAME1,Frame1[state_index]);
READ_MICRO_CHUNK(cload,BAGDEF_VARIABLE_ANIMATIONENABLED,AnimationEnabled[state_index]);
default:
WWDEBUG_SAY(( "Unrecognized BuildingAggregateDef Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
return true;
}

View File

@@ -0,0 +1,159 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingaggregate.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 11/21/01 2:47p $*
* *
* $Revision:: 8 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef BUILDINGAGGREGATE_H
#define BUILDINGAGGREGATE_H
#include "always.h"
#include "staticanimphys.h"
#include "buildingstate.h"
class BuildingAggregateDefClass;
/**
** BuildingAggregateClass (BAG)
** This class implements the behavior of a "building aggregate". Building aggregates are animated
** static objects which display segments of their animation depending on the state of the building.
*/
class BuildingAggregateClass : public StaticAnimPhysClass
{
public:
// Constructor and Destructor
BuildingAggregateClass( void );
virtual ~BuildingAggregateClass( void );
// Definitions
void Init( const BuildingAggregateDefClass & definition );
const BuildingAggregateDefClass * Get_BuildingAggregateDef( void ) const { WWASSERT( Definition ); return (BuildingAggregateDefClass *)Definition; }
// State changing
int Get_Current_State(void);
void Set_Current_State(int new_state,bool force_update = false);
bool Is_MCT(void);
// Save / Load
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual void Save_State( ChunkSaveClass & csave );
virtual void Load_State( ChunkLoadClass & cload );
virtual void On_Post_Load( void );
virtual const PersistFactoryClass & Get_Factory( void ) const;
protected:
bool Is_Power_On(int state);
int CurrentState;
};
/**
** BuildingAggregateDefClass (BAGDef!)
** The data contained in this class defines the behavior of a "building aggregate". Building
** aggregates are animated static objects which display segments of their animation depending
** on the state of the building.
** Obviously, this is a very special case object; designed specifically to provide a set of
** features needed by the building logic in Renegade.
*/
class BuildingAggregateDefClass : public StaticAnimPhysDefClass
{
public:
BuildingAggregateDefClass(void);
virtual uint32 Get_Class_ID( void ) const;
virtual const char * Get_Type_Name(void) { return "BuildingAggregateDef"; }
virtual bool Is_Type(const char *);
virtual PersistClass * Create( void ) const ;
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
DECLARE_EDITABLE( BuildingAggregateDefClass, StaticAnimPhysDefClass );
protected:
bool Save_State_Animation_Data(ChunkSaveClass & csave,int state_index);
bool Load_State_Animation_Data(ChunkLoadClass & cload,int state_index);
/*
** Animation Logic Setting
** ANIM_LOGIC_LINEAR - Frame0 is used for each state, if the damage state changes, the animation
** is played to the new state's Frame0. If the power state changes, we pop to the same relative
** position in the alternate power state.
** ANIM_LOGIC_LOOP - In this mode, each state has a pair of frames which it loops between. Whenever
** the state changes, we pop to the same relative position in the new loop. In addition, certain
** states can have animation disabled; this will cause the object to freeze on the appropriate frame
** right after the state change.
*/
enum
{
ANIM_LOGIC_LINEAR = 0,
ANIM_LOGIC_LOOP,
ANIM_LOGIC_SEQUENCE,
};
int AnimLogicMode;
bool IsMCT;
/*
** Animation controls for each state. In LOOP mode, we use Frame0 and Frame1 to define a loop. In
** Linear mode, only Frame0 is used.
*/
int Frame0[BuildingStateClass::STATE_COUNT];
int Frame1[BuildingStateClass::STATE_COUNT];
bool AnimationEnabled[BuildingStateClass::STATE_COUNT];
friend class BuildingAggregateClass;
};
#endif //BUILDINGAGGREGATE_H

View File

@@ -0,0 +1,115 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingmonitor.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/05/01 1:46p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "buildingmonitor.h"
#include "building.h"
////////////////////////////////////////////////////////////////
//
// Killed
//
////////////////////////////////////////////////////////////////
void
BuildingMonitorClass::Killed (GameObject *game_obj, GameObject *killer)
{
WWASSERT (Building != NULL);
//
// Notify the building
//
Building->On_Destroyed ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Damaged
//
////////////////////////////////////////////////////////////////
void
BuildingMonitorClass::Damaged (GameObject *game_obj, GameObject *killer, float amount )
{
// Only report damage not heal
if (amount > 0.0f) {
WWASSERT (Building != NULL);
// If the building has been damaged to the point of being destroyed
// then do not report the damaged event. A killed event will be sent
// later.
DefenseObjectClass* defense = Building->Get_Defense_Object();
if (defense && (defense->Get_Health() <= 0.0f)) {
return;
}
DamageableGameObj* damager = NULL;
if (killer) {
damager = killer->As_DamageableGameObj();
}
bool friendlyFire = (damager && (damager->Get_Player_Type() == Building->Get_Player_Type()));
// Notify the building
if (!friendlyFire) {
Building->On_Damaged();
}
}
}
////////////////////////////////////////////////////////////////
//
// Custom
//
////////////////////////////////////////////////////////////////
void
BuildingMonitorClass::Custom (GameObject *game_obj, int type, int param, GameObject *sender)
{
WWASSERT (Building != NULL);
//
// Notify the controller
//
if (type == CUSTOM_EVENT_BUILDING_POWER_CHANGED) {
//Building->On_Building_Damaged (game_obj->As_BuldingGameObj ());
}
return ;
}

View File

@@ -0,0 +1,108 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingmonitor.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/29/01 11:03a $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __BUILDINGMONITOR_H
#define __BUILDINGMONITOR_H
#include "gameobjobserver.h"
////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////
class BuildingGameObj;
////////////////////////////////////////////////////////////////
//
// BuildingMonitorClass
//
////////////////////////////////////////////////////////////////
class BuildingMonitorClass : public GameObjObserverClass
{
public:
////////////////////////////////////////////////////////////////////
// Public constructors/destructors
////////////////////////////////////////////////////////////////////
BuildingMonitorClass (void) :
Building (NULL) {}
~BuildingMonitorClass (void) {}
////////////////////////////////////////////////////////////////////
// Public methods
////////////////////////////////////////////////////////////////////
void Set_Building (BuildingGameObj *building) { Building = building; }
//
// From GameObjObeserverClass
//
const char * Get_Name (void) { return "BuildingMonitorClass"; }
void Killed (GameObject *game_obj, GameObject *killer);
void Damaged (GameObject *game_obj, GameObject *damager, float amount );
void Custom (GameObject *game_obj, int type, int param, GameObject *sender);
//
// Unused methods from the base class
//
void Attach (GameObject *) {}
void Detach (GameObject *) {}
void Created (GameObject *) {}
void Destroyed (GameObject *) {}
void Sound_Heard (GameObject *, const CombatSound &) {}
void Enemy_Seen (GameObject *, GameObject *) {}
void Action_Complete (GameObject *, int, ActionCompleteReason) {}
void Timer_Expired (GameObject *, int) {}
void Animation_Complete (GameObject *, const char *) {}
void Poked (GameObject *, GameObject *) {}
void Entered (GameObject *, GameObject *) {}
void Exited (GameObject *, GameObject *) {}
private:
////////////////////////////////////////////////////////////////////
// Private member data
////////////////////////////////////////////////////////////////////
BuildingGameObj * Building;
};
#endif //__BUILDINGMONITOR_H

View File

@@ -0,0 +1,154 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingstate.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 9/08/00 10:37a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "buildingstate.h"
#include "wwdebug.h"
/*
** Static data used by BuildingStateClass
*/
static int _EquivalentPowerOnState[] =
{
BuildingStateClass::HEALTH100_POWERON,
BuildingStateClass::HEALTH75_POWERON,
BuildingStateClass::HEALTH50_POWERON,
BuildingStateClass::HEALTH25_POWERON,
BuildingStateClass::DESTROYED_POWERON,
BuildingStateClass::HEALTH100_POWERON,
BuildingStateClass::HEALTH75_POWERON,
BuildingStateClass::HEALTH50_POWERON,
BuildingStateClass::HEALTH25_POWERON,
BuildingStateClass::DESTROYED_POWERON,
};
static int _EquivalentPowerOffState[] =
{
BuildingStateClass::HEALTH100_POWEROFF,
BuildingStateClass::HEALTH75_POWEROFF,
BuildingStateClass::HEALTH50_POWEROFF,
BuildingStateClass::HEALTH25_POWEROFF,
BuildingStateClass::DESTROYED_POWEROFF,
BuildingStateClass::HEALTH100_POWEROFF,
BuildingStateClass::HEALTH75_POWEROFF,
BuildingStateClass::HEALTH50_POWEROFF,
BuildingStateClass::HEALTH25_POWEROFF,
BuildingStateClass::DESTROYED_POWEROFF,
};
static const char * _StateNames[] =
{
"Building State: Health 100%, Power ON",
"Building State: Health 75%, Power ON",
"Building State: Health 50%, Power ON",
"Building State: Health 25%, Power ON",
"Building State: Destroyed, Power ON",
"Building State: Health 100%, Power OFF",
"Building State: Health 75%, Power OFF",
"Building State: Health 50%, Power OFF",
"Building State: Health 25%, Power OFF",
"Building State: Destroyed, Power OFF",
};
int BuildingStateClass::Get_Health_State(int building_state)
{
int state = building_state;
if (state >= HEALTH100_POWEROFF) {
state -= HEALTH100_POWEROFF;
}
return state;
}
int BuildingStateClass::Percentage_To_Health_State(float health)
{
if (health <= 0.0f) {
return HEALTH_0;
}
if (health <= 25.0f) {
return HEALTH_25;
}
if (health <= 50.0f) {
return HEALTH_50;
}
if (health <= 75.0f) {
return HEALTH_75;
}
return HEALTH_100;
}
bool BuildingStateClass::Is_Power_On(int building_state)
{
return (building_state < HEALTH100_POWEROFF);
}
int BuildingStateClass::Enable_Power(int input_state,bool onoff)
{
if (onoff) {
return _EquivalentPowerOnState[input_state];
} else {
return _EquivalentPowerOffState[input_state];
}
}
int BuildingStateClass::Compose_State(int health_state,bool power_onoff)
{
int state = health_state;
if (power_onoff == false) {
state += HEALTH100_POWEROFF;
}
return state;
}
const char * BuildingStateClass::Get_State_Name(int state)
{
WWASSERT(state >= 0);
WWASSERT(state < STATE_COUNT);
return _StateNames[state];
}

102
Code/Combat/buildingstate.h Normal file
View File

@@ -0,0 +1,102 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/buildingstate.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 2/07/01 6:00p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef BUILDINGSTATES_H
#define BUILDINGSTATES_H
#include "always.h"
/**
** BuildingStateClass
** This 'class' encapsulates some functions which work with the enumerated states that buildings can
** have. These enumerations are used by BuildingGameObj and BuildingAggregateClass...
**
** WARNING: Don't change these enumerations without checking the BuildingGameObj and BuildingAggregateClass
** to see what problems you might cause with save-load and their general operation...
*/
class BuildingStateClass
{
public:
enum
{
HEALTH100_POWERON = 0,
HEALTH75_POWERON,
HEALTH50_POWERON,
HEALTH25_POWERON,
DESTROYED_POWERON,
HEALTH100_POWEROFF,
HEALTH75_POWEROFF,
HEALTH50_POWEROFF,
HEALTH25_POWEROFF,
DESTROYED_POWEROFF,
STATE_COUNT
};
enum
{
HEALTH_100 = 0,
HEALTH_75,
HEALTH_50,
HEALTH_25,
HEALTH_0,
};
static int Get_Health_State(int building_state);
static int Percentage_To_Health_State(float health);
static bool Is_Power_On(int building_state);
static int Enable_Power(int input_state,bool onoff);
static int Compose_State(int health_state,bool power_onoff);
static const char * Get_State_Name(int state);
};
#endif // BUILDINGSTATES_H

1073
Code/Combat/bullet.cpp Normal file

File diff suppressed because it is too large Load Diff

71
Code/Combat/bullet.h Normal file
View File

@@ -0,0 +1,71 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/bullet.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 4/16/01 3:19p $*
* *
* $Revision:: 51 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef BULLET_H
#define BULLET_H
#ifndef ALWAYS_H
#include "always.h"
#endif
class ChunkSaveClass;
class ChunkLoadClass;
class AmmoDefinitionClass;
class Vector3;
class ArmedGameObj;
class DamageableGameObj;
/*
** BulletManager
*/
class BulletManager {
public:
static void Init( void );
static void Shutdown( void );
static void Update( void );
static bool Save( ChunkSaveClass &csave );
static bool Load( ChunkLoadClass &cload );
static void Create_Bullet( const AmmoDefinitionClass * def, const Vector3 & position,
const Vector3 & velocity, const ArmedGameObj * owner, float progress_time, const Vector3 & target, DamageableGameObj * target_object = NULL );
};
#endif // BULLET_H

906
Code/Combat/c4.cpp Normal file
View File

@@ -0,0 +1,906 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/c4.cpp $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 2/12/02 10:25a $*
* *
* $Revision:: 72 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "c4.h"
#include "debug.h"
#include "phys.h"
#include "combat.h"
#include "explosion.h"
#include "soldier.h"
#include "persistfactory.h"
#include "combatchunkid.h"
#include "weaponmanager.h"
#include "simpledefinitionfactory.h"
#include "wwhack.h"
#include "decophys.h"
#include "assets.h"
#include "gameobjmanager.h"
#include "wwaudio.h"
#include "wwprofile.h"
#include "projectile.h"
#include "wwphysids.h"
#include "buildingaggregate.h"
#include "rendobj.h"
#include "definitionmgr.h"
#include "apppackettypes.h"
#include "bitpackids.h"
#include "surfaceeffects.h"
#include "gametype.h"
/*
** C4GameObjDef
*/
DECLARE_FORCE_LINK( C4 )
SimplePersistFactoryClass<C4GameObjDef, CHUNKID_GAME_OBJECT_DEF_C4> _C4GameObjDefPersistFactory;
DECLARE_DEFINITION_FACTORY(C4GameObjDef, CLASSID_GAME_OBJECT_DEF_C4, "C4") _C4GameObjDefDefFactory;
C4GameObjDef::C4GameObjDef( void ) :
ThrowVelocity( 5 )
{
EDITABLE_PARAM (C4GameObjDef, ParameterClass::TYPE_FLOAT, ThrowVelocity);
}
uint32 C4GameObjDef::Get_Class_ID (void) const
{
return CLASSID_GAME_OBJECT_DEF_C4;
}
PersistClass * C4GameObjDef::Create( void ) const
{
C4GameObj * obj = new C4GameObj;
obj->Init( *this );
return obj;
}
enum {
CHUNKID_DEF_PARENT = 930991700,
CHUNKID_DEF_VARIABLES,
MICROCHUNKID_DEF_THROW_VELOCITY = 1,
};
bool C4GameObjDef::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_DEF_PARENT );
PhysicalGameObjDef::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_THROW_VELOCITY, ThrowVelocity );
csave.End_Chunk();
return true;
}
bool C4GameObjDef::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_DEF_PARENT:
PhysicalGameObjDef::Load( cload );
break;
case CHUNKID_DEF_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_THROW_VELOCITY, ThrowVelocity );
default:
Debug_Say(("Unhandled Micro Chunk:%d File:%s Line:%d\r\n",cload.Cur_Micro_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(( "Unrecognized SimpleDef chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
const PersistFactoryClass & C4GameObjDef::Get_Factory (void) const
{
return _C4GameObjDefPersistFactory;
}
/*
**
*/
SimplePersistFactoryClass<C4GameObj, CHUNKID_GAME_OBJECT_C4> _C4GameObjPersistFactory;
const PersistFactoryClass & C4GameObj::Get_Factory (void) const
{
return _C4GameObjPersistFactory;
}
/*
**
*/
C4GameObj::C4GameObj( void ) :
AmmoDefinition( NULL ),
Stuck( false ),
StuckMCT( false ),
StuckToObject( false ),
StuckBone( 0 ),
StuckStaticAnimObj(NULL),
OwnerBackup( NULL ),
Age( 0 )
{
Set_App_Packet_Type(APPPACKETTYPE_C4);
}
C4GameObj::~C4GameObj()
{
REF_PTR_RELEASE(StuckStaticAnimObj);
}
/*
**
*/
void C4GameObj::Init( void )
{
Init( Get_Definition() );
}
/*
**
*/
void C4GameObj::Init( const C4GameObjDef & definition )
{
SimpleGameObj::Init( definition );
Peek_Physical_Object()->Set_Collision_Group( TERRAIN_AND_BULLET_COLLISION_GROUP );
Peek_Physical_Object()->Set_Collision_Group( DEFAULT_COLLISION_GROUP );
}
const C4GameObjDef & C4GameObj::Get_Definition( void ) const
{
return (const C4GameObjDef &)BaseGameObj::Get_Definition();
}
void C4GameObj::Init_C4( const AmmoDefinitionClass * def, SoldierGameObj *owner, int detonation_mode, const Matrix3D & tm )
{
WWASSERT( AmmoDefinition == NULL );
AmmoDefinition = def;
if ( !def->ModelName.Is_Empty() ) {
Peek_Physical_Object()->Set_Model_By_Name( def->ModelName ) ;
}
Owner = owner;
DetonationMode = detonation_mode;
Set_Transform( tm );
Stuck = false;
StuckMCT = false;
StuckToObject = false;
Peek_Physical_Object()->Set_Collision_Group( DEFAULT_COLLISION_GROUP );
OwnerBackup = NULL;
if ( owner ) {
Set_Player_Type( owner->Get_Player_Type() );
OwnerBackup = owner->Get_Player_Data();
if ( CombatManager::I_Am_Server() && !IS_MISSION ) {
Maintain_C4_Limit( Get_Player_Type() );
}
}
int type = AmmoDefinition->AmmoType;
if ( type != AmmoDefinitionClass::AMMO_TYPE_C4_REMOTE ) {
// Setup Arming Timer
float time = def->C4TriggerTime1;
if ( detonation_mode == 2 ) time = def->C4TriggerTime2;
if ( detonation_mode == 3 ) time = def->C4TriggerTime3;
Timer = time;
}
float sound_id = def->C4TimingSound1ID;
if ( detonation_mode == 2 ) sound_id = def->C4TimingSound1ID;
if ( detonation_mode == 3 ) sound_id = def->C4TimingSound1ID;
if ( sound_id ) {
RefCountedGameObjReference *owner_ref = new RefCountedGameObjReference(Owner);
WWAudioClass::Get_Instance()->Create_Instant_Sound( sound_id, Get_Transform(), owner_ref);
REF_PTR_RELEASE(owner_ref);
}
ProjectileClass * po = Peek_Physical_Object()->As_ProjectileClass();
if ( po ) {
po->Set_Velocity( tm.Get_X_Vector() * Get_Definition().ThrowVelocity );
}
//
// "Dirty" the object for networking
//
Set_Object_Dirty_Bit( NetworkObjectClass::BIT_RARE, true );
}
CollisionReactionType C4GameObj::Collision_Occurred( const CollisionEventClass & event )
{
Debug_Say(( "C4 collision\n" ));
// if ( ( !Stuck ) && (CombatManager::I_Am_Server()) )
if (!Stuck)
{
// Figure out who/what/where we hit
PhysicalGameObj * other = NULL;
BuildingGameObj * building = NULL;
bool hit_projectile = event.OtherObj->As_ProjectileClass() != NULL;
if ( event.OtherObj->Get_Observer() != NULL ) {
other = ((CombatPhysObserverClass *)event.OtherObj->Get_Observer())->As_PhysicalGameObj();
building = ((CombatPhysObserverClass *)event.OtherObj->Get_Observer())->As_BuildingGameObj();
}
Restore_Owner();
// Ignore my owner and my owners vehicle
if ( other != NULL && Get_Owner() != NULL ) {
VehicleGameObj * vehicle = other->As_VehicleGameObj();
SoldierGameObj * soldier = Get_Owner()->As_SoldierGameObj();
if ( vehicle != NULL && vehicle == soldier->Get_Vehicle() ) {
return COLLISION_REACTION_NO_BOUNCE;
}
if ( other == Get_Owner() ) {
return COLLISION_REACTION_NO_BOUNCE;
}
// if ( !other->Is_Teammate( Get_Owner() ) )
{
Debug_Say(( "Sticking to game object %p (%p)\n", other, Get_Owner() ));
Stuck = true;
StuckToObject = true;
StuckObject = other;
StuckBone = 0;
RenderObjClass * parent_model = other->Peek_Model();
if ( parent_model ) {
StuckBone = parent_model->Get_Sub_Object_Bone_Index( event.CollidedRenderObj );
}
Vector3 my_pos;
Get_Position(&my_pos);
Matrix3D::Inverse_Transform_Vector( parent_model->Get_Bone_Transform( StuckBone ), my_pos, &StuckOffset );
Peek_Physical_Object()->Enable_User_Control( true );
if (CombatManager::I_Am_Server()) {
Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true);
}
return COLLISION_REACTION_STOP_MOTION;
}
} else if ( building != NULL ) {
// Stick to the building
Stuck = true;
StuckObject = (ScriptableGameObj*)building;
StuckMCT = false;
// Check for MCT collision
if (event.OtherObj->Get_Factory().Chunk_ID() == PHYSICS_CHUNKID_BUILDINGAGGREGATE) {
if (((BuildingAggregateClass *)event.OtherObj)->Is_MCT()) {
StuckMCT = true;
}
}
Peek_Physical_Object()->Enable_User_Control( true );
if (CombatManager::I_Am_Server()) {
Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true);
}
return COLLISION_REACTION_STOP_MOTION;
} else if ( other == NULL && !hit_projectile ) {
// if this is a static anim, then try to stick to it
if (event.OtherObj->As_StaticAnimPhysClass() != NULL) {
Debug_Say(( "Sticking to static anim object %p (%p)\n", event.OtherObj ));
REF_PTR_SET(StuckStaticAnimObj,(StaticAnimPhysClass *)event.OtherObj);
StuckBone = 0;
if ( StuckStaticAnimObj->Peek_Model() ) {
StuckBone = StuckStaticAnimObj->Peek_Model()->Get_Sub_Object_Bone_Index( event.CollidedRenderObj );
Vector3 my_pos;
Get_Position(&my_pos);
Matrix3D::Inverse_Transform_Vector( StuckStaticAnimObj->Peek_Model()->Get_Bone_Transform( StuckBone ), my_pos, &StuckOffset );
}
}
// If we hit permiable, pass through
if ( event.CollisionResult != NULL &&
SurfaceEffectsManager::Is_Surface_Permeable( event.CollisionResult->SurfaceType ) ) {
Debug_Say(( "C4 passes through permeable\n" ));
return COLLISION_REACTION_NO_BOUNCE;
}
// We are hitting a static terrain, just stick
Debug_Say(( "Sticking to terrain\n" ));
Peek_Physical_Object()->Enable_User_Control( true );
Stuck = true;
if (CombatManager::I_Am_Server()) {
Set_Object_Dirty_Bit(NetworkObjectClass::BIT_RARE, true);
}
return COLLISION_REACTION_STOP_MOTION;
}
}
return COLLISION_REACTION_NO_BOUNCE;
}
/*
** C4GameObj Save and Load
*/
enum {
CHUNKID_PARENT = 922991750,
CHUNKID_VARIABLES,
XXXCHUNKID_C4_TIMER,
CHUNKID_OWNER,
CHUNKID_STUCK_OBJECT,
XXXXMICROCHUNKID_PARAMS_NAME = 1,
XXXXXMICROCHUNKID_PARAMS_NAME,
MICROCHUNKID_AMMO_DEF_ID,
MICROCHUNKID_DETONATION_MODE,
MICROCHUNKID_TIMER,
MICROCHUNKID_STUCK,
MICROCHUNKID_STUCK_OFFSET,
MICROCHUNKID_STUCK_MCT,
MICROCHUNKID_STUCK_BONE,
MICROCHUNKID_STUCK_STATIC_ANIM_OBJ_ID,
MICROCHUNKID_STUCK_TO_OBJECT,
MICROCHUNKID_AGE,
};
bool C4GameObj::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_PARENT );
SimpleGameObj::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_VARIABLES );
int ammo_def_id = AmmoDefinition->Get_ID();
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_AMMO_DEF_ID, ammo_def_id );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DETONATION_MODE, DetonationMode );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TIMER, Timer );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK, Stuck );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK_OFFSET, StuckOffset );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK_MCT, StuckMCT );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK_BONE, StuckBone );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK_TO_OBJECT, StuckToObject );
if (StuckStaticAnimObj != NULL) {
uint32 id = StuckStaticAnimObj->Get_ID();
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_STUCK_STATIC_ANIM_OBJ_ID, id);
}
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_AGE, Age );
csave.End_Chunk();
if ( Owner != NULL ) {
csave.Begin_Chunk( CHUNKID_OWNER );
Owner.Save( csave );
csave.End_Chunk();
}
if ( StuckObject != NULL ) {
csave.Begin_Chunk( CHUNKID_STUCK_OBJECT );
StuckObject.Save( csave );
csave.End_Chunk();
}
return true;
}
bool C4GameObj::Load( ChunkLoadClass &cload )
{
REF_PTR_RELEASE(StuckStaticAnimObj);
uint32 static_anim_obj_id = 0xFFFFFFFF;
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_PARENT:
SimpleGameObj::Load( cload );
break;
case CHUNKID_VARIABLES:
{
int ammo_def_id = 0;
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_AMMO_DEF_ID, ammo_def_id );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DETONATION_MODE, DetonationMode );
READ_MICRO_CHUNK( cload, MICROCHUNKID_TIMER, Timer );
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK, Stuck );
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK_OFFSET, StuckOffset );
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK_MCT, StuckMCT );
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK_BONE, StuckBone );
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK_STATIC_ANIM_OBJ_ID, static_anim_obj_id);
READ_MICRO_CHUNK( cload, MICROCHUNKID_STUCK_TO_OBJECT, StuckToObject );
READ_MICRO_CHUNK( cload, MICROCHUNKID_AGE, Age );
default:
Debug_Say(( "Unrecognized C4 Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
WWASSERT( AmmoDefinition == NULL );
AmmoDefinition = WeaponManager::Find_Ammo_Definition( ammo_def_id );
WWASSERT( AmmoDefinition != NULL );
break;
}
case CHUNKID_OWNER:
Owner.Load( cload );
break;
case CHUNKID_STUCK_OBJECT:
StuckObject.Load( cload );
break;
default:
Debug_Say(( "Unrecognized C4 chunkID\n" ));
break;
}
cload.Close_Chunk();
}
if (static_anim_obj_id != 0xFFFFFFFF) {
StaticPhysClass * pobj = PhysicsSceneClass::Get_Instance()->Get_Static_Object_By_ID(static_anim_obj_id);
if (pobj && (pobj->As_StaticAnimPhysClass() != NULL)) {
REF_PTR_SET(StuckStaticAnimObj,(StaticAnimPhysClass *)pobj);
}
REF_PTR_RELEASE(pobj);
}
return true;
}
void C4GameObj::Think( void )
{
SimpleGameObj::Think();
WWPROFILE( "C4 Think" );
if ( !CombatManager::I_Am_Server() ) {
return;
}
Age += TimeManager::Get_Frame_Seconds();
int type = AmmoDefinition->AmmoType;
WWASSERT( type >= AmmoDefinitionClass::AMMO_TYPE_C4_REMOTE );
WWASSERT( type <= AmmoDefinitionClass::AMMO_TYPE_C4_PROXIMITY );
Restore_Owner();
if ( type == AmmoDefinitionClass::AMMO_TYPE_C4_REMOTE ) {
if ( CombatManager::I_Am_Server() ) {
// Check for owner to detonate
SoldierGameObj * owner = Get_Owner();
if ( owner == NULL ) {
Defuse();
} else if ( owner->Detonate_C4() ) {
Detonate();
}
} else {
Set_Delete_Pending();
}
}
if ( type == AmmoDefinitionClass::AMMO_TYPE_C4_TIMED ) {
// Check for time's up
Timer -= TimeManager::Get_Frame_Seconds();
if ( Timer <= 0 ) {
Detonate();
}
}
if ( type == AmmoDefinitionClass::AMMO_TYPE_C4_PROXIMITY ) {
Timer -= TimeManager::Get_Frame_Seconds();
if ( Timer <= 0 ) {
// Reset Timer
// Timer += 1; // Check every second
Timer += 0.25; // Check every 1/4 second
// Check for smart objs in proximity
float trigger_range = AmmoDefinition->C4TriggerRange1;
if ( DetonationMode == 2 ) trigger_range = AmmoDefinition->C4TriggerRange2;
if ( DetonationMode == 3 ) trigger_range = AmmoDefinition->C4TriggerRange3;
Vector3 c4_pos;
Get_Position( &c4_pos );
SLNode<SmartGameObj> * smart_objnode;
for (smart_objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head(); smart_objnode; smart_objnode = smart_objnode->Next()) {
SmartGameObj * obj = smart_objnode->Data();
if ( obj && Is_Enemy( obj ) ) {
Vector3 obj_pos;
obj->Get_Position( &obj_pos );
float range = (obj_pos - c4_pos).Length();
if ( range <= trigger_range ) {
Detonate();
}
}
}
}
}
}
void C4GameObj::Post_Think( void )
{
SimpleGameObj::Post_Think();
WWPROFILE( "C4 Post_Think" );
// Follow your stuck object
if ( Stuck ) {
if ( StuckObject.Get_Ptr() != NULL ) {
PhysicalGameObj * obj = StuckObject.Get_Ptr()->As_PhysicalGameObj();
if ( obj ) {
RenderObjClass * parent_model = obj->Peek_Model();
Vector3 pos;
if ( parent_model ) {
pos = parent_model->Get_Bone_Transform( StuckBone ) * StuckOffset;
} else {
pos = obj->Get_Transform() * StuckOffset;
}
Set_Position( pos );
if (obj->As_SoldierGameObj()) {
bool hide = (obj->As_SoldierGameObj()->Get_Vehicle() != NULL);
if (Peek_Model()) {
Peek_Model()->Set_Hidden(hide);
}
}
}
} else if ( StuckStaticAnimObj != NULL) {
Vector3 pos;
pos = StuckStaticAnimObj->Peek_Model()->Get_Bone_Transform( StuckBone ) * StuckOffset;
Set_Position(pos);
} else {
// Delete without exploding if my object is gone
if ( StuckToObject ) {
Set_Delete_Pending();
}
}
}
}
void C4GameObj::Detonate( void )
{
if ( CombatManager::I_Am_Server() ) {
Restore_Owner();
if ( AmmoDefinition && AmmoDefinition->ExplosionDefID ) {
int owner_id = 0;
if ( Get_Owner() ) {
owner_id = Get_Owner()->Get_ID();
}
DamageableGameObj * force_victim = NULL;
if ( Stuck && StuckToObject ) {
force_victim = (DamageableGameObj *)StuckObject.Get_Ptr();
}
ExplosionManager::Server_Explode( AmmoDefinition->ExplosionDefID, Get_Transform().Get_Translation(), owner_id, force_victim );
}
// If I am stuck to a building, apply damage to that building
if ( Stuck ) {
if ( StuckObject.Get_Ptr() != NULL ) {
BuildingGameObj * building = StuckObject.Get_Ptr()->As_BuildingGameObj();
if ( building ) {
ExplosionManager::Explosion_Damage_Building( AmmoDefinition->ExplosionDefID, building, StuckMCT, Get_Owner() );
}
}
}
}
Set_Delete_Pending();
}
void C4GameObj::Completely_Damaged( const OffenseObjectClass & damager )
{
Defuse();
}
/*
**
*/
void C4GameObj::Get_Information( StringClass & string )
{
SimpleGameObj::Get_Information( string );
int type = AmmoDefinition->AmmoType;
if ( type == AmmoDefinitionClass::AMMO_TYPE_C4_TIMED ) {
StringClass temp(0,true);
temp.Format( "Timer: %1.1f\n", Timer );
string += temp;
}
}
/*
**
*/
void C4GameObj::Export_Rare( BitStreamClass &packet )
{
SimpleGameObj::Export_Rare( packet );
int ammo_def_id = 0;
if ( AmmoDefinition != NULL ) {
ammo_def_id = AmmoDefinition->Get_ID();
}
packet.Add( ammo_def_id );
int owner_id = 0;
if (Get_Owner()) {
owner_id = Get_Owner()->Get_ID();
}
packet.Add(owner_id);
Vector3 pos(0,0,0);
Vector3 vel(0,0,0);
ProjectileClass * po = Peek_Physical_Object()->As_ProjectileClass();
if ( po ) {
po->Get_Velocity(&vel);
po->Get_Position(&pos);
}
packet.Add(vel.X, BITPACK_VEHICLE_VELOCITY);
packet.Add(vel.Y, BITPACK_VEHICLE_VELOCITY);
packet.Add(vel.Z, BITPACK_VEHICLE_VELOCITY);
//
// Synchronize the stuck state of C4
//
packet.Add(Stuck);
if (Stuck) {
packet.Add(pos.X, BITPACK_WORLD_POSITION_X);
packet.Add(pos.Y, BITPACK_WORLD_POSITION_Y);
packet.Add(pos.Z, BITPACK_WORLD_POSITION_Z);
packet.Add(StuckMCT);
packet.Add(StuckToObject);
int stuck_object_id=0;
if (StuckObject.Get_Ptr()) {
stuck_object_id = StuckObject.Get_Ptr()->Get_ID();
}
packet.Add(stuck_object_id);
if (StuckToObject) {
packet.Add(StuckOffset.X, BITPACK_VEHICLE_VELOCITY); // offset, using velocity packing...
packet.Add(StuckOffset.Y, BITPACK_VEHICLE_VELOCITY);
packet.Add(StuckOffset.Z, BITPACK_VEHICLE_VELOCITY);
packet.Add(StuckBone);
}
bool stuck_static_anim = (StuckStaticAnimObj != NULL);
packet.Add(stuck_static_anim);
if (stuck_static_anim) {
packet.Add(StuckStaticAnimObj->Get_ID());
}
}
}
void C4GameObj::Import_Rare( BitStreamClass &packet )
{
SimpleGameObj::Import_Rare( packet );
int ammo_def_id = packet.Get( ammo_def_id );
if ( ammo_def_id != 0 ) {
AmmoDefinition = (AmmoDefinitionClass *)DefinitionMgrClass::Find_Definition( ammo_def_id );
if ( !AmmoDefinition->ModelName.Is_Empty() ) {
Peek_Physical_Object()->Set_Model_By_Name( AmmoDefinition->ModelName ) ;
}
}
int owner_id = packet.Get(owner_id);
if (owner_id != 0) {
Owner = GameObjManager::Find_SmartGameObj(owner_id);
} else {
Owner = NULL;
}
Vector3 vel;
packet.Get(vel.X, BITPACK_VEHICLE_VELOCITY);
packet.Get(vel.Y, BITPACK_VEHICLE_VELOCITY);
packet.Get(vel.Z, BITPACK_VEHICLE_VELOCITY);
ProjectileClass * po = Peek_Physical_Object()->As_ProjectileClass();
if ( po ) {
po->Set_Velocity(vel);
}
//
// Synchronize the stuck state of C4
//
Stuck = packet.Get(Stuck);
if (Stuck) {
Peek_Physical_Object()->Enable_User_Control( true );
// Update the position
Vector3 pos;
packet.Get(pos.X, BITPACK_WORLD_POSITION_X);
packet.Get(pos.Y, BITPACK_WORLD_POSITION_Y);
packet.Get(pos.Z, BITPACK_WORLD_POSITION_Z);
ProjectileClass * po = Peek_Physical_Object()->As_ProjectileClass();
if ( po ) {
Vector3 local_pos;
po->Get_Position(&local_pos);
if ((local_pos - pos).Length2() > 0.5f * 0.5f) {
po->Set_Position(pos);
}
}
WWDEBUG_SAY(("C4 %d is now STUCK, pos= %f, %f, %f",(int)this, pos.X,pos.Y,pos.Z));
packet.Get(StuckMCT);
packet.Get(StuckToObject);
int stuck_object_id;
packet.Get(stuck_object_id);
StuckObject = GameObjManager::Find_ScriptableGameObj(stuck_object_id);
if (StuckToObject) {
packet.Get(StuckOffset.X, BITPACK_VEHICLE_VELOCITY); // offset, using velocity packing...
packet.Get(StuckOffset.Y, BITPACK_VEHICLE_VELOCITY);
packet.Get(StuckOffset.Z, BITPACK_VEHICLE_VELOCITY);
packet.Get(StuckBone);
}
bool stuck_static_anim;
packet.Get(stuck_static_anim);
if (stuck_static_anim) {
uint32 static_anim_obj_id = 0;
packet.Get(static_anim_obj_id);
if (static_anim_obj_id != 0xFFFFFFFF) {
StaticPhysClass * pobj = PhysicsSceneClass::Get_Instance()->Get_Static_Object_By_ID(static_anim_obj_id);
if (pobj && (pobj->As_StaticAnimPhysClass() != NULL)) {
REF_PTR_SET(StuckStaticAnimObj,(StaticAnimPhysClass *)pobj);
}
REF_PTR_RELEASE(pobj);
}
}
}
}
void C4GameObj::Defuse( void )
{
if ( CombatManager::I_Am_Server() ) {
Restore_Owner();
const AmmoDefinitionClass * disarmed_ammo = WeaponManager::Find_Ammo_Definition( "KilledC4" );
if ( disarmed_ammo && disarmed_ammo->ExplosionDefID ) {
int owner_id = 0;
if ( Get_Owner() ) {
owner_id = Get_Owner()->Get_ID();
}
ExplosionManager::Server_Explode( disarmed_ammo->ExplosionDefID, Get_Transform().Get_Translation(), owner_id );
}
}
Set_Delete_Pending();
}
void C4GameObj::Restore_Owner( void )
{
if ( Get_Owner() == NULL && OwnerBackup != NULL &&
AmmoDefinition && (int)AmmoDefinition->AmmoType != (int)AmmoDefinitionClass::AMMO_TYPE_C4_REMOTE ) {
// Try and find a smart game obj with the same playerdata
SLNode<SmartGameObj> * smart_objnode;
for (smart_objnode = GameObjManager::Get_Smart_Game_Obj_List()->Head(); smart_objnode; smart_objnode = smart_objnode->Next()) {
SmartGameObj * obj = smart_objnode->Data();
if ( obj->Get_Player_Data() == OwnerBackup ) {
Owner = obj;
Debug_Say(( "Found C4 owner\n" ));
}
}
if ( Get_Owner() == NULL ) {
OwnerBackup = NULL;
Defuse();
Debug_Say(( "Didn't find C4 owner\n" ));
}
}
}
/*
**
*/
#define C4_LIMIT 30
void C4GameObj::Maintain_C4_Limit( int player_type )
{
if ( !CombatManager::I_Am_Server() || IS_MISSION ) {
return;
}
SLNode<BaseGameObj> *objnode;
C4GameObj * oldest_c4 = NULL;
int count = 0;
for ( objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
PhysicalGameObj * phys = objnode->Data()->As_PhysicalGameObj();
if ( phys ) {
C4GameObj * c4 = phys->As_C4GameObj();
if ( c4 &&
c4->Get_Player_Type() == player_type &&
c4->AmmoDefinition &&
(int)c4->AmmoDefinition->AmmoType != (int)AmmoDefinitionClass::AMMO_TYPE_C4_TIMED ) {
count++;
if ( (oldest_c4 == NULL) || (c4->Age > oldest_c4->Age) ) {
oldest_c4 = c4;
}
}
}
}
if ( count > C4_LIMIT && oldest_c4 != NULL ) {
oldest_c4->Defuse();
}
}

145
Code/Combat/c4.h Normal file
View File

@@ -0,0 +1,145 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/c4.h $*
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 1/08/02 3:05p $*
* *
* $Revision:: 33 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef C4_H
#define C4_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef SIMPLEGAMEOBJ_H
#include "simplegameobj.h"
#endif
#ifndef TIMEMGR_H
#include "timemgr.h"
#endif
class AmmoDefinitionClass;
class StaticAnimPhysClass;
/*
** C4GameObjDef - Defintion class for a C4GameObj
*/
class C4GameObjDef : public SimpleGameObjDef
{
public:
C4GameObjDef( void );
virtual uint32 Get_Class_ID( void ) const;
virtual PersistClass * Create( void ) const ;
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
DECLARE_EDITABLE( C4GameObjDef, SimpleGameObjDef );
float ThrowVelocity;
protected:
friend class C4GameObj;
};
/*
**
*/
class C4GameObj : public SimpleGameObj {
public:
C4GameObj();
virtual ~C4GameObj();
// Definitions
virtual void Init( void );
void Init( const C4GameObjDef & definition );
const C4GameObjDef & Get_Definition( void ) const ;
// Save / Load / Construction Factory
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
virtual C4GameObj * As_C4GameObj( void ) { return this; }
void Init_C4( const AmmoDefinitionClass * def, SoldierGameObj *owner, int detonation_mode, const Matrix3D & tm );
virtual CollisionReactionType Collision_Occurred( const CollisionEventClass & event );
virtual void Think();
virtual void Post_Think();
virtual void Get_Information( StringClass & string );
virtual void Export_Rare( BitStreamClass &packet );
virtual void Import_Rare( BitStreamClass &packet );
ScriptableGameObj * Get_Stuck_Object(void) { return StuckObject.Get_Ptr(); }
virtual void Completely_Damaged( const OffenseObjectClass & damager );
SoldierGameObj *Get_Owner( void ) const { return (SoldierGameObj *)Owner.Get_Ptr(); }
void Defuse( void );
static void Maintain_C4_Limit( int player_type );
private:
float Timer;
GameObjReference Owner;
void * OwnerBackup;
const AmmoDefinitionClass * AmmoDefinition;
int DetonationMode;
bool Stuck;
bool StuckToObject;
GameObjReference StuckObject;
Vector3 StuckOffset;
int StuckBone;
StaticAnimPhysClass * StuckStaticAnimObj;
bool StuckMCT;
float Age;
void Detonate( void );
void Restore_Owner( void );
};
#endif // C4_H

1716
Code/Combat/ccamera.cpp Normal file

File diff suppressed because it is too large Load Diff

201
Code/Combat/ccamera.h Normal file
View File

@@ -0,0 +1,201 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/ccamera.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 12/10/01 2:08p $*
* *
* $Revision:: 62 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CCAMERA_H
#define CCAMERA_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef CAMERA_H
#include "camera.h"
#endif
#ifndef WWSTRING_H
#include "wwstring.h"
#endif
class CCameraProfileClass;
class Listener3DClass;
/*
** CCameraClass (Commando Camera Class)
*/
class CCameraClass : public CameraClass
{
public:
// Constructor & Destructor
CCameraClass();
virtual ~CCameraClass();
// Get all the profiles loaded
static void Init( void );
static void Shutdown( void );
// Save and Load
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
// Function to update the camera's parameters each frame.
virtual void Update();
bool Is_In_Cinematic( void ) { return HostModel != NULL; }
bool Is_Valid( void ) { return IsValid; }
const Vector2 &Get_Camera_Target_2D_Offset() { return CameraTarget2DOffset; }
void Set_Anchor_Position( Vector3 pos );
void Force_Look( const Vector3 & target );
// Profile access
void Use_Profile( const char * name );
void Use_Default_Profile( void );
void Set_Profile_Height( float height );
void Set_Profile_Distance( float distance );
float Get_Profile_Zoom( void );
void Force_Heading( float heading ) { Heading = heading; }
float Get_Heading( void ) { return Heading; }
void Set_Tilt( float tilt ) { Tilt = tilt; }
float Get_Tilt( void ) { return Tilt; }
void Set_Lerp_Time( float time );
bool Is_Lerping( void ) { return LerpTimeTotal != 0; }
void Set_Host_Model( RenderObjClass * host );
bool Is_Using_Host_Model( void ) { return (HostModel != NULL); }
void Enable_2D_Targeting( bool on_off ) { Enable2DTargeting = on_off; }
bool Is_2D_Targeting( void ) { return Enable2DTargeting; }
void Enable_Weapon_Help( bool on_off ) { EnableWeaponHelp = on_off; }
bool Is_Weapon_Help_Enabled( void ) { return EnableWeaponHelp; }
// Sniper Mode
bool Draw_Sniper( void );
void Cinematic_Sniper_Control( bool enabled, float zoom );
void Set_Is_Star_Sniping( bool yes );
bool Is_Star_Sniping( void ) { return IsStarSniping; }
float Get_Sniper_Zoom( void ) { return SniperZoom; }
void Set_Sniper_Distance( float dist );
float Get_Sniper_Distance( void ) { return SniperDistance; }
Vector3 Get_First_Person_Offset_Tweak( void );
void Reset_First_Person_Offset_Tweak( void );
// Snap Shot Mode
void Set_Snap_Shot_Mode( bool mode ) { SnapShotMode = mode ? SNAPSHOT_ON : SNAPSHOT_OFF; }
bool Is_Snap_Shot_Mode( void ) { return SnapShotMode == SNAPSHOT_ON; }
protected:
// Camera Host Model
RenderObjClass * HostModel;
// Camera Anchor Position
Vector3 AnchorPosition;
bool IsValid;
// Current orientation of the camera
float Tilt;
float Heading;
float DistanceFraction;
bool Enable2DTargeting;
float LagPersistTimer;
bool DisableLag;
// WeaponHelp
bool EnableWeaponHelp;
float WeaponHelpTimer;
int WeaponHelpTargetID; // Should probably be changed to a ObjRef
Vector3 StarTargetingPosition;
Vector2 CameraTarget2DOffset;
// Linear Interpolation
float LerpTimeTotal;
float LerpTimeRemaining;
Vector3 LastAnchorPosition;
float LastHeading;
// Parameter profile
CCameraProfileClass * CurrentProfile;
CCameraProfileClass * LastProfile;
CCameraProfileClass * DefaultProfile;
StringClass CurrentProfileName;
StringClass LastProfileName;
StringClass DefaultProfileName;
float NearClipPlane;
float FarClipPlane;
// Sniper Mode
bool IsStarSniping;
bool WasStarSniping;
float SniperZoom;
float SniperDistance;
Listener3DClass * SniperListener;
bool CinematicSnipingEnabled;
float CinematicSnipingDesiredZoom;
enum {
SNAPSHOT_OFF,
SNAPSHOT_ON,
SNAPSHOT_PROGRESS,
};
int SnapShotMode;
/*
**
*/
Vector3 Get_Camera_Pos( const Vector3 & offset,
float distance, Vector3 * intermediate_pos );
void Use_Host_Model( void );
void Handle_Input();
// Targeting
bool Determine_Targeting_Position( void );
void Apply_Weapon_Help( void );
void Update_Sniper_Listener_Pos( void );
void Handle_Snap_Shot_Mode( void );
};
#endif // CCAMERA_H

View File

@@ -0,0 +1,662 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/characterclasssettings.cpp $*
* *
* $Author:: Patrick $*
* *
* $Modtime:: 3/21/01 9:38a $*
* *
* $Revision:: 4 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "characterclasssettings.h"
#include "combatchunkid.h"
#include "wwhack.h"
#include "persistfactory.h"
#include "definitionfactory.h"
#include "simpledefinitionfactory.h"
#include "debug.h"
#include "objectives.h"
DECLARE_FORCE_LINK (CharClassSettings)
///////////////////////////////////////////////////////////////////////////////////////////
// Static member initialization
///////////////////////////////////////////////////////////////////////////////////////////
CharacterClassSettingsDefClass * CharacterClassSettingsDefClass::GlobalInstance = NULL;
///////////////////////////////////////////////////////////////////////////////////////////
// Factories
///////////////////////////////////////////////////////////////////////////////////////////
SimplePersistFactoryClass<CharacterClassSettingsDefClass, CHUNKID_GLOBAL_SETTINGS_DEF_CHAR_CLASS> _CharClassDefPersistFactory;
DECLARE_DEFINITION_FACTORY(CharacterClassSettingsDefClass, CLASSID_GLOBAL_SETTINGS_DEF_CHAR_CLASS, "Character Classes") _CharClassDefDefFactory;
///////////////////////////////////////////////////////////////////////////////////////////
// Constants
///////////////////////////////////////////////////////////////////////////////////////////
static const char * CHAR_CLASS_NAMES[CharacterClassSettingsDefClass::CLASS_COUNT] =
{
"Minigunner",
"Rocket Soldier",
"Grenadier",
"Engineer",
"Flame Thrower",
"Mutant"
};
static const char * CHAR_RANK_NAMES[CharacterClassSettingsDefClass::RANK_COUNT] =
{
"Enlisted",
"Officer",
"Special-Forces",
"Boss"
};
static const char * CHAR_TEAM_NAMES[CharacterClassSettingsDefClass::TEAM_COUNT] =
{
"GDI",
"NOD",
};
///////////////////////////////////////////////////////////////////////////////////////////
// Save/load constants
///////////////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_PARENT = 0x12021027,
CHUNKID_VARIABLES,
VARID_COST_GDI_MINIGUNNER_ENLISTED = 1,
VARID_COST_GDI_MINIGUNNER_OFFICER,
VARID_COST_GDI_MINIGUNNER_SPECIAL_FORCES,
VARID_COST_GDI_MINIGUNNER_BOSS,
VARID_COST_GDI_ROCKET_SOLDIER_ENLISTED,
VARID_COST_GDI_ROCKET_SOLDIER_OFFICER,
VARID_COST_GDI_ROCKET_SOLDIER_SPECIAL_FORCES,
VARID_COST_GDI_ROCKET_SOLDIER_BOSS,
VARID_COST_GDI_GRENADIER_ENLISTED,
VARID_COST_GDI_GRENADIER_OFFICER,
VARID_COST_GDI_GRENADIER_SPECIAL_FORCES,
VARID_COST_GDI_GRENADIER_BOSS,
VARID_COST_GDI_ENGINEER_ENLISTED,
VARID_COST_GDI_ENGINEER_OFFICER,
VARID_COST_GDI_ENGINEER_SPECIAL_FORCES,
VARID_COST_GDI_ENGINEER_BOSS,
VARID_COST_GDI_FLAME_THROWER_ENLISTED,
VARID_COST_GDI_FLAME_THROWER_OFFICER,
VARID_COST_GDI_FLAME_THROWER_SPECIAL_FORCES,
VARID_COST_GDI_FLAME_THROWER_BOSS,
VARID_COST_GDI_MUTANT_ENLISTED,
VARID_COST_GDI_MUTANT_OFFICER,
VARID_COST_GDI_MUTANT_SPECIAL_FORCES,
VARID_COST_GDI_MUTANT_BOSS,
VARID_COST_NOD_MINIGUNNER_ENLISTED,
VARID_COST_NOD_MINIGUNNER_OFFICER,
VARID_COST_NOD_MINIGUNNER_SPECIAL_FORCES,
VARID_COST_NOD_MINIGUNNER_BOSS,
VARID_COST_NOD_ROCKET_SOLDIER_ENLISTED,
VARID_COST_NOD_ROCKET_SOLDIER_OFFICER,
VARID_COST_NOD_ROCKET_SOLDIER_SPECIAL_FORCES,
VARID_COST_NOD_ROCKET_SOLDIER_BOSS,
VARID_COST_NOD_GRENADIER_ENLISTED,
VARID_COST_NOD_GRENADIER_OFFICER,
VARID_COST_NOD_GRENADIER_SPECIAL_FORCES,
VARID_COST_NOD_GRENADIER_BOSS,
VARID_COST_NOD_ENGINEER_ENLISTED,
VARID_COST_NOD_ENGINEER_OFFICER,
VARID_COST_NOD_ENGINEER_SPECIAL_FORCES,
VARID_COST_NOD_ENGINEER_BOSS,
VARID_COST_NOD_FLAME_THROWER_ENLISTED,
VARID_COST_NOD_FLAME_THROWER_OFFICER,
VARID_COST_NOD_FLAME_THROWER_SPECIAL_FORCES,
VARID_COST_NOD_FLAME_THROWER_BOSS,
VARID_COST_NOD_MUTANT_ENLISTED,
VARID_COST_NOD_MUTANT_OFFICER,
VARID_COST_NOD_MUTANT_SPECIAL_FORCES,
VARID_COST_NOD_MUTANT_BOSS,
VARID_DEFID_GDI_MINIGUNNER_ENLISTED,
VARID_DEFID_GDI_MINIGUNNER_OFFICER,
VARID_DEFID_GDI_MINIGUNNER_SPECIAL_FORCES,
VARID_DEFID_GDI_MINIGUNNER_BOSS,
VARID_DEFID_GDI_ROCKET_SOLDIER_ENLISTED,
VARID_DEFID_GDI_ROCKET_SOLDIER_OFFICER,
VARID_DEFID_GDI_ROCKET_SOLDIER_SPECIAL_FORCES,
VARID_DEFID_GDI_ROCKET_SOLDIER_BOSS,
VARID_DEFID_GDI_GRENADIER_ENLISTED,
VARID_DEFID_GDI_GRENADIER_OFFICER,
VARID_DEFID_GDI_GRENADIER_SPECIAL_FORCES,
VARID_DEFID_GDI_GRENADIER_BOSS,
VARID_DEFID_GDI_ENGINEER_ENLISTED,
VARID_DEFID_GDI_ENGINEER_OFFICER,
VARID_DEFID_GDI_ENGINEER_SPECIAL_FORCES,
VARID_DEFID_GDI_ENGINEER_BOSS,
VARID_DEFID_GDI_FLAME_THROWER_ENLISTED,
VARID_DEFID_GDI_FLAME_THROWER_OFFICER,
VARID_DEFID_GDI_FLAME_THROWER_SPECIAL_FORCES,
VARID_DEFID_GDI_FLAME_THROWER_BOSS,
VARID_DEFID_GDI_MUTANT_ENLISTED,
VARID_DEFID_GDI_MUTANT_OFFICER,
VARID_DEFID_GDI_MUTANT_SPECIAL_FORCES,
VARID_DEFID_GDI_MUTANT_BOSS,
VARID_DEFID_NOD_MINIGUNNER_ENLISTED,
VARID_DEFID_NOD_MINIGUNNER_OFFICER,
VARID_DEFID_NOD_MINIGUNNER_SPECIAL_FORCES,
VARID_DEFID_NOD_MINIGUNNER_BOSS,
VARID_DEFID_NOD_ROCKET_SOLDIER_ENLISTED,
VARID_DEFID_NOD_ROCKET_SOLDIER_OFFICER,
VARID_DEFID_NOD_ROCKET_SOLDIER_SPECIAL_FORCES,
VARID_DEFID_NOD_ROCKET_SOLDIER_BOSS,
VARID_DEFID_NOD_GRENADIER_ENLISTED,
VARID_DEFID_NOD_GRENADIER_OFFICER,
VARID_DEFID_NOD_GRENADIER_SPECIAL_FORCES,
VARID_DEFID_NOD_GRENADIER_BOSS,
VARID_DEFID_NOD_ENGINEER_ENLISTED,
VARID_DEFID_NOD_ENGINEER_OFFICER,
VARID_DEFID_NOD_ENGINEER_SPECIAL_FORCES,
VARID_DEFID_NOD_ENGINEER_BOSS,
VARID_DEFID_NOD_FLAME_THROWER_ENLISTED,
VARID_DEFID_NOD_FLAME_THROWER_OFFICER,
VARID_DEFID_NOD_FLAME_THROWER_SPECIAL_FORCES,
VARID_DEFID_NOD_FLAME_THROWER_BOSS,
VARID_DEFID_NOD_MUTANT_ENLISTED,
VARID_DEFID_NOD_MUTANT_OFFICER,
VARID_DEFID_NOD_MUTANT_SPECIAL_FORCES,
VARID_DEFID_NOD_MUTANT_BOSS,
};
///////////////////////////////////////////////////////////////////////////////////////////
//
// CharacterClassSettingsDefClass
//
///////////////////////////////////////////////////////////////////////////////////////////
CharacterClassSettingsDefClass::CharacterClassSettingsDefClass (void)
{
//
// Initialize the cost and definition tables
//
::memset (CostTable, 0, sizeof (CostTable));
::memset (DefinitionTable, 0, sizeof (DefinitionTable));
//
// Configure the editable system
//
for (int class_index = 0; class_index < CLASS_COUNT; class_index ++) {
for (int team_index = 0; team_index < TEAM_COUNT; team_index ++) {
//
// Add a separator for this character class
//
StringClass name;
name.Format ("Class %s (%s)", CHAR_CLASS_NAMES[class_index], CHAR_TEAM_NAMES[team_index]);
PARAM_SEPARATOR (CharacterClassSettingsDefClass, (const char *)name);
//
// Add a pair of parameters for each rank
//
for (int rank_index = 0; rank_index < RANK_COUNT; rank_index ++) {
name.Format ("%s Cost", CHAR_RANK_NAMES[rank_index]);
NAMED_EDITABLE_PARAM (CharacterClassSettingsDefClass, ParameterClass::TYPE_INT, CostTable[class_index][rank_index][team_index], (const char *)name);
name.Format ("%s Object", CHAR_RANK_NAMES[rank_index]);
#ifdef PARAM_EDITING_ON
GenericDefParameterClass *param = new GenericDefParameterClass (&(DefinitionTable[class_index][rank_index][team_index]));
param->Set_Class_ID (CLASSID_GAME_OBJECT_DEF_SOLDIER);
param->Set_Name (name);
GENERIC_EDITABLE_PARAM(CharacterClassSettingsDefClass, param)
#endif //PARAM_EDITING_ON
}
}
}
GlobalInstance = this;
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// ~CharacterClassSettingsDefClass
//
///////////////////////////////////////////////////////////////////////////////////////////
CharacterClassSettingsDefClass::~CharacterClassSettingsDefClass (void)
{
GlobalInstance = NULL;
return ;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Class_ID
//
///////////////////////////////////////////////////////////////////////////////////////////
uint32
CharacterClassSettingsDefClass::Get_Class_ID (void) const
{
return CLASSID_GLOBAL_SETTINGS_DEF_CHAR_CLASS;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
///////////////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
CharacterClassSettingsDefClass::Get_Factory (void) const
{
return _CharClassDefPersistFactory;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Create
//
///////////////////////////////////////////////////////////////////////////////////////////
PersistClass *
CharacterClassSettingsDefClass::Create (void) const
{
WWASSERT (0);
return NULL;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Save
//
///////////////////////////////////////////////////////////////////////////////////////////
bool
CharacterClassSettingsDefClass::Save (ChunkSaveClass &csave)
{
csave.Begin_Chunk (CHUNKID_PARENT);
DefinitionClass::Save (csave);
csave.End_Chunk ();
//
// Save the cost and definition tables...
// Note: We save each with its own specific ID because the format (rows/cols)
// of this table is likely to change...
//
csave.Begin_Chunk (CHUNKID_VARIABLES);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MINIGUNNER_ENLISTED, CostTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MINIGUNNER_OFFICER, CostTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MINIGUNNER_SPECIAL_FORCES, CostTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MINIGUNNER_BOSS, CostTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ROCKET_SOLDIER_ENLISTED, CostTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ROCKET_SOLDIER_OFFICER, CostTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ROCKET_SOLDIER_SPECIAL_FORCES, CostTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ROCKET_SOLDIER_BOSS, CostTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_GRENADIER_ENLISTED, CostTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_GRENADIER_OFFICER, CostTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_GRENADIER_SPECIAL_FORCES, CostTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_GRENADIER_BOSS, CostTable[CLASS_GRENADIER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ENGINEER_ENLISTED, CostTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ENGINEER_OFFICER, CostTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ENGINEER_SPECIAL_FORCES, CostTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_ENGINEER_BOSS, CostTable[CLASS_ENGINEER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_FLAME_THROWER_ENLISTED, CostTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_FLAME_THROWER_OFFICER, CostTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_FLAME_THROWER_SPECIAL_FORCES, CostTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_FLAME_THROWER_BOSS, CostTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MUTANT_ENLISTED, CostTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MUTANT_OFFICER, CostTable[CLASS_MUTANT][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MUTANT_SPECIAL_FORCES, CostTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_GDI_MUTANT_BOSS, CostTable[CLASS_MUTANT][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MINIGUNNER_ENLISTED, DefinitionTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MINIGUNNER_OFFICER, DefinitionTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MINIGUNNER_SPECIAL_FORCES, DefinitionTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MINIGUNNER_BOSS, DefinitionTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ROCKET_SOLDIER_ENLISTED, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ROCKET_SOLDIER_OFFICER, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ROCKET_SOLDIER_SPECIAL_FORCES, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ROCKET_SOLDIER_BOSS, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_GRENADIER_ENLISTED, DefinitionTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_GRENADIER_OFFICER, DefinitionTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_GRENADIER_SPECIAL_FORCES, DefinitionTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_GRENADIER_BOSS, DefinitionTable[CLASS_GRENADIER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ENGINEER_ENLISTED, DefinitionTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ENGINEER_OFFICER, DefinitionTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ENGINEER_SPECIAL_FORCES, DefinitionTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_ENGINEER_BOSS, DefinitionTable[CLASS_ENGINEER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_FLAME_THROWER_ENLISTED, DefinitionTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_FLAME_THROWER_OFFICER, DefinitionTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_FLAME_THROWER_SPECIAL_FORCES, DefinitionTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_FLAME_THROWER_BOSS, DefinitionTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MUTANT_ENLISTED, DefinitionTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MUTANT_OFFICER, DefinitionTable[CLASS_MUTANT][RANK_OFFICER][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MUTANT_SPECIAL_FORCES, DefinitionTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_GDI_MUTANT_BOSS, DefinitionTable[CLASS_MUTANT][RANK_BOSS][TEAM_GDI]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MINIGUNNER_ENLISTED, CostTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MINIGUNNER_OFFICER, CostTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MINIGUNNER_SPECIAL_FORCES, CostTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MINIGUNNER_BOSS, CostTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ROCKET_SOLDIER_ENLISTED, CostTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ROCKET_SOLDIER_OFFICER, CostTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ROCKET_SOLDIER_SPECIAL_FORCES, CostTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ROCKET_SOLDIER_BOSS, CostTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_GRENADIER_ENLISTED, CostTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_GRENADIER_OFFICER, CostTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_GRENADIER_SPECIAL_FORCES, CostTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_GRENADIER_BOSS, CostTable[CLASS_GRENADIER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ENGINEER_ENLISTED, CostTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ENGINEER_OFFICER, CostTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ENGINEER_SPECIAL_FORCES, CostTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_ENGINEER_BOSS, CostTable[CLASS_ENGINEER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_FLAME_THROWER_ENLISTED, CostTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_FLAME_THROWER_OFFICER, CostTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_FLAME_THROWER_SPECIAL_FORCES, CostTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_FLAME_THROWER_BOSS, CostTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MUTANT_ENLISTED, CostTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MUTANT_OFFICER, CostTable[CLASS_MUTANT][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MUTANT_SPECIAL_FORCES, CostTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_COST_NOD_MUTANT_BOSS, CostTable[CLASS_MUTANT][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MINIGUNNER_ENLISTED, DefinitionTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MINIGUNNER_OFFICER, DefinitionTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MINIGUNNER_SPECIAL_FORCES, DefinitionTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MINIGUNNER_BOSS, DefinitionTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ROCKET_SOLDIER_ENLISTED, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ROCKET_SOLDIER_OFFICER, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ROCKET_SOLDIER_SPECIAL_FORCES, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ROCKET_SOLDIER_BOSS, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_GRENADIER_ENLISTED, DefinitionTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_GRENADIER_OFFICER, DefinitionTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_GRENADIER_SPECIAL_FORCES, DefinitionTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_GRENADIER_BOSS, DefinitionTable[CLASS_GRENADIER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ENGINEER_ENLISTED, DefinitionTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ENGINEER_OFFICER, DefinitionTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ENGINEER_SPECIAL_FORCES, DefinitionTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_ENGINEER_BOSS, DefinitionTable[CLASS_ENGINEER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_FLAME_THROWER_ENLISTED, DefinitionTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_FLAME_THROWER_OFFICER, DefinitionTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_FLAME_THROWER_SPECIAL_FORCES, DefinitionTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_FLAME_THROWER_BOSS, DefinitionTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MUTANT_ENLISTED, DefinitionTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MUTANT_OFFICER, DefinitionTable[CLASS_MUTANT][RANK_OFFICER][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MUTANT_SPECIAL_FORCES, DefinitionTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_NOD]);
WRITE_MICRO_CHUNK (csave, VARID_DEFID_NOD_MUTANT_BOSS, DefinitionTable[CLASS_MUTANT][RANK_BOSS][TEAM_NOD]);
csave.End_Chunk();
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Load
//
///////////////////////////////////////////////////////////////////////////////////////////
bool
CharacterClassSettingsDefClass::Load (ChunkLoadClass &cload)
{
while (cload.Open_Chunk ()) {
switch(cload.Cur_Chunk_ID ()) {
case CHUNKID_PARENT:
DefinitionClass::Load (cload);
break;
case CHUNKID_VARIABLES:
while (cload.Open_Micro_Chunk ()) {
switch(cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MINIGUNNER_ENLISTED, CostTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MINIGUNNER_OFFICER, CostTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MINIGUNNER_SPECIAL_FORCES, CostTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MINIGUNNER_BOSS, CostTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ROCKET_SOLDIER_ENLISTED, CostTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ROCKET_SOLDIER_OFFICER, CostTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ROCKET_SOLDIER_SPECIAL_FORCES, CostTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ROCKET_SOLDIER_BOSS, CostTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_GRENADIER_ENLISTED, CostTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_GRENADIER_OFFICER, CostTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_GRENADIER_SPECIAL_FORCES, CostTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_GRENADIER_BOSS, CostTable[CLASS_GRENADIER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ENGINEER_ENLISTED, CostTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ENGINEER_OFFICER, CostTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ENGINEER_SPECIAL_FORCES, CostTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_ENGINEER_BOSS, CostTable[CLASS_ENGINEER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_FLAME_THROWER_ENLISTED, CostTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_FLAME_THROWER_OFFICER, CostTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_FLAME_THROWER_SPECIAL_FORCES, CostTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_FLAME_THROWER_BOSS, CostTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MUTANT_ENLISTED, CostTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MUTANT_OFFICER, CostTable[CLASS_MUTANT][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MUTANT_SPECIAL_FORCES, CostTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_GDI_MUTANT_BOSS, CostTable[CLASS_MUTANT][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MINIGUNNER_ENLISTED, DefinitionTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MINIGUNNER_OFFICER, DefinitionTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MINIGUNNER_SPECIAL_FORCES, DefinitionTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MINIGUNNER_BOSS, DefinitionTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ROCKET_SOLDIER_ENLISTED, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ROCKET_SOLDIER_OFFICER, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ROCKET_SOLDIER_SPECIAL_FORCES, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ROCKET_SOLDIER_BOSS, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_GRENADIER_ENLISTED, DefinitionTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_GRENADIER_OFFICER, DefinitionTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_GRENADIER_SPECIAL_FORCES, DefinitionTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_GRENADIER_BOSS, DefinitionTable[CLASS_GRENADIER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ENGINEER_ENLISTED, DefinitionTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ENGINEER_OFFICER, DefinitionTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ENGINEER_SPECIAL_FORCES, DefinitionTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_ENGINEER_BOSS, DefinitionTable[CLASS_ENGINEER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_FLAME_THROWER_ENLISTED, DefinitionTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_FLAME_THROWER_OFFICER, DefinitionTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_FLAME_THROWER_SPECIAL_FORCES, DefinitionTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_FLAME_THROWER_BOSS, DefinitionTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MUTANT_ENLISTED, DefinitionTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MUTANT_OFFICER, DefinitionTable[CLASS_MUTANT][RANK_OFFICER][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MUTANT_SPECIAL_FORCES, DefinitionTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_DEFID_GDI_MUTANT_BOSS, DefinitionTable[CLASS_MUTANT][RANK_BOSS][TEAM_GDI]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MINIGUNNER_ENLISTED, CostTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MINIGUNNER_OFFICER, CostTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MINIGUNNER_SPECIAL_FORCES, CostTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MINIGUNNER_BOSS, CostTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ROCKET_SOLDIER_ENLISTED, CostTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ROCKET_SOLDIER_OFFICER, CostTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ROCKET_SOLDIER_SPECIAL_FORCES, CostTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ROCKET_SOLDIER_BOSS, CostTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_GRENADIER_ENLISTED, CostTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_GRENADIER_OFFICER, CostTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_GRENADIER_SPECIAL_FORCES, CostTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_GRENADIER_BOSS, CostTable[CLASS_GRENADIER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ENGINEER_ENLISTED, CostTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ENGINEER_OFFICER, CostTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ENGINEER_SPECIAL_FORCES, CostTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_ENGINEER_BOSS, CostTable[CLASS_ENGINEER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_FLAME_THROWER_ENLISTED, CostTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_FLAME_THROWER_OFFICER, CostTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_FLAME_THROWER_SPECIAL_FORCES, CostTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_FLAME_THROWER_BOSS, CostTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MUTANT_ENLISTED, CostTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MUTANT_OFFICER, CostTable[CLASS_MUTANT][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MUTANT_SPECIAL_FORCES, CostTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_COST_NOD_MUTANT_BOSS, CostTable[CLASS_MUTANT][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MINIGUNNER_ENLISTED, DefinitionTable[CLASS_MINIGUNNER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MINIGUNNER_OFFICER, DefinitionTable[CLASS_MINIGUNNER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MINIGUNNER_SPECIAL_FORCES, DefinitionTable[CLASS_MINIGUNNER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MINIGUNNER_BOSS, DefinitionTable[CLASS_MINIGUNNER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ROCKET_SOLDIER_ENLISTED, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ROCKET_SOLDIER_OFFICER, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ROCKET_SOLDIER_SPECIAL_FORCES, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ROCKET_SOLDIER_BOSS, DefinitionTable[CLASS_ROCKET_SOLDIER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_GRENADIER_ENLISTED, DefinitionTable[CLASS_GRENADIER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_GRENADIER_OFFICER, DefinitionTable[CLASS_GRENADIER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_GRENADIER_SPECIAL_FORCES, DefinitionTable[CLASS_GRENADIER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_GRENADIER_BOSS, DefinitionTable[CLASS_GRENADIER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ENGINEER_ENLISTED, DefinitionTable[CLASS_ENGINEER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ENGINEER_OFFICER, DefinitionTable[CLASS_ENGINEER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ENGINEER_SPECIAL_FORCES, DefinitionTable[CLASS_ENGINEER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_ENGINEER_BOSS, DefinitionTable[CLASS_ENGINEER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_FLAME_THROWER_ENLISTED, DefinitionTable[CLASS_FLAME_THROWER][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_FLAME_THROWER_OFFICER, DefinitionTable[CLASS_FLAME_THROWER][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_FLAME_THROWER_SPECIAL_FORCES, DefinitionTable[CLASS_FLAME_THROWER][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_FLAME_THROWER_BOSS, DefinitionTable[CLASS_FLAME_THROWER][RANK_BOSS][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MUTANT_ENLISTED, DefinitionTable[CLASS_MUTANT][RANK_ENLISTED][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MUTANT_OFFICER, DefinitionTable[CLASS_MUTANT][RANK_OFFICER][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MUTANT_SPECIAL_FORCES, DefinitionTable[CLASS_MUTANT][RANK_SPECIAL_FORCES][TEAM_NOD]);
READ_MICRO_CHUNK (cload, VARID_DEFID_NOD_MUTANT_BOSS, DefinitionTable[CLASS_MUTANT][RANK_BOSS][TEAM_NOD]);
default:
Debug_Say(("Unhandled Micro Chunk:%d File:%s Line:%d\r\n",cload.Cur_Micro_Chunk_ID (),__FILE__,__LINE__));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
break;
}
cload.Close_Chunk();
}
return true;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Cost
//
///////////////////////////////////////////////////////////////////////////////////////////
int
CharacterClassSettingsDefClass::Get_Cost
(
CLASS char_class,
RANK char_rank,
TEAM char_team
)
{
int cost = -1;
//
// Lookup the cost if we have an entry for the given coords
//
if ( char_class >= 0 && char_class < CLASS_COUNT &&
char_rank >= 0 && char_rank < RANK_COUNT &&
char_team >= 0 && char_team < TEAM_COUNT)
{
cost = CostTable[char_class][char_rank][char_team];
}
return cost;
}
///////////////////////////////////////////////////////////////////////////////////////////
//
// Get_Definition
//
///////////////////////////////////////////////////////////////////////////////////////////
int
CharacterClassSettingsDefClass::Get_Definition
(
CLASS char_class,
RANK char_rank,
TEAM char_team
)
{
int definition_id = -1;
//
// Lookup the definition if we have an entry for the given coords
//
if ( char_class >= 0 && char_class < CLASS_COUNT &&
char_rank >= 0 && char_rank < RANK_COUNT &&
char_team >= 0 && char_team < TEAM_COUNT)
{
definition_id = DefinitionTable[char_class][char_rank][char_team];
}
return definition_id;
}

View File

@@ -0,0 +1,131 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/characterclasssettings.h $*
* *
* $Author:: Patrick $*
* *
* $Modtime:: 2/12/01 11:20a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __CHARACTER_CLASS_SETTINGS_H
#define __CHARACTER_CLASS_SETTINGS_H
#include "always.h"
#include "definition.h"
///////////////////////////////////////////////////////////////////////////////////////////
//
// CharacterClassSettingsDefClass
//
///////////////////////////////////////////////////////////////////////////////////////////
class CharacterClassSettingsDefClass : public DefinitionClass
{
public:
//////////////////////////////////////////////////////////////////////////
// Public constants
//////////////////////////////////////////////////////////////////////////
typedef enum
{
CLASS_MINIGUNNER = 0,
CLASS_ROCKET_SOLDIER,
CLASS_GRENADIER,
CLASS_ENGINEER,
CLASS_FLAME_THROWER,
CLASS_MUTANT,
CLASS_COUNT
} CLASS;
typedef enum
{
RANK_ENLISTED = 0,
RANK_OFFICER,
RANK_SPECIAL_FORCES,
RANK_BOSS,
RANK_COUNT
} RANK;
typedef enum
{
TEAM_GDI = 0,
TEAM_NOD,
TEAM_COUNT
} TEAM;
//////////////////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////////////////
CharacterClassSettingsDefClass (void);
~CharacterClassSettingsDefClass (void);
//////////////////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////////////////
//
// From DefinitionClass
//
virtual uint32 Get_Class_ID (void) const;
virtual PersistClass * Create (void) const ;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual const PersistFactoryClass & Get_Factory (void) const;
static CharacterClassSettingsDefClass * Get_Instance (void) { return GlobalInstance; }
//
// Accessors
//
int Get_Cost (CLASS char_class, RANK char_rank, TEAM char_team);
int Get_Definition (CLASS char_class, RANK char_rank, TEAM char_team);
//
// Editable support
//
DECLARE_EDITABLE (CharacterClassSettingsDefClass, DefinitionClass);
protected:
//////////////////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////////////////
int CostTable[CLASS_COUNT][RANK_COUNT][TEAM_COUNT];
int DefinitionTable[CLASS_COUNT][RANK_COUNT][TEAM_COUNT];
static CharacterClassSettingsDefClass * GlobalInstance;
};
#endif // __CHARACTER_CLASS_SETTINGS_H

73
Code/Combat/cheatmgr.cpp Normal file
View File

@@ -0,0 +1,73 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : combat *
* *
* $Archive:: /Commando/Code/Combat/cheatmgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/23/01 3:38p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "cheatmgr.h"
#include "always.h"
//////////////////////////////////////////////////////////////////////
// Static member initialization
//////////////////////////////////////////////////////////////////////
CheatMgrClass * CheatMgrClass::_TheInstance = NULL;
//////////////////////////////////////////////////////////////////////
//
// CheatMgrClass
//
//////////////////////////////////////////////////////////////////////
CheatMgrClass::CheatMgrClass (void) :
Flags (0),
HistoryFlags (0)
{
_TheInstance = this;
return ;
}
//////////////////////////////////////////////////////////////////////
//
// ~CheatMgrClass
//
//////////////////////////////////////////////////////////////////////
CheatMgrClass::~CheatMgrClass (void)
{
_TheInstance = NULL;
return ;
}

121
Code/Combat/cheatmgr.h Normal file
View File

@@ -0,0 +1,121 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : combat *
* *
* $Archive:: /Commando/Code/Combat/cheatmgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 12/06/01 11:35a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __CHEATMGR_H
#define __CHEATMGR_H
#include "gametype.h"
//////////////////////////////////////////////////////////////////////
//
// CheatMgrClass
//
//////////////////////////////////////////////////////////////////////
class CheatMgrClass
{
public:
///////////////////////////////////////////////////////////////////
// Public flags
///////////////////////////////////////////////////////////////////
enum
{
CHEAT_INVULNERABILITY = 1,
CHEAT_INFINITE_AMMO = 2,
CHEAT_ALL_WEAPONS = 4,
ALL_CHEATS = 0x07,
};
///////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////
CheatMgrClass (void);
virtual ~CheatMgrClass (void);
///////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////
//
// Singleton access
//
static CheatMgrClass * Get_Instance (void) { return _TheInstance; }
//
// Cheat control
//
virtual void Enable_Cheat (int cheat, bool onoff) { if (onoff) Flags |= cheat; else Flags &= (~cheat); HistoryFlags |= Flags; }
virtual bool Is_Cheat_Enabled (int /*cheat*/) const { return false; }
virtual bool Is_Cheat_Set (int /*cheat*/) const { return false; }
virtual bool Was_Cheat_Used (int /*cheat*/) const { return false; }
virtual void Update_History (void) { HistoryFlags |= Flags; }
virtual void Reset_History (void) { HistoryFlags = Flags; }
virtual int Get_History (void) const { return HistoryFlags; }
virtual void Set_History (int flags) { HistoryFlags = flags; }
//
// Notifications
//
virtual void Apply_Cheats (void) {}
protected:
///////////////////////////////////////////////////////////////////
// Protected methods
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// Protected member data
///////////////////////////////////////////////////////////////////
int Flags;
int HistoryFlags;
//
// Static member data
//
static CheatMgrClass *_TheInstance;
};
#endif //__CHEATMGR_H

View File

@@ -0,0 +1,515 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/cinematicgameobj.cpp $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 10/10/01 11:37a $*
* *
* $Revision:: 32 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
** Includes
*/
#include "cinematicgameobj.h"
#include "debug.h"
#include "animcontrol.h"
#include "Sound3D.H"
#include "combat.h"
#include "pscene.h"
#include "persistfactory.h"
#include "combatchunkid.h"
#include "simpledefinitionfactory.h"
#include "wwhack.h"
#include "weapons.h"
#include "gameobjmanager.h"
#include "assets.h"
#include "ccamera.h"
#include "explosion.h"
#include "damage.h"
#include "dynamicanimphys.h"
#include "wwprofile.h"
#include "apppackettypes.h"
/*
** CinematicGameObjDef
*/
DECLARE_FORCE_LINK( Cinematic )
SimplePersistFactoryClass<CinematicGameObjDef, CHUNKID_GAME_OBJECT_DEF_CINEMATIC> _CinematicGameObjDefPersistFactory;
DECLARE_DEFINITION_FACTORY(CinematicGameObjDef, CLASSID_GAME_OBJECT_DEF_CINEMATIC, "Cinematic") _CinematicGameObjDefDefFactory;
CinematicGameObjDef::CinematicGameObjDef( void ) :
SoundDefID( 0 ),
AutoFireWeapon( false ),
DestroyAfterAnimation( true ),
CameraRelative( false )
{
MODEL_DEF_PARAM( CinematicGameObjDef, PhysDefID, "DynamicAnimPhysDef" );
EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, SoundDefID );
EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_STRING, SoundBoneName );
FILENAME_PARAM( CinematicGameObjDef, AnimationName, "Animation", ".W3D" );
EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, AutoFireWeapon );
EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, DestroyAfterAnimation );
EDITABLE_PARAM( CinematicGameObjDef, ParameterClass::TYPE_BOOL, CameraRelative );
}
uint32 CinematicGameObjDef::Get_Class_ID (void) const
{
return CLASSID_GAME_OBJECT_DEF_CINEMATIC;
}
const PersistFactoryClass & CinematicGameObjDef::Get_Factory (void) const
{
return _CinematicGameObjDefPersistFactory;
}
PersistClass * CinematicGameObjDef::Create( void ) const
{
CinematicGameObj * obj = new CinematicGameObj;
obj->Init( *this );
return obj;
}
enum {
CHUNKID_DEF_PARENT = 418001957,
CHUNKID_DEF_VARIABLES,
MICROCHUNKID_DEF_SOUND_DEF_ID = 1,
MICROCHUNKID_DEF_SOUND_BONE_NAME,
XXX_MICROCHUNKID_DEF_ANIMATION_NAME,
MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,
MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION,
MICROCHUNKID_DEF_CAMERA_RELATIVE,
};
bool CinematicGameObjDef::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_DEF_PARENT );
ArmedGameObjDef::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_SOUND_DEF_ID, SoundDefID );
WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_DEF_SOUND_BONE_NAME, SoundBoneName );
WRITE_MICRO_CHUNK_WWSTRING( csave, XXX_MICROCHUNKID_DEF_ANIMATION_NAME, AnimationName );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,AutoFireWeapon );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION, DestroyAfterAnimation );
WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_CAMERA_RELATIVE, CameraRelative );
csave.End_Chunk();
return true;
}
bool CinematicGameObjDef::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_DEF_PARENT:
ArmedGameObjDef::Load( cload );
break;
case CHUNKID_DEF_VARIABLES:
while (cload.Open_Micro_Chunk()) {
switch(cload.Cur_Micro_Chunk_ID()) {
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_SOUND_DEF_ID, SoundDefID );
READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_DEF_SOUND_BONE_NAME, SoundBoneName );
READ_MICRO_CHUNK_WWSTRING( cload, XXX_MICROCHUNKID_DEF_ANIMATION_NAME, AnimationName );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_AUTO_FIRE_WEAPON,AutoFireWeapon );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_DESTROY_AFTER_ANIMATION, DestroyAfterAnimation );
READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_CAMERA_RELATIVE, CameraRelative );
default:
Debug_Say(( "Unrecognized CinematicDef Variable chunkID\n" ));
break;
}
cload.Close_Micro_Chunk();
}
break;
default:
Debug_Say(( "Unrecognized CinematicDef chunkID\n" ));
break;
}
cload.Close_Chunk();
}
return true;
}
/*
** CinematicGameObj
*/
SimplePersistFactoryClass<CinematicGameObj, CHUNKID_GAME_OBJECT_CINEMATIC> _CinematicGameObjPersistFactory;
const PersistFactoryClass & CinematicGameObj::Get_Factory (void) const
{
return _CinematicGameObjPersistFactory;
}
CinematicGameObj::CinematicGameObj() :
Sound( NULL )
{
Set_App_Packet_Type(APPPACKETTYPE_CINEMATIC);
}
CinematicGameObj::~CinematicGameObj()
{
Set_Sound( 0 );
COMBAT_SCENE->Remove_From_Dirty_Cull_List( Peek_Physical_Object() );
}
/*
**
*/
void CinematicGameObj::Init( void )
{
Init( Get_Definition() );
}
/*
**
*/
void CinematicGameObj::Init( const CinematicGameObjDef & definition )
{
ArmedGameObj::Init( definition );
Cinematic_Init();
}
void CinematicGameObj::Cinematic_Init( void )
{
/*
** (gth) cinematic game objects behave like animated terrain so they are in the
** terrain collision group
*/
Peek_Physical_Object()->Set_Collision_Group( PhysicsSceneClass::COLLISION_GROUP_WORLD );
// COMBAT_SCENE->Add_To_Dirty_Cull_List( Peek_Physical_Object() );
Set_Sound( Get_Definition().SoundDefID, Get_Definition().SoundBoneName );
}
const CinematicGameObjDef & CinematicGameObj::Get_Definition( void ) const
{
return (const CinematicGameObjDef &)BaseGameObj::Get_Definition();
}
/*
** CinematicGameObj Save and Load
*/
enum {
CHUNKID_PARENT = 418002008,
XXXCHUNKID_VARIABLES,
XXXCHUNKID_ANIM_CONTROL,
XXXMICROCHUNKID_PHYSICAL_OBJECT = 1,
};
bool CinematicGameObj::Save( ChunkSaveClass & csave )
{
csave.Begin_Chunk( CHUNKID_PARENT );
ArmedGameObj::Save( csave );
csave.End_Chunk();
// We don't need to save the sound
return true;
}
bool CinematicGameObj::Load( ChunkLoadClass &cload )
{
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_PARENT:
ArmedGameObj::Load( cload );
break;
default:
Debug_Say(( "Unrecognized Cinematic chunkID\n" ));
break;
}
cload.Close_Chunk();
}
SaveLoadSystemClass::Register_Post_Load_Callback(this);
return true;
}
void CinematicGameObj::On_Post_Load( void )
{
ArmedGameObj::On_Post_Load();
Cinematic_Init();
}
/*
**
*/
void CinematicGameObj::Set_Sound( int sound_def_id, const char * bone_name )
{
// Stop Old Sound
if ( Sound != NULL ) {
Sound->Stop();
Sound->Attach_To_Object( NULL );
Sound->Remove_From_Scene();
Sound->Release_Ref();
Sound = NULL;
}
// Start new Sound
if ( sound_def_id != 0 ) {
Sound = WWAudioClass::Get_Instance()->Create_Continuous_Sound( sound_def_id );
if ( Sound != NULL ) {
RenderObjClass * model = Peek_Model();
WWASSERT( model );
int bone_index = model->Get_Bone_Index( bone_name );
Sound->Attach_To_Object( Peek_Model(), bone_index );
Sound->Add_To_Scene( true );
}
}
}
void CinematicGameObj::Think( void )
{
{ WWPROFILE( "Cinematic Think" );
// If auto fire weapon
if ( Get_Definition().AutoFireWeapon ) {
PhysicalGameObj * enemy = NULL;
Vector3 my_pos;
Get_Position( &my_pos );
// if any enemies can be found in range
SLNode<BaseGameObj> *objnode;
for ( objnode = GameObjManager::Get_Game_Obj_List()->Head(); objnode; objnode = objnode->Next()) {
PhysicalGameObj *obj = objnode->Data()->As_PhysicalGameObj();
if ( obj && obj->Peek_Physical_Object() ) { // zones have no phy obj CHANGE THIS
if ( obj == this ) {
continue;
}
if ( Is_Teammate( obj ) ) {
continue;
}
Vector3 v;
obj->Get_Position(&v);
v -= my_pos;
if ( v.Length() < Get_Weapon()->Get_Range() ) {
enemy = obj;
}
}
}
if ( enemy != NULL ) {
Vector3 enemy_pos;
enemy->Get_Position( &enemy_pos );
enemy_pos.Z += 1;
if ( Set_Targeting( enemy_pos ) == false ) {
Get_Weapon()->Set_Primary_Triggered( false );
} else {
Get_Weapon()->Set_Primary_Triggered( true ); // Fire Primary
}
} else {
Get_Weapon()->Set_Primary_Triggered( false );
}
}
if ( Get_Definition().CameraRelative && COMBAT_CAMERA != NULL ) {
Matrix3D tm = COMBAT_CAMERA->Get_Transform();
tm.Rotate_Z( DEG_TO_RADF(90.0) );
tm.Rotate_Y( DEG_TO_RADF(90.0) );
Set_Transform( tm );
}
}
ArmedGameObj::Think();
}
void CinematicGameObj::Post_Think( void )
{
ArmedGameObj::Post_Think();
WWPROFILE( "Cinematic PostThink" );
// Animation is handled by the DynamicAnimPhysClass for this class
WWASSERT(Get_Anim_Control() == NULL);
if (Get_Definition().DestroyAfterAnimation) {
PhysClass * pobj = Peek_Physical_Object();
if (pobj != NULL) {
DynamicAnimPhysClass * dpobj = pobj->As_DynamicAnimPhysClass();
if ((dpobj != NULL) &&
(dpobj->Get_Animation_Manager().Peek_Animation() != NULL) &&
(dpobj->Get_Animation_Manager().Is_At_Target()) )
{
Set_Delete_Pending();
}
}
}
}
void CinematicGameObj::Completely_Damaged( const OffenseObjectClass & damager )
{
if ( Get_Definition().KilledExplosion != 0 ) {
Vector3 pos;
Get_Position(&pos);
WWASSERT(pos.Is_Valid());// most likely candidate for explosion damage bug....?
// If the object has a moving bounding box, use its center point for the explosion
RenderObjClass * model = Peek_Model();
if (model != NULL) {
RenderObjClass * bbox = model->Get_Sub_Object_By_Name("BoundingBox");
if (bbox != NULL) {
Matrix3D bbox_tm = bbox->Get_Transform();
bbox_tm.Get_Translation(&pos);
REF_PTR_RELEASE(bbox);
}
}
ExplosionManager::Create_Explosion_At( Get_Definition().KilledExplosion, pos, damager.Get_Owner() ); // no one gets credit for this
}
Set_Delete_Pending();
}
float CinematicGameObj::Get_Animation_Length( void )
{
float length = 0;
//
// Try to get the dynamic anim phys object from the physics object
//
PhysClass *phys_obj = Peek_Physical_Object();
if (phys_obj != NULL) {
DynamicAnimPhysClass * dynamic_anim_phys = phys_obj->As_DynamicAnimPhysClass();
if (dynamic_anim_phys != NULL) {
//
// Peek at this object's animation
//
AnimCollisionManagerClass &anim_mgr = dynamic_anim_phys->Get_Animation_Manager();
HAnimClass *anim = anim_mgr.Peek_Animation();
if (anim != NULL) {
//
// Return the length of the animation to the caller
//
length = anim->Get_Total_Time();
}
}
}
return length;
}
/*
void
CinematicGameObj::Import_Creation( BitStreamClass &packet )
{
ArmedGameObj::Import_Creation (packet);
return ;
}
*/
void CinematicGameObj::Export_Rare( BitStreamClass &packet )
{
ArmedGameObj::Export_Rare( packet );
StringClass animation_name;
AnimCollisionManagerClass::AnimModeType anim_mode = AnimCollisionManagerClass::ANIMATE_TARGET;
//
// Dig the animation data out of the physics object
//
DynamicAnimPhysClass *dynanim = Peek_Physical_Object()->As_DynamicAnimPhysClass();
if (dynanim != NULL) {
AnimCollisionManagerClass &anim_mgr = dynanim->Get_Animation_Manager();
//
// Get the animation name
//
HAnimClass *anim = anim_mgr.Peek_Animation();
if (anim != NULL) {
animation_name = anim->Get_Name();
}
//
// Get the animation mode
//
anim_mode = anim_mgr.Get_Animation_Mode ();
}
//
// Send the animation data to the client
//
packet.Add_Terminated_String( (const char *)animation_name, true );
packet.Add( anim_mode );
return ;
}
void CinematicGameObj::Import_Rare( BitStreamClass &packet )
{
ArmedGameObj::Import_Rare( packet );
//
// Get information about the animation
//
StringClass animation_name;
int anim_mode = AnimCollisionManagerClass::ANIMATE_TARGET;
packet.Get_Terminated_String( animation_name.Get_Buffer( 256 ), 256, true );
packet.Get( anim_mode );
//
// Pass the animation information onto the controller
//
DynamicAnimPhysClass *dynanim = Peek_Physical_Object()->As_DynamicAnimPhysClass();
if (dynanim != NULL) {
AnimCollisionManagerClass &anim_mgr = dynanim->Get_Animation_Manager();
anim_mgr.Set_Animation( animation_name );
anim_mgr.Set_Animation_Mode( (AnimCollisionManagerClass::AnimModeType)anim_mode );
}
return ;
}

View File

@@ -0,0 +1,129 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/cinematicgameobj.h $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/17/01 4:24p $*
* *
* $Revision:: 19 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef CINEMATICGAMEOBJ_H
#define CINEMATICGAMEOBJ_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef ARMEDGAMEOBJ_H
#include "armedgameobj.h"
#endif
class AudibleSoundClass;
/*
** CinematicGameObjDef - Defintion class for a CinematicGameObj
*/
class CinematicGameObjDef : public ArmedGameObjDef
{
public:
CinematicGameObjDef( void );
virtual uint32 Get_Class_ID( void ) const;
virtual PersistClass * Create( void ) const ;
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
virtual const PersistFactoryClass & Get_Factory( void ) const;
DECLARE_EDITABLE( CinematicGameObjDef, ArmedGameObjDef );
protected:
int SoundDefID;
StringClass SoundBoneName;
StringClass AnimationName;
bool AutoFireWeapon;
bool DestroyAfterAnimation;
bool CameraRelative;
friend class CinematicGameObj;
};
/*
**
*/
class CinematicGameObj : public ArmedGameObj {
public:
CinematicGameObj();
virtual ~CinematicGameObj();
// Definitions
virtual void Init( void );
void Init( const CinematicGameObjDef & definition );
const CinematicGameObjDef & Get_Definition( void ) const ;
void Cinematic_Init( void );
// Save / Load / Construction Factory
virtual bool Save( ChunkSaveClass & csave );
virtual bool Load( ChunkLoadClass & cload );
virtual void On_Post_Load( void );
virtual const PersistFactoryClass & Get_Factory( void ) const;
// Think
virtual void Think( void );
virtual void Post_Think( void );
// Type Identification
virtual CinematicGameObj *As_CinematicGameObj( void ) { return this; }
// Sound
void Set_Sound( int sound_def_id, const char * bone_name = "" );
// Damage
virtual bool Takes_Explosion_Damage( void ) { return false; }
virtual void Completely_Damaged( const OffenseObjectClass & damager );
// Information
float Get_Animation_Length( void );
// Network support
//TSS: why import with no export?
//virtual void Import_Creation( BitStreamClass &packet );
// Network support
virtual void Export_Rare( BitStreamClass &packet );
virtual void Import_Rare( BitStreamClass &packet );
protected:
AudibleSoundClass *Sound;
};
#endif // CINEMATICGAMEOBJ_H

View File

@@ -0,0 +1,179 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/clientcontrol.cpp $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/21/01 10:44a $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "clientcontrol.h"
#include "networkobjectfactory.h"
#include "combat.h"
#include "smartgameobj.h"
#include "gameobjmanager.h"
#include "apppackettypes.h"
CClientControl * PClientControl = NULL;
DECLARE_NETWORKOBJECT_FACTORY(CClientControl, NETCLASSID_CLIENTCONTROL);
#pragma message("(TSS) high priority for me to fix this CClientControl bug...")
//
// TSS2001 problem: destruction of this object on the server. Quitting and rejoining
// a game will crash the server.
//
//-----------------------------------------------------------------------------
CClientControl::CClientControl(void)
{
ClientId = -1;
SmartObjId = -1;
Set_App_Packet_Type(APPPACKETTYPE_CLIENTCONTROL);
}
//-----------------------------------------------------------------------------
CClientControl::~CClientControl(void)
{
}
//-----------------------------------------------------------------------------
void
CClientControl::Init(void)
{
WWASSERT(CombatManager::I_Am_Client());
ClientId = CombatManager::Get_My_Id();
Set_Network_ID(NetworkObjectMgrClass::Get_New_Client_ID());
Set_Object_Dirty_Bit(0, NetworkObjectClass::BIT_CREATION, true);
}
//-----------------------------------------------------------------------------
void
CClientControl::Set_Update_Flag(int id)
{
WWASSERT(CombatManager::I_Am_Client());
SmartObjId = id;
if (id != -1) {
Set_Object_Dirty_Bit(0, NetworkObjectClass::BIT_FREQUENT, true);
}
}
//-----------------------------------------------------------------------------
void
CClientControl::Export_Creation(BitStreamClass & packet)
{
WWASSERT(CombatManager::I_Am_Client());
NetworkObjectClass::Export_Creation(packet);
packet.Add(ClientId);
}
//-----------------------------------------------------------------------------
void
CClientControl::Import_Creation(BitStreamClass & packet)
{
WWASSERT(CombatManager::I_Am_Server());
NetworkObjectClass::Import_Creation(packet);
packet.Get(ClientId);
}
//-----------------------------------------------------------------------------
void
CClientControl::Export_Frequent(BitStreamClass & packet)
{
WWASSERT(CombatManager::I_Am_Client());
/*
packet.Add(SmartObjId);
if (SmartObjId != -1) {
SmartGameObj * p_smart_go = GameObjManager::Find_SmartGameObj(SmartObjId);
WWASSERT(p_smart_go != NULL);
p_smart_go->Export_Control_Cs(packet);
p_smart_go->Export_State_Cs(packet);
}
*/
SmartGameObj * p_smart_go = NULL;
if (SmartObjId != -1) {
p_smart_go = GameObjManager::Find_SmartGameObj(SmartObjId);
if (p_smart_go == NULL) {
SmartObjId = -1;
}
}
packet.Add(SmartObjId);
if (SmartObjId != -1) {
WWASSERT(p_smart_go != NULL);
p_smart_go->Export_Control_Cs(packet);
p_smart_go->Export_State_Cs(packet);
}
SmartObjId = -1;//hack
}
//-----------------------------------------------------------------------------
void
CClientControl::Import_Frequent(BitStreamClass & packet)
{
WWASSERT(CombatManager::I_Am_Server());
packet.Get(SmartObjId);
if (SmartObjId != -1) {
SmartGameObj * p_smart_go = GameObjManager::Find_SmartGameObj(SmartObjId);
//WWASSERT(p_smart_go != NULL);
if (p_smart_go == NULL) {
packet.Flush();
} else {
p_smart_go->Import_Control_Cs(packet);
//
// Note: org code had control owner test here, reapply if problems arise.
//
p_smart_go->Import_State_Cs(packet);
}
}
}

View File

@@ -0,0 +1,79 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/clientcontrol.h $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/17/01 4:18p $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef __CLIENTCONTROL_H__
#define __CLIENTCONTROL_H__
#include "networkobject.h"
#include "netclassids.h"
#include "control.h"
//-----------------------------------------------------------------------------
//
// A C-S mirrored object to represent client control and targeting data
//
class CClientControl : public NetworkObjectClass
{
public:
CClientControl();
~CClientControl();
void Init(void);
virtual uint32 Get_Network_Class_ID(void) const {return NETCLASSID_CLIENTCONTROL;}
virtual void Delete(void) {delete this;}
void Set_Update_Flag(int id);
virtual void Export_Creation(BitStreamClass &packet);
virtual void Import_Creation(BitStreamClass &packet);
virtual void Export_Frequent(BitStreamClass &packet);
virtual void Import_Frequent(BitStreamClass &packet);
private:
int ClientId;
int SmartObjId;
};
//-----------------------------------------------------------------------------
extern CClientControl * PClientControl;
//-----------------------------------------------------------------------------
#endif // __CLIENTCONTROL_H__

52
Code/Combat/colors.cpp Normal file
View File

@@ -0,0 +1,52 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/colors.cpp $*
* *
* $Author:: Tom_s $*
* *
* $Modtime:: 9/25/00 3:44p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "colors.h"
#include "playertype.h"
#include "wwdebug.h"
Vector3 Get_Color_For_Team(int team)
{
WWASSERT(team == PLAYERTYPE_NOD || team == PLAYERTYPE_GDI);
if (team == PLAYERTYPE_NOD) {
return COLOR_TEAM_0;
} else {
return COLOR_TEAM_1;
}
}

67
Code/Combat/colors.h Normal file
View File

@@ -0,0 +1,67 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/colors.h $*
* *
* $Author:: Denzil_l $*
* *
* $Modtime:: 11/07/01 7:53p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COLORS_H
#define COLORS_H
#include "vector3.h"
const Vector3 COLOR_TEAM_0 = Vector3(1.0f, 0.0f, 0.0f);
const Vector3 COLOR_TEAM_1 = Vector3(1.0f, 0.8f, 0.0f);
const Vector3 COLOR_NEUTRAL = Vector3(0.8f, 0.8f, 0.8f);
const Vector3 COLOR_RENEGADE = Vector3(1.0f, 1.0f, 1.0f);
const Vector3 COLOR_PUBLIC_TEXT = Vector3(1.0f, 1.0f, 1.0f);
const Vector3 COLOR_PRIVATE_TEXT = Vector3(0.0f, 0.0f, 1.0f);
const Vector3 COLOR_PAGED_TEXT = Vector3(0.0f, 1.0f, 1.0f);
const Vector3 COLOR_INVITE_TEXT = Vector3(1.0f, 0.0f, 1.0f);
const Vector3 COLOR_CONSOLE_TEXT = Vector3(1.0f, 1.0f, 1.0f);
Vector3 Get_Color_For_Team(int team);
#endif // COLORS_H
//const Vector3 COLOR_KOTH = Vector3(0.2f, 1.0f, 0.2f);
//const Vector3 COLOR_CHAMPION = Vector3(0.0f, 1.0f, 1.0f);

1374
Code/Combat/combat.cpp Normal file

File diff suppressed because it is too large Load Diff

351
Code/Combat/combat.h Normal file
View File

@@ -0,0 +1,351 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/combat.h $*
* *
* $Author:: Bhayes $*
* *
* $Modtime:: 2/17/02 10:27a $*
* *
* $Revision:: 130 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBAT_H
#define COMBAT_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef GAMEOBJREF_H
#include "gameobjref.h"
#endif
#ifndef VECTOR3_H
#include "vector3.h"
#endif
#ifndef WWSTRING_H
#include "wwstring.h"
#endif
/*
**
*/
class PhysicsSceneClass;
class CameraClass;
class CCameraClass;
class SmartGameObj;
class ArmedGameObj;
class PhysicalGameObj;
class SimpleSceneClass;
class BaseGameObj;
class VehicleGameObj;
class SoldierGameObj;
class DazzleLayerClass;
class MessageWindowClass;
class SoundEnvironmentClass;
/*
**
*/
#define COMBAT_CAMERA CombatManager::Get_Camera()
#define COMBAT_STAR CombatManager::Get_The_Star()
#define COMBAT_SCENE CombatManager::Get_Scene()
#define COMBAT_DAZZLE_LAYER CombatManager::Get_Dazzle_Layer()
/*
** Collision Groups
*/
typedef enum {
DEFAULT_COLLISION_GROUP = 0, // collides with everything
UNCOLLIDEABLE_GROUP, // collides with nothing
TERRAIN_ONLY_COLLISION_GROUP, // collides only with terrain
BULLET_COLLISION_GROUP, // collides with everything but itself
TERRAIN_AND_BULLET_COLLISION_GROUP, // collides with terrain and bullets
BULLET_ONLY_COLLISION_GROUP, // collides only with bullets
SOLDIER_COLLISION_GROUP, // collides with everything (but only soldiers use it)
SOLDIER_GHOST_COLLISION_GROUP, // collides with everything but soldiers
TERRAIN_COLLISION_GROUP = 15, // Terrain must be 15
} Collision_Group_Type;
/*
**
*/
class CombatNetworkHandlerClass {
public:
virtual bool Can_Damage(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim) = 0;
virtual float Get_Damage_Factor(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim) = 0;
virtual void On_Soldier_Kill(SoldierGameObj * p_soldier, SoldierGameObj * p_victim) = 0;
virtual void On_Soldier_Death(SoldierGameObj * p_soldier) = 0;
virtual bool Is_Gameplay_Permitted(void) = 0;
};
/*
**
*/
class CombatMiscHandlerClass {
public:
virtual void Mission_Complete( bool success ) = 0;
virtual void Star_Killed( void ) = 0;
};
/*
**
*/
class CombatManager {
public:
// Init and Shutdown should be called once per program execution
static void Init( bool render_available = true );
static void Shutdown( void );
// Scene_Init is called by the game, but not the editor
static void Scene_Init( void );
// Level Loading functions get called for each level loaded.
static void Pre_Load_Level( bool render_available = true );
static void Load_Level_Threaded( const char * map_name, bool preload_assets );
static bool Is_Load_Level_Complete( void );
static bool Is_Loading_Level( void );
static void Post_Load_Level( void );
static void Unload_Level( void );
// Main Loop functions
static void Generate_Control( void );
static void Think( void );
static void Render( void );
static void Handle_Input( void );
// Save/Load
static bool Save( ChunkSaveClass &csave );
static bool Load( ChunkLoadClass &cload );
// Client/Server Settings
static void Set_I_Am_Server( bool yes ) { IAmServer = yes; }
static void Set_I_Am_Client( bool yes ) { IAmClient = yes; }
static bool I_Am_Server( void ) { return IAmServer; }
static bool I_Am_Client( void ) { return IAmClient; }
static bool I_Am_Only_Client( void ) { return IAmClient && !IAmServer; }
static bool I_Am_Only_Server( void ) { return IAmServer && !IAmClient; }
static bool I_Am_Client_Server(void) { return IAmClient && IAmServer;}
static void Set_Friendly_Fire_Permitted( bool yes ) { FriendlyFirePermitted = yes; }
static bool Is_Friendly_Fire_Permitted( void ) { return FriendlyFirePermitted; }
static void Set_Beacon_Placement_Ends_Game( bool yes ){ BeaconPlacementEndsGame = yes; }
static bool Does_Beacon_Placement_Ends_Game( void ) { return BeaconPlacementEndsGame; }
static void Set_My_Id( int id ) { MyId = id; }
static int Get_My_Id( void ) { return MyId; }
// Latency support
static void Set_Last_Round_Trip_Ping_Ms( DWORD ping ) { LastRoundTripPingMs = ping; }
static DWORD Get_Last_Round_Trip_Ping_Ms( void ) { return LastRoundTripPingMs; }
static void Set_Avg_Round_Trip_Ping_Ms( DWORD ping ) { AvgRoundTripPingMs = ping; }
static DWORD Get_Avg_Round_Trip_Ping_Ms( void ) { return AvgRoundTripPingMs; }
// Network Handler Functions
static void Set_Combat_Network_Handler( CombatNetworkHandlerClass * handler ) { NetworkHandler = handler; }
static bool Can_Damage(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim);
static float Get_Damage_Factor(ArmedGameObj * p_armed_damager, PhysicalGameObj * p_phys_victim);
static void On_Soldier_Kill(SoldierGameObj * p_soldier, SoldierGameObj * p_victim);
static void On_Soldier_Death(SoldierGameObj * p_soldier);
static bool Is_Gameplay_Permitted(void);
// Misc Handler
static void Set_Combat_Misc_Handler( CombatMiscHandlerClass * handler ) { MiscHandler = handler; }
static void Mission_Complete( bool success );
static void Star_Killed( void );
// The Star
static void Set_The_Star( SoldierGameObj *target, bool is_star_determining_target = true );
static SoldierGameObj * Get_The_Star( void ) { return (SoldierGameObj *)TheStar.Get_Ptr(); }
static void Update_Star( void );
static void Update_Star_Targeting( void );
static bool Is_Star_Determining_Target(void) {return IsStarDeterminingTarget;}
static void Set_Is_Star_Determining_Target(bool flag) {IsStarDeterminingTarget = flag;}
// The Scene
static PhysicsSceneClass *Get_Scene( void );
static SimpleSceneClass *Get_Background_Scene( void ) { return BackgroundScene; }
static CCameraClass *Get_Camera( void ) { return MainCamera; }
static SoundEnvironmentClass *Get_Sound_Environment( void ) { return SoundEnvironment; }
static void Set_Camera_Profile( const char * profile_name );
static void Set_Camera_Vehicle( VehicleGameObj * obj, int seat = 0 );
static bool Is_In_Camera_Frustrum(Vector3 & position);
static bool Are_Observers_Active( void ) { return AreObserversActive; }
static void Set_Observers_Active( bool onoff ) { AreObserversActive = onoff; }
static bool Is_First_Load( void ) { return IsFirstLoad; }
static void Set_First_Load( bool onoff ) { IsFirstLoad = onoff; }
static void Do_Skeleton_Slider_Demo( void );
static void Toggle_Skeleton_Slider_Demo( void ) { EnableSkeletonSliderDemo = !EnableSkeletonSliderDemo; }
static bool Is_Skeleton_Slider_Demo_Enabled( void ) { return EnableSkeletonSliderDemo; }
static DazzleLayerClass * Get_Dazzle_Layer(void) { return DazzleLayer; }
// First Person
static void Set_First_Person( bool on_off ) { FirstPerson = on_off; }
static bool Is_First_Person( void ) { return FirstPerson; }
static void Set_First_Person_Default( bool on_off ) { FirstPersonDefault = on_off; }
static bool Get_First_Person_Default( void ) { return FirstPersonDefault; }
// Difficulty
static void Set_Difficulty_Level( int level ) { DifficultyLevel = level; }
static int Get_Difficulty_Level( void ) { return DifficultyLevel; }
static bool Are_Transitions_Automatic( void ) { return AutoTransitions; }
static void Set_Transitions_Automatic( bool state ) { AutoTransitions = state; }
// Message window
static MessageWindowClass * Get_Message_Window (void) { return MessageWindow; }
static void Show_Star_Damage_Direction( int direction ) { StarDamageDirection |= 1 << (direction&7); }
static int Get_Star_Damage_Direction( void ) { return StarDamageDirection; }
static void Clear_Star_Damage_Direction( void ) { StarDamageDirection = 0; }
static int Get_Sync_Time( void ) { return SyncTime; }
static bool Is_Game_Paused( void ) { return IsGamePaused; }
static void Register_Star_Killer( ArmedGameObj * killer );
static const char * Get_Start_Script( void ) { return StartScript; }
static const char * Get_Respawn_Script( void ) { return RespawnScript; }
static void Set_Start_Script( const char * string ) { StartScript = string; }
static void Set_Respawn_Script( const char * string ) { RespawnScript = string; }
static void Request_Autosave( bool state = true ) { AutosaveRequested = state; }
static bool Is_Autosave_Requested( void ) { return AutosaveRequested; }
static int Get_Reload_Count( void ) { return ReloadCount; }
static bool Is_Hit_Reticle_Enabled( void ) { return HitReticleEnabled; }
static void Toggle_Hit_Reticle_Enabled( void ) { HitReticleEnabled = !HitReticleEnabled; }
static const char * Get_Last_LSD_Name( void ) { return LastLSDName; };
static void Set_Last_LSD_Name( const char * name ) { LastLSDName = name; };
static int Get_Load_Progress( void ) { return LoadProgress; };
static void Inc_Load_Progress( void ) { LoadProgress++; };
static void Set_Load_Progress( int set ) { LoadProgress = set; };
private:
static bool IAmServer;
static bool IAmClient;
static bool IAmOnlyClient;
static bool IAmOnlyServer;
static int MyId;
static int SyncTime;
static bool IsGamePaused;
static bool IsLevelInitialized;
static bool FriendlyFirePermitted;
static bool BeaconPlacementEndsGame;
static bool FirstPerson;
static bool FirstPersonDefault;
static CCameraClass * MainCamera;
static SimpleSceneClass * BackgroundScene;
static SoundEnvironmentClass * SoundEnvironment;
static DazzleLayerClass * DazzleLayer;
static MessageWindowClass * MessageWindow;
static GameObjReference TheStar;
static bool IsStarDeterminingTarget;
static bool IsFirstLoad;
static bool AreObserversActive;
static bool EnableSkeletonSliderDemo;
static int DifficultyLevel;
static bool AutoTransitions;
static int StarDamageDirection;
static int StarKillerID;
static CombatNetworkHandlerClass * NetworkHandler;
static CombatMiscHandlerClass * MiscHandler;
static StringClass StartScript;
static StringClass RespawnScript;
static int ReloadCount;
static bool HitReticleEnabled;
static bool IsGameplayPermitted;
/*
** Combat Mode Management
*/
typedef enum {
COMBAT_MODE_NONE,
COMBAT_MODE_FIRST_PERSON,
COMBAT_MODE_THIRD_PERSON,
COMBAT_MODE_SNIPING,
COMBAT_MODE_IN_VEHICLE,
COMBAT_MODE_ON_LADDER,
COMBAT_MODE_DIEING,
COMBAT_MODE_CORPSE,
COMBAT_MODE_SNAP_SHOT,
};
static int CombatMode;
static bool AutosaveRequested;
static void Set_Combat_Mode( int mode );
static void Update_Combat_Mode( void );
/*
** Latency Support
*/
static DWORD LastRoundTripPingMs;
static DWORD AvgRoundTripPingMs;
static StringClass LastLSDName;
static int LoadProgress;
static bool MultiplayRenderingAllowed;
};
#endif

304
Code/Combat/combatchunkid.h Normal file
View File

@@ -0,0 +1,304 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/combatchunkid.h $*
* *
* $Author:: Denzil_l $*
* *
* $Modtime:: 11/21/01 10:26a $*
* *
* $Revision:: 55 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBATCHUNKID_H
#define COMBATCHUNKID_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef SAVELOADIDS_H
#include "saveloadids.h"
#endif
#ifndef DEFINITIONCLASSIDS_H
#include "definitionclassids.h"
#endif
/*
** CHUNKIDs
*/
enum {
CHUNKID_COMBAT = CHUNKID_COMBAT_BEGIN,
CHUNKID_TIMER,
CHUNKID_TIMER_GAME_OBJ,
CHUNKID_TIMER_GAME_OBJ_CUSTOM,
CHUNKID_GAME_OBJECTS_BEGIN = CHUNKID_COMBAT_BEGIN + 0x100,
CHUNKID_GAME_OBJECT_BULLET,
CHUNKID_GAME_OBJECT_C4,
CHUNKID_GAME_OBJECT_DEF_C4,
XXXCHUNKID_GAME_OBJECT_COMMANDO,
XXXCHUNKID_GAME_OBJECT_DEF_COMMANDO,
CHUNKID_GAME_OBJECT_POWERUP,
CHUNKID_GAME_OBJECT_DEF_POWERUP,
CHUNKID_GAME_OBJECT_SAMSITE,
CHUNKID_GAME_OBJECT_DEF_SAMSITE,
CHUNKID_GAME_OBJECT_SIMPLE,
CHUNKID_GAME_OBJECT_DEF_SIMPLE,
XXXCHUNKID_GAME_OBJECT_SIMPLE3,
XXXCHUNKID_GAME_OBJECT_DEF_SIMPLE3,
CHUNKID_GAME_OBJECT_SOLDIER,
CHUNKID_GAME_OBJECT_DEF_SOLDIER,
CHUNKID_GAME_OBJECT_VEHICLE,
CHUNKID_GAME_OBJECT_VISUAL,
CHUNKID_GAME_OBJECT_TIMED_VISUAL,
CHUNKID_GAME_OBJECT_ANIMATED_VISUAL,
CHUNKID_GAME_OBJECT_PROJECTILE_VISUAL,
CHUNKID_GAME_OBJECT_XXXXXXXXXXXXXXXXX,
XXXCHUNKID_GAME_OBJECT_TANK,
XXXCHUNKID_GAME_OBJECT_DEF_TANK,
XXXCHUNKID_GAME_OBJECT_TURRET,
XXXCHUNKID_GAME_OBJECT_DEF_TURRET,
XXXCHUNKID_GAME_OBJECT_BIKE,
XXXCHUNKID_GAME_OBJECT_DEF_BIKE,
XXXCHUNKID_GAME_OBJECT_FLYING,
XXXCHUNKID_GAME_OBJECT_DEF_FLYING,
XXXCHUNKID_GAME_OBJECT_CAR,
XXXCHUNKID_GAME_OBJECT_DEF_CAR,
CHUNKID_SPAWNER,
CHUNKID_SPAWNER_DEF,
CHUNKID_GAME_OBJECT_SCRIPT_ZONE,
CHUNKID_GAME_OBJECT_DEF_SCRIPT_ZONE,
CHUNKID_GAME_OBJECT_TRANSITION,
CHUNKID_GAME_OBJECT_DEF_TRANSITION,
// MISC ITEMS
CHUNKID_BACKGROUND_MGR,
CHUNKID_WEAPON_DEF,
CHUNKID_AMMO_DEF,
CHUNKID_GAME_OBJECT_DEF_VEHICLE,
CHUNKID_EXPLOSION_DEF,
CHUNKID_GAME_OBJECT_CINEMATIC,
CHUNKID_GAME_OBJECT_DEF_CINEMATIC,
CHUNKID_GAME_OBJECT_DAMAGE_ZONE,
CHUNKID_GAME_OBJECT_DEF_DAMAGE_ZONE,
CHUNKID_GAME_OBJECT_SPECIAL_EFFECTS,
CHUNKID_GAME_OBJECT_DEF_SPECIAL_EFFECTS,
CHUNKID_GAME_OBJECT_SAKURA_BOSS,
CHUNKID_GAME_OBJECT_DEF_SAKURA_BOSS,
CHUNKID_GAME_OBJECT_BUILDING,
CHUNKID_GAME_OBJECT_DEF_BUILDING,
CHUNKID_GAME_OBJECT_BEACON,
CHUNKID_GAME_OBJECT_DEF_BEACON,
CHUNKID_GAME_OBJECT_REFINERY,
CHUNKID_GAME_OBJECT_DEF_REFINERY,
CHUNKID_GAME_OBJECT_POWERPLANT,
CHUNKID_GAME_OBJECT_DEF_POWERPLANT,
CHUNKID_GAME_OBJECT_SOLDIER_FACTORY,
CHUNKID_GAME_OBJECT_DEF_SOLDIER_FACTORY,
CHUNKID_GAME_OBJECT_VEHICLE_FACTORY,
CHUNKID_GAME_OBJECT_DEF_VEHICLE_FACTORY,
CHUNKID_GAME_OBJECT_AIRSTRIP,
CHUNKID_GAME_OBJECT_DEF_AIRSTRIP,
CHUNKID_GAME_OBJECT_WARFACTORY,
CHUNKID_GAME_OBJECT_DEF_WARFACTORY,
CHUNKID_GAME_OBJECT_COMCENTER,
CHUNKID_GAME_OBJECT_DEF_COMCENTER,
CHUNKID_GAME_OBJECT_REPAIR_BAY,
CHUNKID_GAME_OBJECT_DEF_REPAIR_BAY,
CHUNKID_MAPMGR,
CHUNKID_ENCYCLOPEDIAMGR,
CHUNKID_GAME_OBJECT_MENDOZA_BOSS,
CHUNKID_GAME_OBJECT_DEF_MENDOZA_BOSS,
CHUNKID_GAME_OBJECT_RAVESHAW_BOSS,
CHUNKID_GAME_OBJECT_DEF_RAVESHAW_BOSS,
CHUNKID_GAME_OBJECT_OBSERVERS_BEGIN = CHUNKID_COMBAT_BEGIN + 0x200,
CHUNKID_SOLDIER_OBSERVER,
CHUNKID_BEACON_MONITOR,
CHUNKID_BUILDINGS_BEGIN = CHUNKID_COMBAT_BEGIN + 0x301,
CHUNKID_BUILDING,
CHUNKID_BUILDINGS_DEF_BEGIN = CHUNKID_COMBAT_BEGIN + 0x401,
CHUNKID_BUILDING_DEF,
CHUNKID_ACTION_CODE_BEGIN = CHUNKID_COMBAT_BEGIN + 0x500,
CHUNKID_ACTION_CODE_FOLLOW_INPUT,
CHUNKID_ACTION_CODE_STAND,
CHUNKID_ACTION_CODE_GOTO,
CHUNKID_ACTION_CODE_ENTER_EXIT,
CHUNKID_ACTION_CODE_ATTACK,
CHUNKID_ACTION_CODE_PLAY_ANIMATION,
CHUNKID_ACTION_CODE_FACE_LOCATION,
CHUNKID_ACTION_CODE_DIVE,
CHUNKID_ACTION_CODE_CONVERSATION,
CHUNKID_ACTION_CODE_DOCK,
CHUNKID_GLOBAL_SETTINGS_DEF = CHUNKID_COMBAT_BEGIN + 0x600,
CHUNKID_GLOBAL_SETTINGS_DEF_HUMAN_LOITER,
CHUNKID_GLOBAL_SETTINGS_DEF_GENERAL,
CHUNKID_GLOBAL_SETTINGS_DEF_HUD,
CHUNKID_GLOBAL_SETTINGS_DEF_EVA,
CHUNKID_GLOBAL_SETTINGS_DEF_CHAR_CLASS,
CHUNKID_GLOBAL_SETTINGS_DEF_HUMAN_ANIM_OVERRIDE,
CHUNKID_GLOBAL_SETTINGS_DEF_PURCHASE,
CHUNKID_GLOBAL_SETTINGS_DEF_TEAM_PURCHASE,
CHUNKID_GLOBAL_SETTINGS_DEF_CNCMODE,
CHUNKID_CONVERSATION_MGR = CHUNKID_COMBAT_BEGIN + 0x700,
CHUNKID_WEATHER_MGR = CHUNKID_COMBAT_BEGIN + 0x800,
CHUNKID_PLAYER_DATA = CHUNKID_COMBAT_BEGIN + 0x900,
CHUNKID_PLAYER_DATA_CPLAYER,
};
/*
** Game Object CLASSIDs
*/
enum {
CLASSID_GAME_OBJECT_DEF_SOLDIER = CLASSID_GAME_OBJECTS + 1,
XXXCLASSID_GAME_OBJECT_DEF_COMMANDO,
CLASSID_GAME_OBJECT_DEF_POWERUP,
CLASSID_GAME_OBJECT_DEF_SIMPLE,
XXXCLASSID_GAME_OBJECT_DEF_SIMPLE3,
CLASSID_GAME_OBJECT_DEF_C4,
CLASSID_GAME_OBJECT_DEF_SAMSITE,
XXCLASSID_GAME_OBJECT_DEF_TANK,
XXCLASSID_GAME_OBJECT_DEF_TURRET,
XXCLASSID_GAME_OBJECT_DEF_BIKE,
XXCLASSID_GAME_OBJECT_DEF_FLYING,
XXCLASSID_GAME_OBJECT_DEF_CAR,
CLASSID_SPAWNER_DEF,
CLASSID_GAME_OBJECT_DEF_SCRIPT_ZONE,
CLASSID_GAME_OBJECT_DEF_TRANSITION,
CLASSID_GAME_OBJECT_DEF_VEHICLE,
CLASSID_GAME_OBJECT_DEF_CINEMATIC,
CLASSID_GAME_OBJECT_DEF_DAMAGE_ZONE,
CLASSID_GAME_OBJECT_DEF_SPECIAL_EFFECTS,
CLASSID_GAME_OBJECT_DEF_SAKURA_BOSS,
XXXCLASSID_GAME_OBJECT_DEF_BUILDING,
CLASSID_GAME_OBJECT_DEF_BEACON,
CLASSID_GAME_OBJECT_DEF_MENDOZA_BOSS,
CLASSID_GAME_OBJECT_DEF_RAVESHAW_BOSS
// MISC DEFINITIONS
};
/*
** Munitions CLASSIDs
*/
enum {
CLASSID_DEF_WEAPON = CLASSID_MUNITIONS + 1,
CLASSID_DEF_AMMO,
CLASSID_DEF_EXPLOSION,
};
/*
** Building CLASSIDs
*/
enum {
CLASSID_GAME_OBJECT_DEF_BUILDING = CLASSID_BUILDINGS + 1,
CLASSID_GAME_OBJECT_DEF_REFINERY,
CLASSID_GAME_OBJECT_DEF_POWERPLANT,
CLASSID_GAME_OBJECT_DEF_SOLDIER_FACTORY,
CLASSID_GAME_OBJECT_DEF_VEHICLE_FACTORY,
CLASSID_GAME_OBJECT_DEF_AIRSTRIP,
CLASSID_GAME_OBJECT_DEF_WARFACTORY,
CLASSID_GAME_OBJECT_DEF_COMCENTER,
CLASSID_GAME_OBJECT_DEF_REPAIR_BAY,
};
/*
** GlobalSettings CLASSIDs
*/
enum {
CLASSID_GLOBAL_SETTINGS_DEF = CLASSID_GLOBAL_SETTINGS + 1,
CLASSID_GLOBAL_SETTINGS_DEF_HUMAN_LOITER,
CLASSID_GLOBAL_SETTINGS_DEF_GENERAL,
CLASSID_GLOBAL_SETTINGS_DEF_HUD,
CLASSID_GLOBAL_SETTINGS_DEF_EVA,
CLASSID_GLOBAL_SETTINGS_DEF_CHAR_CLASS,
CLASSID_GLOBAL_SETTINGS_DEF_HUMAN_ANIM_OVERRIDE,
CLASSID_GLOBAL_SETTINGS_DEF_PURCHASE,
CLASSID_GLOBAL_SETTINGS_DEF_TEAM_PURCHASE,
CLASSID_GLOBAL_SETTINGS_DEF_CNCMODE,
};
#endif // COMBATCHUNKID_H

View File

@@ -0,0 +1,112 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Renegade *
* *
* $Archive:: /Commando/Code/Combat/combatdazzle.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 6/15/01 9:09a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* CombatDazzleClass::Compute_Dazzle_Visibility -- Computes visibility of a dazzle object in *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "combatdazzle.h"
#include "rinfo.h"
#include "camera.h"
#include "pscene.h"
#include "physcoltest.h"
#include "phys.h"
#include "combat.h"
#include "soldier.h"
CombatDazzleClass _TheCombatDazzleHandler;
/***********************************************************************************************
* CombatDazzleClass::Compute_Dazzle_Visibility -- Computes visibility of a dazzle object in t *
* *
* This dazzle visibility handler is used for the background and game scene in renegade. *
* *
* INPUT: *
* *
* OUTPUT: *
* *
* WARNINGS: *
* *
* HISTORY: *
* 6/13/2001 gth : Created. *
*=============================================================================================*/
float CombatDazzleClass::Compute_Dazzle_Visibility
(
RenderInfoClass & rinfo,
DazzleRenderObjClass * obj,
const Vector3 & point
) const
{
/*
** If we are in first-person mode, don't collide against the star
*/
bool ignore_player = CombatManager::Is_First_Person();
if (ignore_player) {
if (COMBAT_STAR != NULL) {
COMBAT_STAR->Peek_Physical_Object()->Inc_Ignore_Counter();
}
}
/*
** Cast a ray from the camera to the dazzle position
*/
CastResultStruct res;
LineSegClass ray(rinfo.Camera.Get_Position(),point);
PhysRayCollisionTestClass raytest(ray,&res,0,COLLISION_TYPE_PROJECTILE);
PhysicsSceneClass * scene = PhysicsSceneClass::Get_Instance();
if (scene != NULL) {
scene->Cast_Ray(raytest);
}
/*
** Done
*/
if (ignore_player) {
if (COMBAT_STAR != NULL) {
COMBAT_STAR->Peek_Physical_Object()->Dec_Ignore_Counter();
}
}
if (res.Fraction == 1.0f) {
return 1.0f;
} else {
return 0.0f;
}
}

View File

@@ -0,0 +1,62 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Renegade *
* *
* $Archive:: /Commando/Code/Combat/combatdazzle.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 6/13/01 9:05a $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBATDAZZLE_H
#define COMBATDAZZLE_H
#include "always.h"
#include "dazzle.h"
/**
** CombatDazzleClass - this class handles the visibility callback for the combat scene.
** This handler should be installed while the background scene and the game scene
** are rendered and it determines visibility by asking the game scene to cast a ray
** from the camera to the dazzle position.
*/
class CombatDazzleClass : public DazzleVisibilityClass
{
float Compute_Dazzle_Visibility( RenderInfoClass & rinfo,
DazzleRenderObjClass * dazzle,
const Vector3 & point) const;
};
extern CombatDazzleClass _TheCombatDazzleHandler;
#endif

View File

@@ -0,0 +1,129 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/combatmaterialeffectmanager.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 10/19/01 10:16a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "combatmaterialeffectmanager.h"
#include "materialeffect.h"
#include "transitioneffect.h"
#include "assetmgr.h"
#include "texture.h"
#include "humanstate.h"
const char * DEATH_TRANSITION_TEXTURE = "REN_death.tga";
const char * SPAWN_TRANSITION_TEXTURE = "REN_spawn.tga";
const char * HEALTH_TEXTURE = "REN_repair.tga";
const char * ELECTROCUTION_TEXTURE = "REN_shock.tga";
const float SPAWN_TRANSITION_TIME = 2.0f;
TransitionEffectClass *
CombatMaterialEffectManager::Get_Spawn_Effect(void)
{
TransitionEffectClass * effect = NEW_REF(TransitionEffectClass,());
effect->Set_Parameter(1.0f);
effect->Set_Target_Parameter(0.0f);
effect->Set_Transition_Time(SPAWN_TRANSITION_TIME);
effect->Enable_Remove_On_Complete(true);
effect->Set_Max_Intensity(0.25f);
TextureClass * tex = WW3DAssetManager::Get_Instance()->Get_Texture(SPAWN_TRANSITION_TEXTURE);
effect->Set_Texture(tex);
REF_PTR_RELEASE(tex);
return effect;
}
TransitionEffectClass *
CombatMaterialEffectManager::Get_Death_Effect(void)
{
TransitionEffectClass * effect = NEW_REF(TransitionEffectClass,());
effect->Set_Parameter(0.0f);
effect->Set_Target_Parameter(1.0f);
effect->Set_Start_Delay(0.75f * CORPSE_PERSIST_TIME);
effect->Set_Transition_Time(0.25f * CORPSE_PERSIST_TIME);
effect->Set_Max_Intensity(0.5f);
effect->Set_Max_UV_Velocity(Vector2(3.75f,-6.0f));
TextureClass * tex = WW3DAssetManager::Get_Instance()->Get_Texture(DEATH_TRANSITION_TEXTURE);
effect->Set_Texture(tex);
REF_PTR_RELEASE(tex);
return effect;
}
TransitionEffectClass *
CombatMaterialEffectManager::Get_Health_Effect(void)
{
TransitionEffectClass * effect = NEW_REF(TransitionEffectClass,());
effect->Set_Parameter(0.0f);
effect->Set_Target_Parameter(0.49f);
effect->Set_Transition_Time(1.0f);
effect->Set_Max_Intensity(0.5f);
effect->Set_Min_UV_Velocity(Vector2(0.0f,-3.0f));
effect->Set_Max_UV_Velocity(Vector2(0.0f,-3.0f));
TextureClass * tex = WW3DAssetManager::Get_Instance()->Get_Texture(HEALTH_TEXTURE);
effect->Set_Texture(tex);
REF_PTR_RELEASE(tex);
return effect;
}
TransitionEffectClass *
CombatMaterialEffectManager::Get_Electrocution_Effect(void)
{
TransitionEffectClass * effect = NEW_REF(TransitionEffectClass,());
effect->Set_Parameter(0.0f);
effect->Set_Target_Parameter(0.49f);
effect->Set_Transition_Time(1.0f);
effect->Set_Max_Intensity(0.5f);
effect->Set_Min_UV_Velocity(Vector2(0.0f,-3.0f));
effect->Set_Max_UV_Velocity(Vector2(0.0f,-3.0f));
TextureClass * tex = WW3DAssetManager::Get_Instance()->Get_Texture(ELECTROCUTION_TEXTURE);
effect->Set_Texture(tex);
REF_PTR_RELEASE(tex);
return effect;
}

View File

@@ -0,0 +1,63 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/Combat/combatmaterialeffectmanager.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 8/06/01 5:05p $*
* *
* $Revision:: 1 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef COMBATMATERIALEFFECTMANAGER_H
#define COMBATMATERIALEFFECTMANAGER_H
#include "always.h"
class TransitionEffectClass;
class CombatMaterialEffectManager
{
public:
static TransitionEffectClass * Get_Spawn_Effect(void);
static TransitionEffectClass * Get_Death_Effect(void);
static TransitionEffectClass * Get_Health_Effect(void);
static TransitionEffectClass * Get_Electrocution_Effect(void);
};
#endif

View File

@@ -0,0 +1,60 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/combatphysobserver.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 2/08/01 11:23a $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBATPHYSOBSERVER_H
#define COMBATPHYSOBSERVER_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef PHYSOBSERVER_H
#include "physobserver.h"
#endif
class DamageableGameObj;
class PhysicalGameObj;
class BuildingGameObj;
class CombatPhysObserverClass : public PhysObserverClass {
public:
virtual DamageableGameObj * As_DamageableGameObj( void ) { return NULL; }
virtual PhysicalGameObj * As_PhysicalGameObj( void ) { return NULL; }
virtual BuildingGameObj * As_BuildingGameObj( void ) { return NULL; }
};
#endif // COMBATPHYSOBSERVER_H

View File

@@ -0,0 +1,238 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/combatsaveload.cpp $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 1/17/02 11:58a $*
* *
* $Revision:: 34 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "combatsaveload.h"
#include "chunkio.h"
#include "gameobjmanager.h"
#include "combat.h"
#include "debug.h"
#include "spawn.h"
#include "timemgr.h"
#include "scripts.h"
#include "persistentgameobjobserver.h"
#include "wwmemlog.h"
#include "cover.h"
#include "objectives.h"
#include "radar.h"
#include "building.h"
#include "bullet.h"
#include "backgroundmgr.h"
#include "weathermgr.h"
#include "weaponview.h"
#include "hud.h"
#include "screenfademanager.h"
/*
**
*/
CombatSaveLoadClass _CombatSaveLoad;
enum {
CHUNKID_GAMEOBJMANAGER = 916991654,
CHUNKID_COMBAT_GAME_MODE,
XXX_CHUNKID_TRANSITIONS,
CHUNKID_SPAWNERS,
XXXCHUNKID_TIME,
CHUNKID_SCRIPTS,
CHUNKID_PERSISTENT_GAME_OBJ_OBSERVERS,
CHUNKID_COVER,
CHUNKID_OBJECTIVES,
CHUNKID_RADAR,
XXXCHUNKID_BUILDINGS,
CHUNKID_GAME_OBJ_OBSERVERS,
CHUNKID_BULLETS,
CHUNKID_WEAPON_VIEW,
CHUNKID_DYNAMIC_BACKGROUND,
CHUNKID_DYNAMIC_WEATHER,
CHUNKID_HUD,
CHUNKID_SCREEN_FADE,
};
/*
**
*/
bool CombatSaveLoadClass::Save( ChunkSaveClass &csave )
{
WWMEMLOG(MEM_GAMEDATA);
csave.Begin_Chunk( CHUNKID_GAMEOBJMANAGER );
GameObjManager::Save( csave );
csave.End_Chunk();
// CombatManager should load before scripts for SyncTime
csave.Begin_Chunk( CHUNKID_COMBAT_GAME_MODE );
CombatManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_SPAWNERS );
SpawnManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_SCRIPTS );
ScriptManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_PERSISTENT_GAME_OBJ_OBSERVERS );
PersistentGameObjObserverManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_COVER );
CoverManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_OBJECTIVES );
ObjectiveManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_RADAR );
RadarManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_GAME_OBJ_OBSERVERS );
GameObjObserverManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_BULLETS );
BulletManager::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_WEAPON_VIEW );
WeaponViewClass::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_DYNAMIC_BACKGROUND );
BackgroundMgrClass::Save_Dynamic( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_DYNAMIC_WEATHER );
WeatherMgrClass::Save_Dynamic( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_HUD );
HUDClass::Save( csave );
csave.End_Chunk();
csave.Begin_Chunk( CHUNKID_SCREEN_FADE );
ScreenFadeManager::Save( csave );
csave.End_Chunk();
return true;
}
bool CombatSaveLoadClass::Load( ChunkLoadClass &cload )
{
WWMEMLOG(MEM_GAMEDATA);
while (cload.Open_Chunk()) {
switch(cload.Cur_Chunk_ID()) {
case CHUNKID_GAMEOBJMANAGER:
GameObjManager::Load( cload );
break;
case CHUNKID_COMBAT_GAME_MODE:
CombatManager::Load( cload );
break;
case CHUNKID_SPAWNERS:
SpawnManager::Load( cload );
break;
case CHUNKID_SCRIPTS:
ScriptManager::Load( cload );
break;
case CHUNKID_PERSISTENT_GAME_OBJ_OBSERVERS:
PersistentGameObjObserverManager::Load( cload );
break;
case CHUNKID_COVER:
CoverManager::Load( cload );
break;
case CHUNKID_OBJECTIVES:
ObjectiveManager::Load( cload );
break;
case CHUNKID_RADAR:
RadarManager::Load( cload );
break;
case CHUNKID_GAME_OBJ_OBSERVERS:
GameObjObserverManager::Load( cload );
break;
case CHUNKID_BULLETS:
BulletManager::Load( cload );
break;
case CHUNKID_WEAPON_VIEW:
WeaponViewClass::Load( cload );
break;
case CHUNKID_DYNAMIC_BACKGROUND:
BackgroundMgrClass::Load_Dynamic( cload );
break;
case CHUNKID_DYNAMIC_WEATHER:
WeatherMgrClass::Load_Dynamic( cload );
break;
case CHUNKID_HUD:
HUDClass::Load( cload );
break;
case CHUNKID_SCREEN_FADE:
ScreenFadeManager::Load( cload );
break;
default:
Debug_Say(( "Unrecognized CombatSaveLoad chunkID\n" ));
break;
}
cload.Close_Chunk();
}
SaveLoadSystemClass::Register_Post_Load_Callback(this);
return true;
}
void CombatSaveLoadClass::On_Post_Load(void)
{
}

View File

@@ -0,0 +1,76 @@
/*
** 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/>.
*/
/***********************************************************************************************
*** Confidential - Westwood Studios ***
***********************************************************************************************
* *
* Project Name : Commando *
* *
* $Archive:: /Commando/Code/Combat/combatsaveload.h $*
* *
* $Author:: Byon_g $*
* *
* $Modtime:: 11/02/00 6:08p $*
* *
* $Revision:: 5 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef COMBATSAVELOAD_H
#define COMBATSAVELOAD_H
#ifndef ALWAYS_H
#include "always.h"
#endif
#ifndef SAVELOADSUBSYSTEM_H
#include "saveloadsubsystem.h"
#endif
#ifndef COMBATCHUNKID_H
#include "combatchunkid.h"
#endif
/*
**
*/
class CombatSaveLoadClass : public SaveLoadSubSystemClass {
public:
CombatSaveLoadClass(void) {}
virtual ~CombatSaveLoadClass(void) {}
virtual uint32 Chunk_ID (void) const { return CHUNKID_COMBAT; }
protected:
virtual bool Save( ChunkSaveClass &csave );
virtual bool Load( ChunkLoadClass &cload );
virtual const char* Name() const { return "CombatSaveLoadClass"; }
virtual void On_Post_Load (void);
};
/*
**
*/
extern CombatSaveLoadClass _CombatSaveLoad;
#endif // COMBATSAVELOAD_H

Some files were not shown because too many files have changed in this diff Show More