321 lines
12 KiB
C++
321 lines
12 KiB
C++
/*
|
|
** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// FILE: Module.h /////////////////////////////////////////////////////////////////////////////////
|
|
// Author: Colin Day, September 2001
|
|
// Desc: Object and drawable modules and actions. These are simply just class
|
|
// instances that we can assign to objects, drawables, and things to contain
|
|
// data and code for specific events, or just to hold data
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#pragma once
|
|
|
|
#ifndef __MODULE_H_
|
|
#define __MODULE_H_
|
|
|
|
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
|
#include "Common/INI.h"
|
|
#include "Common/GameMemory.h"
|
|
#include "Common/NameKeyGenerator.h"
|
|
#include "Common/Snapshot.h"
|
|
|
|
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
|
enum TimeOfDay;
|
|
enum StaticGameLODLevel;
|
|
class Drawable;
|
|
class Object;
|
|
class Player;
|
|
class Thing;
|
|
class W3DModelDrawModuleData; // ugh, hack (srj)
|
|
struct FieldParse;
|
|
|
|
// TYPES //////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------------------------------
|
|
enum ModuleType
|
|
{
|
|
MODULETYPE_BEHAVIOR = 0,
|
|
|
|
//
|
|
// drawable module types - you should *NOT* remove drawable module types, we write
|
|
// modules into save game files in buckets of module types ... if you do remove one
|
|
// here you will have to update the xfer code for a drawable.
|
|
//
|
|
// ALSO note that new drawable module types should go at the end of the existing drawable modules
|
|
//
|
|
MODULETYPE_DRAW = 1,
|
|
MODULETYPE_CLIENT_UPDATE = 2,
|
|
// put new drawable module types here
|
|
|
|
NUM_MODULE_TYPES, // keep this last!
|
|
|
|
FIRST_DRAWABLE_MODULE_TYPE = MODULETYPE_DRAW,
|
|
LAST_DRAWABLE_MODULE_TYPE = MODULETYPE_CLIENT_UPDATE,
|
|
NUM_DRAWABLE_MODULE_TYPES = (LAST_DRAWABLE_MODULE_TYPE - FIRST_DRAWABLE_MODULE_TYPE + 1)
|
|
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------------------------------
|
|
enum ModuleInterfaceType
|
|
{
|
|
MODULEINTERFACE_UPDATE = 0x00000001,
|
|
MODULEINTERFACE_DIE = 0x00000002,
|
|
MODULEINTERFACE_DAMAGE = 0x00000004,
|
|
MODULEINTERFACE_CREATE = 0x00000008,
|
|
MODULEINTERFACE_COLLIDE = 0x00000010,
|
|
MODULEINTERFACE_BODY = 0x00000020,
|
|
MODULEINTERFACE_CONTAIN = 0x00000040,
|
|
MODULEINTERFACE_UPGRADE = 0x00000080,
|
|
MODULEINTERFACE_SPECIAL_POWER = 0x00000100,
|
|
MODULEINTERFACE_DESTROY = 0x00000200,
|
|
MODULEINTERFACE_DRAW = 0x00000400,
|
|
MODULEINTERFACE_CLIENT_UPDATE = 0x00000800
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** Base class for data-read-from-INI for modules. */
|
|
//-------------------------------------------------------------------------------------------------
|
|
/// @todo srj -- make ModuleData be MemoryPool based
|
|
class ModuleData : public Snapshot
|
|
{
|
|
public:
|
|
ModuleData() { }
|
|
virtual ~ModuleData() { }
|
|
|
|
void setModuleTagNameKey( NameKeyType key ) { m_moduleTagNameKey = key; }
|
|
NameKeyType getModuleTagNameKey() const { return m_moduleTagNameKey; }
|
|
|
|
virtual Bool isAiModuleData() const { return false; }
|
|
|
|
// ugh, hack
|
|
virtual const W3DModelDrawModuleData* getAsW3DModelDrawModuleData() const { return NULL; }
|
|
virtual StaticGameLODLevel getMinimumRequiredGameLOD() const { return (StaticGameLODLevel)0;}
|
|
|
|
static void buildFieldParse(MultiIniFieldParse& p)
|
|
{
|
|
// nothing
|
|
}
|
|
|
|
public:
|
|
virtual void crc( Xfer *xfer ) {}
|
|
virtual void xfer( Xfer *xfer ) {}
|
|
virtual void loadPostProcess( void ) {}
|
|
|
|
private:
|
|
NameKeyType m_moduleTagNameKey; ///< module tag key, unique among all modules for an object instance
|
|
};
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
// This macro is to assist in the creation of new modules, contains the common
|
|
// things that all module definitions must have in order to work with
|
|
// the module creation factory
|
|
//-------------------------------------------------------------------------------------------------
|
|
#define MAKE_STANDARD_MODULE_MACRO( cls ) \
|
|
public: \
|
|
static Module* friend_newModuleInstance( Thing *thing, const ModuleData* moduleData ) { return newInstance( cls )( thing, moduleData ); } \
|
|
virtual NameKeyType getModuleNameKey() const { static NameKeyType nk = NAMEKEY(#cls); return nk; } \
|
|
protected: \
|
|
virtual void crc( Xfer *xfer ); \
|
|
virtual void xfer( Xfer *xfer ); \
|
|
virtual void loadPostProcess( void );
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// For the creation of abstract module classes
|
|
// ------------------------------------------------------------------------------------------------
|
|
#define MAKE_STANDARD_MODULE_MACRO_ABC( cls ) \
|
|
protected: \
|
|
virtual void crc( Xfer *xfer ); \
|
|
virtual void xfer( Xfer *xfer ); \
|
|
virtual void loadPostProcess( void );
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
// only use this macro for an ABC. for a real class, use MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA.
|
|
#define MAKE_STANDARD_MODULE_DATA_MACRO_ABC( cls, clsmd ) \
|
|
private: \
|
|
const clsmd* get##clsmd() const { return (clsmd*)getModuleData(); } \
|
|
public: \
|
|
static ModuleData* friend_newModuleData(INI* ini) \
|
|
{ \
|
|
clsmd* data = MSGNEW( "AllModuleData" ) clsmd; \
|
|
if (ini) ini->initFromINIMultiProc(data, clsmd::buildFieldParse); \
|
|
return data; \
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
#define MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( cls, clsmd ) \
|
|
MAKE_STANDARD_MODULE_MACRO(cls) \
|
|
MAKE_STANDARD_MODULE_DATA_MACRO_ABC(cls, clsmd)
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** Common interface for thing modules, we want a single common base class
|
|
* for all the modules (either object or drawable) so that we can use
|
|
* a single module factory to handle instancing them ... it's just
|
|
* convenient this way */
|
|
//-------------------------------------------------------------------------------------------------
|
|
class Module : public MemoryPoolObject,
|
|
public Snapshot
|
|
{
|
|
|
|
MEMORY_POOL_GLUE_ABC( Module ) ///< this abstract class needs memory pool hooks
|
|
|
|
public:
|
|
|
|
Module(const ModuleData* moduleData) : m_moduleData(moduleData) { }
|
|
// virtual destructor prototype defined by MemoryPoolObject
|
|
|
|
// this method should NEVER be overridden by user code, only via the MAKE_STANDARD_MODULE_xxx macros!
|
|
// it should also NEVER be called directly; it's only for use by ModuleFactory!
|
|
static ModuleData* friend_newModuleData(INI* ini);
|
|
|
|
virtual NameKeyType getModuleNameKey() const = 0;
|
|
|
|
inline NameKeyType getModuleTagNameKey() const { return getModuleData()->getModuleTagNameKey(); }
|
|
|
|
/** this is called after all the Modules for a given Thing are created; it
|
|
allows Modules to resolve any inter-Module dependencies.
|
|
*/
|
|
virtual void onObjectCreated() { }
|
|
|
|
/**
|
|
this is called whenever a drawable is bound to the object.
|
|
drawable is NOT guaranteed to be non-null.
|
|
*/
|
|
virtual void onDrawableBoundToObject() { }
|
|
|
|
/// preload any assets we might have for this time of day
|
|
virtual void preloadAssets( TimeOfDay timeOfDay ) { }
|
|
|
|
/** onDelete() will be called on all modules contained by an object or drawable before
|
|
the actual deletion of each of those modules happens */
|
|
virtual void onDelete( void ) { }
|
|
|
|
protected:
|
|
|
|
inline const ModuleData* getModuleData() const { return m_moduleData; }
|
|
|
|
virtual void crc( Xfer *xfer );
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void );
|
|
|
|
private:
|
|
const ModuleData* m_moduleData;
|
|
|
|
}; // end Module
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
//=================================================================================================
|
|
// OBJECT Module interface and modules
|
|
//=================================================================================================
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** Module interface specific for Objects, this is really just to make a clear distinction
|
|
* between modules intended for use in objects and modules intended for use
|
|
* in drawables */
|
|
//-------------------------------------------------------------------------------------------------
|
|
class ObjectModule : public Module
|
|
{
|
|
|
|
MEMORY_POOL_GLUE_ABC( ObjectModule ) ///< this abstract class needs memory pool hooks
|
|
|
|
public:
|
|
|
|
ObjectModule( Thing *thing, const ModuleData* moduleData );
|
|
// virtual destructor prototype defined by MemoryPoolObject
|
|
|
|
virtual void onCapture( Player *oldOwner, Player *newOwner ) { }
|
|
|
|
protected:
|
|
|
|
inline Object *getObject() { return m_object; }
|
|
inline const Object *getObject() const { return m_object; }
|
|
|
|
virtual void crc( Xfer *xfer );
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void );
|
|
|
|
private:
|
|
|
|
// it shouldn't be legal for subclasses to ever modify this, only to look at it;
|
|
// so, we'll enforce this by making it private and providing a protected access method.
|
|
Object *m_object; ///< the object this module is a part of
|
|
|
|
};
|
|
//-------------------------------------------------------------------------------------------------
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//=================================================================================================
|
|
// DRAWABLE module interface and modules
|
|
//=================================================================================================
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** Module interface specific for Drawbles, this is really just to make a clear distinction
|
|
* between modules intended for use in objects and modules intended for use
|
|
* in drawables */
|
|
//-------------------------------------------------------------------------------------------------
|
|
class DrawableModule : public Module
|
|
{
|
|
|
|
MEMORY_POOL_GLUE_ABC( DrawableModule ) ///< this abstract class needs memory pool hooks
|
|
|
|
public:
|
|
|
|
DrawableModule( Thing *thing, const ModuleData* moduleData );
|
|
// virtual destructor prototype defined by MemoryPoolObject
|
|
|
|
protected:
|
|
|
|
inline Drawable *getDrawable() { return m_drawable; }
|
|
inline const Drawable *getDrawable() const { return m_drawable; }
|
|
|
|
virtual void crc( Xfer *xfer );
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void );
|
|
|
|
private:
|
|
|
|
// it shouldn't be legal for subclasses to ever modify this, only to look at it;
|
|
// so, we'll enforce this by making it private and providing a protected access method.
|
|
Drawable *m_drawable; ///< the drawble this module is a part of
|
|
|
|
};
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------
|
|
/** VARIOUS MODULE INTERFACES */
|
|
//-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
#endif // __MODULE_H_
|
|
|