1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #ifndef LUA_HANDLE_H
4 #define LUA_HANDLE_H
5 #include <boost/cstdint.hpp>
6
7 #include "System/EventClient.h"
8 //FIXME#include "LuaArrays.h"
9 #include "LuaContextData.h"
10 #include "LuaHashString.h"
11 #include "lib/lua/include/LuaInclude.h" //FIXME needed for GetLuaContextData
12
13 #include <string>
14 #include <vector>
15 #include <set>
16 using std::string;
17 using std::vector;
18 using std::set;
19
20
21 #define LUA_HANDLE_ORDER_RULES 100
22 #define LUA_HANDLE_ORDER_UNITS 200
23 #define LUA_HANDLE_ORDER_GAIA 300
24 #define LUA_HANDLE_ORDER_RULES_UNSYNCED 1100
25 #define LUA_HANDLE_ORDER_UNITS_UNSYNCED 1200
26 #define LUA_HANDLE_ORDER_GAIA_UNSYNCED 1300
27 #define LUA_HANDLE_ORDER_UI 2000
28 #define LUA_HANDLE_ORDER_INTRO 3000
29
30
31 class CUnit;
32 class CWeapon;
33 class CFeature;
34 class CProjectile;
35 struct Command;
36 struct SRectangle;
37 struct LuaHashString;
38 struct lua_State;
39 class LuaRBOs;
40 class LuaFBOs;
41 class LuaTextures;
42 class LuaShaders;
43 class CLuaDisplayLists;
44 class CLuaRules;
45
46
47 class CLuaHandle : public CEventClient
48 {
49 public:
50 void CheckStack();
GetCallInErrors()51 int GetCallInErrors() const { return callinErrors; }
ResetCallinErrors()52 void ResetCallinErrors() { callinErrors = 0; }
53
54 public:
55 #define PERMISSIONS_FUNCS(Name, type, dataArg) \
56 void Set ## Name(type _ ## dataArg) { GetLuaContextData(L)->dataArg = _ ## dataArg; } \
57 type Get ## Name() const { return GetLuaContextData(L)->dataArg; } \
58 static void SetHandle ## Name(const lua_State* L, type _ ## dataArg) { GetLuaContextData(L)->dataArg = _ ## dataArg;; } \
59 static type GetHandle ## Name(const lua_State* L) { return GetLuaContextData(L)->dataArg; }
60
61 PERMISSIONS_FUNCS(FullRead, bool, fullRead); // virtual function in CEventClient
62 PERMISSIONS_FUNCS(FullCtrl, bool, fullCtrl);
63 PERMISSIONS_FUNCS(CtrlTeam, int, ctrlTeam);
64 PERMISSIONS_FUNCS(ReadTeam, int, readTeam);
65 PERMISSIONS_FUNCS(ReadAllyTeam, int, readAllyTeam); // virtual function in CEventClient
66 PERMISSIONS_FUNCS(SelectTeam, int, selectTeam);
67
68 #undef PERMISSIONS_FUNCS
69
GetHandleSynced(const lua_State * L)70 static bool GetHandleSynced(const lua_State* L) { return GetLuaContextData(L)->synced; }
71
GetUserMode()72 bool GetUserMode() const { return userMode; }
GetHandleUserMode(const lua_State * L)73 static bool GetHandleUserMode(const lua_State* L) { return GetLuaContextData(L)->owner->GetUserMode(); }
74
CheckModUICtrl()75 bool CheckModUICtrl() const { return GetModUICtrl() || GetUserMode(); }
CheckModUICtrl(lua_State * L)76 static bool CheckModUICtrl(lua_State* L) { return GetModUICtrl() || GetHandleUserMode(L); }
77
GetHandleAllowChanges(const lua_State * L)78 static int GetHandleAllowChanges(const lua_State* L) { return GetLuaContextData(L)->allowChanges; }
79
GetHandle(lua_State * L)80 static CLuaHandle* GetHandle(lua_State* L) { return GetLuaContextData(L)->owner; }
81
SetHandleRunning(lua_State * L,const bool _running)82 static void SetHandleRunning(lua_State* L, const bool _running) {
83 GetLuaContextData(L)->running += (_running) ? +1 : -1;
84 assert( GetLuaContextData(L)->running >= 0);
85 }
IsHandleRunning(lua_State * L)86 static bool IsHandleRunning(lua_State* L) { return (GetLuaContextData(L)->running > 0); }
IsRunning()87 bool IsRunning() const { return IsHandleRunning(L); }
88
IsValid()89 bool IsValid() const { return (L != NULL); }
90
91 //FIXME needed by LuaSyncedTable (can be solved cleaner?)
GetLuaState()92 lua_State* GetLuaState() const { return L; }
93
94 LuaShaders& GetShaders(const lua_State* L = NULL) { return GetLuaContextData(L)->shaders; }
95 LuaTextures& GetTextures(const lua_State* L = NULL) { return GetLuaContextData(L)->textures; }
96 LuaFBOs& GetFBOs(const lua_State* L = NULL) { return GetLuaContextData(L)->fbos; }
97 LuaRBOs& GetRBOs(const lua_State* L = NULL) { return GetLuaContextData(L)->rbos; }
98 CLuaDisplayLists& GetDisplayLists(const lua_State* L = NULL) { return GetLuaContextData(L)->displayLists; }
99
100 public: // call-ins
WantsEvent(const string & name)101 bool WantsEvent(const string& name) { return HasCallIn(L, name); }
102 virtual bool HasCallIn(lua_State* L, const string& name);
103 virtual bool UpdateCallIn(lua_State* L, const string& name);
104
105 void Load(IArchive* archive);
106
107 void GamePreload();
108 void GameStart();
109 void GameOver(const std::vector<unsigned char>& winningAllyTeams);
110 void GamePaused(int playerID, bool paused);
111 void GameFrame(int frameNum);
112 void GameID(const unsigned char* gameID, unsigned int numBytes);
113
114 void TeamDied(int teamID);
115 void TeamChanged(int teamID);
116 void PlayerChanged(int playerID);
117 void PlayerAdded(int playerID);
118 void PlayerRemoved(int playerID, int reason);
119
120 void UnitCreated(const CUnit* unit, const CUnit* builder);
121 void UnitFinished(const CUnit* unit);
122 void UnitFromFactory(const CUnit* unit, const CUnit* factory,
123 bool userOrders);
124 void UnitDestroyed(const CUnit* unit, const CUnit* attacker);
125 void UnitTaken(const CUnit* unit, int oldTeam, int newTeam);
126 void UnitGiven(const CUnit* unit, int oldTeam, int newTeam);
127
128 void UnitIdle(const CUnit* unit);
129 void UnitCommand(const CUnit* unit, const Command& command);
130 void UnitCmdDone(const CUnit* unit, const Command& command);
131 void UnitDamaged(
132 const CUnit* unit,
133 const CUnit* attacker,
134 float damage,
135 int weaponDefID,
136 int projectileID,
137 bool paralyzer);
138 void UnitExperience(const CUnit* unit, float oldExperience);
139 void UnitHarvestStorageFull(const CUnit* unit);
140
141 void UnitSeismicPing(const CUnit* unit, int allyTeam,
142 const float3& pos, float strength);
143 void UnitEnteredRadar(const CUnit* unit, int allyTeam);
144 void UnitEnteredLos(const CUnit* unit, int allyTeam);
145 void UnitLeftRadar(const CUnit* unit, int allyTeam);
146 void UnitLeftLos(const CUnit* unit, int allyTeam);
147
148 void UnitEnteredWater(const CUnit* unit);
149 void UnitEnteredAir(const CUnit* unit);
150 void UnitLeftWater(const CUnit* unit);
151 void UnitLeftAir(const CUnit* unit);
152
153 void UnitLoaded(const CUnit* unit, const CUnit* transport);
154 void UnitUnloaded(const CUnit* unit, const CUnit* transport);
155
156 void UnitCloaked(const CUnit* unit);
157 void UnitDecloaked(const CUnit* unit);
158
159 void UnitUnitCollision(const CUnit* collider, const CUnit* collidee);
160 void UnitFeatureCollision(const CUnit* collider, const CFeature* collidee);
161 void UnitMoveFailed(const CUnit* unit);
162
163 void FeatureCreated(const CFeature* feature);
164 void FeatureDestroyed(const CFeature* feature);
165 void FeatureDamaged(
166 const CFeature* feature,
167 const CUnit* attacker,
168 float damage,
169 int weaponDefID,
170 int projectileID);
171
172 void ProjectileCreated(const CProjectile* p);
173 void ProjectileDestroyed(const CProjectile* p);
174
175 bool Explosion(int weaponID, int projectileID, const float3& pos, const CUnit* owner);
176
177 void StockpileChanged(const CUnit* owner,
178 const CWeapon* weapon, int oldCount);
179
180 void Save(zipFile archive);
181
182 void UnsyncedHeightMapUpdate(const SRectangle& rect);
183 void Update();
184
185 bool KeyPress(int key, bool isRepeat);
186 bool KeyRelease(int key);
187 bool TextInput(const std::string& utf8);
188 bool MouseMove(int x, int y, int dx, int dy, int button);
189 bool MousePress(int x, int y, int button);
190 void MouseRelease(int x, int y, int button);
191 bool MouseWheel(bool up, float value);
192 bool JoystickEvent(const std::string& event, int val1, int val2);
193 bool IsAbove(int x, int y);
194 string GetTooltip(int x, int y);
195
196 bool DefaultCommand(const CUnit* unit, const CFeature* feature, int& cmd);
197
198 bool CommandNotify(const Command& cmd);
199
200 bool AddConsoleLine(const string& msg, const string& section, int level);
201
202 bool GroupChanged(int groupID);
203
204 bool GameSetup(const string& state, bool& ready,
205 const map<int, string>& playerStates);
206
207 const char* RecvSkirmishAIMessage(int aiID, const char* data, int inSize);
208
209 string WorldTooltip(const CUnit* unit,
210 const CFeature* feature,
211 const float3* groundPos);
212
213 bool MapDrawCmd(int playerID, int type,
214 const float3* pos0,
215 const float3* pos1,
216 const string* labe);
217
218 void ViewResize();
219
220 void DrawGenesis();
221 void DrawWorld();
222 void DrawWorldPreUnit();
223 void DrawWorldShadow();
224 void DrawWorldReflection();
225 void DrawWorldRefraction();
226 void DrawScreenEffects();
227 void DrawScreen();
228 void DrawInMiniMap();
229 void DrawInMiniMapBackground();
230
231 void GameProgress(int frameNum);
232
233 void CollectGarbage();
234
235 public: // Non-eventhandler call-ins
236 void Shutdown();
237 bool GotChatMsg(const string& msg, int playerID);
238 bool RecvLuaMsg(const string& msg, int playerID);
239
240 public: // custom call-in (inter-script calls)
HasXCall(const string & funcName)241 bool HasXCall(const string& funcName) { return HasCallIn(L, funcName); }
242 int XCall(lua_State* srcState, const string& funcName);
243
244 protected:
245 CLuaHandle(const string& name, int order, bool userMode, bool synced);
246 virtual ~CLuaHandle();
247
248 void KillLua();
249
250 static void PushTracebackFuncToRegistry(lua_State* L);
251
252 bool AddBasicCalls(lua_State* L);
253 bool LoadCode(lua_State* L, const string& code, const string& debug);
254 static bool AddEntriesToTable(lua_State* L, const char* name, bool (*entriesFunc)(lua_State*));
255
256 /// returns error code and sets traceback on error
257 int RunCallInTraceback(lua_State* L, const LuaHashString* hs, int inArgs, int outArgs, int errFuncIndex, std::string& tracebackMsg, bool popErrFunc);
258 /// returns false and prints message to log on error
259 bool RunCallInTraceback(lua_State* L, const LuaHashString& hs, int inArgs, int outArgs, int errFuncIndex, bool popErrFunc = true);
260 /// returns false and and sets errormessage on error
261 bool RunCallIn(lua_State* L, int inArgs, int outArgs, std::string& errormessage);
262 /// returns false and prints message to log on error
263 bool RunCallIn(lua_State* L, const LuaHashString& hs, int inArgs, int outArgs);
264
265 void LosCallIn(const LuaHashString& hs, const CUnit* unit, int allyTeam);
266 void UnitCallIn(const LuaHashString& hs, const CUnit* unit);
267
268 void RunDrawCallIn(const LuaHashString& hs);
269
270 protected:
271 bool userMode;
272
273 lua_State* L;
274 luaContextData D;
275
276 lua_State* L_GC;
277
278 bool killMe;
279 string killMsg;
280
281 vector<bool> watchUnitDefs;
282 vector<bool> watchFeatureDefs;
283 vector<bool> watchWeaponDefs; // for the Explosion call-in
284
285 int callinErrors;
286
287 private: // call-outs
288 static int KillActiveHandle(lua_State* L);
289 static int CallOutGetName(lua_State* L);
290 static int CallOutGetSynced(lua_State* L);
291 static int CallOutGetFullCtrl(lua_State* L);
292 static int CallOutGetFullRead(lua_State* L);
293 static int CallOutGetCtrlTeam(lua_State* L);
294 static int CallOutGetReadTeam(lua_State* L);
295 static int CallOutGetReadAllyTeam(lua_State* L);
296 static int CallOutGetSelectTeam(lua_State* L);
297 static int CallOutGetGlobal(lua_State* L);
298 static int CallOutGetRegistry(lua_State* L);
299 static int CallOutGetCallInList(lua_State* L);
300 static int CallOutUpdateCallIn(lua_State* L);
301 static int CallOutIsEngineMinVersion(lua_State* L);
302
303 public: // static
GetActiveShaders(lua_State * L)304 static inline LuaShaders& GetActiveShaders(lua_State* L) { return GetLuaContextData(L)->shaders; }
GetActiveTextures(lua_State * L)305 static inline LuaTextures& GetActiveTextures(lua_State* L) { return GetLuaContextData(L)->textures; }
GetActiveFBOs(lua_State * L)306 static inline LuaFBOs& GetActiveFBOs(lua_State* L) { return GetLuaContextData(L)->fbos; }
GetActiveRBOs(lua_State * L)307 static inline LuaRBOs& GetActiveRBOs(lua_State* L) { return GetLuaContextData(L)->rbos; }
GetActiveDisplayLists(lua_State * L)308 static inline CLuaDisplayLists& GetActiveDisplayLists(lua_State* L) { return GetLuaContextData(L)->displayLists; }
309
SetDevMode(bool value)310 static void SetDevMode(bool value) { devMode = value; }
GetDevMode()311 static bool GetDevMode() { return devMode; }
312
SetModUICtrl(bool value)313 static void SetModUICtrl(bool value) { modUICtrl = value; }
GetModUICtrl()314 static bool GetModUICtrl() { return modUICtrl; }
315
316 static void HandleLuaMsg(int playerID, int script, int mode,
317 const std::vector<boost::uint8_t>& msg);
318
319 protected: // static
320 static bool devMode; // allows real file access
321 static bool modUICtrl; // allows non-user scripts to use UI controls
322
323 // FIXME: because CLuaUnitScript needs to access RunCallIn
324 friend class CLuaUnitScript;
325
326 // FIXME needs access to L & RunCallIn
327 friend class CLuaRules;
328 };
329
330
RunCallIn(lua_State * L,const LuaHashString & hs,int inArgs,int outArgs)331 inline bool CLuaHandle::RunCallIn(lua_State* L, const LuaHashString& hs, int inArgs, int outArgs)
332 {
333 return RunCallInTraceback(L, hs, inArgs, outArgs, 0, false);
334 }
335
336
RunCallIn(lua_State * L,int inArgs,int outArgs,std::string & errorMsg)337 inline bool CLuaHandle::RunCallIn(lua_State* L, int inArgs, int outArgs, std::string& errorMsg)
338 {
339 return RunCallInTraceback(L, NULL, inArgs, outArgs, 0, errorMsg, false);
340 }
341
342
343 /******************************************************************************/
344 /******************************************************************************/
345
346
347 #endif /* LUA_HANDLE_H */
348
349