Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
parent
2e338c00cb
commit
3d0ee53a05
6072 changed files with 2283311 additions and 0 deletions
758
Generals/Code/GameEngine/Include/Common/ThingTemplate.h
Normal file
758
Generals/Code/GameEngine/Include/Common/ThingTemplate.h
Normal file
|
@ -0,0 +1,758 @@
|
|||
/*
|
||||
** 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: ThingTemplate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, April 2001
|
||||
// Desc: Thing templates are a 'roadmap' to creating things
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __THINGTEMPLATE_H_
|
||||
#define __THINGTEMPLATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Lib/BaseType.h"
|
||||
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "Common/FileSystem.h"
|
||||
#include "Common/GameCommon.h"
|
||||
#include "Common/Geometry.h"
|
||||
#include "Common/KindOf.h"
|
||||
#include "Common/ModuleFactory.h"
|
||||
#include "Common/Overridable.h"
|
||||
#include "Common/ProductionPrerequisite.h"
|
||||
#include "Common/Science.h"
|
||||
#include "Common/UnicodeString.h"
|
||||
|
||||
#include "GameLogic/ArmorSet.h"
|
||||
#include "GameLogic/WeaponSet.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameClient/Color.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class AIUpdateModuleData;
|
||||
class Image;
|
||||
class Object;
|
||||
class Drawable;
|
||||
class ProductionPrerequisite;
|
||||
struct FieldParse;
|
||||
class Player;
|
||||
class INI;
|
||||
enum RadarPriorityType;
|
||||
enum ScienceType;
|
||||
enum EditorSortingType;
|
||||
enum ShadowType;
|
||||
class WeaponTemplateSet;
|
||||
class ArmorTemplateSet;
|
||||
class FXList;
|
||||
|
||||
// TYPEDEFS FOR FILE //////////////////////////////////////////////////////////////////////////////
|
||||
typedef std::map<AsciiString, AudioEventRTS> PerUnitSoundMap;
|
||||
typedef std::map<AsciiString, const FXList*> PerUnitFXMap;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//Code renderer handles these states now.
|
||||
//enum InventoryImageType
|
||||
//{
|
||||
// INV_IMAGE_ENABLED = 0,
|
||||
// INV_IMAGE_DISABLED,
|
||||
// INV_IMAGE_HILITE,
|
||||
// INV_IMAGE_PUSHED,
|
||||
//
|
||||
// INV_IMAGE_NUM_IMAGES // keep this last
|
||||
//
|
||||
//};
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
MAX_UPGRADE_CAMEO_UPGRADES = 5
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum ThingTemplateAudioType
|
||||
{
|
||||
TTAUDIO_voiceSelect, ///< Response when unit is selected
|
||||
TTAUDIO_voiceGroupSelect, ///< Response when a group of this unit is selected
|
||||
TTAUDIO_voiceSelectElite, ///< Response when unit is selected and elite
|
||||
TTAUDIO_voiceMove, ///< Response when unit moves
|
||||
TTAUDIO_voiceAttack, ///< Response when unit is told to attack
|
||||
TTAUDIO_voiceEnter, ///< Response when unit is told to enter a building
|
||||
TTAUDIO_voiceFear, ///< Response when unit is under attack
|
||||
TTAUDIO_voiceCreated, ///< Response when unit is created
|
||||
TTAUDIO_voiceNearEnemy, ///< Unit is near an enemy
|
||||
TTAUDIO_voiceTaskUnable, ///< Unit is told to do something impossible
|
||||
TTAUDIO_voiceTaskComplete, ///< Unit completes a move, or other task indicated
|
||||
TTAUDIO_voiceMeetEnemy, ///< Unit meets an enemy unit
|
||||
TTAUDIO_soundMoveStart, ///< Sound when unit starts moving
|
||||
TTAUDIO_soundMoveStartDamaged, ///< Sound when unit starts moving and is damaged
|
||||
TTAUDIO_soundMoveLoop, ///< Sound when unit is moving
|
||||
TTAUDIO_soundMoveLoopDamaged, ///< Sound when unit is moving and is damaged
|
||||
TTAUDIO_soundDie, ///< Sound when unit is dieing
|
||||
TTAUDIO_soundCrush, ///< Sound when unit is crushed
|
||||
TTAUDIO_soundAmbient, ///< Ambient sound for unit during normal status. Also the default sound
|
||||
TTAUDIO_soundAmbientDamaged, ///< Ambient sound for unit if damaged. Corresponds to body info damage
|
||||
TTAUDIO_soundAmbientReallyDamaged,///< Ambient sound for unit if badly damaged.
|
||||
TTAUDIO_soundAmbientRubble, ///< Ambient sound for unit if it is currently rubble. (Dam, for instance)
|
||||
TTAUDIO_soundStealthOn, ///< Sound when unit stealths
|
||||
TTAUDIO_soundStealthOff, ///< Sound when unit destealths
|
||||
TTAUDIO_soundCreated, ///< Sound when unit is created
|
||||
TTAUDIO_soundOnDamaged, ///< Sound when unit enters damaged state
|
||||
TTAUDIO_soundOnReallyDamaged, ///< Sound when unit enters reallyd damaged state
|
||||
TTAUDIO_soundDieFire, ///< Sound when unit dies by fire. NOTE: Replaces soundDie if present and unit dies by fire.
|
||||
TTAUDIO_soundDieToxin, ///< Sound when unit dies by Toxin. NOTE: Replaces soundDie if present and unit dies by fire.
|
||||
TTAUDIO_soundEnter, ///< Sound when another unit enters me.
|
||||
TTAUDIO_soundExit, ///< Sound when another unit exits me.
|
||||
TTAUDIO_soundPromotedVeteran, ///< Sound when unit gets promoted to Veteran level
|
||||
TTAUDIO_soundPromotedElite, ///< Sound when unit gets promoted to Elite level
|
||||
TTAUDIO_soundPromotedHero, ///< Sound when unit gets promoted to Hero level
|
||||
TTAUDIO_voiceGarrison, ///< Unit is ordered to enter a garrisonable building
|
||||
TTAUDIO_soundFalling, ///< This sound is actually called on a unit when it is exiting another.
|
||||
///< However, there is a soundExit which refers to the container, and this is only used for bombs falling from planes.
|
||||
#ifdef ALLOW_SURRENDER
|
||||
TTAUDIO_voiceSurrender, ///< Unit surrenders
|
||||
#endif
|
||||
TTAUDIO_voiceDefect, ///< Unit is forced to defect
|
||||
TTAUDIO_voiceAttackSpecial, ///< Unit is ordered to use a special attack
|
||||
TTAUDIO_voiceAttackAir, ///< Unit is ordered to attack an airborne unit
|
||||
TTAUDIO_voiceGuard, ///< Unit is ordered to guard an area
|
||||
|
||||
TTAUDIO_COUNT // keep last!
|
||||
};
|
||||
|
||||
class AudioArray
|
||||
{
|
||||
public:
|
||||
DynamicAudioEventRTS* m_audio[TTAUDIO_COUNT];
|
||||
|
||||
AudioArray()
|
||||
{
|
||||
for (Int i = 0; i < TTAUDIO_COUNT; ++i)
|
||||
m_audio[i] = NULL;
|
||||
}
|
||||
|
||||
~AudioArray()
|
||||
{
|
||||
for (Int i = 0; i < TTAUDIO_COUNT; ++i)
|
||||
if (m_audio[i])
|
||||
m_audio[i]->deleteInstance();
|
||||
}
|
||||
|
||||
AudioArray(const AudioArray& that)
|
||||
{
|
||||
for (Int i = 0; i < TTAUDIO_COUNT; ++i)
|
||||
{
|
||||
if (that.m_audio[i])
|
||||
m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]);
|
||||
else
|
||||
m_audio[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AudioArray& operator=(const AudioArray& that)
|
||||
{
|
||||
if (this != &that)
|
||||
{
|
||||
for (Int i = 0; i < TTAUDIO_COUNT; ++i)
|
||||
{
|
||||
if (that.m_audio[i])
|
||||
{
|
||||
if (m_audio[i])
|
||||
*m_audio[i] = *that.m_audio[i];
|
||||
else
|
||||
m_audio[i] = newInstance(DynamicAudioEventRTS)(*that.m_audio[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_audio[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Object class type enumeration */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum BuildCompletionType
|
||||
{
|
||||
BC_INVALID = 0,
|
||||
BC_APPEARS_AT_RALLY_POINT, ///< unit appears at rally point of its #1 prereq
|
||||
BC_PLACED_BY_PLAYER, ///< unit must be manually placed by player
|
||||
|
||||
BC_NUM_TYPES // leave this last
|
||||
};
|
||||
#ifdef DEFINE_BUILD_COMPLETION_NAMES
|
||||
static const char *BuildCompletionNames[] =
|
||||
{
|
||||
"INVALID",
|
||||
"APPEARS_AT_RALLY_POINT",
|
||||
"PLACED_BY_PLAYER",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif // end DEFINE_BUILD_COMPLETION_NAMES
|
||||
|
||||
enum BuildableStatus
|
||||
{
|
||||
// saved into savegames... do not change or remove values!
|
||||
BSTATUS_YES = 0,
|
||||
BSTATUS_IGNORE_PREREQUISITES,
|
||||
BSTATUS_NO,
|
||||
BSTATUS_ONLY_BY_AI,
|
||||
|
||||
BSTATUS_NUM_TYPES // leave this last
|
||||
};
|
||||
|
||||
#ifdef DEFINE_BUILDABLE_STATUS_NAMES
|
||||
static const char *BuildableStatusNames[] =
|
||||
{
|
||||
"Yes",
|
||||
"Ignore_Prerequisites",
|
||||
"No",
|
||||
"Only_By_AI",
|
||||
NULL
|
||||
};
|
||||
#endif // end DEFINE_BUILDABLE_STATUS_NAMES
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum ModuleParseMode
|
||||
{
|
||||
MODULEPARSE_NORMAL,
|
||||
MODULEPARSE_ADD_REMOVE_REPLACE,
|
||||
MODULEPARSE_INHERITABLE
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ModuleInfo
|
||||
{
|
||||
private:
|
||||
struct Nugget
|
||||
{
|
||||
AsciiString first;
|
||||
AsciiString m_moduleTag;
|
||||
const ModuleData* second;
|
||||
Int interfaceMask;
|
||||
Bool copiedFromDefault;
|
||||
Bool inheritable;
|
||||
|
||||
Nugget(const AsciiString& n, const AsciiString& moduleTag, const ModuleData* d, Int i, Bool inh)
|
||||
: first(n),
|
||||
m_moduleTag(moduleTag),
|
||||
second(d),
|
||||
interfaceMask(i),
|
||||
copiedFromDefault(false),
|
||||
inheritable(inh)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
std::vector<Nugget> m_info;
|
||||
|
||||
public:
|
||||
|
||||
ModuleInfo() { }
|
||||
|
||||
void addModuleInfo(ThingTemplate *thingTemplate, const AsciiString& name, const AsciiString& moduleTag, const ModuleData* data, Int interfaceMask, Bool inheritable);
|
||||
const ModuleInfo::Nugget *ModuleInfo::getNuggetWithTag( const AsciiString& tag ) const;
|
||||
|
||||
Int getCount() const
|
||||
{
|
||||
return m_info.size();
|
||||
}
|
||||
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
Bool containsPartialName(const char* n) const
|
||||
{
|
||||
for (int i = 0; i < m_info.size(); i++)
|
||||
if (strstr(m_info[i].first.str(), n) != NULL)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
AsciiString getNthName(Int i) const
|
||||
{
|
||||
if (i >= 0 && i < m_info.size())
|
||||
{
|
||||
return m_info[i].first;
|
||||
}
|
||||
return AsciiString::TheEmptyString;
|
||||
}
|
||||
|
||||
AsciiString getNthTag(Int i) const
|
||||
{
|
||||
if (i >= 0 && i < m_info.size())
|
||||
{
|
||||
return m_info[i].m_moduleTag;
|
||||
}
|
||||
return AsciiString::TheEmptyString;
|
||||
}
|
||||
|
||||
const ModuleData* getNthData(Int i) const
|
||||
{
|
||||
if (i >= 0 && i < m_info.size())
|
||||
{
|
||||
return m_info[i].second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// for use only by ThingTemplate::friend_getAIModuleInfo
|
||||
ModuleData* friend_getNthData(Int i);
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_info.clear();
|
||||
}
|
||||
|
||||
void setCopiedFromDefault(Bool v)
|
||||
{
|
||||
for (int i = 0; i < m_info.size(); i++)
|
||||
m_info[i].copiedFromDefault = v;
|
||||
}
|
||||
|
||||
Bool clearModuleDataWithTag(const AsciiString& tagToClear, AsciiString& clearedModuleNameOut);
|
||||
Bool clearCopiedFromDefaultEntries(Int interfaceMask);
|
||||
Bool clearAiModuleInfo();
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Definition of a thing template to read from our game data framework */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ThingTemplate : public Overridable
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ThingTemplate, "ThingTemplatePool" )
|
||||
|
||||
private:
|
||||
ThingTemplate(const ThingTemplate& that) : m_geometryInfo(that.m_geometryInfo)
|
||||
{
|
||||
DEBUG_CRASH(("This should never be called\n"));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
ThingTemplate();
|
||||
|
||||
// copy the guts of that into this, but preserve this' name, id, and list-links.
|
||||
void copyFrom(const ThingTemplate* that);
|
||||
|
||||
/// called by ThingFactory after all templates have been loaded.
|
||||
void resolveNames();
|
||||
|
||||
#ifdef LOAD_TEST_ASSETS
|
||||
void initForLTA(const AsciiString& name);
|
||||
inline AsciiString getLTAName() const { return m_LTAName; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
return a unique identifier suitable for identifying this ThingTemplate on machines playing
|
||||
across the net. this should be considered a Magic Cookie and used only for net traffic or
|
||||
similar sorts of things. To convert an id back to a ThingTemplate, use ThingFactory::findByID().
|
||||
Note that 0 is always an invalid id. NOTE that we are not referencing m_override here
|
||||
because even though we actually have multiple templates here representing overrides,
|
||||
we still only conceptually have one template and want to always use one single
|
||||
pointer for comparisons of templates. However, even if we did reference m_override
|
||||
the IDs would be the same for each one since every override first *COPIES* data
|
||||
from the current/parent template data.
|
||||
*/
|
||||
UnsignedShort getTemplateID() const { return m_templateID; }
|
||||
|
||||
// note that m_override is not used here, see getTemplateID(), for it is the same reasons
|
||||
const AsciiString& getName() const { return m_nameString; } ///< return the name of this template
|
||||
|
||||
/// get the display color (used for the editor)
|
||||
Color getDisplayColor() const { return m_displayColor; }
|
||||
|
||||
/// get the editor sorting
|
||||
EditorSortingType getEditorSorting() const { return (EditorSortingType)m_editorSorting; }
|
||||
|
||||
/// return true iff the template has the specified kindOf flag set.
|
||||
inline Bool isKindOf(KindOfType t) const
|
||||
{
|
||||
return TEST_KINDOFMASK(m_kindof, t);
|
||||
}
|
||||
|
||||
/// convenience for doing multiple kindof testing at once.
|
||||
inline Bool isKindOfMulti(const KindOfMaskType& mustBeSet, const KindOfMaskType& mustBeClear) const
|
||||
{
|
||||
return TEST_KINDOFMASK_MULTI(m_kindof, mustBeSet, mustBeClear);
|
||||
}
|
||||
|
||||
inline Bool isAnyKindOf( const KindOfMaskType& anyKindOf ) const
|
||||
{
|
||||
return TEST_KINDOFMASK_ANY(m_kindof, anyKindOf);
|
||||
}
|
||||
|
||||
/// set the display name
|
||||
const UnicodeString& getDisplayName() const { return m_displayName; } ///< return display name
|
||||
|
||||
RadarPriorityType getDefaultRadarPriority() const { return (RadarPriorityType)m_radarPriority; } ///< return radar priority from INI
|
||||
|
||||
// note, you should not call this directly; rather, call Object::getTransportSlotCount().
|
||||
Int getRawTransportSlotCount() const { return m_transportSlotCount; }
|
||||
|
||||
Real getFenceWidth() const { return m_fenceWidth; } // return fence width
|
||||
|
||||
Real getFenceXOffset() const { return m_fenceXOffset; } // return fence offset
|
||||
|
||||
Bool isBridge() const { return m_isBridge; } // return fence offset
|
||||
|
||||
// Only Object can ask this. Everyone else should ask the Object. In fact, you really should ask the Object everything.
|
||||
Real friend_getVisionRange() const { return m_visionRange; } ///< get vision range
|
||||
Real friend_getShroudClearingRange() const { return m_shroudClearingRange; } ///< get vision range for Shroud ONLY (Design requested split)
|
||||
|
||||
// This function is only for use by the AIUpdateModuleData::parseLocomotorSet function.
|
||||
AIUpdateModuleData *friend_getAIModuleInfo(void);
|
||||
|
||||
ShadowType getShadowType() const { return (ShadowType)m_shadowType; }
|
||||
Real getShadowSizeX() const { return m_shadowSizeX; }
|
||||
Real getShadowSizeY() const { return m_shadowSizeY; }
|
||||
Real getShadowOffsetX() const { return m_shadowOffsetX; }
|
||||
Real getShadowOffsetY() const { return m_shadowOffsetY; }
|
||||
|
||||
const AsciiString& getShadowTextureName( void ) const { return m_shadowTextureName; }
|
||||
UnsignedInt getOcclusionDelay(void) const { return m_occlusionDelay;}
|
||||
|
||||
const ModuleInfo& getBehaviorModuleInfo() const { return m_behaviorModuleInfo; }
|
||||
const ModuleInfo& getDrawModuleInfo() const { return m_drawModuleInfo; }
|
||||
const ModuleInfo& getClientUpdateModuleInfo() const { return m_clientUpdateModuleInfo; }
|
||||
|
||||
const Image *getSelectedPortraitImage( void ) const { return m_selectedPortraitImage; }
|
||||
const Image *getButtonImage( void ) const { return m_buttonImage; }
|
||||
|
||||
//Code renderer handles these states now.
|
||||
//const AsciiString& getInventoryImageName( InventoryImageType type ) const { return m_inventoryImage[ type ]; }
|
||||
|
||||
Int getSkillPointValue(Int level) const;
|
||||
|
||||
Int getExperienceValue(Int level) const { return m_experienceValues[level]; }
|
||||
Int getExperienceRequired(Int level) const {return m_experienceRequired[level]; }
|
||||
Bool isTrainable() const{return m_isTrainable; }
|
||||
|
||||
const AudioEventRTS *getVoiceSelect() const { return getAudio(TTAUDIO_voiceSelect); }
|
||||
const AudioEventRTS *getVoiceGroupSelect() const { return getAudio(TTAUDIO_voiceGroupSelect); }
|
||||
const AudioEventRTS *getVoiceMove() const { return getAudio(TTAUDIO_voiceMove); }
|
||||
const AudioEventRTS *getVoiceAttack() const { return getAudio(TTAUDIO_voiceAttack); }
|
||||
const AudioEventRTS *getVoiceEnter() const { return getAudio(TTAUDIO_voiceEnter); }
|
||||
const AudioEventRTS *getVoiceFear() const { return getAudio(TTAUDIO_voiceFear); }
|
||||
const AudioEventRTS *getVoiceSelectElite() const { return getAudio(TTAUDIO_voiceSelectElite); }
|
||||
const AudioEventRTS *getVoiceCreated() const { return getAudio(TTAUDIO_voiceCreated); }
|
||||
const AudioEventRTS *getVoiceNearEnemy() const { return getAudio(TTAUDIO_voiceNearEnemy); }
|
||||
const AudioEventRTS *getVoiceTaskUnable() const { return getAudio(TTAUDIO_voiceTaskUnable); }
|
||||
const AudioEventRTS *getVoiceTaskComplete() const { return getAudio(TTAUDIO_voiceTaskComplete); }
|
||||
const AudioEventRTS *getVoiceMeetEnemy() const { return getAudio(TTAUDIO_voiceMeetEnemy); }
|
||||
const AudioEventRTS *getVoiceGarrison() const { return getAudio(TTAUDIO_voiceGarrison); }
|
||||
#ifdef ALLOW_SURRENDER
|
||||
const AudioEventRTS *getVoiceSurrender() const { return getAudio(TTAUDIO_voiceSurrender); }
|
||||
#endif
|
||||
const AudioEventRTS *getVoiceDefect() const { return getAudio(TTAUDIO_voiceDefect); }
|
||||
const AudioEventRTS *getVoiceAttackSpecial() const { return getAudio(TTAUDIO_voiceAttackSpecial); }
|
||||
const AudioEventRTS *getVoiceAttackAir() const { return getAudio(TTAUDIO_voiceAttackAir); }
|
||||
const AudioEventRTS *getVoiceGuard() const { return getAudio(TTAUDIO_voiceGuard); }
|
||||
const AudioEventRTS *getSoundMoveStart() const { return getAudio(TTAUDIO_soundMoveStart); }
|
||||
const AudioEventRTS *getSoundMoveStartDamaged() const { return getAudio(TTAUDIO_soundMoveStartDamaged); }
|
||||
const AudioEventRTS *getSoundMoveLoop() const { return getAudio(TTAUDIO_soundMoveLoop); }
|
||||
const AudioEventRTS *getSoundMoveLoopDamaged() const { return getAudio(TTAUDIO_soundMoveLoopDamaged); }
|
||||
const AudioEventRTS *getSoundDie() const { return getAudio(TTAUDIO_soundDie); }
|
||||
const AudioEventRTS *getSoundCrush() const { return getAudio(TTAUDIO_soundCrush); }
|
||||
const AudioEventRTS *getSoundAmbient() const { return getAudio(TTAUDIO_soundAmbient); }
|
||||
const AudioEventRTS *getSoundAmbientDamaged() const { return getAudio(TTAUDIO_soundAmbientDamaged); }
|
||||
const AudioEventRTS *getSoundAmbientReallyDamaged() const { return getAudio(TTAUDIO_soundAmbientReallyDamaged); }
|
||||
const AudioEventRTS *getSoundAmbientRubble() const { return getAudio(TTAUDIO_soundAmbientRubble); }
|
||||
const AudioEventRTS *getSoundStealthOn() const { return getAudio(TTAUDIO_soundStealthOn); }
|
||||
const AudioEventRTS *getSoundStealthOff() const { return getAudio(TTAUDIO_soundStealthOff); }
|
||||
const AudioEventRTS *getSoundCreated() const { return getAudio(TTAUDIO_soundCreated); }
|
||||
const AudioEventRTS *getSoundOnDamaged() const { return getAudio(TTAUDIO_soundOnDamaged); }
|
||||
const AudioEventRTS *getSoundOnReallyDamaged() const { return getAudio(TTAUDIO_soundOnReallyDamaged); }
|
||||
const AudioEventRTS *getSoundDieFire() const { return getAudio(TTAUDIO_soundDieFire); }
|
||||
const AudioEventRTS *getSoundDieToxin() const { return getAudio(TTAUDIO_soundDieToxin); }
|
||||
const AudioEventRTS *getSoundEnter() const { return getAudio(TTAUDIO_soundEnter); }
|
||||
const AudioEventRTS *getSoundExit() const { return getAudio(TTAUDIO_soundExit); }
|
||||
const AudioEventRTS *getSoundPromotedVeteran() const { return getAudio(TTAUDIO_soundPromotedVeteran); }
|
||||
const AudioEventRTS *getSoundPromotedElite() const { return getAudio(TTAUDIO_soundPromotedElite); }
|
||||
const AudioEventRTS *getSoundPromotedHero() const { return getAudio(TTAUDIO_soundPromotedHero); }
|
||||
const AudioEventRTS *getSoundFalling() const { return getAudio(TTAUDIO_soundFalling); }
|
||||
|
||||
const AudioEventRTS *getPerUnitSound(const AsciiString& soundName) const;
|
||||
const FXList* getPerUnitFX(const AsciiString& fxName) const;
|
||||
|
||||
UnsignedInt getThreatValue() const { return m_threatValue; }
|
||||
UnsignedInt getMaxSimultaneousOfType() const { return m_maxSimultaneousOfType; }
|
||||
|
||||
void validate();
|
||||
|
||||
// The version that does not take an Object argument is labeled friend for use by WorldBuilder. All game requests
|
||||
// for CommandSet must use Object::getCommandSetString, as we have two different sources for dynamic answers.
|
||||
const AsciiString& friend_getCommandSetString() const { return m_commandSetString; }
|
||||
|
||||
const std::vector<AsciiString>& getBuildVariations() const { return m_buildVariations; }
|
||||
|
||||
Real getAssetScale() const { return m_assetScale; } ///< return uniform scaling
|
||||
Real getInstanceScaleFuzziness() const { return m_instanceScaleFuzziness; } ///< return uniform scaling
|
||||
Real getStructureRubbleHeight() const { return (Real)m_structureRubbleHeight; } ///< return uniform scaling
|
||||
|
||||
/*
|
||||
NOTE: if you have a Thing, don't call this function; call Thing::getGeometryInfo instead, since
|
||||
geometry can now vary on a per-object basis. Only call this when you have no Thing around,
|
||||
and want to get info for the "prototype" (eg, for building new Things)...
|
||||
*/
|
||||
const GeometryInfo& getTemplateGeometryInfo() const { return m_geometryInfo; }
|
||||
|
||||
//
|
||||
// these are intended ONLY for the private use of ThingFactory and do not use
|
||||
// the m_override pointer, it deals only with templates at the "top" level
|
||||
//
|
||||
inline void friend_setTemplateName( const AsciiString& name ) { m_nameString = name; }
|
||||
inline ThingTemplate *friend_getNextTemplate() const { return m_nextThingTemplate; }
|
||||
inline void friend_setNextTemplate(ThingTemplate *tmplate) { m_nextThingTemplate = tmplate; }
|
||||
inline void friend_setTemplateID(UnsignedShort id) { m_templateID = id; }
|
||||
|
||||
Int getEnergyProduction() const { return m_energyProduction; }
|
||||
Int getEnergyBonus() const { return m_energyBonus; }
|
||||
|
||||
// these are NOT publicly available; you should call calcCostToBuild() or calcTimeToBuild()
|
||||
// instead, because they will take player handicaps into account.
|
||||
// Int getBuildCost() const { return m_buildCost; }
|
||||
|
||||
Int getRefundValue() const { return m_refundValue; }
|
||||
|
||||
BuildCompletionType getBuildCompletion() const { return (BuildCompletionType)m_buildCompletion; }
|
||||
|
||||
BuildableStatus getBuildable() const;
|
||||
|
||||
Int getPrereqCount() const { return m_prereqInfo.size(); }
|
||||
const ProductionPrerequisite *getNthPrereq(Int i) const { return &m_prereqInfo[i]; }
|
||||
|
||||
/**
|
||||
return the BuildFacilityTemplate, if any.
|
||||
|
||||
if this template needs no build facility, null is returned.
|
||||
|
||||
if the template needs a build facility but the given player doesn't have any in existence,
|
||||
null will be returned.
|
||||
|
||||
if you pass null for player, we'll return the 'natural' build facility.
|
||||
*/
|
||||
const ThingTemplate *getBuildFacilityTemplate( const Player *player ) const;
|
||||
|
||||
Bool isBuildableItem(void) const;
|
||||
|
||||
/// calculate how long (in logic frames) it will take the given player to build this unit
|
||||
Int calcTimeToBuild( const Player* player) const;
|
||||
|
||||
/// calculate how much money it will take the given player to build this unit
|
||||
Int calcCostToBuild( const Player* player) const;
|
||||
|
||||
/// Used only by Skirmish AI. Everyone else should call calcCostToBuild.
|
||||
Int friend_getBuildCost() const { return m_buildCost; }
|
||||
|
||||
const AsciiString& getDefaultOwningSide() const { return m_defaultOwningSide; }
|
||||
|
||||
/// get us the table to parse the fields for thing templates
|
||||
const FieldParse* getFieldParse() const { return s_objectFieldParseTable; }
|
||||
const FieldParse* getReskinFieldParse() const { return s_objectReskinFieldParseTable; }
|
||||
|
||||
Bool isBuildFacility() const { return m_isBuildFacility; }
|
||||
Real getPlacementViewAngle( void ) const { return m_placementViewAngle; }
|
||||
|
||||
Real getFactoryExitWidth() const { return m_factoryExitWidth; }
|
||||
Real getFactoryExtraBibWidth() const { return m_factoryExtraBibWidth; }
|
||||
|
||||
void setCopiedFromDefault();
|
||||
|
||||
void setReskinnedFrom(const ThingTemplate* tt) { DEBUG_ASSERTCRASH(m_reskinnedFrom == NULL, ("should be null")); m_reskinnedFrom = tt; }
|
||||
|
||||
Bool isPrerequisite() const { return m_isPrerequisite; }
|
||||
|
||||
const WeaponTemplateSet* findWeaponTemplateSet(const WeaponSetFlags& t) const;
|
||||
const ArmorTemplateSet* findArmorTemplateSet(const ArmorSetFlags& t) const;
|
||||
|
||||
// returns true iff we have at least one weaponset that contains a weapon.
|
||||
// returns false if we have no weaponsets, or they are all empty.
|
||||
Bool canPossiblyHaveAnyWeapon() const;
|
||||
|
||||
Bool isEquivalentTo(const ThingTemplate* tt) const;
|
||||
|
||||
UnsignedByte getCrushableLevel() const { return m_crushableLevel; }
|
||||
UnsignedByte getCrusherLevel() const { return m_crusherLevel; }
|
||||
|
||||
AsciiString getUpgradeCameoName( Int n)const{ return m_upgradeCameoUpgradeNames[n]; }
|
||||
|
||||
protected:
|
||||
|
||||
//
|
||||
// these are NOT publicly available; you should call calcCostToBuild() or calcTimeToBuild()
|
||||
// instead, because they will take player handicaps into account.
|
||||
//
|
||||
Int getBuildCost() const { return m_buildCost; }
|
||||
Real getBuildTime() const { return m_buildTime; }
|
||||
const PerUnitSoundMap* getAllPerUnitSounds( void ) const { return &m_perUnitSounds; }
|
||||
void validateAudio();
|
||||
const AudioEventRTS* getAudio(ThingTemplateAudioType t) const { return m_audioarray.m_audio[t] ? &m_audioarray.m_audio[t]->m_event : &s_audioEventNoSound; }
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
/** Table for parsing the object fields */
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
static void parseArmorTemplateSet( INI* ini, void *instance, void *store, const void* /*userData*/ );
|
||||
static void parseWeaponTemplateSet( INI* ini, void *instance, void *store, const void* /*userData*/ );
|
||||
static void parsePrerequisites( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
|
||||
static void parseModuleName(INI* ini, void *instance, void* /*store*/, const void* userData);
|
||||
static void parseIntList(INI* ini, void *instance, void* store, const void* userData);
|
||||
|
||||
static void parsePerUnitSounds(INI* ini, void *instance, void* store, const void* userData);
|
||||
static void parsePerUnitFX(INI* ini, void *instance, void* store, const void* userData);
|
||||
|
||||
static void parseAddModule(INI *ini, void *instance, void *store, const void *userData);
|
||||
static void parseRemoveModule(INI *ini, void *instance, void *store, const void *userData);
|
||||
static void parseReplaceModule(INI *ini, void *instance, void *store, const void *userData);
|
||||
static void parseInheritableModule(INI *ini, void *instance, void *store, const void *userData);
|
||||
|
||||
Bool removeModuleInfo(const AsciiString& moduleToRemove, AsciiString& clearedModuleNameOut);
|
||||
|
||||
private:
|
||||
static const FieldParse s_objectFieldParseTable[]; ///< the parse table
|
||||
static const FieldParse s_objectReskinFieldParseTable[]; ///< the parse table
|
||||
static AudioEventRTS s_audioEventNoSound;
|
||||
|
||||
private:
|
||||
|
||||
// ---- Strings
|
||||
UnicodeString m_displayName; ///< UI display for onscreen display
|
||||
AsciiString m_nameString; ///< name of this thing template
|
||||
AsciiString m_defaultOwningSide; ///< default owning side (owning player is inferred)
|
||||
AsciiString m_commandSetString;
|
||||
AsciiString m_selectedPortraitImageName;
|
||||
AsciiString m_buttonImageName;
|
||||
AsciiString m_upgradeCameoUpgradeNames[MAX_UPGRADE_CAMEO_UPGRADES]; ///< Use these to find the upgrade images to display on the control bar
|
||||
AsciiString m_shadowTextureName; ///< name of texture to use for shadow decal
|
||||
AsciiString m_moduleBeingReplacedName; ///< used only during map.ini loading... name (not tag) of Module being replaced, or empty if not inside ReplaceModule block
|
||||
AsciiString m_moduleBeingReplacedTag; ///< used only during map.ini loading... tag (not name) of Module being replaced, or empty if not inside ReplaceModule block
|
||||
#ifdef LOAD_TEST_ASSETS
|
||||
AsciiString m_LTAName;
|
||||
#endif
|
||||
|
||||
// ---- Misc Larger-than-int things
|
||||
GeometryInfo m_geometryInfo; ///< geometry information
|
||||
KindOfMaskType m_kindof; ///< kindof bits
|
||||
AudioArray m_audioarray;
|
||||
ModuleInfo m_behaviorModuleInfo;
|
||||
ModuleInfo m_drawModuleInfo;
|
||||
ModuleInfo m_clientUpdateModuleInfo;
|
||||
|
||||
// ---- Misc Arrays-of-things
|
||||
Int m_skillPointValues[LEVEL_COUNT];
|
||||
Int m_experienceValues[LEVEL_COUNT]; ///< How much I am worth at each experience level
|
||||
Int m_experienceRequired[LEVEL_COUNT]; ///< How many experience points I need for each level
|
||||
|
||||
//Code renderer handles these states now.
|
||||
//AsciiString m_inventoryImage[ INV_IMAGE_NUM_IMAGES ]; ///< portrait inventory pictures
|
||||
|
||||
// ---- STL-sized things
|
||||
std::vector<ProductionPrerequisite> m_prereqInfo; ///< the unit Prereqs for this tech
|
||||
std::vector<AsciiString> m_buildVariations; /**< if we build a unit of this type via script or ui, randomly choose one
|
||||
of these templates instead. (doesn't apply to MapObject-created items) */
|
||||
WeaponTemplateSetVector m_weaponTemplateSets; ///< our weaponsets
|
||||
WeaponTemplateSetFinder m_weaponTemplateSetFinder; ///< helper to allow us to find the best sets, quickly
|
||||
ArmorTemplateSetVector m_armorTemplateSets; ///< our armorsets
|
||||
ArmorTemplateSetFinder m_armorTemplateSetFinder; ///< helper to allow us to find the best sets, quickly
|
||||
PerUnitSoundMap m_perUnitSounds; ///< An additional set of sounds that only apply for this template.
|
||||
PerUnitFXMap m_perUnitFX; ///< An additional set of fx that only apply for this template.
|
||||
|
||||
// ---- Pointer-sized things
|
||||
ThingTemplate* m_nextThingTemplate;
|
||||
const ThingTemplate* m_reskinnedFrom; ///< non NULL if we were generated via a reskin
|
||||
const Image * m_selectedPortraitImage; /// portrait image when selected (to display in GUI)
|
||||
const Image * m_buttonImage;
|
||||
|
||||
// ---- Real-sized things
|
||||
Real m_fenceWidth; ///< Fence width for fence type objects.
|
||||
Real m_fenceXOffset; ///< Fence X offset for fence type objects.
|
||||
Real m_visionRange; ///< object "sees" this far around itself
|
||||
Real m_shroudClearingRange; ///< Since So many things got added to "Seeing" functionality, we need to split this part out.
|
||||
Real m_placementViewAngle; ///< when placing buildings this will be the angle of the building when "floating" at the mouse
|
||||
Real m_factoryExitWidth; ///< when placing buildings this will be the width of the reserved exit area on the right side.
|
||||
Real m_factoryExtraBibWidth; ///< when placing buildings this will be the width of the reserved exit area on the right side.
|
||||
Real m_buildTime; ///< Seconds to build
|
||||
Real m_assetScale;
|
||||
Real m_instanceScaleFuzziness; ///< scale randomization tolerance to init for each Drawable instance,
|
||||
Real m_shadowSizeX; ///< world-space extent of decal shadow texture
|
||||
Real m_shadowSizeY; ///< world-space extent of decal shadow texture
|
||||
Real m_shadowOffsetX; ///< world-space offset of decal shadow texture
|
||||
Real m_shadowOffsetY; ///< world-space offset of decal shadow texture
|
||||
|
||||
// ---- Int-sized things
|
||||
Int m_energyProduction; ///< how much Energy this takes (negative values produce Energy, rather than consuming it)
|
||||
Int m_energyBonus; ///< how much extra Energy this produces due to the upgrade
|
||||
Color m_displayColor; ///< for the editor display color
|
||||
UnsignedInt m_occlusionDelay; ///< delay after object creation before building occlusion is allowed.
|
||||
|
||||
// ---- Short-sized things
|
||||
UnsignedShort m_templateID; ///< id for net (etc.) transmission purposes
|
||||
UnsignedShort m_buildCost; ///< money to build (0 == not buildable)
|
||||
UnsignedShort m_refundValue; ///< custom resale value, if sold. (0 == use default)
|
||||
UnsignedShort m_threatValue; ///< Threat map info
|
||||
UnsignedShort m_maxSimultaneousOfType; ///< max simultaneous of this unit we can have (per player) at one time. (0 == unlimited)
|
||||
|
||||
// ---- Bool-sized things
|
||||
Bool m_isPrerequisite; ///< Is this thing considered in a prerequisite for any other thing?
|
||||
Bool m_isBridge; ///< True if this model is a bridge.
|
||||
Bool m_isBuildFacility; ///< is this the build facility for something? (calculated based on other template's prereqs)
|
||||
Bool m_isTrainable; ///< Whether or not I can even gain experience
|
||||
Bool m_isForbidden; ///< useful when overriding in <mapfile>.ini
|
||||
Bool m_armorCopiedFromDefault;
|
||||
Bool m_weaponsCopiedFromDefault;
|
||||
|
||||
// ---- Byte-sized things
|
||||
Byte m_radarPriority; ///< does object appear on radar, and if so at what priority
|
||||
Byte m_transportSlotCount; ///< how many "slots" we take in a transport (0 == not transportable)
|
||||
Byte m_buildable; ///< is this thing buildable at all?
|
||||
Byte m_buildCompletion; ///< how the units come into the world when build is complete
|
||||
Byte m_editorSorting; ///< editor sorting type, see EditorSortingType enum
|
||||
Byte m_structureRubbleHeight;
|
||||
Byte m_shadowType; ///< settings which determine the type of shadow rendered
|
||||
Byte m_moduleParsingMode;
|
||||
UnsignedByte m_crusherLevel; ///< crusher > crushable level to actually crush
|
||||
UnsignedByte m_crushableLevel; ///< Specifies the level of crushability (must be hit by a crusher greater than this to crush me).
|
||||
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Inlining
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Externals
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __THINGTEMPLATE_H_
|
||||
|
Reference in a new issue