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
760
Generals/Code/GameEngine/Include/Common/Team.h
Normal file
760
Generals/Code/GameEngine/Include/Common/Team.h
Normal file
|
@ -0,0 +1,760 @@
|
|||
/*
|
||||
** 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: Team.h ///////////////////////////////////////////////////////////////
|
||||
// Team interface definition
|
||||
// Author: Michael S. Booth, Steven Johnson, March 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _TEAM_H_
|
||||
#define _TEAM_H_
|
||||
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/Snapshot.h"
|
||||
#include "Common/Thing.h"
|
||||
#include "GameLogic/Object.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef UnsignedInt TeamID;
|
||||
#define TEAM_ID_INVALID 0
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef UnsignedInt TeamPrototypeID;
|
||||
#define TEAM_PROTOTYPE_ID_INVALID 0
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef std::hash_map< TeamID, Relationship, std::hash<TeamID>, std::equal_to<TeamID> > TeamRelationMapType;
|
||||
class TeamRelationMap : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( TeamRelationMap, "TeamRelationMapPool" )
|
||||
|
||||
public:
|
||||
|
||||
TeamRelationMap( void );
|
||||
// virtual destructor provided by memory pool object
|
||||
|
||||
/** @todo I'm jsut wrappign this up in a nice snapshot object, we really should isolate
|
||||
* m_map from public access and make access methods for our operations */
|
||||
TeamRelationMapType m_map;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef void (*ObjectIterateFunc)( Object *obj, void *userData ); ///< callback type for iterating objects
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
How are teams represented in mapfiles?
|
||||
|
||||
-- All Players always have at least one top-level team, with the name "team<playername>"
|
||||
(WB will enforce this in mapfiles.)
|
||||
-- We'll have a TeamDict list that is parallel to the PlayerDict list
|
||||
-- All Teams (toplevel and subteams) are in the list
|
||||
-- Each TeamDict contains:
|
||||
-- Team Name (an internal ascii str)
|
||||
-- Owning Team (or Player), by Name
|
||||
-- Misc Flags
|
||||
-- Teams we are allies with, by name (only for toplevel teams)
|
||||
-- Teams we are enemies with, by name (only for toplevel teams)
|
||||
|
||||
-- Note that Players and Teams share the same namespace, so you cannot have a team
|
||||
with the same name as a player (or vice versa).
|
||||
|
||||
-- MapObject Dicts will be revised to have an "owning team" rather than "owning player" entry
|
||||
|
||||
-- BuildLists must also have a way to assign units to Teams, as appropriate
|
||||
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class AIGroup;
|
||||
class Dict;
|
||||
class Player;
|
||||
class PolygonTrigger;
|
||||
class Script;
|
||||
class SidesList;
|
||||
class TeamFactory;
|
||||
class TeamPrototype;
|
||||
class Team;
|
||||
class ThingTemplate;
|
||||
class Waypoint;
|
||||
class PlayerRelationMap;
|
||||
|
||||
enum AttitudeType;
|
||||
|
||||
typedef struct {
|
||||
Int minUnits;
|
||||
Int maxUnits;
|
||||
AsciiString unitThingName;
|
||||
} TCreateUnitsInfo;
|
||||
|
||||
enum { MAX_GENERIC_SCRIPTS = 16 };
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/// This is the info for creating reinforcement and AI teams.
|
||||
class TeamTemplateInfo : public Snapshot
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
TeamTemplateInfo(Dict *d);
|
||||
|
||||
enum {MAX_UNIT_TYPES = 7};
|
||||
typedef enum {NORMAL=0, IGNORE_DISTRACTIONS=1, DEAL_AGGRESSIVELY=2} TBehavior;
|
||||
|
||||
TCreateUnitsInfo m_unitsInfo[MAX_UNIT_TYPES]; ///< Quantity of units to create or build.
|
||||
Int m_numUnitsInfo; ///< Number of entries in m_unitsInfo
|
||||
Coord3D m_homeLocation; ///< Spawn location for team.
|
||||
Bool m_hasHomeLocation; ///< True is m_homeLocation is valid.
|
||||
AsciiString m_scriptOnCreate; ///< Script executed when team is created.
|
||||
AsciiString m_scriptOnIdle; ///< Script executed when team is idle.
|
||||
Int m_initialIdleFrames; ///< Number of frames to continue recruiting after the minimum team size is achieved.
|
||||
AsciiString m_scriptOnEnemySighted; ///< Script executed when enemy is sighted.
|
||||
AsciiString m_scriptOnAllClear; ///< Script executed when enemy is sighted.
|
||||
AsciiString m_scriptOnUnitDestroyed; ///< Script executed each time a unit on this team dies.
|
||||
AsciiString m_scriptOnDestroyed; ///< Script executed m_destroyedThreshold of member units are destroyed.
|
||||
Real m_destroyedThreshold; ///< OnDestroyed threshold - 1.0 = 100% = all destroyed, .5 = 50% = half of the units destroyed, 0 = useless.
|
||||
Bool m_isAIRecruitable; ///< True if other ai teams can recruit.
|
||||
Bool m_isBaseDefense; ///< True if is base defense team.
|
||||
Bool m_isPerimeterDefense; ///< True if is a perimeter base defense team.
|
||||
Bool m_automaticallyReinforce; ///< True is team automatically tries to reinforce.
|
||||
Bool m_transportsReturn; ///< True if transports return to base after unloading.
|
||||
Bool m_avoidThreats; ///< True if the team avoids threats.
|
||||
Bool m_attackCommonTarget; ///< True if the team attacks the same target unit.
|
||||
Int m_maxInstances; ///< Maximum number of instances of a team that is not singleton.
|
||||
mutable Int m_productionPriority; ///< Production priority.
|
||||
Int m_productionPrioritySuccessIncrease; ///< Production priority increase on success.
|
||||
Int m_productionPriorityFailureDecrease; ///< Production priority decrease on failure.
|
||||
AttitudeType m_initialTeamAttitude; ///< The initial team attitude
|
||||
|
||||
AsciiString m_transportUnitType; ///< Unit used to transport the team.
|
||||
AsciiString m_startReinforceWaypoint; ///< Waypoint where the reinforcement team starts.
|
||||
Bool m_teamStartsFull; ///< If true, team loads into member transports.
|
||||
Bool m_transportsExit; ///< True if the transports leave after deploying team.
|
||||
VeterancyLevel m_veterancy; ///< Veterancy level;
|
||||
|
||||
// Production scripts stuff
|
||||
AsciiString m_productionCondition; ///< Script that contains the production conditions.
|
||||
Bool m_executeActions; ///< If this is true, then when the production condition becomes true, we also execute the actions.
|
||||
|
||||
AsciiString m_teamGenericScripts[MAX_GENERIC_SCRIPTS];
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class Team : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Team, "TeamPool" )
|
||||
|
||||
private:
|
||||
|
||||
TeamPrototype *m_proto; ///< the prototype used to create this Team
|
||||
TeamID m_id; ///< unique team id
|
||||
|
||||
// lists we own
|
||||
/// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
|
||||
MAKE_DLINK_HEAD(Object, TeamMemberList) ///< the members of this team
|
||||
|
||||
// lists we are members of
|
||||
/// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
|
||||
MAKE_DLINK(Team, TeamInstanceList) ///< the instances of our prototype
|
||||
|
||||
AsciiString m_state; ///< Name of the current AI state.
|
||||
|
||||
Bool m_enteredOrExited; ///< True if a team member entered or exited a trigger area this frame.
|
||||
Bool m_active; ///< True if a team is complete. False while members are being added.
|
||||
Bool m_created; ///< True when first activated.
|
||||
|
||||
// Enemy sighted & All Clear:
|
||||
Bool m_checkEnemySighted;///< True if we have an on enemy sighted or all clear script.
|
||||
Bool m_seeEnemy; ///< True if we see an enemy.
|
||||
Bool m_prevSeeEnemy; ///< Last value.
|
||||
|
||||
// Idle flag.
|
||||
Bool m_wasIdle; ///< True if idle last frame.
|
||||
|
||||
// On %Destroyed
|
||||
Int m_destroyThreshold;
|
||||
Int m_curUnits;
|
||||
|
||||
// Following waypoint paths as a team.
|
||||
const Waypoint *m_currentWaypoint;
|
||||
|
||||
// Should check/Execute generic script
|
||||
Bool m_shouldAttemptGenericScript[MAX_GENERIC_SCRIPTS];
|
||||
|
||||
// Recruitablity.
|
||||
Bool m_isRecruitablitySet; ///< If false, recruitability is team proto value. If true, m_isRecruitable.
|
||||
Bool m_isRecruitable;
|
||||
|
||||
// Attack target.
|
||||
ObjectID m_commonAttackTarget;
|
||||
|
||||
TeamRelationMap *m_teamRelations; ///< override allies & enemies
|
||||
PlayerRelationMap *m_playerRelations; ///< override allies & enemies
|
||||
|
||||
std::list< ObjectID > m_xferMemberIDList; ///< list for post processing and restoring object pointers after a load
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
public:
|
||||
|
||||
Team( TeamPrototype *proto, TeamID id );
|
||||
// ~Team();
|
||||
|
||||
/// return the prototype used to create this team
|
||||
const TeamPrototype *getPrototype( void ) { return m_proto; }
|
||||
|
||||
void setID( TeamID id ) { m_id = id; }
|
||||
TeamID getID() const { return m_id; }
|
||||
|
||||
/**
|
||||
Set the attack priority name for a team.
|
||||
*/
|
||||
void setAttackPriorityName(AsciiString name);
|
||||
|
||||
/**
|
||||
return the player currently controlling this team (backtracking up if necessary)
|
||||
*/
|
||||
Player *getControllingPlayer() const;
|
||||
|
||||
/**
|
||||
set the team's owner. (NULL is not allowed)
|
||||
*/
|
||||
void setControllingPlayer(Player *newController);
|
||||
|
||||
/**
|
||||
Get the team's state
|
||||
*/
|
||||
const AsciiString& getState(void) const {return m_state;}
|
||||
|
||||
/**
|
||||
fill pAIGroup (which must be NONNULL) with the members of this team as a Group.
|
||||
*/
|
||||
void getTeamAsAIGroup(AIGroup *pAIGroup);
|
||||
|
||||
/**
|
||||
Get the team's state
|
||||
*/
|
||||
inline const AsciiString& getName() const;
|
||||
|
||||
/**
|
||||
Get the count of live things that are either alive or are buildings.
|
||||
*/
|
||||
Int getTargetableCount() const;
|
||||
|
||||
/**
|
||||
Set the team's AI state.
|
||||
*/
|
||||
void setState(const AsciiString& state) {m_state = state;}
|
||||
|
||||
/**
|
||||
Set the team's AI recruitablity.
|
||||
*/
|
||||
void setRecruitable(Bool recruitable) {m_isRecruitablitySet = true; m_isRecruitable = recruitable;}
|
||||
|
||||
/**
|
||||
Set the team's target object.
|
||||
*/
|
||||
void setTeamTargetObject(const Object *target) ;
|
||||
|
||||
/**
|
||||
Set the team's target object.
|
||||
*/
|
||||
Object *getTeamTargetObject(void);
|
||||
|
||||
/**
|
||||
Set the team as active. A team is considered created when set active.
|
||||
*/
|
||||
void setActive(void) {if (!m_active) { m_created = true;m_active = true;}}
|
||||
|
||||
/**
|
||||
Is this team active?
|
||||
*/
|
||||
Bool isActive(void) {return m_active;}
|
||||
|
||||
/**
|
||||
Is this team just createc? (stays true one logic frame.)
|
||||
*/
|
||||
Bool isCreated(void) {return m_created;}
|
||||
|
||||
/**
|
||||
Note that a team member entered or exited a trigger area.
|
||||
*/
|
||||
void setEnteredExited(void) {m_enteredOrExited = true;}
|
||||
|
||||
/**
|
||||
Did a team member enter or exit a trigger area.
|
||||
*/
|
||||
Bool didEnterOrExit(void) {return m_enteredOrExited;}
|
||||
|
||||
/**
|
||||
Clear the flag that a team member entered or exited a trigger area.
|
||||
Also checks and executes any onCreate scripts, and clears the created flag.
|
||||
*/
|
||||
void updateState(void);
|
||||
|
||||
void notifyTeamOfObjectDeath( void );
|
||||
|
||||
Bool didAllEnter(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members entered the area
|
||||
Bool didPartialEnter(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< One member entered the area
|
||||
Bool didAllExit(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members exited the area
|
||||
Bool didPartialExit(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< One member exited the area
|
||||
Bool allInside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members are inside the area
|
||||
Bool someInsideSomeOutside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const;///< One or more in, one or more out.
|
||||
Bool noneInside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< No members are in the area.
|
||||
|
||||
Object * tryToRecruit(const ThingTemplate *, const Coord3D *teamHome, Real maxDist); ///< Try to recruit the closest unit of this thing type. Return true if successful.
|
||||
|
||||
/**
|
||||
return our relationship with the other team.
|
||||
this is done as follows:
|
||||
|
||||
-- if there's a TeamRelationship between this team and that team, return it.
|
||||
-- otherwise, we use the relationship between our players.
|
||||
|
||||
*/
|
||||
Relationship getRelationship(const Team *that) const;
|
||||
|
||||
/**
|
||||
set a special relationship between this team and that team, that overrides
|
||||
the one between our Players. (note that this doesn't imply anything about the
|
||||
relation of that to this.)
|
||||
*/
|
||||
void setOverrideTeamRelationship( TeamID teamID, Relationship r );
|
||||
|
||||
/**
|
||||
remove the special relation (if any) between this and that.
|
||||
remove all special relations for 'this' if that==null.
|
||||
return true if anything removed.
|
||||
*/
|
||||
Bool removeOverrideTeamRelationship( TeamID teamID );
|
||||
|
||||
/**
|
||||
set a special relationship between this team and that Player, that overrides
|
||||
the one between our Players. (note that this doesn't imply anything about the
|
||||
relation of that to this.) Note that override-team relationships take precedence
|
||||
over override-player relationships.
|
||||
*/
|
||||
void setOverridePlayerRelationship( Int playerIndex, Relationship r );
|
||||
|
||||
/**
|
||||
remove the special relation (if any) between this and that.
|
||||
remove all special relations for 'this' if that==null.
|
||||
return true if anything removed.
|
||||
*/
|
||||
Bool removeOverridePlayerRelationship( Int playerIndex );
|
||||
|
||||
/**
|
||||
a convenience routine to count the number of owned objects that match a set of ThingTemplates.
|
||||
You input the count and an array of ThingTemplate*, and provide an array of Int of the same
|
||||
size. It fills in the array to the correct counts. This is handy because we must traverse
|
||||
the team's list-of-objects only once.
|
||||
*/
|
||||
void countObjectsByThingTemplate(Int numTmplates, const ThingTemplate* const* things, Bool ignoreDead, Int *counts, Bool ignoreUnderConstruction = TRUE ) const;
|
||||
|
||||
|
||||
/**
|
||||
returns the number of buildings on this team, by checking each things' template kindof against KINDOF_STRUCTURE
|
||||
*/
|
||||
Int countBuildings(void);
|
||||
|
||||
/**
|
||||
simply returns the number of objects on this team with a specific KindOfMaskType
|
||||
*/
|
||||
Int countObjects(KindOfMaskType setMask, KindOfMaskType clearMask);
|
||||
|
||||
/**
|
||||
This Team will heal all its members
|
||||
*/
|
||||
void healAllObjects();
|
||||
|
||||
/**
|
||||
* Iterate all members of the team
|
||||
*/
|
||||
void iterateObjects( ObjectIterateFunc func, void *userData );
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildings are owned.
|
||||
*/
|
||||
Bool hasAnyBuildings(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildings with a specific KindOfType flag are owned.
|
||||
*/
|
||||
Bool hasAnyBuildings(KindOfMaskType kindOf) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any units are owned.
|
||||
*/
|
||||
Bool hasAnyUnits(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any objects are owned.
|
||||
*/
|
||||
Bool hasAnyObjects(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if all the units are idle.
|
||||
*/
|
||||
Bool isIdle(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any objects are in a trigger area.
|
||||
*/
|
||||
Bool unitsEntered(PolygonTrigger *pTrigger) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildfacilities are owned.
|
||||
*/
|
||||
Bool hasAnyBuildFacility(void) const;
|
||||
|
||||
/**
|
||||
Move team to destination.
|
||||
*/
|
||||
void moveTeamTo(Coord3D destination);
|
||||
|
||||
/**
|
||||
a convenience routine to quickly destroy a team.
|
||||
*/
|
||||
Bool damageTeamMembers(Real amount);
|
||||
|
||||
/**
|
||||
a convenience routine to destroy this team. The team goes through all shutdown stuff.
|
||||
Note that this doesn't actually call deleteInstance, the team will actually be
|
||||
deleted on the next update, if it is a deletable team.
|
||||
IgnoreDead lets you not delete people who are dying anyway. Needed for scripts.
|
||||
*/
|
||||
void deleteTeam(Bool ignoreDead = FALSE);
|
||||
|
||||
/**
|
||||
a convenience routine used to estimate the team's position by just returning the position
|
||||
of the first member of the team
|
||||
*/
|
||||
const Coord3D* getEstimateTeamPosition(void);
|
||||
|
||||
/**
|
||||
a convenience routine to move a team's units to another team.
|
||||
*/
|
||||
void transferUnitsTo(Team *newTeam);
|
||||
|
||||
/**
|
||||
a function to kill all members of a team
|
||||
*/
|
||||
void killTeam(void);
|
||||
|
||||
/**
|
||||
a function to make all containers on a team to dump contents
|
||||
*/
|
||||
void evacuateTeam(void);
|
||||
|
||||
/**
|
||||
the current waypoint for a team following a waypoint path.
|
||||
*/
|
||||
const Waypoint *getCurrentWaypoint(void) {return m_currentWaypoint;}
|
||||
void setCurrentWaypoint(const Waypoint *way) {m_currentWaypoint = way;}
|
||||
|
||||
/**
|
||||
Update the generic scripts, allow them to see if they should run, etc.
|
||||
*/
|
||||
|
||||
void updateGenericScripts(void);
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
Note that TeamPrototype is used to hold information that is invariant between
|
||||
multiple instances of a given Team (e.g., alliance info).
|
||||
|
||||
However, a TeamPrototype doesn't contain any build-list style info; that is handled
|
||||
by the BuildList stuff.
|
||||
*/
|
||||
class TeamPrototype : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(TeamPrototype, "TeamPrototypePool" )
|
||||
|
||||
public:
|
||||
|
||||
TeamPrototype( TeamFactory *tf,
|
||||
const AsciiString& name,
|
||||
Player *ownerPlayer,
|
||||
Bool isSingleton,
|
||||
Dict *d,
|
||||
TeamPrototypeID id );
|
||||
// virtual destructor prototype provided by memory pool object
|
||||
|
||||
inline TeamPrototypeID getID() const { return m_id; }
|
||||
inline const AsciiString& getName() const { return m_name; }
|
||||
inline Bool getIsSingleton() const { return (m_flags & TEAM_SINGLETON) != 0; }
|
||||
inline const TeamTemplateInfo *getTemplateInfo(void) const {return &m_teamTemplate;}
|
||||
/**
|
||||
return the team's owner (backtracking up if necessary)
|
||||
*/
|
||||
Player *getControllingPlayer() const;
|
||||
|
||||
/**
|
||||
* Return a team with matching team ID if present
|
||||
*/
|
||||
Team *findTeamByID( TeamID teamID );
|
||||
|
||||
/**
|
||||
set the team's owner. (NULL is not allowed)
|
||||
*/
|
||||
void setControllingPlayer(Player *newController);
|
||||
|
||||
/**
|
||||
Evaluate team's production condition.
|
||||
*/
|
||||
Bool evaluateProductionCondition(void);
|
||||
|
||||
/**
|
||||
count for all the team instances belonging to this prototype.
|
||||
*/
|
||||
void countObjectsByThingTemplate(Int numTmplates, const ThingTemplate* const* things, Bool ignoreDead, Int *counts, Bool ignoreUnderConstruction = TRUE ) const;
|
||||
|
||||
/**
|
||||
count the buildings owned by this Team template
|
||||
*/
|
||||
Int countBuildings(void);
|
||||
|
||||
/**
|
||||
simply returns the number of objects on this team with a specific KindOfMaskType
|
||||
*/
|
||||
Int countObjects(KindOfMaskType setMask, KindOfMaskType clearMask);
|
||||
|
||||
/**
|
||||
This TeamProtoType will heal all objects in all its instances
|
||||
*/
|
||||
void healAllObjects();
|
||||
|
||||
/**
|
||||
* Iterate all members of the team
|
||||
*/
|
||||
void iterateObjects( ObjectIterateFunc func, void *userData );
|
||||
|
||||
/// count the number of teams that have been instanced by this prototype
|
||||
Int countTeamInstances( void );
|
||||
|
||||
/**
|
||||
Checks & clears the flags that a team member entered or exited a trigger area, or was created.
|
||||
*/
|
||||
void updateState(void);
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildings are owned.
|
||||
*/
|
||||
Bool hasAnyBuildings(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildings with a specific KindOfType flag are owned.
|
||||
*/
|
||||
Bool hasAnyBuildings(KindOfMaskType kindOf) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any units are owned.
|
||||
*/
|
||||
Bool hasAnyUnits(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any objects are owned.
|
||||
*/
|
||||
Bool hasAnyObjects(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly check if any buildfacilities are owned.
|
||||
*/
|
||||
Bool hasAnyBuildFacility(void) const;
|
||||
|
||||
/**
|
||||
a convenience routine to quickly destroy a team.
|
||||
*/
|
||||
void damageTeamMembers(Real amount);
|
||||
|
||||
/**
|
||||
Move team to destination.
|
||||
*/
|
||||
void moveTeamTo(Coord3D destination);
|
||||
|
||||
// this is intended for use ONLY by class Player.
|
||||
void friend_setOwningPlayer(Player* p) { m_owningPlayer = p; }
|
||||
|
||||
void teamAboutToBeDeleted(Team* team);
|
||||
|
||||
Script *getGenericScript(Int scriptToRetrieve);
|
||||
|
||||
// Make a team more likely to be selected by the ai for building due to success.
|
||||
void increaseAIPriorityForSuccess(void) const;
|
||||
// Make a team less likely to be selected by the ai for building due to failure.
|
||||
void decreaseAIPriorityForFailure(void) const;
|
||||
|
||||
void setAttackPriorityName(const AsciiString &name) { m_attackPriorityName = name;}
|
||||
AsciiString getAttackPriorityName(void) const { return m_attackPriorityName;}
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
private:
|
||||
|
||||
enum TeamPrototypeFlags
|
||||
{
|
||||
/**
|
||||
if set, this prototype should only produce one team. if there's already a team
|
||||
by this name, newly produced team members are added to it, rather than
|
||||
put into a new team of the same name.
|
||||
*/
|
||||
TEAM_SINGLETON = 0x01
|
||||
};
|
||||
|
||||
TeamFactory *m_factory; ///< the factory that created us
|
||||
Player *m_owningPlayer; ///< the Player that currently controls the team-proto (null if NOT a top-level team)
|
||||
|
||||
TeamPrototypeID m_id; ///< unique prototype ID
|
||||
AsciiString m_name; ///< name of the team(s) produced
|
||||
Int m_flags; ///< misc team flags
|
||||
|
||||
Bool m_productionConditionAlwaysFalse; ///< Flag set to true if we don't have a production condition.
|
||||
Script *m_productionConditionScript; ///< Script to evaluate for production condition.
|
||||
|
||||
Bool m_retrievedGenericScripts;
|
||||
Script *m_genericScriptsToRun[MAX_GENERIC_SCRIPTS];
|
||||
|
||||
TeamTemplateInfo m_teamTemplate; ///< Team template info.
|
||||
|
||||
AsciiString m_attackPriorityName;
|
||||
// lists we own
|
||||
/// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
|
||||
MAKE_DLINK_HEAD(Team, TeamInstanceList) ///< the instances of this prototype
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class TeamFactory : public SubsystemInterface,
|
||||
public Snapshot
|
||||
{
|
||||
public:
|
||||
|
||||
TeamFactory();
|
||||
~TeamFactory();
|
||||
|
||||
// subsystem methods
|
||||
virtual void init( void );
|
||||
virtual void reset( void );
|
||||
virtual void update( void );
|
||||
|
||||
void clear();
|
||||
void initFromSides(SidesList *sides);
|
||||
|
||||
/// create a new TeamPrototype and if singleton, a team.
|
||||
void initTeam(const AsciiString& name, const AsciiString& owner, Bool isSingleton, Dict *d);
|
||||
|
||||
/// return the TeamPrototype with the given name. if none exists, return null.
|
||||
TeamPrototype *findTeamPrototype(const AsciiString& name);
|
||||
|
||||
/// return TeamPrototype with matching ID. if none exists NULL is returned
|
||||
TeamPrototype *findTeamPrototypeByID( TeamPrototypeID id );
|
||||
|
||||
/// search all prototypes for the team with the matching id, if none found NULL is returned
|
||||
Team *findTeamByID( TeamID teamID );
|
||||
|
||||
// note that there is no way to directly destroy a specific TeamPrototype (or a Team); the only
|
||||
// way to do this is to call TeamFactory::reset(), which destroys all of them.
|
||||
|
||||
// ------ routines for dealing with Teams
|
||||
|
||||
/// create a team. there must be a TeamPrototype with the given name, or an exception is thrown.
|
||||
Team *createTeam(const AsciiString& name);
|
||||
|
||||
/// create a team given an explicity team prototype rather than a prototype name
|
||||
Team *createTeamOnPrototype( TeamPrototype *prototype );
|
||||
|
||||
/// create a team. there must be a TeamPrototype with the given name, or an exception is thrown.
|
||||
Team *createInactiveTeam(const AsciiString& name);
|
||||
|
||||
/// return the team with the given name, or null if none exists. if multiple instances exist, return one arbitrarily.
|
||||
Team *findTeam(const AsciiString& name);
|
||||
|
||||
void addTeamPrototypeToList(TeamPrototype* team);
|
||||
void removeTeamPrototypeFromList(TeamPrototype* team);
|
||||
|
||||
void teamAboutToBeDeleted(Team* team);
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map< NameKeyType, TeamPrototype*, std::less<NameKeyType> > TeamPrototypeMap;
|
||||
|
||||
TeamPrototypeMap m_prototypes;
|
||||
TeamPrototypeID m_uniqueTeamPrototypeID; ///< used to assign unique ids to each team prototype
|
||||
TeamID m_uniqueTeamID; ///< used to assign unique team ids to each team instance
|
||||
|
||||
};
|
||||
|
||||
extern TeamFactory *TheTeamFactory;
|
||||
|
||||
|
||||
// inline function ------------------------------------------------------------------------
|
||||
const AsciiString& Team::getName(void) const
|
||||
{
|
||||
return m_proto->getName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
#endif // _TEAM_H_
|
Reference in a new issue