File: CommandAI.h

package info (click to toggle)
spring 103.0%2Bdfsg2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 43,720 kB
  • ctags: 63,685
  • sloc: cpp: 368,283; ansic: 33,988; python: 12,417; java: 12,203; awk: 5,879; sh: 1,846; xml: 655; perl: 405; php: 211; objc: 194; makefile: 77; sed: 2
file content (177 lines) | stat: -rw-r--r-- 5,621 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _COMMAND_AI_H
#define _COMMAND_AI_H

#include <vector>
#include <set>

#include "System/Object.h"
#include "CommandDescription.h"
#include "CommandQueue.h"
#include "System/float3.h"

class CUnit;
class CFeature;
class CWeapon;
struct Command;

class CCommandAI : public CObject
{
	CR_DECLARE(CCommandAI)

public:
	CCommandAI(CUnit* owner);
	CCommandAI();
	virtual ~CCommandAI();

	void DependentDied(CObject* o);

	static void InitCommandDescriptionCache();
	static void KillCommandDescriptionCache();

	inline void SetOrderTarget(CUnit* o);

	void SetScriptMaxSpeed(float speed, bool persistent);
	void SlowUpdateMaxSpeed();

	virtual void AddDeathDependence(CObject* o, DependenceType dep);
	virtual void DeleteDeathDependence(CObject* o, DependenceType dep);
	void AddCommandDependency(const Command& c);
	void ClearCommandDependencies();
	/// feeds into GiveCommandReal()
	void GiveCommand(const Command& c, bool fromSynced = true);
	void ClearTargetLock(const Command& fc);
	virtual bool CanWeaponAutoTarget(const CWeapon* weapon) const { return true; }
	virtual int GetDefaultCmd(const CUnit* pointed, const CFeature* feature);
	virtual void SlowUpdate();
	virtual void GiveCommandReal(const Command& c, bool fromSynced = true);
	virtual void FinishCommand();
	void WeaponFired(CWeapon* weapon, const bool searchForNewTarget);
	virtual void BuggerOff(const float3& pos, float radius) {}
	/**
	 * @brief Determines if c will cancel a queued command
	 * @return true if c will cancel a queued command
	 */
		bool WillCancelQueued(const Command& c);
	virtual bool CanSetMaxSpeed() const { return false; }
	virtual void StopMove() { return; }

	/**
	 * Removes attack commands targeted at our new ally.
	 */
	void StopAttackingAllyTeam(int ally);

	bool HasCommand(int cmdID) const;
	bool HasMoreMoveCommands(bool skipFirstCmd = true) const;

	int CancelCommands(const Command& c, CCommandQueue& queue, bool& first);
	/**
	 * @brief Finds the queued command that would be canceled by the Command c
	 * @return An iterator pointing at the command, or commandQue.end(),
	 *   if no such queued command exists
	 */
	CCommandQueue::iterator GetCancelQueued(const Command& c,
	                                        CCommandQueue& queue);
	/**
	 * @brief Returns commands that overlap c, but will not be canceled by c
	 * @return a vector containing commands that overlap c
	 */
	std::vector<Command> GetOverlapQueued(const Command& c);
	std::vector<Command> GetOverlapQueued(const Command& c,
	                                      CCommandQueue& queue);

	const std::vector<const SCommandDescription*>& GetPossibleCommands() const { return possibleCommands; }

	/**
	 * @brief Causes this CommandAI to execute the attack order c
	 */
	virtual void ExecuteAttack(Command& c);

	/**
	 * @brief executes the stop command c
	 */
	virtual void ExecuteStop(Command& c);

	void UpdateCommandDescription(unsigned int cmdDescIdx, const Command& cmd);
	void UpdateCommandDescription(unsigned int cmdDescIdx, const SCommandDescription& modCmdDesc);
	void InsertCommandDescription(unsigned int cmdDescIdx, const SCommandDescription& cmdDesc);
	bool RemoveCommandDescription(unsigned int cmdDescIdx);

	void UpdateNonQueueingCommands();

	void SetCommandDescParam0(const Command& c);
	bool ExecuteStateCommand(const Command& c);

	void ExecuteInsert(const Command& c, bool fromSynced = true);
	void ExecuteRemove(const Command& c);

	void AddStockpileWeapon(CWeapon* weapon);
	void StockpileChanged(CWeapon* weapon);
	void UpdateStockpileIcon();
	bool CanChangeFireState();

	virtual bool AllowedCommand(const Command& c, bool fromSynced);

	CWeapon* stockpileWeapon;

	std::vector<const SCommandDescription*> possibleCommands;
	std::set<int> nonQueingCommands;

	CCommandQueue commandQue;

	int lastUserCommand;
	int selfDCountdown;
	int lastFinishCommand;

	CUnit* owner;
	CUnit* orderTarget;

	bool targetDied;
	bool inCommand;
	bool repeatOrders;
	int lastSelectedCommandPage;
	bool unimportantMove;

protected:
	// return true by default so non-AirCAI's trigger FinishCommand
	virtual bool SelectNewAreaAttackTargetOrPos(const Command& ac) { return true; }

	bool IsAttackCapable() const;
	bool SkipParalyzeTarget(const CUnit* target);
	void GiveAllowedCommand(const Command& c, bool fromSynced = true);
	void GiveWaitCommand(const Command& c);
	/**
	 * @brief Returns the command that keeps the unit close to the path
	 * @return a Fight Command with 6 arguments, the first three being where to
	 *   return to (the current position of the unit), and the second being
	 *   the location of the original command.
	 */
	void PushOrUpdateReturnFight(const float3& cmdPos1, const float3& cmdPos2);
	int UpdateTargetLostTimer(int unitID);
	void DrawDefaultCommand(const Command& c) const;

private:
	std::set<CObject*> commandDeathDependences;
	/**
	 * continuously set to some non-zero value while target is in radar
	 * decremented by 1 every SlowUpdate (!), command is canceled when
	 * timer reaches 0
	 */
	int targetLostTimer;
};

inline void CCommandAI::SetOrderTarget(CUnit* o) {
	if (orderTarget != NULL) {
		// NOTE As we do not include Unit.h,
		//   the compiler does not know that CUnit derives from CObject,
		//   and thus we can not use static_cast<CObject*>(...) here.
		DeleteDeathDependence(reinterpret_cast<CObject*>(orderTarget), DEPENDENCE_ORDERTARGET);
	}
	orderTarget = o;
	if (orderTarget != NULL) {
		AddDeathDependence(reinterpret_cast<CObject*>(orderTarget), DEPENDENCE_ORDERTARGET);
	}
}

#endif // _COMMAND_AI_H