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
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef LUAUNITSCRIPT_H
#define LUAUNITSCRIPT_H
#include <map>
#include "UnitScript.h"
#include "NullUnitScript.h"
#include "Sim/Units/Unit.h"
class CLuaHandle;
struct lua_State;
// Hack for creg:
// Since CLuaUnitScript isn't creged, during loading it will
// construct a CNullUnitScript instead.
class CLuaUnitScript : public CNullUnitScript
{
private:
static CUnit* activeUnit;
static CUnitScript* activeScript;
// remember whether we are running in LuaRules or LuaGaia
CLuaHandle* handle;
// needed to luaL_unref our refs in ~CLuaUnitScript
lua_State* L;
// contrary to COB the list of functions may differ per unit,
// so the LUAFN_* -> function mapping can differ per unit too.
std::vector<int> scriptIndex;
std::map<std::string, int> scriptNames;
// used to enforce SetDeathScriptFinished can only be used inside Killed
bool inKilled;
protected:
void ShowScriptError(const std::string& msg) override;
// only called from CreateScript, instance can not be created from C++
CLuaUnitScript(lua_State* L, CUnit* unit);
virtual ~CLuaUnitScript();
int UpdateCallIn();
void UpdateCallIn(const std::string& fname, int ref);
void RemoveCallIn(const std::string& fname);
float PopNumber(int fn, float def);
bool PopBoolean(int fn, bool def);
int RunQueryCallIn(int fn);
int RunQueryCallIn(int fn, float arg1);
void Call(int fn) { RawCall(scriptIndex[fn]); }
void Call(int fn, float arg1);
void Call(int fn, float arg1, float arg2);
void Call(int fn, float arg1, float arg2, float arg3);
void RawPushFunction(int functionId);
void PushFunction(int id);
void PushUnit(const CUnit* targetUnit);
bool RunCallIn(int id, int inArgs, int outArgs);
bool RawRunCallIn(int functionId, int inArgs, int outArgs);
std::string GetScriptName(int functionId) const;
public:
// takes LUAFN_* constant as argument
bool HasFunction(int id) const { return scriptIndex[id] >= 0; }
bool HasBlockShot(int weaponNum) const override;
bool HasTargetWeight(int weaponNum) const override;
// callins, called throughout sim
void RawCall(int functionId) override;
void Create() override;
void Killed() override;
void WindChanged(float heading, float speed) override;
void ExtractionRateChanged(float speed) override;
void WorldRockUnit(const float3& rockDir) override {
RockUnit(unit->GetObjectSpaceVec(rockDir));
}
void RockUnit(const float3& rockDir) override;
void WorldHitByWeapon(const float3& hitDir, int weaponDefId, float& inoutDamage) override {
HitByWeapon(unit->GetObjectSpaceVec(hitDir), weaponDefId, inoutDamage);
}
void HitByWeapon(const float3& hitDir, int weaponDefId, float& inoutDamage) override;
void SetSFXOccupy(int curTerrainType) override;
void QueryLandingPads(std::vector<int>& out_pieces) override;
void BeginTransport(const CUnit* unit) override;
int QueryTransport(const CUnit* unit) override;
void TransportPickup(const CUnit* unit) override;
void TransportDrop(const CUnit* unit, const float3& pos) override;
void StartBuilding(float heading, float pitch) override;
int QueryNanoPiece() override;
int QueryBuildInfo() override;
void Destroy() override;
void StartMoving(bool reversing) override;
void StopMoving() override;
void StartUnload() override;
void EndTransport() override;
void StartBuilding() override;
void StopBuilding() override;
void Falling() override;
void Landed() override;
void Activate() override;
void Deactivate() override;
void MoveRate(int curRate) override;
void FireWeapon(int weaponNum) override;
void EndBurst(int weaponNum) override;
// weapon callins
int QueryWeapon(int weaponNum) override;
void AimWeapon(int weaponNum, float heading, float pitch) override;
void AimShieldWeapon(CPlasmaRepulser* weapon) override;
int AimFromWeapon(int weaponNum) override;
void Shot(int weaponNum) override;
bool BlockShot(int weaponNum, const CUnit* targetUnit, bool userTarget) override;
float TargetWeight(int weaponNum, const CUnit* targetUnit) override;
// special callin to allow Lua to resume threads blocking on this anim
void AnimFinished(AnimType type, int piece, int axis) override;
public:
static void HandleFreed(CLuaHandle* handle);
static bool PushEntries(lua_State* L);
private:
static int CreateScript(lua_State* L);
static int UpdateCallIn(lua_State* L);
// other call-outs are stateful
static int CallAsUnit(lua_State* L);
// Lua COB replacement support funcs (+SpawnCEG, PlaySoundFile, etc.)
static int GetUnitValue(lua_State* L, CUnitScript* script, int arg);
static int GetUnitValue(lua_State* L);
static int GetUnitCOBValue(lua_State* L); // backward compat
static int SetUnitValue(lua_State* L, CUnitScript* script, int arg);
static int SetUnitValue(lua_State* L);
static int SetUnitCOBValue(lua_State* L); // backward compat
static int SetPieceVisibility(lua_State* L);
static int EmitSfx(lua_State* L); // TODO: better names?
static int AttachUnit(lua_State* L);
static int DropUnit(lua_State* L);
static int Explode(lua_State* L);
static int ShowFlare(lua_State* L);
// Lua COB replacement animation support funcs
static int Spin(lua_State* L);
static int StopSpin(lua_State* L);
static int Turn(lua_State* L);
static int Move(lua_State* L);
static int IsInAnimation(lua_State* L, const char* caller, AnimType type);
static int IsInTurn(lua_State* L);
static int IsInMove(lua_State* L);
static int IsInSpin(lua_State* L);
static int WaitForAnimation(lua_State* L, const char* caller, AnimType type);
static int WaitForTurn(lua_State* L);
static int WaitForMove(lua_State* L);
// Lua COB function to work around lack of working CBCobThreadFinish
static int SetDeathScriptFinished(lua_State* L);
static int GetPieceTranslation(lua_State* L); // matches Move
static int GetPieceRotation(lua_State* L); // matches Turn
static int GetPiecePosDir(lua_State* L); // EmitDirPos (in unit space)
static int GetActiveUnitID(lua_State* L);
};
#endif
|