DarkflameServer/dLua/LuaScript.h
wincent 5f689104af Initial work on LUA scripting.
This LUA scripting implementation uses the sol header only C++ wrapper for the native LUA libraries.

The API does not follow the original LU scripting. Each instance of a script is in its own LUA-State, and has 'self' as a global. There are hooks to all the implemented CppScript methods, as well as a subset of the entity functionallity. Has to be expanded upon.

This is local work which has been sitting for awhile; thought someone might like to take a look at it.
2022-04-13 19:51:14 +02:00

427 lines
14 KiB
C++

#include "dLua.h"
#include "CppScripts.h"
#include "Game.h"
#include "dLogger.h"
#include "LuaTerminateBehavior.h"
#include "lEntity.h"
class Entity;
class LuaScript : public CppScripts::Script
{
private:
sol::state m_State;
LuaTerminateBehavior m_TerminateBehavior;
int32_t m_Hooks;
bool m_Terminating;
bool m_AttemptingToFinalize;
void CheckHooks();
void AttemptToFinalize();
public:
LuaScript(LuaTerminateBehavior terminateBehavior);
sol::state& GetState();
void Script(const std::string& script);
void SetEntity(Entity* entity);
Entity* GetEntity();
/**
* Add a callback timer.
*/
void AddCallbackTimer(float seconds, sol::function callback);
template <typename F, typename ...Types>
void Invoke(F function, Types... args)
{
sol::function func = m_State[function];
if (!func.valid())
{
return;
}
func(std::forward<Types>(args)...);
}
// ======================================================================
// CppScripts::Script overrides
// ======================================================================
/**
* Invoked one frame after the script is loaded.
*
* Equivalent to 'function onStartup(self)'
*/
void OnStartup(Entity* self) override {
Invoke("onStartup");
}
/**
* Invoked upon an entity entering the phantom collider on self.
*
* Equivalent to 'function onCollisionPhantom(self, msg)'
*/
void OnCollisionPhantom(Entity* self, Entity* target) override {
Invoke("onCollisionPhantom", lEntity(target));
}
/**
* Invoked when a player accepted a mission.
*
* Equivalent to 'function onMissionDialogueOK(self, msg)'
*/
void OnMissionDialogueOK(Entity* self, Entity* target, int missionID, MissionState missionState) override {
Invoke("onMissionDialogueOK", lEntity(target), missionID, (int32_t) missionState);
}
/**
* Invoked when the client or the server invoked an event server-side.
*
* Equivalent to 'function onFireEventServerSide(self, msg)'
*/
void OnFireEventServerSide(Entity *self, Entity *sender, std::string args, int32_t param1, int32_t param2, int32_t param3) override {
Invoke("onFireEventServerSide", lEntity(sender), args, param1, param2, param3);
}
/**
* Invoked upon sending a object notification.
*
* Equivalent to 'function onNotifyObject(self, msg)'
*/
void OnNotifyObject(Entity *self, Entity *sender, const std::string& name, int32_t param1 = 0, int32_t param2 = 0) override {
Invoke("onNotifyObject", lEntity(sender), name, param1, param2);
}
/**
* Invoked upon a player exiting the modular build minigame.
*
* Equivalent to 'function onModularBuildExit(self, msg)'
*/
void OnModularBuildExit(Entity* self, Entity* player, bool bCompleted, std::vector<LOT> modules) override {
Invoke("onModularBuildExit", lEntity(player), bCompleted, modules);
}
/**
* Invoked when a player has loaded into the zone.
*
* Equivalent to 'function onPlayerLoaded(self, msg)'
*/
void OnPlayerLoaded(Entity* self, Entity* player) override {
Invoke("onPlayerLoaded", lEntity(player));
}
/**
* Invoked when a player has died.
*
* Equivalent to 'function onPlayerDied(self, msg)'
*/
void OnPlayerDied(Entity* self, Entity* player) override {
Invoke("onPlayerDied", lEntity(player));
}
/**
* Invoked when a player has resurrected.
*
* Equivalent to 'function onPlayerResurrected(self, msg)'
*/
void OnPlayerResurrected(Entity* self, Entity* player) override {
Invoke("onPlayerResurrected", lEntity(player));
}
/**
* Invoked when a player has left the zone.
*
* Equivalent to 'function onPlayerExit(self, msg)'
*/
void OnPlayerExit(Entity* self, Entity* player) override {
Invoke("onPlayerExit", lEntity(player));
}
/**
* Invoked when a player has interacted with the proximity collider on self.
*
* Equivalent to 'function onProximityUpdate(self, msg)'
*
* @param name The name of the proximity collider recviving an interaction.
* @param status "ENTER" if a player has entered the proximity collider; "LEAVE" if a player has left the proximity collider
*/
void OnProximityUpdate(Entity* self, Entity* entering, std::string name, std::string status) override {
Invoke("onProximityUpdate", lEntity(entering), name, status);
}
/**
* Invoked when a timer on self has expired.
*
* Equivalent to 'function onTimerDone(self, msg)'
*/
void OnTimerDone(Entity* self, std::string timerName) override {
Invoke("onTimerDone", timerName);
}
/**
* Invoked when a player interactions with self.
*
* Equivalent to 'function onUse(self, msg)'
*/
void OnUse(Entity* self, Entity* user) override {
Invoke("onUse", lEntity(user));
}
/**
* Invoked when self has died.
*
* Equivalent to 'function onDie(self, msg)'
*/
void OnDie(Entity* self, Entity* killer) override {
Invoke("onDie", lEntity(killer));
}
/**
* Invoked when self has received a hit.
*
* Equivalent to 'function onHit(self, msg)'
*/
void OnHit(Entity* self, Entity* attacker) override {
Invoke("onHit", lEntity(attacker));
}
/**
* Invoked when self has received an emote from a player.
*
* Equivalent to 'function onEmoteReceived(self, msg)'
*/
void OnEmoteReceived(Entity* self, int32_t emote, Entity* target) override {
Invoke("onEmoteReceived", emote, lEntity(target));
}
/**
* Invoked when a player has started building this quickbuild.
*
* Equivalent to 'function onRebuildStart(self, msg)'
*/
void OnRebuildStart(Entity* self, Entity* target) override {
Invoke("onRebuildStart", lEntity(target));
}
/**
* Invoked when this quickbuild has changed state.
*
* Equivalent to 'function onRebuildNotifyState(self, msg)'
*/
void OnRebuildNotifyState(Entity* self, eRebuildState state) override {
Invoke("onRebuildNotifyState", (int32_t) state);
}
/**
* Invoked when this quickbuild has been completed.
*
* Equivalent to 'function onRebuildComplete(self, msg)'
*/
void OnRebuildComplete(Entity* self, Entity* target) override {
Invoke("onRebuildComplete", lEntity(target));
}
/**
* Invoked when self has received either a hit or heal.
*
* Equivalent to 'function onHitOrHealResult(self, msg)'
*/
void OnHitOrHealResult(Entity* self, Entity* attacker, int32_t damage) override {
Invoke("onHitOrHealResult", lEntity(attacker), damage);
}
/**
* Invoked when a player has responsed to a mission.
*
* Equivalent to 'function onRespondToMission(self, msg)'
*/
void OnRespondToMission(Entity* self, int missionID, Entity* player, int reward) override {
Invoke("onRespondToMission", missionID, lEntity(player), reward);
}
/**
* Invoked once per frame.
*
* No LUA eqivalent.
*/
void OnUpdate(Entity* self) override {
Invoke("onUpdate");
}
/**
* Invoked when this property has been rented.
*
* Equivalent to 'function onZonePropertyRented(self, msg)'
*/
void OnZonePropertyRented(Entity* self, Entity* renter) override {
Invoke("onZonePropertyRented", lEntity(renter));
}
/**
* Invoked when a player has begun to edit this property.
*
* Equivalent to 'function onZonePropertyEditBegin(self, msg)'
*/
void OnZonePropertyEditBegin(Entity* self) override {
Invoke("onZonePropertyEditBegin");
}
/**
* Invoked when a player has concluded editing this property.
*
* Equivalent to 'function onZonePropertyEditEnd(self, msg)'
*/
void OnZonePropertyEditEnd(Entity* self) override {
Invoke("onZonePropertyEditEnd");
}
/**
* Invoked when a player has equipped a model while editing this property.
*
* Equivalent to 'function onZonePropertyModelEquipped(self, msg)'
*/
void OnZonePropertyModelEquipped(Entity* self) override {
Invoke("onZonePropertyModelEquipped");
}
/**
* Invoked when a player has placed a model while editing this property.
*
* Equivalent to 'function onZonePropertyModelPlaced(self, msg)'
*/
void OnZonePropertyModelPlaced(Entity* self, Entity* player) override {
Invoke("onZonePropertyModelPlaced", lEntity(player));
}
/**
* Invoked when a player has picked up a model while editing this property.
*
* Equivalent to 'function onZonePropertyModelPickedUp(self, msg)'
*/
void OnZonePropertyModelPickedUp(Entity* self, Entity* player) override {
Invoke("onZonePropertyModelPickedUp", lEntity(player));
}
/**
* Invoked when a player removed a model while editing this property.
*
* Equivalent to 'function onZonePropertyModelRemoved(self, msg)'
*/
void OnZonePropertyModelRemoved(Entity* self, Entity* player) override {
Invoke("onZonePropertyModelRemoved", lEntity(player));
}
/**
* Invoked when a player removed a model while holding it when editing this property.
*
* Equivalent to 'function onZonePropertyModelRemoved(self, msg)'
*/
void OnZonePropertyModelRemovedWhileEquipped(Entity* self, Entity* player) override {
Invoke("onZonePropertyModelRemovedWhileEquipped", lEntity(player));
}
/**
* Invoked when a player rotated a model while editing this property.
*
* Equivalent to 'function onZonePropertyModelRotated(self, msg)'
*/
void OnZonePropertyModelRotated(Entity* self, Entity* player) override {
Invoke("onZonePropertyModelRotated", lEntity(player));
}
/**
* Invoked when the pet taming minigame encounted an event.
*
* Equivalent to 'function onNotifyPetTamingMinigame(self, msg)'
*/
void OnNotifyPetTamingMinigame(Entity* self, Entity* tamer, eNotifyType type) override {
Invoke("onNotifyPetTamingMinigame", lEntity(tamer), (int32_t) type);
}
/**
* Invoked when a player responded to a message box.
*
* Equivalent to 'function onMessageBoxResponse(self, msg)'
*/
void OnMessageBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& identifier, const std::u16string& userData) override {
Invoke("onMessageBoxResponse", lEntity(sender), button, GeneralUtils::UTF16ToWTF8(identifier), GeneralUtils::UTF16ToWTF8(userData));
}
/**
* Invoked when a player responded to a choice box.
*
* Equivalent to 'function onChoiceBoxResponse(self, msg)'
*/
void OnChoiceBoxResponse(Entity* self, Entity* sender, int32_t button, const std::u16string& buttonIdentifier, const std::u16string& identifier) override {
Invoke("onChoiceBoxResponse", lEntity(sender), button, GeneralUtils::UTF16ToWTF8(buttonIdentifier), GeneralUtils::UTF16ToWTF8(identifier));
}
/**
* Invoked when self arrived at a moving platform waypoint.
*
* Equivalent to 'function onWaypointReached(self, msg)'
*/
void OnWaypointReached(Entity* self, uint32_t waypointIndex) override {
Invoke("onWaypointReached", waypointIndex);
}
/**
* Invoked when a player fired a skill event on self.
*
* Equivalent to 'function onSkillEventFired(self, msg)'
*/
void OnSkillEventFired(Entity* self, Entity* caster, const std::string& message) override {
Invoke("onSkillEventFired", lEntity(caster), message);
}
/**
* Invoked when self casted a skill.
*
* Equivalent to 'function onSkillCast(self, msg)'
*/
void OnSkillCast(Entity* self, uint32_t skillID) override {
Invoke("onSkillCast", skillID);
}
/**
* Invoked when a player on a rail reaches a waypoint
* Equivalent to: 'onPlayerRailArrivedNotification(self, msg)'
* @param self the parent of the script
* @param sender the entity that sent the event
* @param pathName the name of the path the entity was on
* @param waypoint the waypoint number of the path the entity was on
*/
void OnPlayerRailArrived(Entity* self, Entity* sender, const std::u16string& pathName, int32_t waypoint) override {
Invoke("onPlayerRailArrived", lEntity(sender), GeneralUtils::UTF16ToWTF8(pathName), waypoint);
}
/**
* Used by legacy minigames to indicate something has changed about the activity
* @param self the entity the script belongs to
* @param senderID the sender of the message
* @param value1 some value to represent the change
* @param value2 some other value to represent the change
* @param stringValue some string value to represent the change
*/
void OnActivityStateChangeRequest(Entity* self, const LWOOBJID senderID, const int32_t value1,
const int32_t value2, const std::u16string& stringValue) override {
Invoke("onActivityStateChangeRequest", senderID, value1, value2, GeneralUtils::UTF16ToWTF8(stringValue));
}
void OnCinematicUpdate(Entity* self, Entity* sender, eCinematicEvent event, const std::u16string& pathName,
float_t pathTime, float_t totalTime, int32_t waypoint) override {
Invoke("onCinematicUpdate", lEntity(sender), (int32_t) event, GeneralUtils::UTF16ToWTF8(pathName), pathTime, totalTime, waypoint);
}
};