File: SkirmishAIWrapper.h

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (146 lines) | stat: -rw-r--r-- 4,406 bytes parent folder | download | duplicates (3)
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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef SKIRMISH_AI_WRAPPER_H
#define SKIRMISH_AI_WRAPPER_H

#include "SkirmishAIKey.h"

class CSkirmishAILibrary;
struct SSkirmishAICallback;

struct Command;
class float3;


/**
 * Acts as an OO wrapper for a Skirmish AI instance.
 * Basically converts function calls to AIEvents,
 * which are then sent to the AI library.
 */
class CSkirmishAIWrapper {
private:
	CR_DECLARE_STRUCT(CSkirmishAIWrapper)

public:
	/// used only by creg
	CSkirmishAIWrapper() = default;

	CSkirmishAIWrapper(const CSkirmishAIWrapper& w) = delete;
	CSkirmishAIWrapper(CSkirmishAIWrapper&& w) = delete;

	CSkirmishAIWrapper& operator = (const CSkirmishAIWrapper& w) = delete;
	CSkirmishAIWrapper& operator = (CSkirmishAIWrapper&& w) = delete;

	void Serialize(creg::ISerializer* s) {}
	void PostLoad() {
		#if 0
		// EngineOutHandler invokes PostLoad directly since
		// it does not (de)serialize AI's, less error-prone
		CreateCallback();
		InitLibrary(true);
		#else
		SendUnitEvents();
		#endif
	}


	void PreInit(int aiID);
	/** Called just before all the units are destroyed. */
	void PreDestroy();

	/**
	 * Initialize the AI instance.
	 * This calls the native init() method, the InitAIEvent is sent afterwards.
	 */
	void Init();
	void Kill();

	/// @see SReleaseEvent in Interface/AISEvents.h
	void Release(int reason = 0 /* = unspecified */);


	// AI Events
	void Load(std::istream *s);
	void Save(std::ostream *s);

	void UnitIdle(int unitId);
	void UnitCreated(int unitId, int builderId);
	void UnitFinished(int unitId);
	void UnitDestroyed(int unitId, int attackerUnitId);
	void UnitDamaged(int unitId, int attackerUnitId, float damage, const float3& dir, int weaponDefId, bool paralyzer);
	void UnitMoveFailed(int unitId);
	void UnitGiven(int unitId, int oldTeam, int newTeam);
	void UnitCaptured(int unitId, int oldTeam, int newTeam);
	void EnemyCreated(int unitId);
	void EnemyFinished(int unitId);
	void EnemyEnterLOS(int unitId);
	void EnemyLeaveLOS(int unitId);
	void EnemyEnterRadar(int unitId);
	void EnemyLeaveRadar(int unitId);
	void EnemyDestroyed(int enemyUnitId, int attackerUnitId);
	void EnemyDamaged(int enemyUnitId, int attackerUnitId, float damage, const float3& dir, int weaponDefId, bool paralyzer);
	void Update(int frame);
	void SendChatMessage(const char* msg, int fromPlayerId);
	void SendLuaMessage(const char* inData, const char** outData);
	void WeaponFired(int unitId, int weaponDefId);
	void PlayerCommandGiven(const std::vector<int>& selectedUnits, const Command& c, int playerId);
	void CommandFinished(int unitId, int commandId, int commandTopicId);
	void SeismicPing(int allyTeam, int unitId, const float3& pos, float strength);

	int GetSkirmishAIID() const { return skirmishAIId; }
	int GetTeamId() const { return teamId; }

	const SkirmishAIKey& GetKey() const { return key; }

	/**
	 * No events are forwarded to the Skirmish AI plugin
	 * after this method has been called.
	 * Do not call this if you want to kill a local AI, but use
	 * the Skirmish AI Handler instead.
	 * @see CSkirmishAIHandler::SetLocalKillFlag()
	 */
	void SetBlockEvents(bool enable) { blockEvents = enable; }
	void SetCheatEvents(bool enable) { cheatEvents = enable; }

	bool CheatEventsEnabled() const { return cheatEvents; }

	bool Active() const { return (skirmishAIId != -1); }

private:
	bool InitLibrary(bool postLoad);
	void CreateCallback();

	void SendInitEvent();
	void SendUnitEvents();

	/**
	 * CAUTION: takes C AI Interface events, not engine C++ ones!
	 */
	int HandleEvent(int topic, const void* data) const;

	uint32_t GetTimerNameHash() const { return *reinterpret_cast<const uint32_t*>(&timerName[0]); }

	const char* GetTimerName() const { return (timerName + sizeof(uint32_t)); }
	      char* GetTimerName()       { return (timerName + sizeof(uint32_t)); }

private:
	SkirmishAIKey key;

	const CSkirmishAILibrary* library = nullptr;
	const SSkirmishAICallback* callback = nullptr;

	// first 4 bytes store hash(timerName + 4)
	char timerName[sizeof(uint32_t) + 60] = {0};


	int skirmishAIId = -1;
	int teamId = -1;

	bool initialized = false; // true after handling Init event
	bool    released = false; // true after handling Release event
	bool libraryInit = false; // CSkirmishAILibrary::Init retval
	bool cheatEvents = false;
	bool blockEvents = false;
};

#endif // SKIRMISH_AI_WRAPPER_H