Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LUA Scripting Language #506

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ set(INCLUDED_DIRECTORIES
"tests/dGameTests/dComponentsTests"
)

if(__include_lua__)
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "dLua")
set(INCLUDED_DIRECTORIES ${INCLUDED_DIRECTORIES} "dLua/sol")
endif()

# Add system specfic includes for Apple, Windows and Other Unix OS' (including Linux)
if (APPLE)
include_directories("/usr/local/include/")
Expand Down Expand Up @@ -317,6 +322,7 @@ add_subdirectory(dDatabase)
add_subdirectory(dChatFilter)
add_subdirectory(dNet)
add_subdirectory(dScripts) # Add for dGame to use
add_subdirectory(dLua)
add_subdirectory(dGame)
add_subdirectory(dZoneManager)
add_subdirectory(dNavigation)
Expand Down
23 changes: 21 additions & 2 deletions dGame/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ foreach(file ${DSCRIPTS_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dScripts/${file}")
endforeach()

add_library(dGame STATIC ${DGAME_SOURCES})
# If we are including LUA, include the dLua files in dGame
if(__include_lua__)
# Append the dLua files to the dGame files
foreach(file ${DGAME_DLUA_SOURCES})
set(DGAME_SOURCES ${DGAME_SOURCES} "${PROJECT_SOURCE_DIR}/dLua/${file}")
endforeach()

find_package(Lua REQUIRED)

add_library(dGame STATIC ${DGAME_SOURCES})

target_link_libraries(dGame dDatabase Recast Detour ${LUA_LIBRARIES})

include_directories("${PROJECT_SOURCE_DIR}/dLua/")

message(STATUS "Linking dGame to LUA " ${LUA_LIBRARIES})
else()
add_library(dGame STATIC ${DGAME_SOURCES})

target_link_libraries(dGame dDatabase Recast Detour)
endif()

target_link_libraries(dGame dDatabase Recast Detour)
78 changes: 20 additions & 58 deletions dGame/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ Player::Player(const LWOOBJID& objectID, const EntityInfo info, User* user, Enti
m_GhostReferencePoint = NiPoint3::ZERO;
m_GhostOverridePoint = NiPoint3::ZERO;
m_GhostOverride = false;
m_ObservedEntitiesLength = 256;
m_ObservedEntitiesUsed = 0;
m_ObservedEntities.resize(m_ObservedEntitiesLength);
m_ObservedEntities.reserve(256);

m_Character->SetEntity(this);

Expand Down Expand Up @@ -113,24 +111,14 @@ void Player::SendToZone(LWOMAPID zoneId, LWOCLONEID cloneId) {
});
}

void Player::AddLimboConstruction(LWOOBJID objectId) {
const auto& iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);

if (iter != m_LimboConstructions.end()) {
return;
}

m_LimboConstructions.push_back(objectId);
void Player::AddLimboConstruction(LWOOBJID objectId)
{
m_LimboConstructions.insert(objectId);
}

void Player::RemoveLimboConstruction(LWOOBJID objectId) {
const auto& iter = std::find(m_LimboConstructions.begin(), m_LimboConstructions.end(), objectId);

if (iter == m_LimboConstructions.end()) {
return;
}

m_LimboConstructions.erase(iter);
void Player::RemoveLimboConstruction(LWOOBJID objectId)
{
m_LimboConstructions.erase(objectId);
}

void Player::ConstructLimboEntities() {
Expand Down Expand Up @@ -179,42 +167,19 @@ bool Player::GetGhostOverride() const {
return m_GhostOverride;
}

void Player::ObserveEntity(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == 0 || m_ObservedEntities[i] == id) {
m_ObservedEntities[i] = id;

return;
}
}

const auto index = m_ObservedEntitiesUsed++;

if (m_ObservedEntitiesUsed > m_ObservedEntitiesLength) {
m_ObservedEntities.resize(m_ObservedEntitiesLength + m_ObservedEntitiesLength);

m_ObservedEntitiesLength = m_ObservedEntitiesLength + m_ObservedEntitiesLength;
}

m_ObservedEntities[index] = id;
void Player::ObserveEntity(int32_t id)
{
m_ObservedEntities.insert(id);
}

bool Player::IsObserved(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == id) {
return true;
}
}

return false;
bool Player::IsObserved(int32_t id)
{
return m_ObservedEntities.find(id) != m_ObservedEntities.end();
}

void Player::GhostEntity(int32_t id) {
for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
if (m_ObservedEntities[i] == id) {
m_ObservedEntities[i] = 0;
}
}
void Player::GhostEntity(int32_t id)
{
m_ObservedEntities.erase(id);
}

Player* Player::GetPlayer(const SystemAddress& sysAddr) {
Expand Down Expand Up @@ -262,19 +227,16 @@ void Player::SetDroppedCoins(uint64_t value) {
Player::~Player() {
Game::logger->Log("Player", "Deleted player");

for (int32_t i = 0; i < m_ObservedEntitiesUsed; i++) {
const auto id = m_ObservedEntities[i];

if (id == 0) {
continue;
}

for (const auto id : m_ObservedEntities)
{
auto* entity = EntityManager::Instance()->GetGhostCandidate(id);

if (entity != nullptr) {
entity->SetObservers(entity->GetObservers() - 1);
}
}

m_ObservedEntities.clear();

m_LimboConstructions.clear();

Expand Down
11 changes: 5 additions & 6 deletions dGame/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

#include "Entity.h"

#include <set>
#include <unordered_set>

/**
* Extended Entity for player data and behavior.
*
Expand Down Expand Up @@ -120,13 +123,9 @@ class Player final : public Entity

bool m_GhostOverride;

std::vector<int32_t> m_ObservedEntities;

int32_t m_ObservedEntitiesLength;

int32_t m_ObservedEntitiesUsed;
std::unordered_set<int32_t> m_ObservedEntities;

std::vector<LWOOBJID> m_LimboConstructions;
std::set<LWOOBJID> m_LimboConstructions;

std::map<LWOOBJID, Loot::Info> m_DroppedLoot;

Expand Down
2 changes: 2 additions & 0 deletions dGame/dComponents/RebuildComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ void RebuildComponent::SpawnActivator() {
info.spawnerID = m_Parent->GetObjectID();
info.pos = m_ActivatorPosition == NiPoint3::ZERO ? m_Parent->GetPosition() : m_ActivatorPosition;

Game::logger->Log("RebuildComponent", "Spawning activator at <%f, %f, %f>", info.pos.x, info.pos.y, info.pos.z);

m_Activator = EntityManager::Instance()->CreateEntity(info, nullptr, m_Parent);
if (m_Activator) {
m_ActivatorId = m_Activator->GetObjectID();
Expand Down
78 changes: 78 additions & 0 deletions dGame/dUtilities/SlashCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@
#include "CDObjectsTable.h"
#include "CDZoneTableTable.h"

#if __include_lua__ == 1
#include "LuaScript.h"
#include "ScriptComponent.h"
#include <filesystem>
#endif

void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) {
auto commandCopy = command;
// Sanity check that a command was given
Expand Down Expand Up @@ -625,6 +631,78 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
return;
}

#if __include_lua__ == 1
if (chatCommand == "lua" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER && args.size() >= 1) {
std::string input = "";

// If the first argument is "load", load the file
bool isFile = false;
if (args[0] == "load") {
isFile = true;
}

// Join the args
for (size_t i = 0; i < args.size(); i++) {
if (i == 0 && isFile) continue;
input += args[i] + " ";
}

// If isFile is true, load the file
if (isFile) {
// Trim last space
input.pop_back();

std::string path = input;

std::ifstream infile(path);

std::stringstream buffer;

if (infile.is_open()) {
std::string line;
while (std::getline(infile, line)) {
buffer << line << "\n";
}
}
else {
ChatPackets::SendSystemMessage(sysAddr, u"Could not open file " + GeneralUtils::ASCIIToUTF16(path));
return;
}

input = buffer.str();

infile.close();
}

LuaScript* lua = new LuaScript(LuaTerminateBehavior::ResetScriptAndDelete);

ScriptComponent* script = entity->GetComponent<ScriptComponent>();

if (script == nullptr) {
script = new ScriptComponent(entity, false);

entity->AddComponent(ScriptComponent::ComponentType, script);
}

script->SetScript(lua);

lua->SetEntity(entity);

// Run the code, and print any errors
try {
lua->Script(input);
}
// Catch sol::error
catch (const sol::error& e) {
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(e.what()));
}
// Catch *any* error
catch (...) {
ChatPackets::SendSystemMessage(sysAddr, u"Unknown error!");
}
}
#endif

if (chatCommand == "addmission" && entity->GetGMLevel() >= eGameMasterLevel::DEVELOPER) {
if (args.size() == 0) return;

Expand Down
5 changes: 5 additions & 0 deletions dLua/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
set(DGAME_DLUA_SOURCES "dLua.cpp"
"lCommonTypes.cpp"
"lEntity.cpp"
"LuaScript.cpp"
PARENT_SCOPE)
Loading