761 lines
25 KiB
C++
761 lines
25 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: 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_
|