mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-04-29 09:09:20 +02:00
11735 lines
301 KiB
C++
11735 lines
301 KiB
C++
/**
|
|
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
|
|
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "otpch.h"
|
|
|
|
#include <boost/range/adaptor/reversed.hpp>
|
|
|
|
#include "luascript.h"
|
|
#include "chat.h"
|
|
#include "player.h"
|
|
#include "game.h"
|
|
#include "protocolstatus.h"
|
|
#include "spells.h"
|
|
#include "iologindata.h"
|
|
#include "configmanager.h"
|
|
#include "teleport.h"
|
|
#include "databasemanager.h"
|
|
#include "bed.h"
|
|
#include "monster.h"
|
|
#include "scheduler.h"
|
|
#include "databasetasks.h"
|
|
|
|
extern Chat* g_chat;
|
|
extern Game g_game;
|
|
extern Monsters g_monsters;
|
|
extern ConfigManager g_config;
|
|
extern Vocations g_vocations;
|
|
extern Spells* g_spells;
|
|
|
|
ScriptEnvironment::DBResultMap ScriptEnvironment::tempResults;
|
|
uint32_t ScriptEnvironment::lastResultId = 0;
|
|
|
|
std::multimap<ScriptEnvironment*, Item*> ScriptEnvironment::tempItems;
|
|
|
|
LuaEnvironment g_luaEnvironment;
|
|
|
|
ScriptEnvironment::ScriptEnvironment()
|
|
{
|
|
resetEnv();
|
|
}
|
|
|
|
ScriptEnvironment::~ScriptEnvironment()
|
|
{
|
|
resetEnv();
|
|
}
|
|
|
|
void ScriptEnvironment::resetEnv()
|
|
{
|
|
scriptId = 0;
|
|
callbackId = 0;
|
|
timerEvent = false;
|
|
interface = nullptr;
|
|
localMap.clear();
|
|
tempResults.clear();
|
|
|
|
auto pair = tempItems.equal_range(this);
|
|
auto it = pair.first;
|
|
while (it != pair.second) {
|
|
Item* item = it->second;
|
|
if (item->getParent() == VirtualCylinder::virtualCylinder) {
|
|
g_game.ReleaseItem(item);
|
|
}
|
|
it = tempItems.erase(it);
|
|
}
|
|
}
|
|
|
|
bool ScriptEnvironment::setCallbackId(int32_t callbackId, LuaScriptInterface* scriptInterface)
|
|
{
|
|
if (this->callbackId != 0) {
|
|
//nested callbacks are not allowed
|
|
if (interface) {
|
|
interface->reportErrorFunc("Nested callbacks!");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
this->callbackId = callbackId;
|
|
interface = scriptInterface;
|
|
return true;
|
|
}
|
|
|
|
void ScriptEnvironment::getEventInfo(int32_t& scriptId, LuaScriptInterface*& scriptInterface, int32_t& callbackId, bool& timerEvent) const
|
|
{
|
|
scriptId = this->scriptId;
|
|
scriptInterface = interface;
|
|
callbackId = this->callbackId;
|
|
timerEvent = this->timerEvent;
|
|
}
|
|
|
|
uint32_t ScriptEnvironment::addThing(Thing* thing)
|
|
{
|
|
if (!thing || thing->isRemoved()) {
|
|
return 0;
|
|
}
|
|
|
|
Creature* creature = thing->getCreature();
|
|
if (creature) {
|
|
return creature->getID();
|
|
}
|
|
|
|
Item* item = thing->getItem();
|
|
for (const auto& it : localMap) {
|
|
if (it.second == item) {
|
|
return it.first;
|
|
}
|
|
}
|
|
|
|
localMap[++lastUID] = item;
|
|
return lastUID;
|
|
}
|
|
|
|
void ScriptEnvironment::insertItem(uint32_t uid, Item* item)
|
|
{
|
|
auto result = localMap.emplace(uid, item);
|
|
if (!result.second) {
|
|
std::cout << std::endl << "Lua Script Error: Thing uid already taken.";
|
|
}
|
|
}
|
|
|
|
Thing* ScriptEnvironment::getThingByUID(uint32_t uid)
|
|
{
|
|
if (uid >= 0x10000000) {
|
|
return g_game.getCreatureByID(uid);
|
|
}
|
|
|
|
auto it = localMap.find(uid);
|
|
if (it != localMap.end()) {
|
|
Item* item = it->second;
|
|
if (!item->isRemoved()) {
|
|
return item;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
Item* ScriptEnvironment::getItemByUID(uint32_t uid)
|
|
{
|
|
Thing* thing = getThingByUID(uid);
|
|
if (!thing) {
|
|
return nullptr;
|
|
}
|
|
return thing->getItem();
|
|
}
|
|
|
|
Container* ScriptEnvironment::getContainerByUID(uint32_t uid)
|
|
{
|
|
Item* item = getItemByUID(uid);
|
|
if (!item) {
|
|
return nullptr;
|
|
}
|
|
return item->getContainer();
|
|
}
|
|
|
|
void ScriptEnvironment::removeItemByUID(uint32_t uid)
|
|
{
|
|
auto it = localMap.find(uid);
|
|
if (it != localMap.end()) {
|
|
localMap.erase(it);
|
|
}
|
|
}
|
|
|
|
void ScriptEnvironment::addTempItem(Item* item)
|
|
{
|
|
tempItems.emplace(this, item);
|
|
}
|
|
|
|
void ScriptEnvironment::removeTempItem(Item* item)
|
|
{
|
|
for (auto it = tempItems.begin(), end = tempItems.end(); it != end; ++it) {
|
|
if (it->second == item) {
|
|
tempItems.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t ScriptEnvironment::addResult(DBResult_ptr res)
|
|
{
|
|
tempResults[++lastResultId] = res;
|
|
return lastResultId;
|
|
}
|
|
|
|
bool ScriptEnvironment::removeResult(uint32_t id)
|
|
{
|
|
auto it = tempResults.find(id);
|
|
if (it == tempResults.end()) {
|
|
return false;
|
|
}
|
|
|
|
tempResults.erase(it);
|
|
return true;
|
|
}
|
|
|
|
DBResult_ptr ScriptEnvironment::getResultByID(uint32_t id)
|
|
{
|
|
auto it = tempResults.find(id);
|
|
if (it == tempResults.end()) {
|
|
return nullptr;
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
std::string LuaScriptInterface::getErrorDesc(ErrorCode_t code)
|
|
{
|
|
switch (code) {
|
|
case LUA_ERROR_PLAYER_NOT_FOUND: return "Player not found";
|
|
case LUA_ERROR_CREATURE_NOT_FOUND: return "Creature not found";
|
|
case LUA_ERROR_ITEM_NOT_FOUND: return "Item not found";
|
|
case LUA_ERROR_THING_NOT_FOUND: return "Thing not found";
|
|
case LUA_ERROR_TILE_NOT_FOUND: return "Tile not found";
|
|
case LUA_ERROR_HOUSE_NOT_FOUND: return "House not found";
|
|
case LUA_ERROR_COMBAT_NOT_FOUND: return "Combat not found";
|
|
case LUA_ERROR_CONDITION_NOT_FOUND: return "Condition not found";
|
|
case LUA_ERROR_AREA_NOT_FOUND: return "Area not found";
|
|
case LUA_ERROR_CONTAINER_NOT_FOUND: return "Container not found";
|
|
case LUA_ERROR_VARIANT_NOT_FOUND: return "Variant not found";
|
|
case LUA_ERROR_VARIANT_UNKNOWN: return "Unknown variant type";
|
|
case LUA_ERROR_SPELL_NOT_FOUND: return "Spell not found";
|
|
default: return "Bad error code";
|
|
}
|
|
}
|
|
|
|
ScriptEnvironment LuaScriptInterface::scriptEnv[16];
|
|
int32_t LuaScriptInterface::scriptEnvIndex = -1;
|
|
|
|
LuaScriptInterface::LuaScriptInterface(std::string interfaceName) : interfaceName(std::move(interfaceName))
|
|
{
|
|
if (!g_luaEnvironment.getLuaState()) {
|
|
g_luaEnvironment.initState();
|
|
}
|
|
}
|
|
|
|
LuaScriptInterface::~LuaScriptInterface()
|
|
{
|
|
closeState();
|
|
}
|
|
|
|
bool LuaScriptInterface::reInitState()
|
|
{
|
|
g_luaEnvironment.clearCombatObjects(this);
|
|
g_luaEnvironment.clearAreaObjects(this);
|
|
|
|
closeState();
|
|
return initState();
|
|
}
|
|
|
|
/// Same as lua_pcall, but adds stack trace to error strings in called function.
|
|
int LuaScriptInterface::protectedCall(lua_State* L, int nargs, int nresults)
|
|
{
|
|
int error_index = lua_gettop(L) - nargs;
|
|
lua_pushcfunction(L, luaErrorHandler);
|
|
lua_insert(L, error_index);
|
|
|
|
int ret = lua_pcall(L, nargs, nresults, error_index);
|
|
lua_remove(L, error_index);
|
|
return ret;
|
|
}
|
|
|
|
int32_t LuaScriptInterface::loadFile(const std::string& file, Npc* npc /* = nullptr*/)
|
|
{
|
|
//loads file as a chunk at stack top
|
|
int ret = luaL_loadfile(luaState, file.c_str());
|
|
if (ret != 0) {
|
|
lastLuaError = popString(luaState);
|
|
return -1;
|
|
}
|
|
|
|
//check that it is loaded as a function
|
|
if (!isFunction(luaState, -1)) {
|
|
return -1;
|
|
}
|
|
|
|
loadingFile = file;
|
|
|
|
if (!reserveScriptEnv()) {
|
|
return -1;
|
|
}
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
env->setScriptId(EVENT_ID_LOADING, this);
|
|
env->setNpc(npc);
|
|
|
|
//execute it
|
|
ret = protectedCall(luaState, 0, 0);
|
|
if (ret != 0) {
|
|
reportError(nullptr, popString(luaState));
|
|
resetScriptEnv();
|
|
return -1;
|
|
}
|
|
|
|
resetScriptEnv();
|
|
return 0;
|
|
}
|
|
|
|
int32_t LuaScriptInterface::getEvent(const std::string& eventName)
|
|
{
|
|
//get our events table
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
|
|
if (!isTable(luaState, -1)) {
|
|
lua_pop(luaState, 1);
|
|
return -1;
|
|
}
|
|
|
|
//get current event function pointer
|
|
lua_getglobal(luaState, eventName.c_str());
|
|
if (!isFunction(luaState, -1)) {
|
|
lua_pop(luaState, 2);
|
|
return -1;
|
|
}
|
|
|
|
//save in our events table
|
|
lua_pushvalue(luaState, -1);
|
|
lua_rawseti(luaState, -3, runningEventId);
|
|
lua_pop(luaState, 2);
|
|
|
|
//reset global value of this event
|
|
lua_pushnil(luaState);
|
|
lua_setglobal(luaState, eventName.c_str());
|
|
|
|
cacheFiles[runningEventId] = loadingFile + ":" + eventName;
|
|
return runningEventId++;
|
|
}
|
|
|
|
int32_t LuaScriptInterface::getMetaEvent(const std::string& globalName, const std::string& eventName)
|
|
{
|
|
//get our events table
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
|
|
if (!isTable(luaState, -1)) {
|
|
lua_pop(luaState, 1);
|
|
return -1;
|
|
}
|
|
|
|
//get current event function pointer
|
|
lua_getglobal(luaState, globalName.c_str());
|
|
lua_getfield(luaState, -1, eventName.c_str());
|
|
if (!isFunction(luaState, -1)) {
|
|
lua_pop(luaState, 3);
|
|
return -1;
|
|
}
|
|
|
|
//save in our events table
|
|
lua_pushvalue(luaState, -1);
|
|
lua_rawseti(luaState, -4, runningEventId);
|
|
lua_pop(luaState, 1);
|
|
|
|
//reset global value of this event
|
|
lua_pushnil(luaState);
|
|
lua_setfield(luaState, -2, eventName.c_str());
|
|
lua_pop(luaState, 2);
|
|
|
|
cacheFiles[runningEventId] = loadingFile + ":" + globalName + "@" + eventName;
|
|
return runningEventId++;
|
|
}
|
|
|
|
const std::string& LuaScriptInterface::getFileById(int32_t scriptId)
|
|
{
|
|
if (scriptId == EVENT_ID_LOADING) {
|
|
return loadingFile;
|
|
}
|
|
|
|
auto it = cacheFiles.find(scriptId);
|
|
if (it == cacheFiles.end()) {
|
|
static const std::string& unk = "(Unknown scriptfile)";
|
|
return unk;
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
std::string LuaScriptInterface::getStackTrace(const std::string& error_desc)
|
|
{
|
|
lua_getglobal(luaState, "debug");
|
|
if (!isTable(luaState, -1)) {
|
|
lua_pop(luaState, 1);
|
|
return error_desc;
|
|
}
|
|
|
|
lua_getfield(luaState, -1, "traceback");
|
|
if (!isFunction(luaState, -1)) {
|
|
lua_pop(luaState, 2);
|
|
return error_desc;
|
|
}
|
|
|
|
lua_replace(luaState, -2);
|
|
pushString(luaState, error_desc);
|
|
lua_call(luaState, 1, 1);
|
|
return popString(luaState);
|
|
}
|
|
|
|
void LuaScriptInterface::reportError(const char* function, const std::string& error_desc, bool stack_trace/* = false*/)
|
|
{
|
|
int32_t scriptId;
|
|
int32_t callbackId;
|
|
bool timerEvent;
|
|
LuaScriptInterface* scriptInterface;
|
|
getScriptEnv()->getEventInfo(scriptId, scriptInterface, callbackId, timerEvent);
|
|
|
|
std::cout << std::endl << "Lua Script Error: ";
|
|
|
|
if (scriptInterface) {
|
|
std::cout << '[' << scriptInterface->getInterfaceName() << "] " << std::endl;
|
|
|
|
if (timerEvent) {
|
|
std::cout << "in a timer event called from: " << std::endl;
|
|
}
|
|
|
|
if (callbackId) {
|
|
std::cout << "in callback: " << scriptInterface->getFileById(callbackId) << std::endl;
|
|
}
|
|
|
|
std::cout << scriptInterface->getFileById(scriptId) << std::endl;
|
|
}
|
|
|
|
if (function) {
|
|
std::cout << function << "(). ";
|
|
}
|
|
|
|
if (stack_trace && scriptInterface) {
|
|
std::cout << scriptInterface->getStackTrace(error_desc) << std::endl;
|
|
} else {
|
|
std::cout << error_desc << std::endl;
|
|
}
|
|
}
|
|
|
|
bool LuaScriptInterface::pushFunction(int32_t functionId)
|
|
{
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
|
|
if (!isTable(luaState, -1)) {
|
|
return false;
|
|
}
|
|
|
|
lua_rawgeti(luaState, -1, functionId);
|
|
lua_replace(luaState, -2);
|
|
return isFunction(luaState, -1);
|
|
}
|
|
|
|
bool LuaScriptInterface::initState()
|
|
{
|
|
luaState = g_luaEnvironment.getLuaState();
|
|
if (!luaState) {
|
|
return false;
|
|
}
|
|
|
|
lua_newtable(luaState);
|
|
eventTableRef = luaL_ref(luaState, LUA_REGISTRYINDEX);
|
|
runningEventId = EVENT_ID_USER;
|
|
return true;
|
|
}
|
|
|
|
bool LuaScriptInterface::closeState()
|
|
{
|
|
if (!g_luaEnvironment.getLuaState() || !luaState) {
|
|
return false;
|
|
}
|
|
|
|
cacheFiles.clear();
|
|
if (eventTableRef != -1) {
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, eventTableRef);
|
|
eventTableRef = -1;
|
|
}
|
|
|
|
luaState = nullptr;
|
|
return true;
|
|
}
|
|
|
|
int LuaScriptInterface::luaErrorHandler(lua_State* L)
|
|
{
|
|
const std::string& errorMessage = popString(L);
|
|
auto interface = getScriptEnv()->getScriptInterface();
|
|
assert(interface); //This fires if the ScriptEnvironment hasn't been setup
|
|
pushString(L, interface->getStackTrace(errorMessage));
|
|
return 1;
|
|
}
|
|
|
|
bool LuaScriptInterface::callFunction(int params)
|
|
{
|
|
bool result = false;
|
|
int size = lua_gettop(luaState);
|
|
if (protectedCall(luaState, params, 1) != 0) {
|
|
LuaScriptInterface::reportError(nullptr, LuaScriptInterface::getString(luaState, -1));
|
|
} else {
|
|
result = LuaScriptInterface::getBoolean(luaState, -1);
|
|
}
|
|
|
|
lua_pop(luaState, 1);
|
|
if ((lua_gettop(luaState) + params + 1) != size) {
|
|
LuaScriptInterface::reportError(nullptr, "Stack size changed!");
|
|
}
|
|
|
|
resetScriptEnv();
|
|
return result;
|
|
}
|
|
|
|
void LuaScriptInterface::callVoidFunction(int params)
|
|
{
|
|
int size = lua_gettop(luaState);
|
|
if (protectedCall(luaState, params, 0) != 0) {
|
|
LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(luaState));
|
|
}
|
|
|
|
if ((lua_gettop(luaState) + params + 1) != size) {
|
|
LuaScriptInterface::reportError(nullptr, "Stack size changed!");
|
|
}
|
|
|
|
resetScriptEnv();
|
|
}
|
|
|
|
void LuaScriptInterface::pushVariant(lua_State* L, const LuaVariant& var)
|
|
{
|
|
lua_createtable(L, 0, 2);
|
|
setField(L, "type", var.type);
|
|
switch (var.type) {
|
|
case VARIANT_NUMBER:
|
|
setField(L, "number", var.number);
|
|
break;
|
|
case VARIANT_STRING:
|
|
setField(L, "string", var.text);
|
|
break;
|
|
case VARIANT_TARGETPOSITION:
|
|
case VARIANT_POSITION: {
|
|
pushPosition(L, var.pos);
|
|
lua_setfield(L, -2, "pos");
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
setMetatable(L, -1, "Variant");
|
|
}
|
|
|
|
void LuaScriptInterface::pushThing(lua_State* L, Thing* thing)
|
|
{
|
|
if (!thing) {
|
|
lua_createtable(L, 0, 4);
|
|
setField(L, "uid", 0);
|
|
setField(L, "itemid", 0);
|
|
setField(L, "actionid", 0);
|
|
setField(L, "type", 0);
|
|
return;
|
|
}
|
|
|
|
if (Item* item = thing->getItem()) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else if (Creature* creature = thing->getCreature()) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
}
|
|
|
|
void LuaScriptInterface::pushCylinder(lua_State* L, Cylinder* cylinder)
|
|
{
|
|
if (Creature* creature = cylinder->getCreature()) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
} else if (Item* parentItem = cylinder->getItem()) {
|
|
pushUserdata<Item>(L, parentItem);
|
|
setItemMetatable(L, -1, parentItem);
|
|
} else if (Tile* tile = cylinder->getTile()) {
|
|
pushUserdata<Tile>(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
} else if (cylinder == VirtualCylinder::virtualCylinder) {
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
}
|
|
|
|
void LuaScriptInterface::pushString(lua_State* L, const std::string& value)
|
|
{
|
|
lua_pushlstring(L, value.c_str(), value.length());
|
|
}
|
|
|
|
void LuaScriptInterface::pushCallback(lua_State* L, int32_t callback)
|
|
{
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
|
|
}
|
|
|
|
std::string LuaScriptInterface::popString(lua_State* L)
|
|
{
|
|
if (lua_gettop(L) == 0) {
|
|
return std::string();
|
|
}
|
|
|
|
std::string str(getString(L, -1));
|
|
lua_pop(L, 1);
|
|
return str;
|
|
}
|
|
|
|
int32_t LuaScriptInterface::popCallback(lua_State* L)
|
|
{
|
|
return luaL_ref(L, LUA_REGISTRYINDEX);
|
|
}
|
|
|
|
// Metatables
|
|
void LuaScriptInterface::setMetatable(lua_State* L, int32_t index, const std::string& name)
|
|
{
|
|
luaL_getmetatable(L, name.c_str());
|
|
lua_setmetatable(L, index - 1);
|
|
}
|
|
|
|
void LuaScriptInterface::setWeakMetatable(lua_State* L, int32_t index, const std::string& name)
|
|
{
|
|
static std::set<std::string> weakObjectTypes;
|
|
const std::string& weakName = name + "_weak";
|
|
|
|
auto result = weakObjectTypes.emplace(name);
|
|
if (result.second) {
|
|
luaL_getmetatable(L, name.c_str());
|
|
int childMetatable = lua_gettop(L);
|
|
|
|
luaL_newmetatable(L, weakName.c_str());
|
|
int metatable = lua_gettop(L);
|
|
|
|
static const std::vector<std::string> methodKeys = {"__index", "__metatable", "__eq"};
|
|
for (const std::string& metaKey : methodKeys) {
|
|
lua_getfield(L, childMetatable, metaKey.c_str());
|
|
lua_setfield(L, metatable, metaKey.c_str());
|
|
}
|
|
|
|
static const std::vector<int> methodIndexes = {'h', 'p', 't'};
|
|
for (int metaIndex : methodIndexes) {
|
|
lua_rawgeti(L, childMetatable, metaIndex);
|
|
lua_rawseti(L, metatable, metaIndex);
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
lua_setfield(L, metatable, "__gc");
|
|
|
|
lua_remove(L, childMetatable);
|
|
} else {
|
|
luaL_getmetatable(L, weakName.c_str());
|
|
}
|
|
lua_setmetatable(L, index - 1);
|
|
}
|
|
|
|
void LuaScriptInterface::setItemMetatable(lua_State* L, int32_t index, const Item* item)
|
|
{
|
|
if (item->getContainer()) {
|
|
luaL_getmetatable(L, "Container");
|
|
} else if (item->getTeleport()) {
|
|
luaL_getmetatable(L, "Teleport");
|
|
} else {
|
|
luaL_getmetatable(L, "Item");
|
|
}
|
|
lua_setmetatable(L, index - 1);
|
|
}
|
|
|
|
void LuaScriptInterface::setCreatureMetatable(lua_State* L, int32_t index, const Creature* creature)
|
|
{
|
|
if (creature->getPlayer()) {
|
|
luaL_getmetatable(L, "Player");
|
|
} else if (creature->getMonster()) {
|
|
luaL_getmetatable(L, "Monster");
|
|
} else {
|
|
luaL_getmetatable(L, "Npc");
|
|
}
|
|
lua_setmetatable(L, index - 1);
|
|
}
|
|
|
|
// Get
|
|
CombatDamage LuaScriptInterface::getCombatDamage(lua_State* L)
|
|
{
|
|
CombatDamage damage;
|
|
damage.value = getNumber<int32_t>(L, -4);
|
|
damage.type = getNumber<CombatType_t>(L, -3);
|
|
damage.min = getNumber<int32_t>(L, -2);
|
|
damage.max = getNumber<CombatType_t>(L, -1);
|
|
|
|
lua_pop(L, 4);
|
|
return damage;
|
|
}
|
|
|
|
std::string LuaScriptInterface::getString(lua_State* L, int32_t arg)
|
|
{
|
|
size_t len;
|
|
const char* c_str = lua_tolstring(L, arg, &len);
|
|
if (!c_str || len == 0) {
|
|
return std::string();
|
|
}
|
|
return std::string(c_str, len);
|
|
}
|
|
|
|
Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg, int32_t& stackpos)
|
|
{
|
|
Position position;
|
|
position.x = getField<uint16_t>(L, arg, "x");
|
|
position.y = getField<uint16_t>(L, arg, "y");
|
|
position.z = getField<uint8_t>(L, arg, "z");
|
|
|
|
lua_getfield(L, arg, "stackpos");
|
|
if (lua_isnil(L, -1) == 1) {
|
|
stackpos = 0;
|
|
} else {
|
|
stackpos = getNumber<int32_t>(L, -1);
|
|
}
|
|
|
|
lua_pop(L, 4);
|
|
return position;
|
|
}
|
|
|
|
Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg)
|
|
{
|
|
Position position;
|
|
position.x = getField<uint16_t>(L, arg, "x");
|
|
position.y = getField<uint16_t>(L, arg, "y");
|
|
position.z = getField<uint8_t>(L, arg, "z");
|
|
|
|
lua_pop(L, 3);
|
|
return position;
|
|
}
|
|
|
|
Outfit_t LuaScriptInterface::getOutfit(lua_State* L, int32_t arg)
|
|
{
|
|
Outfit_t outfit;
|
|
outfit.lookAddons = getField<uint8_t>(L, arg, "lookAddons");
|
|
|
|
outfit.lookFeet = getField<uint8_t>(L, arg, "lookFeet");
|
|
outfit.lookLegs = getField<uint8_t>(L, arg, "lookLegs");
|
|
outfit.lookBody = getField<uint8_t>(L, arg, "lookBody");
|
|
outfit.lookHead = getField<uint8_t>(L, arg, "lookHead");
|
|
|
|
outfit.lookTypeEx = getField<uint8_t>(L, arg, "lookTypeEx");
|
|
outfit.lookType = getField<uint8_t>(L, arg, "lookType");
|
|
|
|
lua_pop(L, 6);
|
|
return outfit;
|
|
}
|
|
|
|
LuaVariant LuaScriptInterface::getVariant(lua_State* L, int32_t arg)
|
|
{
|
|
LuaVariant var;
|
|
switch (var.type = getField<LuaVariantType_t>(L, arg, "type")) {
|
|
case VARIANT_NUMBER: {
|
|
var.number = getField<uint32_t>(L, arg, "number");
|
|
lua_pop(L, 2);
|
|
break;
|
|
}
|
|
|
|
case VARIANT_STRING: {
|
|
var.text = getFieldString(L, arg, "string");
|
|
lua_pop(L, 2);
|
|
break;
|
|
}
|
|
|
|
case VARIANT_POSITION:
|
|
case VARIANT_TARGETPOSITION: {
|
|
lua_getfield(L, arg, "pos");
|
|
var.pos = getPosition(L, lua_gettop(L));
|
|
lua_pop(L, 2);
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
var.type = VARIANT_NONE;
|
|
lua_pop(L, 1);
|
|
break;
|
|
}
|
|
}
|
|
return var;
|
|
}
|
|
|
|
Thing* LuaScriptInterface::getThing(lua_State* L, int32_t arg)
|
|
{
|
|
Thing* thing;
|
|
if (lua_getmetatable(L, arg) != 0) {
|
|
lua_rawgeti(L, -1, 't');
|
|
switch(getNumber<uint32_t>(L, -1)) {
|
|
case LuaData_Item:
|
|
thing = getUserdata<Item>(L, arg);
|
|
break;
|
|
case LuaData_Container:
|
|
thing = getUserdata<Container>(L, arg);
|
|
break;
|
|
case LuaData_Teleport:
|
|
thing = getUserdata<Teleport>(L, arg);
|
|
break;
|
|
case LuaData_Player:
|
|
thing = getUserdata<Player>(L, arg);
|
|
break;
|
|
case LuaData_Monster:
|
|
thing = getUserdata<Monster>(L, arg);
|
|
break;
|
|
case LuaData_Npc:
|
|
thing = getUserdata<Npc>(L, arg);
|
|
break;
|
|
default:
|
|
thing = nullptr;
|
|
break;
|
|
}
|
|
lua_pop(L, 2);
|
|
} else {
|
|
thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, arg));
|
|
}
|
|
return thing;
|
|
}
|
|
|
|
Creature* LuaScriptInterface::getCreature(lua_State* L, int32_t arg)
|
|
{
|
|
if (isUserdata(L, arg)) {
|
|
return getUserdata<Creature>(L, arg);
|
|
}
|
|
return g_game.getCreatureByID(getNumber<uint32_t>(L, arg));
|
|
}
|
|
|
|
Player* LuaScriptInterface::getPlayer(lua_State* L, int32_t arg)
|
|
{
|
|
if (isUserdata(L, arg)) {
|
|
return getUserdata<Player>(L, arg);
|
|
}
|
|
return g_game.getPlayerByID(getNumber<uint32_t>(L, arg));
|
|
}
|
|
|
|
std::string LuaScriptInterface::getFieldString(lua_State* L, int32_t arg, const std::string& key)
|
|
{
|
|
lua_getfield(L, arg, key.c_str());
|
|
return getString(L, -1);
|
|
}
|
|
|
|
LuaDataType LuaScriptInterface::getUserdataType(lua_State* L, int32_t arg)
|
|
{
|
|
if (lua_getmetatable(L, arg) == 0) {
|
|
return LuaData_Unknown;
|
|
}
|
|
lua_rawgeti(L, -1, 't');
|
|
|
|
LuaDataType type = getNumber<LuaDataType>(L, -1);
|
|
lua_pop(L, 2);
|
|
|
|
return type;
|
|
}
|
|
|
|
// Push
|
|
void LuaScriptInterface::pushBoolean(lua_State* L, bool value)
|
|
{
|
|
lua_pushboolean(L, value ? 1 : 0);
|
|
}
|
|
|
|
void LuaScriptInterface::pushCombatDamage(lua_State* L, const CombatDamage& damage)
|
|
{
|
|
lua_pushnumber(L, damage.value);
|
|
lua_pushnumber(L, damage.type);
|
|
lua_pushnumber(L, damage.min);
|
|
lua_pushnumber(L, damage.max);
|
|
lua_pushnumber(L, damage.origin);
|
|
}
|
|
|
|
|
|
void LuaScriptInterface::pushPosition(lua_State* L, const Position& position, int32_t stackpos/* = 0*/)
|
|
{
|
|
lua_createtable(L, 0, 4);
|
|
|
|
setField(L, "x", position.x);
|
|
setField(L, "y", position.y);
|
|
setField(L, "z", position.z);
|
|
setField(L, "stackpos", stackpos);
|
|
|
|
setMetatable(L, -1, "Position");
|
|
}
|
|
|
|
void LuaScriptInterface::pushOutfit(lua_State* L, const Outfit_t& outfit)
|
|
{
|
|
lua_createtable(L, 0, 6);
|
|
setField(L, "lookType", outfit.lookType);
|
|
setField(L, "lookTypeEx", outfit.lookTypeEx);
|
|
setField(L, "lookHead", outfit.lookHead);
|
|
setField(L, "lookBody", outfit.lookBody);
|
|
setField(L, "lookLegs", outfit.lookLegs);
|
|
setField(L, "lookFeet", outfit.lookFeet);
|
|
setField(L, "lookAddons", outfit.lookAddons);
|
|
}
|
|
|
|
#define registerEnum(value) { std::string enumName = #value; registerGlobalVariable(enumName.substr(enumName.find_last_of(':') + 1), value); }
|
|
#define registerEnumIn(tableName, value) { std::string enumName = #value; registerVariable(tableName, enumName.substr(enumName.find_last_of(':') + 1), value); }
|
|
|
|
void LuaScriptInterface::registerFunctions()
|
|
{
|
|
//getPlayerFlagValue(cid, flag)
|
|
lua_register(luaState, "getPlayerFlagValue", LuaScriptInterface::luaGetPlayerFlagValue);
|
|
|
|
//getPlayerInstantSpellCount(cid)
|
|
lua_register(luaState, "getPlayerInstantSpellCount", LuaScriptInterface::luaGetPlayerInstantSpellCount);
|
|
|
|
//getPlayerInstantSpellInfo(cid, index)
|
|
lua_register(luaState, "getPlayerInstantSpellInfo", LuaScriptInterface::luaGetPlayerInstantSpellInfo);
|
|
|
|
//doPlayerAddItem(uid, itemid, <optional: default: 1> count/subtype)
|
|
//doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
|
|
//Returns uid of the created item
|
|
lua_register(luaState, "doPlayerAddItem", LuaScriptInterface::luaDoPlayerAddItem);
|
|
|
|
//doCreateItem(itemid, type/count, pos)
|
|
//Returns uid of the created item, only works on tiles.
|
|
lua_register(luaState, "doCreateItem", LuaScriptInterface::luaDoCreateItem);
|
|
|
|
//doCreateItemEx(itemid, <optional> count/subtype)
|
|
lua_register(luaState, "doCreateItemEx", LuaScriptInterface::luaDoCreateItemEx);
|
|
|
|
//doTileAddItemEx(pos, uid)
|
|
lua_register(luaState, "doTileAddItemEx", LuaScriptInterface::luaDoTileAddItemEx);
|
|
|
|
//doMoveCreature(cid, direction)
|
|
lua_register(luaState, "doMoveCreature", LuaScriptInterface::luaDoMoveCreature);
|
|
|
|
//doSetCreatureLight(cid, lightLevel, lightColor, time)
|
|
lua_register(luaState, "doSetCreatureLight", LuaScriptInterface::luaDoSetCreatureLight);
|
|
|
|
//getCreatureCondition(cid, condition[, subId])
|
|
lua_register(luaState, "getCreatureCondition", LuaScriptInterface::luaGetCreatureCondition);
|
|
|
|
//isValidUID(uid)
|
|
lua_register(luaState, "isValidUID", LuaScriptInterface::luaIsValidUID);
|
|
|
|
//isDepot(uid)
|
|
lua_register(luaState, "isDepot", LuaScriptInterface::luaIsDepot);
|
|
|
|
//isMovable(uid)
|
|
lua_register(luaState, "isMovable", LuaScriptInterface::luaIsMoveable);
|
|
|
|
//doAddContainerItem(uid, itemid, <optional> count/subtype)
|
|
lua_register(luaState, "doAddContainerItem", LuaScriptInterface::luaDoAddContainerItem);
|
|
|
|
//getDepotId(uid)
|
|
lua_register(luaState, "getDepotId", LuaScriptInterface::luaGetDepotId);
|
|
|
|
//getWorldTime()
|
|
lua_register(luaState, "getWorldTime", LuaScriptInterface::luaGetWorldTime);
|
|
|
|
//getWorldLight()
|
|
lua_register(luaState, "getWorldLight", LuaScriptInterface::luaGetWorldLight);
|
|
|
|
//getWorldUpTime()
|
|
lua_register(luaState, "getWorldUpTime", LuaScriptInterface::luaGetWorldUpTime);
|
|
|
|
//createCombatArea( {area}, <optional> {extArea} )
|
|
lua_register(luaState, "createCombatArea", LuaScriptInterface::luaCreateCombatArea);
|
|
|
|
//doAreaCombatHealth(cid, type, pos, area, min, max, effect)
|
|
lua_register(luaState, "doAreaCombatHealth", LuaScriptInterface::luaDoAreaCombatHealth);
|
|
|
|
//doTargetCombatHealth(cid, target, type, min, max, effect)
|
|
lua_register(luaState, "doTargetCombatHealth", LuaScriptInterface::luaDoTargetCombatHealth);
|
|
|
|
//doAreaCombatMana(cid, pos, area, min, max, effect)
|
|
lua_register(luaState, "doAreaCombatMana", LuaScriptInterface::luaDoAreaCombatMana);
|
|
|
|
//doTargetCombatMana(cid, target, min, max, effect)
|
|
lua_register(luaState, "doTargetCombatMana", LuaScriptInterface::luaDoTargetCombatMana);
|
|
|
|
//doAreaCombatCondition(cid, pos, area, condition, effect)
|
|
lua_register(luaState, "doAreaCombatCondition", LuaScriptInterface::luaDoAreaCombatCondition);
|
|
|
|
//doTargetCombatCondition(cid, target, condition, effect)
|
|
lua_register(luaState, "doTargetCombatCondition", LuaScriptInterface::luaDoTargetCombatCondition);
|
|
|
|
//doAreaCombatDispel(cid, pos, area, type, effect)
|
|
lua_register(luaState, "doAreaCombatDispel", LuaScriptInterface::luaDoAreaCombatDispel);
|
|
|
|
//doTargetCombatDispel(cid, target, type, effect)
|
|
lua_register(luaState, "doTargetCombatDispel", LuaScriptInterface::luaDoTargetCombatDispel);
|
|
|
|
//doChallengeCreature(cid, target)
|
|
lua_register(luaState, "doChallengeCreature", LuaScriptInterface::luaDoChallengeCreature);
|
|
|
|
//doSetMonsterOutfit(cid, name, time)
|
|
lua_register(luaState, "doSetMonsterOutfit", LuaScriptInterface::luaSetMonsterOutfit);
|
|
|
|
//doSetItemOutfit(cid, item, time)
|
|
lua_register(luaState, "doSetItemOutfit", LuaScriptInterface::luaSetItemOutfit);
|
|
|
|
//doSetCreatureOutfit(cid, outfit, time)
|
|
lua_register(luaState, "doSetCreatureOutfit", LuaScriptInterface::luaSetCreatureOutfit);
|
|
|
|
//isInArray(array, value)
|
|
lua_register(luaState, "isInArray", LuaScriptInterface::luaIsInArray);
|
|
|
|
//addEvent(callback, delay, ...)
|
|
lua_register(luaState, "addEvent", LuaScriptInterface::luaAddEvent);
|
|
|
|
//stopEvent(eventid)
|
|
lua_register(luaState, "stopEvent", LuaScriptInterface::luaStopEvent);
|
|
|
|
//saveServer()
|
|
lua_register(luaState, "saveServer", LuaScriptInterface::luaSaveServer);
|
|
|
|
//cleanMap()
|
|
lua_register(luaState, "cleanMap", LuaScriptInterface::luaCleanMap);
|
|
|
|
//debugPrint(text)
|
|
lua_register(luaState, "debugPrint", LuaScriptInterface::luaDebugPrint);
|
|
|
|
//isInWar(cid, target)
|
|
lua_register(luaState, "isInWar", LuaScriptInterface::luaIsInWar);
|
|
|
|
//getWaypointPosition(name)
|
|
lua_register(luaState, "getWaypointPositionByName", LuaScriptInterface::luaGetWaypointPositionByName);
|
|
|
|
#ifndef LUAJIT_VERSION
|
|
//bit operations for Lua, based on bitlib project release 24
|
|
//bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift
|
|
luaL_register(luaState, "bit", LuaScriptInterface::luaBitReg);
|
|
#endif
|
|
|
|
//configManager table
|
|
luaL_register(luaState, "configManager", LuaScriptInterface::luaConfigManagerTable);
|
|
|
|
//db table
|
|
luaL_register(luaState, "db", LuaScriptInterface::luaDatabaseTable);
|
|
|
|
//result table
|
|
luaL_register(luaState, "result", LuaScriptInterface::luaResultTable);
|
|
|
|
/* New functions */
|
|
//registerClass(className, baseClass, newFunction)
|
|
//registerTable(tableName)
|
|
//registerMethod(className, functionName, function)
|
|
//registerMetaMethod(className, functionName, function)
|
|
//registerGlobalMethod(functionName, function)
|
|
//registerVariable(tableName, name, value)
|
|
//registerGlobalVariable(name, value)
|
|
//registerEnum(value)
|
|
//registerEnumIn(tableName, value)
|
|
|
|
// Enums
|
|
registerEnum(ACCOUNT_TYPE_NORMAL)
|
|
registerEnum(ACCOUNT_TYPE_TUTOR)
|
|
registerEnum(ACCOUNT_TYPE_SENIORTUTOR)
|
|
registerEnum(ACCOUNT_TYPE_GAMEMASTER)
|
|
registerEnum(ACCOUNT_TYPE_GOD)
|
|
|
|
registerEnum(CALLBACK_PARAM_LEVELMAGICVALUE)
|
|
registerEnum(CALLBACK_PARAM_SKILLVALUE)
|
|
registerEnum(CALLBACK_PARAM_TARGETTILE)
|
|
registerEnum(CALLBACK_PARAM_TARGETCREATURE)
|
|
|
|
registerEnum(COMBAT_FORMULA_UNDEFINED)
|
|
registerEnum(COMBAT_FORMULA_LEVELMAGIC)
|
|
registerEnum(COMBAT_FORMULA_SKILL)
|
|
registerEnum(COMBAT_FORMULA_DAMAGE)
|
|
|
|
registerEnum(DIRECTION_NORTH)
|
|
registerEnum(DIRECTION_EAST)
|
|
registerEnum(DIRECTION_SOUTH)
|
|
registerEnum(DIRECTION_WEST)
|
|
registerEnum(DIRECTION_SOUTHWEST)
|
|
registerEnum(DIRECTION_SOUTHEAST)
|
|
registerEnum(DIRECTION_NORTHWEST)
|
|
registerEnum(DIRECTION_NORTHEAST)
|
|
|
|
registerEnum(COMBAT_NONE)
|
|
registerEnum(COMBAT_PHYSICALDAMAGE)
|
|
registerEnum(COMBAT_ENERGYDAMAGE)
|
|
registerEnum(COMBAT_EARTHDAMAGE)
|
|
registerEnum(COMBAT_FIREDAMAGE)
|
|
registerEnum(COMBAT_DROWNDAMAGE)
|
|
registerEnum(COMBAT_UNDEFINEDDAMAGE)
|
|
registerEnum(COMBAT_LIFEDRAIN)
|
|
registerEnum(COMBAT_MANADRAIN)
|
|
registerEnum(COMBAT_HEALING)
|
|
|
|
registerEnum(COMBAT_PARAM_TYPE)
|
|
registerEnum(COMBAT_PARAM_EFFECT)
|
|
registerEnum(COMBAT_PARAM_DISTANCEEFFECT)
|
|
registerEnum(COMBAT_PARAM_BLOCKSHIELD)
|
|
registerEnum(COMBAT_PARAM_BLOCKARMOR)
|
|
registerEnum(COMBAT_PARAM_TARGETCASTERORTOPMOST)
|
|
registerEnum(COMBAT_PARAM_CREATEITEM)
|
|
registerEnum(COMBAT_PARAM_AGGRESSIVE)
|
|
registerEnum(COMBAT_PARAM_DISPEL)
|
|
registerEnum(COMBAT_PARAM_USECHARGES)
|
|
registerEnum(COMBAT_PARAM_DECREASEDAMAGE)
|
|
registerEnum(COMBAT_PARAM_MAXIMUMDECREASEDDAMAGE)
|
|
|
|
registerEnum(CONDITION_NONE)
|
|
registerEnum(CONDITION_POISON)
|
|
registerEnum(CONDITION_FIRE)
|
|
registerEnum(CONDITION_ENERGY)
|
|
registerEnum(CONDITION_DROWN)
|
|
registerEnum(CONDITION_HASTE)
|
|
registerEnum(CONDITION_PARALYZE)
|
|
registerEnum(CONDITION_OUTFIT)
|
|
registerEnum(CONDITION_INVISIBLE)
|
|
registerEnum(CONDITION_LIGHT)
|
|
registerEnum(CONDITION_MANASHIELD)
|
|
registerEnum(CONDITION_INFIGHT)
|
|
registerEnum(CONDITION_DRUNK)
|
|
registerEnum(CONDITION_REGENERATION)
|
|
registerEnum(CONDITION_SOUL)
|
|
registerEnum(CONDITION_MUTED)
|
|
registerEnum(CONDITION_CHANNELMUTEDTICKS)
|
|
registerEnum(CONDITION_YELLTICKS)
|
|
registerEnum(CONDITION_ATTRIBUTES)
|
|
registerEnum(CONDITION_EXHAUST)
|
|
registerEnum(CONDITION_PACIFIED)
|
|
|
|
registerEnum(CONDITIONID_DEFAULT)
|
|
registerEnum(CONDITIONID_COMBAT)
|
|
registerEnum(CONDITIONID_HEAD)
|
|
registerEnum(CONDITIONID_NECKLACE)
|
|
registerEnum(CONDITIONID_BACKPACK)
|
|
registerEnum(CONDITIONID_ARMOR)
|
|
registerEnum(CONDITIONID_RIGHT)
|
|
registerEnum(CONDITIONID_LEFT)
|
|
registerEnum(CONDITIONID_LEGS)
|
|
registerEnum(CONDITIONID_FEET)
|
|
registerEnum(CONDITIONID_RING)
|
|
registerEnum(CONDITIONID_AMMO)
|
|
|
|
registerEnum(CONDITION_PARAM_OWNER)
|
|
registerEnum(CONDITION_PARAM_TICKS)
|
|
registerEnum(CONDITION_PARAM_HEALTHGAIN)
|
|
registerEnum(CONDITION_PARAM_HEALTHTICKS)
|
|
registerEnum(CONDITION_PARAM_MANAGAIN)
|
|
registerEnum(CONDITION_PARAM_MANATICKS)
|
|
registerEnum(CONDITION_PARAM_DELAYED)
|
|
registerEnum(CONDITION_PARAM_SPEED)
|
|
registerEnum(CONDITION_PARAM_LIGHT_LEVEL)
|
|
registerEnum(CONDITION_PARAM_LIGHT_COLOR)
|
|
registerEnum(CONDITION_PARAM_SOULGAIN)
|
|
registerEnum(CONDITION_PARAM_SOULTICKS)
|
|
registerEnum(CONDITION_PARAM_MINVALUE)
|
|
registerEnum(CONDITION_PARAM_MAXVALUE)
|
|
registerEnum(CONDITION_PARAM_STARTVALUE)
|
|
registerEnum(CONDITION_PARAM_TICKINTERVAL)
|
|
registerEnum(CONDITION_PARAM_SKILL_MELEE)
|
|
registerEnum(CONDITION_PARAM_SKILL_FIST)
|
|
registerEnum(CONDITION_PARAM_SKILL_CLUB)
|
|
registerEnum(CONDITION_PARAM_SKILL_SWORD)
|
|
registerEnum(CONDITION_PARAM_SKILL_AXE)
|
|
registerEnum(CONDITION_PARAM_SKILL_DISTANCE)
|
|
registerEnum(CONDITION_PARAM_SKILL_SHIELD)
|
|
registerEnum(CONDITION_PARAM_SKILL_FISHING)
|
|
registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTS)
|
|
registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTS)
|
|
registerEnum(CONDITION_PARAM_STAT_MAGICPOINTS)
|
|
registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT)
|
|
registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT)
|
|
registerEnum(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT)
|
|
registerEnum(CONDITION_PARAM_PERIODICDAMAGE)
|
|
registerEnum(CONDITION_PARAM_HIT_DAMAGE)
|
|
registerEnum(CONDITION_PARAM_SKILL_MELEEPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_FISTPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_CLUBPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_SWORDPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_AXEPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_DISTANCEPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_SHIELDPERCENT)
|
|
registerEnum(CONDITION_PARAM_SKILL_FISHINGPERCENT)
|
|
registerEnum(CONDITION_PARAM_SUBID)
|
|
registerEnum(CONDITION_PARAM_FIELD)
|
|
|
|
registerEnum(CONST_ME_NONE)
|
|
registerEnum(CONST_ME_DRAWBLOOD)
|
|
registerEnum(CONST_ME_LOSEENERGY)
|
|
registerEnum(CONST_ME_POFF)
|
|
registerEnum(CONST_ME_BLOCKHIT)
|
|
registerEnum(CONST_ME_EXPLOSIONAREA)
|
|
registerEnum(CONST_ME_EXPLOSIONHIT)
|
|
registerEnum(CONST_ME_FIREAREA)
|
|
registerEnum(CONST_ME_YELLOW_RINGS)
|
|
registerEnum(CONST_ME_GREEN_RINGS)
|
|
registerEnum(CONST_ME_HITAREA)
|
|
registerEnum(CONST_ME_TELEPORT)
|
|
registerEnum(CONST_ME_ENERGYHIT)
|
|
registerEnum(CONST_ME_MAGIC_BLUE)
|
|
registerEnum(CONST_ME_MAGIC_RED)
|
|
registerEnum(CONST_ME_MAGIC_GREEN)
|
|
registerEnum(CONST_ME_HITBYFIRE)
|
|
registerEnum(CONST_ME_HITBYPOISON)
|
|
registerEnum(CONST_ME_MORTAREA)
|
|
registerEnum(CONST_ME_SOUND_GREEN)
|
|
registerEnum(CONST_ME_SOUND_RED)
|
|
registerEnum(CONST_ME_POISONAREA)
|
|
registerEnum(CONST_ME_SOUND_YELLOW)
|
|
registerEnum(CONST_ME_SOUND_PURPLE)
|
|
registerEnum(CONST_ME_SOUND_BLUE)
|
|
registerEnum(CONST_ME_SOUND_WHITE)
|
|
registerEnum(CONST_ME_BUBBLES)
|
|
registerEnum(CONST_ME_CRAPS)
|
|
registerEnum(CONST_ME_GIFT_WRAPS)
|
|
registerEnum(CONST_ME_FIREWORK_YELLOW)
|
|
registerEnum(CONST_ME_FIREWORK_RED)
|
|
registerEnum(CONST_ME_FIREWORK_BLUE)
|
|
registerEnum(CONST_ANI_NONE)
|
|
registerEnum(CONST_ANI_SPEAR)
|
|
registerEnum(CONST_ANI_BOLT)
|
|
registerEnum(CONST_ANI_ARROW)
|
|
registerEnum(CONST_ANI_FIRE)
|
|
registerEnum(CONST_ANI_ENERGY)
|
|
registerEnum(CONST_ANI_POISONARROW)
|
|
registerEnum(CONST_ANI_BURSTARROW)
|
|
registerEnum(CONST_ANI_THROWINGSTAR)
|
|
registerEnum(CONST_ANI_THROWINGKNIFE)
|
|
registerEnum(CONST_ANI_SMALLSTONE)
|
|
registerEnum(CONST_ANI_DEATH)
|
|
registerEnum(CONST_ANI_LARGEROCK)
|
|
registerEnum(CONST_ANI_SNOWBALL)
|
|
registerEnum(CONST_ANI_POWERBOLT)
|
|
registerEnum(CONST_ANI_POISON)
|
|
registerEnum(CONST_ANI_INFERNALBOLT)
|
|
|
|
registerEnum(CONST_PROP_BLOCKSOLID)
|
|
registerEnum(CONST_PROP_HASHEIGHT)
|
|
registerEnum(CONST_PROP_BLOCKPROJECTILE)
|
|
registerEnum(CONST_PROP_BLOCKPATH)
|
|
registerEnum(CONST_PROP_ISVERTICAL)
|
|
registerEnum(CONST_PROP_ISHORIZONTAL)
|
|
registerEnum(CONST_PROP_MOVEABLE)
|
|
registerEnum(CONST_PROP_IMMOVABLEBLOCKSOLID)
|
|
registerEnum(CONST_PROP_IMMOVABLEBLOCKPATH)
|
|
registerEnum(CONST_PROP_IMMOVABLENOFIELDBLOCKPATH)
|
|
registerEnum(CONST_PROP_NOFIELDBLOCKPATH)
|
|
registerEnum(CONST_PROP_SUPPORTHANGABLE)
|
|
|
|
registerEnum(CONST_SLOT_HEAD)
|
|
registerEnum(CONST_SLOT_NECKLACE)
|
|
registerEnum(CONST_SLOT_BACKPACK)
|
|
registerEnum(CONST_SLOT_ARMOR)
|
|
registerEnum(CONST_SLOT_RIGHT)
|
|
registerEnum(CONST_SLOT_LEFT)
|
|
registerEnum(CONST_SLOT_LEGS)
|
|
registerEnum(CONST_SLOT_FEET)
|
|
registerEnum(CONST_SLOT_RING)
|
|
registerEnum(CONST_SLOT_AMMO)
|
|
|
|
registerEnum(CREATURE_EVENT_NONE)
|
|
registerEnum(CREATURE_EVENT_LOGIN)
|
|
registerEnum(CREATURE_EVENT_LOGOUT)
|
|
registerEnum(CREATURE_EVENT_THINK)
|
|
registerEnum(CREATURE_EVENT_PREPAREDEATH)
|
|
registerEnum(CREATURE_EVENT_DEATH)
|
|
registerEnum(CREATURE_EVENT_KILL)
|
|
registerEnum(CREATURE_EVENT_ADVANCE)
|
|
registerEnum(CREATURE_EVENT_EXTENDED_OPCODE)
|
|
|
|
registerEnum(GAME_STATE_STARTUP)
|
|
registerEnum(GAME_STATE_INIT)
|
|
registerEnum(GAME_STATE_NORMAL)
|
|
registerEnum(GAME_STATE_CLOSED)
|
|
registerEnum(GAME_STATE_SHUTDOWN)
|
|
registerEnum(GAME_STATE_CLOSING)
|
|
registerEnum(GAME_STATE_MAINTAIN)
|
|
|
|
registerEnum(MESSAGE_STATUS_CONSOLE_BLUE)
|
|
registerEnum(MESSAGE_STATUS_CONSOLE_RED)
|
|
registerEnum(MESSAGE_STATUS_DEFAULT)
|
|
registerEnum(MESSAGE_STATUS_WARNING)
|
|
registerEnum(MESSAGE_EVENT_ADVANCE)
|
|
registerEnum(MESSAGE_STATUS_SMALL)
|
|
registerEnum(MESSAGE_INFO_DESCR)
|
|
registerEnum(MESSAGE_EVENT_DEFAULT)
|
|
registerEnum(MESSAGE_STATUS_CONSOLE_ORANGE)
|
|
|
|
registerEnum(CLIENTOS_LINUX)
|
|
registerEnum(CLIENTOS_WINDOWS)
|
|
registerEnum(CLIENTOS_FLASH)
|
|
registerEnum(CLIENTOS_OTCLIENT_LINUX)
|
|
registerEnum(CLIENTOS_OTCLIENT_WINDOWS)
|
|
registerEnum(CLIENTOS_OTCLIENT_MAC)
|
|
|
|
registerEnum(ITEM_ATTRIBUTE_NONE)
|
|
registerEnum(ITEM_ATTRIBUTE_ACTIONID)
|
|
registerEnum(ITEM_ATTRIBUTE_MOVEMENTID)
|
|
registerEnum(ITEM_ATTRIBUTE_DESCRIPTION)
|
|
registerEnum(ITEM_ATTRIBUTE_TEXT)
|
|
registerEnum(ITEM_ATTRIBUTE_DATE)
|
|
registerEnum(ITEM_ATTRIBUTE_WRITER)
|
|
registerEnum(ITEM_ATTRIBUTE_NAME)
|
|
registerEnum(ITEM_ATTRIBUTE_ARTICLE)
|
|
registerEnum(ITEM_ATTRIBUTE_PLURALNAME)
|
|
registerEnum(ITEM_ATTRIBUTE_WEIGHT)
|
|
registerEnum(ITEM_ATTRIBUTE_ATTACK)
|
|
registerEnum(ITEM_ATTRIBUTE_DEFENSE)
|
|
registerEnum(ITEM_ATTRIBUTE_ARMOR)
|
|
registerEnum(ITEM_ATTRIBUTE_SHOOTRANGE)
|
|
registerEnum(ITEM_ATTRIBUTE_OWNER)
|
|
registerEnum(ITEM_ATTRIBUTE_DURATION)
|
|
registerEnum(ITEM_ATTRIBUTE_DECAYSTATE)
|
|
registerEnum(ITEM_ATTRIBUTE_CORPSEOWNER)
|
|
registerEnum(ITEM_ATTRIBUTE_CHARGES)
|
|
registerEnum(ITEM_ATTRIBUTE_FLUIDTYPE)
|
|
registerEnum(ITEM_ATTRIBUTE_DOORID)
|
|
registerEnum(ITEM_ATTRIBUTE_KEYNUMBER)
|
|
registerEnum(ITEM_ATTRIBUTE_KEYHOLENUMBER)
|
|
registerEnum(ITEM_ATTRIBUTE_DOORQUESTNUMBER)
|
|
registerEnum(ITEM_ATTRIBUTE_DOORQUESTVALUE)
|
|
registerEnum(ITEM_ATTRIBUTE_DOORLEVEL)
|
|
registerEnum(ITEM_ATTRIBUTE_CHESTQUESTNUMBER)
|
|
|
|
registerEnum(ITEM_TYPE_DEPOT)
|
|
registerEnum(ITEM_TYPE_MAILBOX)
|
|
registerEnum(ITEM_TYPE_CONTAINER)
|
|
registerEnum(ITEM_TYPE_DOOR)
|
|
registerEnum(ITEM_TYPE_MAGICFIELD)
|
|
registerEnum(ITEM_TYPE_TELEPORT)
|
|
registerEnum(ITEM_TYPE_BED)
|
|
registerEnum(ITEM_TYPE_KEY)
|
|
registerEnum(ITEM_TYPE_RUNE)
|
|
registerEnum(ITEM_TYPE_CHEST)
|
|
|
|
registerEnum(ITEM_GOLD_COIN)
|
|
registerEnum(ITEM_PLATINUM_COIN)
|
|
registerEnum(ITEM_CRYSTAL_COIN)
|
|
registerEnum(ITEM_AMULETOFLOSS)
|
|
registerEnum(ITEM_PARCEL)
|
|
registerEnum(ITEM_LABEL)
|
|
registerEnum(ITEM_FIREFIELD_PVP_FULL)
|
|
registerEnum(ITEM_FIREFIELD_PVP_MEDIUM)
|
|
registerEnum(ITEM_FIREFIELD_PVP_SMALL)
|
|
registerEnum(ITEM_FIREFIELD_PERSISTENT_FULL)
|
|
registerEnum(ITEM_FIREFIELD_PERSISTENT_MEDIUM)
|
|
registerEnum(ITEM_FIREFIELD_PERSISTENT_SMALL)
|
|
registerEnum(ITEM_FIREFIELD_NOPVP)
|
|
registerEnum(ITEM_POISONFIELD_PVP)
|
|
registerEnum(ITEM_POISONFIELD_PERSISTENT)
|
|
registerEnum(ITEM_POISONFIELD_NOPVP)
|
|
registerEnum(ITEM_ENERGYFIELD_PVP)
|
|
registerEnum(ITEM_ENERGYFIELD_PERSISTENT)
|
|
registerEnum(ITEM_ENERGYFIELD_NOPVP)
|
|
registerEnum(ITEM_MAGICWALL)
|
|
registerEnum(ITEM_MAGICWALL_PERSISTENT)
|
|
registerEnum(ITEM_WILDGROWTH)
|
|
registerEnum(ITEM_WILDGROWTH_PERSISTENT)
|
|
|
|
registerEnum(PlayerFlag_CannotUseCombat)
|
|
registerEnum(PlayerFlag_CannotAttackPlayer)
|
|
registerEnum(PlayerFlag_CannotAttackMonster)
|
|
registerEnum(PlayerFlag_CannotBeAttacked)
|
|
registerEnum(PlayerFlag_CanConvinceAll)
|
|
registerEnum(PlayerFlag_CanSummonAll)
|
|
registerEnum(PlayerFlag_CanIllusionAll)
|
|
registerEnum(PlayerFlag_CanSenseInvisibility)
|
|
registerEnum(PlayerFlag_IgnoredByMonsters)
|
|
registerEnum(PlayerFlag_NotGainInFight)
|
|
registerEnum(PlayerFlag_HasInfiniteMana)
|
|
registerEnum(PlayerFlag_HasInfiniteSoul)
|
|
registerEnum(PlayerFlag_HasNoExhaustion)
|
|
registerEnum(PlayerFlag_CannotUseSpells)
|
|
registerEnum(PlayerFlag_CannotPickupItem)
|
|
registerEnum(PlayerFlag_CanAlwaysLogin)
|
|
registerEnum(PlayerFlag_CanBroadcast)
|
|
registerEnum(PlayerFlag_CanEditHouses)
|
|
registerEnum(PlayerFlag_CannotBeBanned)
|
|
registerEnum(PlayerFlag_CannotBePushed)
|
|
registerEnum(PlayerFlag_HasInfiniteCapacity)
|
|
registerEnum(PlayerFlag_CanPushAllCreatures)
|
|
registerEnum(PlayerFlag_CanTalkRedPrivate)
|
|
registerEnum(PlayerFlag_CanTalkRedChannel)
|
|
registerEnum(PlayerFlag_TalkOrangeHelpChannel)
|
|
registerEnum(PlayerFlag_NotGainExperience)
|
|
registerEnum(PlayerFlag_NotGainMana)
|
|
registerEnum(PlayerFlag_NotGainHealth)
|
|
registerEnum(PlayerFlag_NotGainSkill)
|
|
registerEnum(PlayerFlag_SetMaxSpeed)
|
|
registerEnum(PlayerFlag_SpecialVIP)
|
|
registerEnum(PlayerFlag_NotGenerateLoot)
|
|
registerEnum(PlayerFlag_CanTalkRedChannelAnonymous)
|
|
registerEnum(PlayerFlag_IgnoreProtectionZone)
|
|
registerEnum(PlayerFlag_IgnoreSpellCheck)
|
|
registerEnum(PlayerFlag_IgnoreWeaponCheck)
|
|
registerEnum(PlayerFlag_CannotBeMuted)
|
|
registerEnum(PlayerFlag_IsAlwaysPremium)
|
|
registerEnum(PlayerFlag_SpecialMoveUse)
|
|
|
|
registerEnum(PLAYERSEX_FEMALE)
|
|
registerEnum(PLAYERSEX_MALE)
|
|
|
|
registerEnum(VOCATION_NONE)
|
|
|
|
registerEnum(FIGHTMODE_ATTACK)
|
|
registerEnum(FIGHTMODE_BALANCED)
|
|
registerEnum(FIGHTMODE_DEFENSE)
|
|
|
|
registerEnum(SKILL_FIST)
|
|
registerEnum(SKILL_CLUB)
|
|
registerEnum(SKILL_SWORD)
|
|
registerEnum(SKILL_AXE)
|
|
registerEnum(SKILL_DISTANCE)
|
|
registerEnum(SKILL_SHIELD)
|
|
registerEnum(SKILL_FISHING)
|
|
registerEnum(SKILL_MAGLEVEL)
|
|
registerEnum(SKILL_LEVEL)
|
|
|
|
registerEnum(SKULL_NONE)
|
|
registerEnum(SKULL_YELLOW)
|
|
registerEnum(SKULL_GREEN)
|
|
registerEnum(SKULL_WHITE)
|
|
registerEnum(SKULL_RED)
|
|
|
|
registerEnum(FLUID_NONE)
|
|
registerEnum(FLUID_WATER)
|
|
registerEnum(FLUID_WINE)
|
|
registerEnum(FLUID_BEER)
|
|
registerEnum(FLUID_MUD)
|
|
registerEnum(FLUID_BLOOD)
|
|
registerEnum(FLUID_SLIME)
|
|
registerEnum(FLUID_OIL)
|
|
registerEnum(FLUID_URINE)
|
|
registerEnum(FLUID_MILK)
|
|
registerEnum(FLUID_MANAFLUID)
|
|
registerEnum(FLUID_LIFEFLUID)
|
|
registerEnum(FLUID_LEMONADE)
|
|
registerEnum(FLUID_RUM)
|
|
registerEnum(FLUID_COCONUTMILK)
|
|
registerEnum(FLUID_FRUITJUICE)
|
|
|
|
registerEnum(TALKTYPE_SAY)
|
|
registerEnum(TALKTYPE_WHISPER)
|
|
registerEnum(TALKTYPE_YELL)
|
|
registerEnum(TALKTYPE_CHANNEL_Y)
|
|
registerEnum(TALKTYPE_CHANNEL_O)
|
|
registerEnum(TALKTYPE_BROADCAST)
|
|
registerEnum(TALKTYPE_CHANNEL_R1)
|
|
registerEnum(TALKTYPE_MONSTER_SAY)
|
|
registerEnum(TALKTYPE_MONSTER_YELL)
|
|
registerEnum(TALKTYPE_CHANNEL_R2)
|
|
|
|
registerEnum(TEXTCOLOR_BLUE)
|
|
registerEnum(TEXTCOLOR_LIGHTGREEN)
|
|
registerEnum(TEXTCOLOR_LIGHTBLUE)
|
|
registerEnum(TEXTCOLOR_MAYABLUE)
|
|
registerEnum(TEXTCOLOR_DARKRED)
|
|
registerEnum(TEXTCOLOR_LIGHTGREY)
|
|
registerEnum(TEXTCOLOR_SKYBLUE)
|
|
registerEnum(TEXTCOLOR_PURPLE)
|
|
registerEnum(TEXTCOLOR_RED)
|
|
registerEnum(TEXTCOLOR_ORANGE)
|
|
registerEnum(TEXTCOLOR_YELLOW)
|
|
registerEnum(TEXTCOLOR_WHITE_EXP)
|
|
registerEnum(TEXTCOLOR_NONE)
|
|
|
|
registerEnum(TILESTATE_NONE)
|
|
registerEnum(TILESTATE_PROTECTIONZONE)
|
|
registerEnum(TILESTATE_NOPVPZONE)
|
|
registerEnum(TILESTATE_NOLOGOUT)
|
|
registerEnum(TILESTATE_PVPZONE)
|
|
registerEnum(TILESTATE_REFRESH)
|
|
registerEnum(TILESTATE_TELEPORT)
|
|
registerEnum(TILESTATE_MAGICFIELD)
|
|
registerEnum(TILESTATE_MAILBOX)
|
|
registerEnum(TILESTATE_BED)
|
|
registerEnum(TILESTATE_DEPOT)
|
|
registerEnum(TILESTATE_BLOCKSOLID)
|
|
registerEnum(TILESTATE_BLOCKPATH)
|
|
registerEnum(TILESTATE_IMMOVABLEBLOCKSOLID)
|
|
registerEnum(TILESTATE_IMMOVABLEBLOCKPATH)
|
|
registerEnum(TILESTATE_IMMOVABLENOFIELDBLOCKPATH)
|
|
registerEnum(TILESTATE_NOFIELDBLOCKPATH)
|
|
registerEnum(TILESTATE_SUPPORTS_HANGABLE)
|
|
|
|
registerEnum(WEAPON_NONE)
|
|
registerEnum(WEAPON_SWORD)
|
|
registerEnum(WEAPON_CLUB)
|
|
registerEnum(WEAPON_AXE)
|
|
registerEnum(WEAPON_SHIELD)
|
|
registerEnum(WEAPON_DISTANCE)
|
|
registerEnum(WEAPON_WAND)
|
|
registerEnum(WEAPON_AMMO)
|
|
|
|
registerEnum(WORLD_TYPE_NO_PVP)
|
|
registerEnum(WORLD_TYPE_PVP)
|
|
registerEnum(WORLD_TYPE_PVP_ENFORCED)
|
|
|
|
// Use with container:addItem, container:addItemEx and possibly other functions.
|
|
registerEnum(FLAG_NOLIMIT)
|
|
registerEnum(FLAG_IGNOREBLOCKITEM)
|
|
registerEnum(FLAG_IGNOREBLOCKCREATURE)
|
|
registerEnum(FLAG_CHILDISOWNER)
|
|
registerEnum(FLAG_PATHFINDING)
|
|
registerEnum(FLAG_IGNOREFIELDDAMAGE)
|
|
registerEnum(FLAG_IGNORENOTMOVEABLE)
|
|
registerEnum(FLAG_IGNOREAUTOSTACK)
|
|
|
|
// Use with itemType:getSlotPosition
|
|
registerEnum(SLOTP_WHEREEVER)
|
|
registerEnum(SLOTP_HEAD)
|
|
registerEnum(SLOTP_NECKLACE)
|
|
registerEnum(SLOTP_BACKPACK)
|
|
registerEnum(SLOTP_ARMOR)
|
|
registerEnum(SLOTP_RIGHT)
|
|
registerEnum(SLOTP_LEFT)
|
|
registerEnum(SLOTP_LEGS)
|
|
registerEnum(SLOTP_FEET)
|
|
registerEnum(SLOTP_RING)
|
|
registerEnum(SLOTP_AMMO)
|
|
registerEnum(SLOTP_DEPOT)
|
|
registerEnum(SLOTP_TWO_HAND)
|
|
|
|
// Use with combat functions
|
|
registerEnum(ORIGIN_NONE)
|
|
registerEnum(ORIGIN_CONDITION)
|
|
registerEnum(ORIGIN_SPELL)
|
|
registerEnum(ORIGIN_MELEE)
|
|
registerEnum(ORIGIN_RANGED)
|
|
|
|
// Use with house:getAccessList, house:setAccessList
|
|
registerEnum(GUEST_LIST)
|
|
registerEnum(SUBOWNER_LIST)
|
|
|
|
// Use with Game.getReturnMessage
|
|
registerEnum(RETURNVALUE_NOERROR)
|
|
registerEnum(RETURNVALUE_NOTPOSSIBLE)
|
|
registerEnum(RETURNVALUE_NOTENOUGHROOM)
|
|
registerEnum(RETURNVALUE_PLAYERISPZLOCKED)
|
|
registerEnum(RETURNVALUE_PLAYERISNOTINVITED)
|
|
registerEnum(RETURNVALUE_CANNOTTHROW)
|
|
registerEnum(RETURNVALUE_THEREISNOWAY)
|
|
registerEnum(RETURNVALUE_DESTINATIONOUTOFREACH)
|
|
registerEnum(RETURNVALUE_CREATUREBLOCK)
|
|
registerEnum(RETURNVALUE_NOTMOVEABLE)
|
|
registerEnum(RETURNVALUE_DROPTWOHANDEDITEM)
|
|
registerEnum(RETURNVALUE_BOTHHANDSNEEDTOBEFREE)
|
|
registerEnum(RETURNVALUE_CANONLYUSEONEWEAPON)
|
|
registerEnum(RETURNVALUE_NEEDEXCHANGE)
|
|
registerEnum(RETURNVALUE_CANNOTBEDRESSED)
|
|
registerEnum(RETURNVALUE_PUTTHISOBJECTINYOURHAND)
|
|
registerEnum(RETURNVALUE_PUTTHISOBJECTINBOTHHANDS)
|
|
registerEnum(RETURNVALUE_TOOFARAWAY)
|
|
registerEnum(RETURNVALUE_FIRSTGODOWNSTAIRS)
|
|
registerEnum(RETURNVALUE_FIRSTGOUPSTAIRS)
|
|
registerEnum(RETURNVALUE_CONTAINERNOTENOUGHROOM)
|
|
registerEnum(RETURNVALUE_NOTENOUGHCAPACITY)
|
|
registerEnum(RETURNVALUE_CANNOTPICKUP)
|
|
registerEnum(RETURNVALUE_THISISIMPOSSIBLE)
|
|
registerEnum(RETURNVALUE_DEPOTISFULL)
|
|
registerEnum(RETURNVALUE_CREATUREDOESNOTEXIST)
|
|
registerEnum(RETURNVALUE_CANNOTUSETHISOBJECT)
|
|
registerEnum(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
|
|
registerEnum(RETURNVALUE_NOTREQUIREDLEVELTOUSERUNE)
|
|
registerEnum(RETURNVALUE_YOUAREALREADYTRADING)
|
|
registerEnum(RETURNVALUE_THISPLAYERISALREADYTRADING)
|
|
registerEnum(RETURNVALUE_YOUMAYNOTLOGOUTDURINGAFIGHT)
|
|
registerEnum(RETURNVALUE_DIRECTPLAYERSHOOT)
|
|
registerEnum(RETURNVALUE_NOTENOUGHLEVEL)
|
|
registerEnum(RETURNVALUE_NOTENOUGHMAGICLEVEL)
|
|
registerEnum(RETURNVALUE_NOTENOUGHMANA)
|
|
registerEnum(RETURNVALUE_NOTENOUGHSOUL)
|
|
registerEnum(RETURNVALUE_YOUAREEXHAUSTED)
|
|
registerEnum(RETURNVALUE_PLAYERISNOTREACHABLE)
|
|
registerEnum(RETURNVALUE_CANONLYUSETHISRUNEONCREATURES)
|
|
registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE)
|
|
registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER)
|
|
registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE)
|
|
registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONWHILEINPROTECTIONZONE)
|
|
registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE)
|
|
registerEnum(RETURNVALUE_YOUCANONLYUSEITONCREATURES)
|
|
registerEnum(RETURNVALUE_CREATUREISNOTREACHABLE)
|
|
registerEnum(RETURNVALUE_TURNSECUREMODETOATTACKUNMARKEDPLAYERS)
|
|
registerEnum(RETURNVALUE_YOUNEEDPREMIUMACCOUNT)
|
|
registerEnum(RETURNVALUE_YOUNEEDTOLEARNTHISSPELL)
|
|
registerEnum(RETURNVALUE_YOURVOCATIONCANNOTUSETHISSPELL)
|
|
registerEnum(RETURNVALUE_YOUNEEDAWEAPONTOUSETHISSPELL)
|
|
registerEnum(RETURNVALUE_PLAYERISPZLOCKEDLEAVEPVPZONE)
|
|
registerEnum(RETURNVALUE_PLAYERISPZLOCKEDENTERPVPZONE)
|
|
registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE)
|
|
registerEnum(RETURNVALUE_YOUCANNOTLOGOUTHERE)
|
|
registerEnum(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
|
|
registerEnum(RETURNVALUE_CANNOTCONJUREITEMHERE)
|
|
registerEnum(RETURNVALUE_YOUNEEDTOSPLITYOURSPEARS)
|
|
registerEnum(RETURNVALUE_NAMEISTOOAMBIGIOUS)
|
|
registerEnum(RETURNVALUE_CANONLYUSEONESHIELD)
|
|
registerEnum(RETURNVALUE_NOPARTYMEMBERSINRANGE)
|
|
registerEnum(RETURNVALUE_YOUARENOTTHEOWNER)
|
|
registerEnum(RETURNVALUE_TRADEPLAYERFARAWAY)
|
|
registerEnum(RETURNVALUE_YOUDONTOWNTHISHOUSE)
|
|
registerEnum(RETURNVALUE_TRADEPLAYERALREADYOWNSAHOUSE)
|
|
registerEnum(RETURNVALUE_TRADEPLAYERHIGHESTBIDDER)
|
|
registerEnum(RETURNVALUE_YOUCANNOTTRADETHISHOUSE)
|
|
|
|
registerEnum(RELOAD_TYPE_ALL)
|
|
registerEnum(RELOAD_TYPE_ACTIONS)
|
|
registerEnum(RELOAD_TYPE_CHAT)
|
|
registerEnum(RELOAD_TYPE_COMMANDS)
|
|
registerEnum(RELOAD_TYPE_CONFIG)
|
|
registerEnum(RELOAD_TYPE_CREATURESCRIPTS)
|
|
registerEnum(RELOAD_TYPE_EVENTS)
|
|
registerEnum(RELOAD_TYPE_GLOBAL)
|
|
registerEnum(RELOAD_TYPE_GLOBALEVENTS)
|
|
registerEnum(RELOAD_TYPE_ITEMS)
|
|
registerEnum(RELOAD_TYPE_MONSTERS)
|
|
registerEnum(RELOAD_TYPE_MOUNTS)
|
|
registerEnum(RELOAD_TYPE_MOVEMENTS)
|
|
registerEnum(RELOAD_TYPE_NPCS)
|
|
registerEnum(RELOAD_TYPE_QUESTS)
|
|
registerEnum(RELOAD_TYPE_RAIDS)
|
|
registerEnum(RELOAD_TYPE_SPELLS)
|
|
registerEnum(RELOAD_TYPE_TALKACTIONS)
|
|
registerEnum(RELOAD_TYPE_WEAPONS)
|
|
|
|
// _G
|
|
registerGlobalVariable("INDEX_WHEREEVER", INDEX_WHEREEVER);
|
|
registerGlobalBoolean("VIRTUAL_PARENT", true);
|
|
|
|
registerGlobalMethod("isType", LuaScriptInterface::luaIsType);
|
|
registerGlobalMethod("rawgetmetatable", LuaScriptInterface::luaRawGetMetatable);
|
|
|
|
// configKeys
|
|
registerTable("configKeys");
|
|
|
|
registerEnumIn("configKeys", ConfigManager::ALLOW_CHANGEOUTFIT)
|
|
registerEnumIn("configKeys", ConfigManager::ONE_PLAYER_ON_ACCOUNT)
|
|
registerEnumIn("configKeys", ConfigManager::REMOVE_RUNE_CHARGES)
|
|
registerEnumIn("configKeys", ConfigManager::EXPERIENCE_FROM_PLAYERS)
|
|
registerEnumIn("configKeys", ConfigManager::FREE_PREMIUM)
|
|
registerEnumIn("configKeys", ConfigManager::REPLACE_KICK_ON_LOGIN)
|
|
registerEnumIn("configKeys", ConfigManager::ALLOW_CLONES)
|
|
registerEnumIn("configKeys", ConfigManager::BIND_ONLY_GLOBAL_ADDRESS)
|
|
registerEnumIn("configKeys", ConfigManager::OPTIMIZE_DATABASE)
|
|
registerEnumIn("configKeys", ConfigManager::STAMINA_SYSTEM)
|
|
registerEnumIn("configKeys", ConfigManager::WARN_UNSAFE_SCRIPTS)
|
|
registerEnumIn("configKeys", ConfigManager::CONVERT_UNSAFE_SCRIPTS)
|
|
registerEnumIn("configKeys", ConfigManager::TELEPORT_NEWBIES)
|
|
|
|
registerEnumIn("configKeys", ConfigManager::MAP_NAME)
|
|
registerEnumIn("configKeys", ConfigManager::HOUSE_RENT_PERIOD)
|
|
registerEnumIn("configKeys", ConfigManager::SERVER_NAME)
|
|
registerEnumIn("configKeys", ConfigManager::OWNER_NAME)
|
|
registerEnumIn("configKeys", ConfigManager::OWNER_EMAIL)
|
|
registerEnumIn("configKeys", ConfigManager::URL)
|
|
registerEnumIn("configKeys", ConfigManager::LOCATION)
|
|
registerEnumIn("configKeys", ConfigManager::IP)
|
|
registerEnumIn("configKeys", ConfigManager::MOTD)
|
|
registerEnumIn("configKeys", ConfigManager::WORLD_TYPE)
|
|
registerEnumIn("configKeys", ConfigManager::MYSQL_HOST)
|
|
registerEnumIn("configKeys", ConfigManager::MYSQL_USER)
|
|
registerEnumIn("configKeys", ConfigManager::MYSQL_PASS)
|
|
registerEnumIn("configKeys", ConfigManager::MYSQL_DB)
|
|
registerEnumIn("configKeys", ConfigManager::MYSQL_SOCK)
|
|
registerEnumIn("configKeys", ConfigManager::DEFAULT_PRIORITY)
|
|
registerEnumIn("configKeys", ConfigManager::MAP_AUTHOR)
|
|
|
|
registerEnumIn("configKeys", ConfigManager::SQL_PORT)
|
|
registerEnumIn("configKeys", ConfigManager::MAX_PLAYERS)
|
|
registerEnumIn("configKeys", ConfigManager::PZ_LOCKED)
|
|
registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRANGE)
|
|
registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRADIUS)
|
|
registerEnumIn("configKeys", ConfigManager::RATE_EXPERIENCE)
|
|
registerEnumIn("configKeys", ConfigManager::RATE_SKILL)
|
|
registerEnumIn("configKeys", ConfigManager::RATE_LOOT)
|
|
registerEnumIn("configKeys", ConfigManager::RATE_MAGIC)
|
|
registerEnumIn("configKeys", ConfigManager::RATE_SPAWN)
|
|
registerEnumIn("configKeys", ConfigManager::MAX_MESSAGEBUFFER)
|
|
registerEnumIn("configKeys", ConfigManager::ACTIONS_DELAY_INTERVAL)
|
|
registerEnumIn("configKeys", ConfigManager::EX_ACTIONS_DELAY_INTERVAL)
|
|
registerEnumIn("configKeys", ConfigManager::KICK_AFTER_MINUTES)
|
|
registerEnumIn("configKeys", ConfigManager::PROTECTION_LEVEL)
|
|
registerEnumIn("configKeys", ConfigManager::DEATH_LOSE_PERCENT)
|
|
registerEnumIn("configKeys", ConfigManager::KNIGHT_CLOSE_ATTACK_DAMAGE_INCREASE_PERCENT)
|
|
registerEnumIn("configKeys", ConfigManager::PALADIN_RANGE_ATTACK_DAMAGE_INCREASE_PERCENT)
|
|
registerEnumIn("configKeys", ConfigManager::STATUSQUERY_TIMEOUT)
|
|
registerEnumIn("configKeys", ConfigManager::WHITE_SKULL_TIME)
|
|
registerEnumIn("configKeys", ConfigManager::RED_SKULL_TIME)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_DAY_RED_SKULL)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_WEEK_RED_SKULL)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_MONTH_RED_SKULL)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_DAY_BANISHMENT)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_WEEK_BANISHMENT)
|
|
registerEnumIn("configKeys", ConfigManager::KILLS_MONTH_BANISHMENT)
|
|
registerEnumIn("configKeys", ConfigManager::GAME_PORT)
|
|
registerEnumIn("configKeys", ConfigManager::LOGIN_PORT)
|
|
registerEnumIn("configKeys", ConfigManager::STATUS_PORT)
|
|
registerEnumIn("configKeys", ConfigManager::STAIRHOP_DELAY)
|
|
registerEnumIn("configKeys", ConfigManager::EXP_FROM_PLAYERS_LEVEL_RANGE)
|
|
registerEnumIn("configKeys", ConfigManager::MAX_PACKETS_PER_SECOND)
|
|
registerEnumIn("configKeys", ConfigManager::NEWBIE_TOWN)
|
|
registerEnumIn("configKeys", ConfigManager::NEWBIE_LEVEL_THRESHOLD)
|
|
registerEnumIn("configKeys", ConfigManager::BLOCK_HEIGHT)
|
|
registerEnumIn("configKeys", ConfigManager::DROP_ITEMS)
|
|
registerEnumIn("configKeys", ConfigManager::CLIENT_VERSION)
|
|
|
|
// os
|
|
registerMethod("os", "mtime", LuaScriptInterface::luaSystemTime);
|
|
|
|
// table
|
|
registerMethod("table", "create", LuaScriptInterface::luaTableCreate);
|
|
|
|
// Game
|
|
registerTable("Game");
|
|
|
|
registerMethod("Game", "getSpectators", LuaScriptInterface::luaGameGetSpectators);
|
|
registerMethod("Game", "getPlayers", LuaScriptInterface::luaGameGetPlayers);
|
|
registerMethod("Game", "loadMap", LuaScriptInterface::luaGameLoadMap);
|
|
|
|
registerMethod("Game", "getExperienceStage", LuaScriptInterface::luaGameGetExperienceStage);
|
|
registerMethod("Game", "getMonsterCount", LuaScriptInterface::luaGameGetMonsterCount);
|
|
registerMethod("Game", "getPlayerCount", LuaScriptInterface::luaGameGetPlayerCount);
|
|
registerMethod("Game", "getNpcCount", LuaScriptInterface::luaGameGetNpcCount);
|
|
|
|
registerMethod("Game", "getTowns", LuaScriptInterface::luaGameGetTowns);
|
|
registerMethod("Game", "getHouses", LuaScriptInterface::luaGameGetHouses);
|
|
|
|
registerMethod("Game", "getGameState", LuaScriptInterface::luaGameGetGameState);
|
|
registerMethod("Game", "setGameState", LuaScriptInterface::luaGameSetGameState);
|
|
|
|
registerMethod("Game", "getWorldType", LuaScriptInterface::luaGameGetWorldType);
|
|
registerMethod("Game", "setWorldType", LuaScriptInterface::luaGameSetWorldType);
|
|
|
|
registerMethod("Game", "getReturnMessage", LuaScriptInterface::luaGameGetReturnMessage);
|
|
|
|
registerMethod("Game", "createItem", LuaScriptInterface::luaGameCreateItem);
|
|
registerMethod("Game", "createContainer", LuaScriptInterface::luaGameCreateContainer);
|
|
registerMethod("Game", "createMonster", LuaScriptInterface::luaGameCreateMonster);
|
|
registerMethod("Game", "createNpc", LuaScriptInterface::luaGameCreateNpc);
|
|
registerMethod("Game", "createTile", LuaScriptInterface::luaGameCreateTile);
|
|
|
|
registerMethod("Game", "startRaid", LuaScriptInterface::luaGameStartRaid);
|
|
|
|
registerMethod("Game", "reload", LuaScriptInterface::luaGameReload);
|
|
|
|
// Variant
|
|
registerClass("Variant", "", LuaScriptInterface::luaVariantCreate);
|
|
|
|
registerMethod("Variant", "getNumber", LuaScriptInterface::luaVariantGetNumber);
|
|
registerMethod("Variant", "getString", LuaScriptInterface::luaVariantGetString);
|
|
registerMethod("Variant", "getPosition", LuaScriptInterface::luaVariantGetPosition);
|
|
|
|
// Position
|
|
registerClass("Position", "", LuaScriptInterface::luaPositionCreate);
|
|
registerMetaMethod("Position", "__add", LuaScriptInterface::luaPositionAdd);
|
|
registerMetaMethod("Position", "__sub", LuaScriptInterface::luaPositionSub);
|
|
registerMetaMethod("Position", "__eq", LuaScriptInterface::luaPositionCompare);
|
|
|
|
registerMethod("Position", "getDistance", LuaScriptInterface::luaPositionGetDistance);
|
|
registerMethod("Position", "isSightClear", LuaScriptInterface::luaPositionIsSightClear);
|
|
|
|
registerMethod("Position", "sendMagicEffect", LuaScriptInterface::luaPositionSendMagicEffect);
|
|
registerMethod("Position", "sendDistanceEffect", LuaScriptInterface::luaPositionSendDistanceEffect);
|
|
registerMethod("Position", "sendMonsterSay", LuaScriptInterface::luaPositionSendMonsterSay);
|
|
|
|
// Tile
|
|
registerClass("Tile", "", LuaScriptInterface::luaTileCreate);
|
|
registerMetaMethod("Tile", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Tile", "getPosition", LuaScriptInterface::luaTileGetPosition);
|
|
registerMethod("Tile", "getGround", LuaScriptInterface::luaTileGetGround);
|
|
registerMethod("Tile", "getThing", LuaScriptInterface::luaTileGetThing);
|
|
registerMethod("Tile", "getThingCount", LuaScriptInterface::luaTileGetThingCount);
|
|
registerMethod("Tile", "getTopVisibleThing", LuaScriptInterface::luaTileGetTopVisibleThing);
|
|
|
|
registerMethod("Tile", "getTopTopItem", LuaScriptInterface::luaTileGetTopTopItem);
|
|
registerMethod("Tile", "getTopDownItem", LuaScriptInterface::luaTileGetTopDownItem);
|
|
registerMethod("Tile", "getFieldItem", LuaScriptInterface::luaTileGetFieldItem);
|
|
|
|
registerMethod("Tile", "getItemById", LuaScriptInterface::luaTileGetItemById);
|
|
registerMethod("Tile", "getItemByType", LuaScriptInterface::luaTileGetItemByType);
|
|
registerMethod("Tile", "getItemByTopOrder", LuaScriptInterface::luaTileGetItemByTopOrder);
|
|
registerMethod("Tile", "getItemCountById", LuaScriptInterface::luaTileGetItemCountById);
|
|
|
|
registerMethod("Tile", "getBottomCreature", LuaScriptInterface::luaTileGetBottomCreature);
|
|
registerMethod("Tile", "getTopCreature", LuaScriptInterface::luaTileGetTopCreature);
|
|
registerMethod("Tile", "getBottomVisibleCreature", LuaScriptInterface::luaTileGetBottomVisibleCreature);
|
|
registerMethod("Tile", "getTopVisibleCreature", LuaScriptInterface::luaTileGetTopVisibleCreature);
|
|
|
|
registerMethod("Tile", "getItems", LuaScriptInterface::luaTileGetItems);
|
|
registerMethod("Tile", "getItemCount", LuaScriptInterface::luaTileGetItemCount);
|
|
registerMethod("Tile", "getDownItemCount", LuaScriptInterface::luaTileGetDownItemCount);
|
|
registerMethod("Tile", "getTopItemCount", LuaScriptInterface::luaTileGetTopItemCount);
|
|
|
|
registerMethod("Tile", "getCreatures", LuaScriptInterface::luaTileGetCreatures);
|
|
registerMethod("Tile", "getCreatureCount", LuaScriptInterface::luaTileGetCreatureCount);
|
|
|
|
registerMethod("Tile", "getThingIndex", LuaScriptInterface::luaTileGetThingIndex);
|
|
|
|
registerMethod("Tile", "hasProperty", LuaScriptInterface::luaTileHasProperty);
|
|
registerMethod("Tile", "hasFlag", LuaScriptInterface::luaTileHasFlag);
|
|
|
|
registerMethod("Tile", "queryAdd", LuaScriptInterface::luaTileQueryAdd);
|
|
|
|
registerMethod("Tile", "getHouse", LuaScriptInterface::luaTileGetHouse);
|
|
|
|
// NetworkMessage
|
|
registerClass("NetworkMessage", "", LuaScriptInterface::luaNetworkMessageCreate);
|
|
registerMetaMethod("NetworkMessage", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
registerMetaMethod("NetworkMessage", "__gc", LuaScriptInterface::luaNetworkMessageDelete);
|
|
registerMethod("NetworkMessage", "delete", LuaScriptInterface::luaNetworkMessageDelete);
|
|
|
|
registerMethod("NetworkMessage", "getByte", LuaScriptInterface::luaNetworkMessageGetByte);
|
|
registerMethod("NetworkMessage", "getU16", LuaScriptInterface::luaNetworkMessageGetU16);
|
|
registerMethod("NetworkMessage", "getU32", LuaScriptInterface::luaNetworkMessageGetU32);
|
|
registerMethod("NetworkMessage", "getU64", LuaScriptInterface::luaNetworkMessageGetU64);
|
|
registerMethod("NetworkMessage", "getString", LuaScriptInterface::luaNetworkMessageGetString);
|
|
registerMethod("NetworkMessage", "getPosition", LuaScriptInterface::luaNetworkMessageGetPosition);
|
|
|
|
registerMethod("NetworkMessage", "addByte", LuaScriptInterface::luaNetworkMessageAddByte);
|
|
registerMethod("NetworkMessage", "addU16", LuaScriptInterface::luaNetworkMessageAddU16);
|
|
registerMethod("NetworkMessage", "addU32", LuaScriptInterface::luaNetworkMessageAddU32);
|
|
registerMethod("NetworkMessage", "addU64", LuaScriptInterface::luaNetworkMessageAddU64);
|
|
registerMethod("NetworkMessage", "addString", LuaScriptInterface::luaNetworkMessageAddString);
|
|
registerMethod("NetworkMessage", "addPosition", LuaScriptInterface::luaNetworkMessageAddPosition);
|
|
registerMethod("NetworkMessage", "addDouble", LuaScriptInterface::luaNetworkMessageAddDouble);
|
|
registerMethod("NetworkMessage", "addItem", LuaScriptInterface::luaNetworkMessageAddItem);
|
|
registerMethod("NetworkMessage", "addItemId", LuaScriptInterface::luaNetworkMessageAddItemId);
|
|
|
|
registerMethod("NetworkMessage", "reset", LuaScriptInterface::luaNetworkMessageReset);
|
|
registerMethod("NetworkMessage", "skipBytes", LuaScriptInterface::luaNetworkMessageSkipBytes);
|
|
registerMethod("NetworkMessage", "sendToPlayer", LuaScriptInterface::luaNetworkMessageSendToPlayer);
|
|
|
|
// Item
|
|
registerClass("Item", "", LuaScriptInterface::luaItemCreate);
|
|
registerMetaMethod("Item", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Item", "isItem", LuaScriptInterface::luaItemIsItem);
|
|
|
|
registerMethod("Item", "getParent", LuaScriptInterface::luaItemGetParent);
|
|
registerMethod("Item", "getTopParent", LuaScriptInterface::luaItemGetTopParent);
|
|
|
|
registerMethod("Item", "getId", LuaScriptInterface::luaItemGetId);
|
|
|
|
registerMethod("Item", "clone", LuaScriptInterface::luaItemClone);
|
|
registerMethod("Item", "split", LuaScriptInterface::luaItemSplit);
|
|
registerMethod("Item", "remove", LuaScriptInterface::luaItemRemove);
|
|
|
|
registerMethod("Item", "getMovementId", LuaScriptInterface::luaItemGetMovementId);
|
|
registerMethod("Item", "setMovementId", LuaScriptInterface::luaItemSetMovementId);
|
|
registerMethod("Item", "getActionId", LuaScriptInterface::luaItemGetActionId);
|
|
registerMethod("Item", "setActionId", LuaScriptInterface::luaItemSetActionId);
|
|
registerMethod("Item", "getUniqueId", LuaScriptInterface::luaItemGetUniqueId);
|
|
|
|
registerMethod("Item", "getCount", LuaScriptInterface::luaItemGetCount);
|
|
registerMethod("Item", "getCharges", LuaScriptInterface::luaItemGetCharges);
|
|
registerMethod("Item", "getFluidType", LuaScriptInterface::luaItemGetFluidType);
|
|
registerMethod("Item", "getWeight", LuaScriptInterface::luaItemGetWeight);
|
|
|
|
registerMethod("Item", "getSubType", LuaScriptInterface::luaItemGetSubType);
|
|
|
|
registerMethod("Item", "getName", LuaScriptInterface::luaItemGetName);
|
|
registerMethod("Item", "getPluralName", LuaScriptInterface::luaItemGetPluralName);
|
|
registerMethod("Item", "getArticle", LuaScriptInterface::luaItemGetArticle);
|
|
|
|
registerMethod("Item", "getPosition", LuaScriptInterface::luaItemGetPosition);
|
|
registerMethod("Item", "getTile", LuaScriptInterface::luaItemGetTile);
|
|
|
|
registerMethod("Item", "hasAttribute", LuaScriptInterface::luaItemHasAttribute);
|
|
registerMethod("Item", "getAttribute", LuaScriptInterface::luaItemGetAttribute);
|
|
registerMethod("Item", "setAttribute", LuaScriptInterface::luaItemSetAttribute);
|
|
registerMethod("Item", "removeAttribute", LuaScriptInterface::luaItemRemoveAttribute);
|
|
|
|
registerMethod("Item", "moveTo", LuaScriptInterface::luaItemMoveTo);
|
|
registerMethod("Item", "transform", LuaScriptInterface::luaItemTransform);
|
|
registerMethod("Item", "decay", LuaScriptInterface::luaItemDecay);
|
|
|
|
registerMethod("Item", "getDescription", LuaScriptInterface::luaItemGetDescription);
|
|
|
|
registerMethod("Item", "hasProperty", LuaScriptInterface::luaItemHasProperty);
|
|
|
|
// Container
|
|
registerClass("Container", "Item", LuaScriptInterface::luaContainerCreate);
|
|
registerMetaMethod("Container", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Container", "getSize", LuaScriptInterface::luaContainerGetSize);
|
|
registerMethod("Container", "getCapacity", LuaScriptInterface::luaContainerGetCapacity);
|
|
registerMethod("Container", "getEmptySlots", LuaScriptInterface::luaContainerGetEmptySlots);
|
|
|
|
registerMethod("Container", "getItemHoldingCount", LuaScriptInterface::luaContainerGetItemHoldingCount);
|
|
registerMethod("Container", "getItemCountById", LuaScriptInterface::luaContainerGetItemCountById);
|
|
|
|
registerMethod("Container", "getItem", LuaScriptInterface::luaContainerGetItem);
|
|
registerMethod("Container", "hasItem", LuaScriptInterface::luaContainerHasItem);
|
|
registerMethod("Container", "addItem", LuaScriptInterface::luaContainerAddItem);
|
|
registerMethod("Container", "addItemEx", LuaScriptInterface::luaContainerAddItemEx);
|
|
|
|
// Teleport
|
|
registerClass("Teleport", "Item", LuaScriptInterface::luaTeleportCreate);
|
|
registerMetaMethod("Teleport", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Teleport", "getDestination", LuaScriptInterface::luaTeleportGetDestination);
|
|
registerMethod("Teleport", "setDestination", LuaScriptInterface::luaTeleportSetDestination);
|
|
|
|
// Creature
|
|
registerClass("Creature", "", LuaScriptInterface::luaCreatureCreate);
|
|
registerMetaMethod("Creature", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Creature", "getEvents", LuaScriptInterface::luaCreatureGetEvents);
|
|
registerMethod("Creature", "registerEvent", LuaScriptInterface::luaCreatureRegisterEvent);
|
|
registerMethod("Creature", "unregisterEvent", LuaScriptInterface::luaCreatureUnregisterEvent);
|
|
|
|
registerMethod("Creature", "isRemoved", LuaScriptInterface::luaCreatureIsRemoved);
|
|
registerMethod("Creature", "isCreature", LuaScriptInterface::luaCreatureIsCreature);
|
|
registerMethod("Creature", "isInGhostMode", LuaScriptInterface::luaCreatureIsInGhostMode);
|
|
|
|
registerMethod("Creature", "canSee", LuaScriptInterface::luaCreatureCanSee);
|
|
registerMethod("Creature", "canSeeCreature", LuaScriptInterface::luaCreatureCanSeeCreature);
|
|
|
|
registerMethod("Creature", "getParent", LuaScriptInterface::luaCreatureGetParent);
|
|
|
|
registerMethod("Creature", "getId", LuaScriptInterface::luaCreatureGetId);
|
|
registerMethod("Creature", "getName", LuaScriptInterface::luaCreatureGetName);
|
|
|
|
registerMethod("Creature", "getTarget", LuaScriptInterface::luaCreatureGetTarget);
|
|
registerMethod("Creature", "setTarget", LuaScriptInterface::luaCreatureSetTarget);
|
|
|
|
registerMethod("Creature", "getFollowCreature", LuaScriptInterface::luaCreatureGetFollowCreature);
|
|
registerMethod("Creature", "setFollowCreature", LuaScriptInterface::luaCreatureSetFollowCreature);
|
|
|
|
registerMethod("Creature", "getMaster", LuaScriptInterface::luaCreatureGetMaster);
|
|
registerMethod("Creature", "setMaster", LuaScriptInterface::luaCreatureSetMaster);
|
|
|
|
registerMethod("Creature", "getLight", LuaScriptInterface::luaCreatureGetLight);
|
|
registerMethod("Creature", "setLight", LuaScriptInterface::luaCreatureSetLight);
|
|
|
|
registerMethod("Creature", "getSpeed", LuaScriptInterface::luaCreatureGetSpeed);
|
|
registerMethod("Creature", "getBaseSpeed", LuaScriptInterface::luaCreatureGetBaseSpeed);
|
|
registerMethod("Creature", "changeSpeed", LuaScriptInterface::luaCreatureChangeSpeed);
|
|
|
|
registerMethod("Creature", "setDropLoot", LuaScriptInterface::luaCreatureSetDropLoot);
|
|
|
|
registerMethod("Creature", "getPosition", LuaScriptInterface::luaCreatureGetPosition);
|
|
registerMethod("Creature", "getTile", LuaScriptInterface::luaCreatureGetTile);
|
|
registerMethod("Creature", "getDirection", LuaScriptInterface::luaCreatureGetDirection);
|
|
registerMethod("Creature", "setDirection", LuaScriptInterface::luaCreatureSetDirection);
|
|
|
|
registerMethod("Creature", "getHealth", LuaScriptInterface::luaCreatureGetHealth);
|
|
registerMethod("Creature", "addHealth", LuaScriptInterface::luaCreatureAddHealth);
|
|
registerMethod("Creature", "getMaxHealth", LuaScriptInterface::luaCreatureGetMaxHealth);
|
|
registerMethod("Creature", "setMaxHealth", LuaScriptInterface::luaCreatureSetMaxHealth);
|
|
registerMethod("Creature", "setHiddenHealth", LuaScriptInterface::luaCreatureSetHiddenHealth);
|
|
|
|
registerMethod("Creature", "getSkull", LuaScriptInterface::luaCreatureGetSkull);
|
|
registerMethod("Creature", "setSkull", LuaScriptInterface::luaCreatureSetSkull);
|
|
|
|
registerMethod("Creature", "getOutfit", LuaScriptInterface::luaCreatureGetOutfit);
|
|
registerMethod("Creature", "setOutfit", LuaScriptInterface::luaCreatureSetOutfit);
|
|
|
|
registerMethod("Creature", "getCondition", LuaScriptInterface::luaCreatureGetCondition);
|
|
registerMethod("Creature", "addCondition", LuaScriptInterface::luaCreatureAddCondition);
|
|
registerMethod("Creature", "removeCondition", LuaScriptInterface::luaCreatureRemoveCondition);
|
|
|
|
registerMethod("Creature", "remove", LuaScriptInterface::luaCreatureRemove);
|
|
registerMethod("Creature", "teleportTo", LuaScriptInterface::luaCreatureTeleportTo);
|
|
registerMethod("Creature", "say", LuaScriptInterface::luaCreatureSay);
|
|
|
|
registerMethod("Creature", "getDamageMap", LuaScriptInterface::luaCreatureGetDamageMap);
|
|
|
|
registerMethod("Creature", "getSummons", LuaScriptInterface::luaCreatureGetSummons);
|
|
|
|
registerMethod("Creature", "getDescription", LuaScriptInterface::luaCreatureGetDescription);
|
|
|
|
registerMethod("Creature", "getPathTo", LuaScriptInterface::luaCreatureGetPathTo);
|
|
|
|
// Player
|
|
registerClass("Player", "Creature", LuaScriptInterface::luaPlayerCreate);
|
|
registerMetaMethod("Player", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Player", "isPlayer", LuaScriptInterface::luaPlayerIsPlayer);
|
|
|
|
registerMethod("Player", "getGuid", LuaScriptInterface::luaPlayerGetGuid);
|
|
registerMethod("Player", "getIp", LuaScriptInterface::luaPlayerGetIp);
|
|
registerMethod("Player", "getAccountId", LuaScriptInterface::luaPlayerGetAccountId);
|
|
registerMethod("Player", "getLastLoginSaved", LuaScriptInterface::luaPlayerGetLastLoginSaved);
|
|
registerMethod("Player", "getLastLogout", LuaScriptInterface::luaPlayerGetLastLogout);
|
|
registerMethod("Player", "hasFlag", LuaScriptInterface::luaPlayerHasFlag);
|
|
|
|
registerMethod("Player", "getAccountType", LuaScriptInterface::luaPlayerGetAccountType);
|
|
registerMethod("Player", "setAccountType", LuaScriptInterface::luaPlayerSetAccountType);
|
|
|
|
registerMethod("Player", "getCapacity", LuaScriptInterface::luaPlayerGetCapacity);
|
|
registerMethod("Player", "setCapacity", LuaScriptInterface::luaPlayerSetCapacity);
|
|
|
|
registerMethod("Player", "getFreeCapacity", LuaScriptInterface::luaPlayerGetFreeCapacity);
|
|
|
|
registerMethod("Player", "getDepotChest", LuaScriptInterface::luaPlayerGetDepotChest);
|
|
|
|
registerMethod("Player", "getMurderTimestamps", LuaScriptInterface::luaPlayerGetMurderTimestamps);
|
|
registerMethod("Player", "getPlayerKillerEnd", LuaScriptInterface::luaPlayerGetPlayerKillerEnd);
|
|
registerMethod("Player", "setPlayerKillerEnd", LuaScriptInterface::luaPlayerSetPlayerKillerEnd);
|
|
registerMethod("Player", "getDeathPenalty", LuaScriptInterface::luaPlayerGetDeathPenalty);
|
|
|
|
registerMethod("Player", "getExperience", LuaScriptInterface::luaPlayerGetExperience);
|
|
registerMethod("Player", "addExperience", LuaScriptInterface::luaPlayerAddExperience);
|
|
registerMethod("Player", "removeExperience", LuaScriptInterface::luaPlayerRemoveExperience);
|
|
registerMethod("Player", "getLevel", LuaScriptInterface::luaPlayerGetLevel);
|
|
|
|
registerMethod("Player", "getMagicLevel", LuaScriptInterface::luaPlayerGetMagicLevel);
|
|
registerMethod("Player", "getBaseMagicLevel", LuaScriptInterface::luaPlayerGetBaseMagicLevel);
|
|
registerMethod("Player", "getMana", LuaScriptInterface::luaPlayerGetMana);
|
|
registerMethod("Player", "addMana", LuaScriptInterface::luaPlayerAddMana);
|
|
registerMethod("Player", "getMaxMana", LuaScriptInterface::luaPlayerGetMaxMana);
|
|
registerMethod("Player", "setMaxMana", LuaScriptInterface::luaPlayerSetMaxMana);
|
|
registerMethod("Player", "getManaSpent", LuaScriptInterface::luaPlayerGetManaSpent);
|
|
registerMethod("Player", "addManaSpent", LuaScriptInterface::luaPlayerAddManaSpent);
|
|
|
|
registerMethod("Player", "getBaseMaxHealth", LuaScriptInterface::luaPlayerGetBaseMaxHealth);
|
|
registerMethod("Player", "getBaseMaxMana", LuaScriptInterface::luaPlayerGetBaseMaxMana);
|
|
|
|
registerMethod("Player", "getSkillLevel", LuaScriptInterface::luaPlayerGetSkillLevel);
|
|
registerMethod("Player", "getEffectiveSkillLevel", LuaScriptInterface::luaPlayerGetEffectiveSkillLevel);
|
|
registerMethod("Player", "getSkillPercent", LuaScriptInterface::luaPlayerGetSkillPercent);
|
|
registerMethod("Player", "getSkillTries", LuaScriptInterface::luaPlayerGetSkillTries);
|
|
registerMethod("Player", "addSkillTries", LuaScriptInterface::luaPlayerAddSkillTries);
|
|
|
|
registerMethod("Player", "getItemCount", LuaScriptInterface::luaPlayerGetItemCount);
|
|
registerMethod("Player", "getItemById", LuaScriptInterface::luaPlayerGetItemById);
|
|
|
|
registerMethod("Player", "getVocation", LuaScriptInterface::luaPlayerGetVocation);
|
|
registerMethod("Player", "setVocation", LuaScriptInterface::luaPlayerSetVocation);
|
|
|
|
registerMethod("Player", "getSex", LuaScriptInterface::luaPlayerGetSex);
|
|
registerMethod("Player", "setSex", LuaScriptInterface::luaPlayerSetSex);
|
|
|
|
registerMethod("Player", "getTown", LuaScriptInterface::luaPlayerGetTown);
|
|
registerMethod("Player", "setTown", LuaScriptInterface::luaPlayerSetTown);
|
|
|
|
registerMethod("Player", "getGuild", LuaScriptInterface::luaPlayerGetGuild);
|
|
registerMethod("Player", "setGuild", LuaScriptInterface::luaPlayerSetGuild);
|
|
|
|
registerMethod("Player", "getGuildLevel", LuaScriptInterface::luaPlayerGetGuildLevel);
|
|
registerMethod("Player", "setGuildLevel", LuaScriptInterface::luaPlayerSetGuildLevel);
|
|
|
|
registerMethod("Player", "getGuildNick", LuaScriptInterface::luaPlayerGetGuildNick);
|
|
registerMethod("Player", "setGuildNick", LuaScriptInterface::luaPlayerSetGuildNick);
|
|
|
|
registerMethod("Player", "getGroup", LuaScriptInterface::luaPlayerGetGroup);
|
|
registerMethod("Player", "setGroup", LuaScriptInterface::luaPlayerSetGroup);
|
|
|
|
registerMethod("Player", "getStamina", LuaScriptInterface::luaPlayerGetStamina);
|
|
registerMethod("Player", "setStamina", LuaScriptInterface::luaPlayerSetStamina);
|
|
|
|
registerMethod("Player", "getSoul", LuaScriptInterface::luaPlayerGetSoul);
|
|
registerMethod("Player", "addSoul", LuaScriptInterface::luaPlayerAddSoul);
|
|
registerMethod("Player", "getMaxSoul", LuaScriptInterface::luaPlayerGetMaxSoul);
|
|
|
|
registerMethod("Player", "getBankBalance", LuaScriptInterface::luaPlayerGetBankBalance);
|
|
registerMethod("Player", "setBankBalance", LuaScriptInterface::luaPlayerSetBankBalance);
|
|
|
|
registerMethod("Player", "getStorageValue", LuaScriptInterface::luaPlayerGetStorageValue);
|
|
registerMethod("Player", "setStorageValue", LuaScriptInterface::luaPlayerSetStorageValue);
|
|
|
|
registerMethod("Player", "addItem", LuaScriptInterface::luaPlayerAddItem);
|
|
registerMethod("Player", "addItemEx", LuaScriptInterface::luaPlayerAddItemEx);
|
|
registerMethod("Player", "removeItem", LuaScriptInterface::luaPlayerRemoveItem);
|
|
|
|
registerMethod("Player", "getMoney", LuaScriptInterface::luaPlayerGetMoney);
|
|
registerMethod("Player", "addMoney", LuaScriptInterface::luaPlayerAddMoney);
|
|
registerMethod("Player", "removeMoney", LuaScriptInterface::luaPlayerRemoveMoney);
|
|
|
|
registerMethod("Player", "showTextDialog", LuaScriptInterface::luaPlayerShowTextDialog);
|
|
|
|
registerMethod("Player", "sendTextMessage", LuaScriptInterface::luaPlayerSendTextMessage);
|
|
registerMethod("Player", "sendPrivateMessage", LuaScriptInterface::luaPlayerSendPrivateMessage);
|
|
registerMethod("Player", "channelSay", LuaScriptInterface::luaPlayerChannelSay);
|
|
registerMethod("Player", "openChannel", LuaScriptInterface::luaPlayerOpenChannel);
|
|
|
|
registerMethod("Player", "getSlotItem", LuaScriptInterface::luaPlayerGetSlotItem);
|
|
|
|
registerMethod("Player", "getParty", LuaScriptInterface::luaPlayerGetParty);
|
|
|
|
registerMethod("Player", "addOutfit", LuaScriptInterface::luaPlayerAddOutfit);
|
|
registerMethod("Player", "addOutfitAddon", LuaScriptInterface::luaPlayerAddOutfitAddon);
|
|
registerMethod("Player", "removeOutfit", LuaScriptInterface::luaPlayerRemoveOutfit);
|
|
registerMethod("Player", "removeOutfitAddon", LuaScriptInterface::luaPlayerRemoveOutfitAddon);
|
|
registerMethod("Player", "hasOutfit", LuaScriptInterface::luaPlayerHasOutfit);
|
|
registerMethod("Player", "sendOutfitWindow", LuaScriptInterface::luaPlayerSendOutfitWindow);
|
|
|
|
registerMethod("Player", "getPremiumDays", LuaScriptInterface::luaPlayerGetPremiumDays);
|
|
registerMethod("Player", "addPremiumDays", LuaScriptInterface::luaPlayerAddPremiumDays);
|
|
registerMethod("Player", "removePremiumDays", LuaScriptInterface::luaPlayerRemovePremiumDays);
|
|
|
|
registerMethod("Player", "hasBlessing", LuaScriptInterface::luaPlayerHasBlessing);
|
|
registerMethod("Player", "addBlessing", LuaScriptInterface::luaPlayerAddBlessing);
|
|
registerMethod("Player", "removeBlessing", LuaScriptInterface::luaPlayerRemoveBlessing);
|
|
|
|
registerMethod("Player", "canLearnSpell", LuaScriptInterface::luaPlayerCanLearnSpell);
|
|
registerMethod("Player", "learnSpell", LuaScriptInterface::luaPlayerLearnSpell);
|
|
registerMethod("Player", "forgetSpell", LuaScriptInterface::luaPlayerForgetSpell);
|
|
registerMethod("Player", "hasLearnedSpell", LuaScriptInterface::luaPlayerHasLearnedSpell);
|
|
|
|
registerMethod("Player", "save", LuaScriptInterface::luaPlayerSave);
|
|
|
|
registerMethod("Player", "isPzLocked", LuaScriptInterface::luaPlayerIsPzLocked);
|
|
|
|
registerMethod("Player", "getClient", LuaScriptInterface::luaPlayerGetClient);
|
|
registerMethod("Player", "getHouse", LuaScriptInterface::luaPlayerGetHouse);
|
|
|
|
registerMethod("Player", "setGhostMode", LuaScriptInterface::luaPlayerSetGhostMode);
|
|
|
|
registerMethod("Player", "getContainerId", LuaScriptInterface::luaPlayerGetContainerId);
|
|
registerMethod("Player", "getContainerById", LuaScriptInterface::luaPlayerGetContainerById);
|
|
registerMethod("Player", "getContainerIndex", LuaScriptInterface::luaPlayerGetContainerIndex);
|
|
|
|
registerMethod("Player", "getTotalDamage", LuaScriptInterface::luaPlayerGetTotalDamage);
|
|
|
|
// Monster
|
|
registerClass("Monster", "Creature", LuaScriptInterface::luaMonsterCreate);
|
|
registerMetaMethod("Monster", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Monster", "isMonster", LuaScriptInterface::luaMonsterIsMonster);
|
|
|
|
registerMethod("Monster", "getType", LuaScriptInterface::luaMonsterGetType);
|
|
|
|
registerMethod("Monster", "getSpawnPosition", LuaScriptInterface::luaMonsterGetSpawnPosition);
|
|
registerMethod("Monster", "isInSpawnRange", LuaScriptInterface::luaMonsterIsInSpawnRange);
|
|
|
|
registerMethod("Monster", "isIdle", LuaScriptInterface::luaMonsterIsIdle);
|
|
registerMethod("Monster", "setIdle", LuaScriptInterface::luaMonsterSetIdle);
|
|
|
|
registerMethod("Monster", "isTarget", LuaScriptInterface::luaMonsterIsTarget);
|
|
registerMethod("Monster", "isOpponent", LuaScriptInterface::luaMonsterIsOpponent);
|
|
registerMethod("Monster", "isFriend", LuaScriptInterface::luaMonsterIsFriend);
|
|
|
|
registerMethod("Monster", "addFriend", LuaScriptInterface::luaMonsterAddFriend);
|
|
registerMethod("Monster", "removeFriend", LuaScriptInterface::luaMonsterRemoveFriend);
|
|
registerMethod("Monster", "getFriendList", LuaScriptInterface::luaMonsterGetFriendList);
|
|
registerMethod("Monster", "getFriendCount", LuaScriptInterface::luaMonsterGetFriendCount);
|
|
|
|
registerMethod("Monster", "addTarget", LuaScriptInterface::luaMonsterAddTarget);
|
|
registerMethod("Monster", "removeTarget", LuaScriptInterface::luaMonsterRemoveTarget);
|
|
registerMethod("Monster", "getTargetList", LuaScriptInterface::luaMonsterGetTargetList);
|
|
registerMethod("Monster", "getTargetCount", LuaScriptInterface::luaMonsterGetTargetCount);
|
|
|
|
registerMethod("Monster", "selectTarget", LuaScriptInterface::luaMonsterSelectTarget);
|
|
registerMethod("Monster", "searchTarget", LuaScriptInterface::luaMonsterSearchTarget);
|
|
|
|
// Npc
|
|
registerClass("Npc", "Creature", LuaScriptInterface::luaNpcCreate);
|
|
registerMetaMethod("Npc", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Npc", "isNpc", LuaScriptInterface::luaNpcIsNpc);
|
|
|
|
registerMethod("Npc", "setMasterPos", LuaScriptInterface::luaNpcSetMasterPos);
|
|
|
|
// Guild
|
|
registerClass("Guild", "", LuaScriptInterface::luaGuildCreate);
|
|
registerMetaMethod("Guild", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Guild", "getId", LuaScriptInterface::luaGuildGetId);
|
|
registerMethod("Guild", "getName", LuaScriptInterface::luaGuildGetName);
|
|
registerMethod("Guild", "getMembersOnline", LuaScriptInterface::luaGuildGetMembersOnline);
|
|
|
|
registerMethod("Guild", "addRank", LuaScriptInterface::luaGuildAddRank);
|
|
registerMethod("Guild", "getRankById", LuaScriptInterface::luaGuildGetRankById);
|
|
registerMethod("Guild", "getRankByLevel", LuaScriptInterface::luaGuildGetRankByLevel);
|
|
|
|
// Group
|
|
registerClass("Group", "", LuaScriptInterface::luaGroupCreate);
|
|
registerMetaMethod("Group", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Group", "getId", LuaScriptInterface::luaGroupGetId);
|
|
registerMethod("Group", "getName", LuaScriptInterface::luaGroupGetName);
|
|
registerMethod("Group", "getFlags", LuaScriptInterface::luaGroupGetFlags);
|
|
registerMethod("Group", "getAccess", LuaScriptInterface::luaGroupGetAccess);
|
|
registerMethod("Group", "getMaxDepotItems", LuaScriptInterface::luaGroupGetMaxDepotItems);
|
|
registerMethod("Group", "getMaxVipEntries", LuaScriptInterface::luaGroupGetMaxVipEntries);
|
|
|
|
// Vocation
|
|
registerClass("Vocation", "", LuaScriptInterface::luaVocationCreate);
|
|
registerMetaMethod("Vocation", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Vocation", "getId", LuaScriptInterface::luaVocationGetId);
|
|
registerMethod("Vocation", "getName", LuaScriptInterface::luaVocationGetName);
|
|
registerMethod("Vocation", "getDescription", LuaScriptInterface::luaVocationGetDescription);
|
|
|
|
registerMethod("Vocation", "getRequiredSkillTries", LuaScriptInterface::luaVocationGetRequiredSkillTries);
|
|
registerMethod("Vocation", "getRequiredManaSpent", LuaScriptInterface::luaVocationGetRequiredManaSpent);
|
|
|
|
registerMethod("Vocation", "getCapacityGain", LuaScriptInterface::luaVocationGetCapacityGain);
|
|
|
|
registerMethod("Vocation", "getHealthGain", LuaScriptInterface::luaVocationGetHealthGain);
|
|
registerMethod("Vocation", "getHealthGainTicks", LuaScriptInterface::luaVocationGetHealthGainTicks);
|
|
registerMethod("Vocation", "getHealthGainAmount", LuaScriptInterface::luaVocationGetHealthGainAmount);
|
|
|
|
registerMethod("Vocation", "getManaGain", LuaScriptInterface::luaVocationGetManaGain);
|
|
registerMethod("Vocation", "getManaGainTicks", LuaScriptInterface::luaVocationGetManaGainTicks);
|
|
registerMethod("Vocation", "getManaGainAmount", LuaScriptInterface::luaVocationGetManaGainAmount);
|
|
|
|
registerMethod("Vocation", "getMaxSoul", LuaScriptInterface::luaVocationGetMaxSoul);
|
|
registerMethod("Vocation", "getSoulGainTicks", LuaScriptInterface::luaVocationGetSoulGainTicks);
|
|
|
|
registerMethod("Vocation", "getAttackSpeed", LuaScriptInterface::luaVocationGetAttackSpeed);
|
|
registerMethod("Vocation", "getBaseSpeed", LuaScriptInterface::luaVocationGetBaseSpeed);
|
|
|
|
registerMethod("Vocation", "getDemotion", LuaScriptInterface::luaVocationGetDemotion);
|
|
registerMethod("Vocation", "getPromotion", LuaScriptInterface::luaVocationGetPromotion);
|
|
|
|
// Town
|
|
registerClass("Town", "", LuaScriptInterface::luaTownCreate);
|
|
registerMetaMethod("Town", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Town", "getId", LuaScriptInterface::luaTownGetId);
|
|
registerMethod("Town", "getName", LuaScriptInterface::luaTownGetName);
|
|
registerMethod("Town", "getTemplePosition", LuaScriptInterface::luaTownGetTemplePosition);
|
|
|
|
// House
|
|
registerClass("House", "", LuaScriptInterface::luaHouseCreate);
|
|
registerMetaMethod("House", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("House", "getId", LuaScriptInterface::luaHouseGetId);
|
|
registerMethod("House", "getName", LuaScriptInterface::luaHouseGetName);
|
|
registerMethod("House", "getTown", LuaScriptInterface::luaHouseGetTown);
|
|
registerMethod("House", "getExitPosition", LuaScriptInterface::luaHouseGetExitPosition);
|
|
registerMethod("House", "getRent", LuaScriptInterface::luaHouseGetRent);
|
|
|
|
registerMethod("House", "getOwnerGuid", LuaScriptInterface::luaHouseGetOwnerGuid);
|
|
registerMethod("House", "setOwnerGuid", LuaScriptInterface::luaHouseSetOwnerGuid);
|
|
registerMethod("House", "startTrade", LuaScriptInterface::luaHouseStartTrade);
|
|
|
|
registerMethod("House", "getBeds", LuaScriptInterface::luaHouseGetBeds);
|
|
registerMethod("House", "getBedCount", LuaScriptInterface::luaHouseGetBedCount);
|
|
|
|
registerMethod("House", "getDoors", LuaScriptInterface::luaHouseGetDoors);
|
|
registerMethod("House", "getDoorCount", LuaScriptInterface::luaHouseGetDoorCount);
|
|
|
|
registerMethod("House", "getTiles", LuaScriptInterface::luaHouseGetTiles);
|
|
registerMethod("House", "getTileCount", LuaScriptInterface::luaHouseGetTileCount);
|
|
|
|
registerMethod("House", "getAccessList", LuaScriptInterface::luaHouseGetAccessList);
|
|
registerMethod("House", "setAccessList", LuaScriptInterface::luaHouseSetAccessList);
|
|
|
|
// ItemType
|
|
registerClass("ItemType", "", LuaScriptInterface::luaItemTypeCreate);
|
|
registerMetaMethod("ItemType", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("ItemType", "isCorpse", LuaScriptInterface::luaItemTypeIsCorpse);
|
|
registerMethod("ItemType", "isDoor", LuaScriptInterface::luaItemTypeIsDoor);
|
|
registerMethod("ItemType", "isContainer", LuaScriptInterface::luaItemTypeIsContainer);
|
|
registerMethod("ItemType", "isChest", LuaScriptInterface::luaItemTypeIsChest);
|
|
registerMethod("ItemType", "isFluidContainer", LuaScriptInterface::luaItemTypeIsFluidContainer);
|
|
registerMethod("ItemType", "isMovable", LuaScriptInterface::luaItemTypeIsMovable);
|
|
registerMethod("ItemType", "isRune", LuaScriptInterface::luaItemTypeIsRune);
|
|
registerMethod("ItemType", "isStackable", LuaScriptInterface::luaItemTypeIsStackable);
|
|
registerMethod("ItemType", "isReadable", LuaScriptInterface::luaItemTypeIsReadable);
|
|
registerMethod("ItemType", "isWritable", LuaScriptInterface::luaItemTypeIsWritable);
|
|
registerMethod("ItemType", "isMagicField", LuaScriptInterface::luaItemTypeIsMagicField);
|
|
registerMethod("ItemType", "isSplash", LuaScriptInterface::luaItemTypeIsSplash);
|
|
registerMethod("ItemType", "isKey", LuaScriptInterface::luaItemTypeIsKey);
|
|
registerMethod("ItemType", "isDisguised", LuaScriptInterface::luaItemTypeIsDisguised);
|
|
registerMethod("ItemType", "isDestroyable", LuaScriptInterface::luaItemTypeIsDestroyable);
|
|
registerMethod("ItemType", "isGroundTile", LuaScriptInterface::luaItemTypeIsGroundTile);
|
|
|
|
registerMethod("ItemType", "getType", LuaScriptInterface::luaItemTypeGetType);
|
|
registerMethod("ItemType", "getId", LuaScriptInterface::luaItemTypeGetId);
|
|
registerMethod("ItemType", "getDisguiseId", LuaScriptInterface::luaItemTypeGetDisguiseId);
|
|
registerMethod("ItemType", "getName", LuaScriptInterface::luaItemTypeGetName);
|
|
registerMethod("ItemType", "getPluralName", LuaScriptInterface::luaItemTypeGetPluralName);
|
|
registerMethod("ItemType", "getArticle", LuaScriptInterface::luaItemTypeGetArticle);
|
|
registerMethod("ItemType", "getDescription", LuaScriptInterface::luaItemTypeGetDescription);
|
|
registerMethod("ItemType", "getSlotPosition", LuaScriptInterface::luaItemTypeGetSlotPosition);
|
|
registerMethod("ItemType", "getDestroyTarget", LuaScriptInterface::luaItemTypeGetDestroyTarget);
|
|
|
|
registerMethod("ItemType", "getCharges", LuaScriptInterface::luaItemTypeGetCharges);
|
|
registerMethod("ItemType", "getFluidSource", LuaScriptInterface::luaItemTypeGetFluidSource);
|
|
registerMethod("ItemType", "getCapacity", LuaScriptInterface::luaItemTypeGetCapacity);
|
|
registerMethod("ItemType", "getWeight", LuaScriptInterface::luaItemTypeGetWeight);
|
|
|
|
registerMethod("ItemType", "getShootRange", LuaScriptInterface::luaItemTypeGetShootRange);
|
|
|
|
registerMethod("ItemType", "getAttack", LuaScriptInterface::luaItemTypeGetAttack);
|
|
registerMethod("ItemType", "getDefense", LuaScriptInterface::luaItemTypeGetDefense);
|
|
registerMethod("ItemType", "getArmor", LuaScriptInterface::luaItemTypeGetArmor);
|
|
registerMethod("ItemType", "getWeaponType", LuaScriptInterface::luaItemTypeGetWeaponType);
|
|
|
|
registerMethod("ItemType", "getTransformEquipId", LuaScriptInterface::luaItemTypeGetTransformEquipId);
|
|
registerMethod("ItemType", "getTransformDeEquipId", LuaScriptInterface::luaItemTypeGetTransformDeEquipId);
|
|
registerMethod("ItemType", "getDecayId", LuaScriptInterface::luaItemTypeGetDecayId);
|
|
registerMethod("ItemType", "getNutrition", LuaScriptInterface::luaItemTypeGetNutrition);
|
|
registerMethod("ItemType", "getRequiredLevel", LuaScriptInterface::luaItemTypeGetRequiredLevel);
|
|
|
|
registerMethod("ItemType", "hasSubType", LuaScriptInterface::luaItemTypeHasSubType);
|
|
|
|
// Combat
|
|
registerClass("Combat", "", LuaScriptInterface::luaCombatCreate);
|
|
registerMetaMethod("Combat", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Combat", "setParameter", LuaScriptInterface::luaCombatSetParameter);
|
|
registerMethod("Combat", "setFormula", LuaScriptInterface::luaCombatSetFormula);
|
|
|
|
registerMethod("Combat", "setArea", LuaScriptInterface::luaCombatSetArea);
|
|
registerMethod("Combat", "setCondition", LuaScriptInterface::luaCombatSetCondition);
|
|
registerMethod("Combat", "setCallback", LuaScriptInterface::luaCombatSetCallback);
|
|
registerMethod("Combat", "setOrigin", LuaScriptInterface::luaCombatSetOrigin);
|
|
|
|
registerMethod("Combat", "execute", LuaScriptInterface::luaCombatExecute);
|
|
|
|
// Condition
|
|
registerClass("Condition", "", LuaScriptInterface::luaConditionCreate);
|
|
registerMetaMethod("Condition", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
registerMetaMethod("Condition", "__gc", LuaScriptInterface::luaConditionDelete);
|
|
registerMethod("Condition", "delete", LuaScriptInterface::luaConditionDelete);
|
|
|
|
registerMethod("Condition", "getId", LuaScriptInterface::luaConditionGetId);
|
|
registerMethod("Condition", "getSubId", LuaScriptInterface::luaConditionGetSubId);
|
|
registerMethod("Condition", "getType", LuaScriptInterface::luaConditionGetType);
|
|
registerMethod("Condition", "getIcons", LuaScriptInterface::luaConditionGetIcons);
|
|
registerMethod("Condition", "getEndTime", LuaScriptInterface::luaConditionGetEndTime);
|
|
|
|
registerMethod("Condition", "clone", LuaScriptInterface::luaConditionClone);
|
|
|
|
registerMethod("Condition", "getTicks", LuaScriptInterface::luaConditionGetTicks);
|
|
registerMethod("Condition", "setTicks", LuaScriptInterface::luaConditionSetTicks);
|
|
|
|
registerMethod("Condition", "setParameter", LuaScriptInterface::luaConditionSetParameter);
|
|
registerMethod("Condition", "setSpeedDelta", LuaScriptInterface::luaConditionSetSpeedDelta);
|
|
registerMethod("Condition", "setOutfit", LuaScriptInterface::luaConditionSetOutfit);
|
|
|
|
registerMethod("Condition", "setTiming", LuaScriptInterface::luaConditionSetTiming);
|
|
|
|
// MonsterType
|
|
registerClass("MonsterType", "", LuaScriptInterface::luaMonsterTypeCreate);
|
|
registerMetaMethod("MonsterType", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("MonsterType", "isAttackable", LuaScriptInterface::luaMonsterTypeIsAttackable);
|
|
registerMethod("MonsterType", "isConvinceable", LuaScriptInterface::luaMonsterTypeIsConvinceable);
|
|
registerMethod("MonsterType", "isSummonable", LuaScriptInterface::luaMonsterTypeIsSummonable);
|
|
registerMethod("MonsterType", "isIllusionable", LuaScriptInterface::luaMonsterTypeIsIllusionable);
|
|
registerMethod("MonsterType", "isHostile", LuaScriptInterface::luaMonsterTypeIsHostile);
|
|
registerMethod("MonsterType", "isPushable", LuaScriptInterface::luaMonsterTypeIsPushable);
|
|
registerMethod("MonsterType", "isHealthShown", LuaScriptInterface::luaMonsterTypeIsHealthShown);
|
|
|
|
registerMethod("MonsterType", "canPushItems", LuaScriptInterface::luaMonsterTypeCanPushItems);
|
|
registerMethod("MonsterType", "canPushCreatures", LuaScriptInterface::luaMonsterTypeCanPushCreatures);
|
|
|
|
registerMethod("MonsterType", "getName", LuaScriptInterface::luaMonsterTypeGetName);
|
|
registerMethod("MonsterType", "getNameDescription", LuaScriptInterface::luaMonsterTypeGetNameDescription);
|
|
|
|
registerMethod("MonsterType", "getHealth", LuaScriptInterface::luaMonsterTypeGetHealth);
|
|
registerMethod("MonsterType", "getMaxHealth", LuaScriptInterface::luaMonsterTypeGetMaxHealth);
|
|
registerMethod("MonsterType", "getRunHealth", LuaScriptInterface::luaMonsterTypeGetRunHealth);
|
|
registerMethod("MonsterType", "getExperience", LuaScriptInterface::luaMonsterTypeGetExperience);
|
|
|
|
registerMethod("MonsterType", "getCombatImmunities", LuaScriptInterface::luaMonsterTypeGetCombatImmunities);
|
|
registerMethod("MonsterType", "getConditionImmunities", LuaScriptInterface::luaMonsterTypeGetConditionImmunities);
|
|
|
|
registerMethod("MonsterType", "getAttackList", LuaScriptInterface::luaMonsterTypeGetAttackList);
|
|
registerMethod("MonsterType", "getDefenseList", LuaScriptInterface::luaMonsterTypeGetDefenseList);
|
|
registerMethod("MonsterType", "getElementList", LuaScriptInterface::luaMonsterTypeGetElementList);
|
|
|
|
registerMethod("MonsterType", "getVoices", LuaScriptInterface::luaMonsterTypeGetVoices);
|
|
registerMethod("MonsterType", "getLoot", LuaScriptInterface::luaMonsterTypeGetLoot);
|
|
registerMethod("MonsterType", "getCreatureEvents", LuaScriptInterface::luaMonsterTypeGetCreatureEvents);
|
|
|
|
registerMethod("MonsterType", "getSummonList", LuaScriptInterface::luaMonsterTypeGetSummonList);
|
|
registerMethod("MonsterType", "getMaxSummons", LuaScriptInterface::luaMonsterTypeGetMaxSummons);
|
|
|
|
registerMethod("MonsterType", "getArmor", LuaScriptInterface::luaMonsterTypeGetArmor);
|
|
registerMethod("MonsterType", "getDefense", LuaScriptInterface::luaMonsterTypeGetDefense);
|
|
registerMethod("MonsterType", "getOutfit", LuaScriptInterface::luaMonsterTypeGetOutfit);
|
|
registerMethod("MonsterType", "getRace", LuaScriptInterface::luaMonsterTypeGetRace);
|
|
registerMethod("MonsterType", "getCorpseId", LuaScriptInterface::luaMonsterTypeGetCorpseId);
|
|
registerMethod("MonsterType", "getManaCost", LuaScriptInterface::luaMonsterTypeGetManaCost);
|
|
registerMethod("MonsterType", "getBaseSpeed", LuaScriptInterface::luaMonsterTypeGetBaseSpeed);
|
|
registerMethod("MonsterType", "getLight", LuaScriptInterface::luaMonsterTypeGetLight);
|
|
|
|
registerMethod("MonsterType", "getTargetDistance", LuaScriptInterface::luaMonsterTypeGetTargetDistance);
|
|
registerMethod("MonsterType", "getChangeTargetChance", LuaScriptInterface::luaMonsterTypeGetChangeTargetChance);
|
|
registerMethod("MonsterType", "getChangeTargetSpeed", LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed);
|
|
|
|
// Party
|
|
registerClass("Party", "", nullptr);
|
|
registerMetaMethod("Party", "__eq", LuaScriptInterface::luaUserdataCompare);
|
|
|
|
registerMethod("Party", "disband", LuaScriptInterface::luaPartyDisband);
|
|
|
|
registerMethod("Party", "getLeader", LuaScriptInterface::luaPartyGetLeader);
|
|
registerMethod("Party", "setLeader", LuaScriptInterface::luaPartySetLeader);
|
|
|
|
registerMethod("Party", "getMembers", LuaScriptInterface::luaPartyGetMembers);
|
|
registerMethod("Party", "getMemberCount", LuaScriptInterface::luaPartyGetMemberCount);
|
|
|
|
registerMethod("Party", "getInvitees", LuaScriptInterface::luaPartyGetInvitees);
|
|
registerMethod("Party", "getInviteeCount", LuaScriptInterface::luaPartyGetInviteeCount);
|
|
|
|
registerMethod("Party", "addInvite", LuaScriptInterface::luaPartyAddInvite);
|
|
registerMethod("Party", "removeInvite", LuaScriptInterface::luaPartyRemoveInvite);
|
|
|
|
registerMethod("Party", "addMember", LuaScriptInterface::luaPartyAddMember);
|
|
registerMethod("Party", "removeMember", LuaScriptInterface::luaPartyRemoveMember);
|
|
|
|
registerMethod("Party", "isSharedExperienceActive", LuaScriptInterface::luaPartyIsSharedExperienceActive);
|
|
registerMethod("Party", "isSharedExperienceEnabled", LuaScriptInterface::luaPartyIsSharedExperienceEnabled);
|
|
registerMethod("Party", "shareExperience", LuaScriptInterface::luaPartyShareExperience);
|
|
registerMethod("Party", "setSharedExperience", LuaScriptInterface::luaPartySetSharedExperience);
|
|
}
|
|
|
|
#undef registerEnum
|
|
#undef registerEnumIn
|
|
|
|
void LuaScriptInterface::registerClass(const std::string& className, const std::string& baseClass, lua_CFunction newFunction/* = nullptr*/)
|
|
{
|
|
// className = {}
|
|
lua_newtable(luaState);
|
|
lua_pushvalue(luaState, -1);
|
|
lua_setglobal(luaState, className.c_str());
|
|
int methods = lua_gettop(luaState);
|
|
|
|
// methodsTable = {}
|
|
lua_newtable(luaState);
|
|
int methodsTable = lua_gettop(luaState);
|
|
|
|
if (newFunction) {
|
|
// className.__call = newFunction
|
|
lua_pushcfunction(luaState, newFunction);
|
|
lua_setfield(luaState, methodsTable, "__call");
|
|
}
|
|
|
|
uint32_t parents = 0;
|
|
if (!baseClass.empty()) {
|
|
lua_getglobal(luaState, baseClass.c_str());
|
|
lua_rawgeti(luaState, -1, 'p');
|
|
parents = getNumber<uint32_t>(luaState, -1) + 1;
|
|
lua_pop(luaState, 1);
|
|
lua_setfield(luaState, methodsTable, "__index");
|
|
}
|
|
|
|
// setmetatable(className, methodsTable)
|
|
lua_setmetatable(luaState, methods);
|
|
|
|
// className.metatable = {}
|
|
luaL_newmetatable(luaState, className.c_str());
|
|
int metatable = lua_gettop(luaState);
|
|
|
|
// className.metatable.__metatable = className
|
|
lua_pushvalue(luaState, methods);
|
|
lua_setfield(luaState, metatable, "__metatable");
|
|
|
|
// className.metatable.__index = className
|
|
lua_pushvalue(luaState, methods);
|
|
lua_setfield(luaState, metatable, "__index");
|
|
|
|
// className.metatable['h'] = hash
|
|
lua_pushnumber(luaState, std::hash<std::string>()(className));
|
|
lua_rawseti(luaState, metatable, 'h');
|
|
|
|
// className.metatable['p'] = parents
|
|
lua_pushnumber(luaState, parents);
|
|
lua_rawseti(luaState, metatable, 'p');
|
|
|
|
// className.metatable['t'] = type
|
|
if (className == "Item") {
|
|
lua_pushnumber(luaState, LuaData_Item);
|
|
} else if (className == "Container") {
|
|
lua_pushnumber(luaState, LuaData_Container);
|
|
} else if (className == "Teleport") {
|
|
lua_pushnumber(luaState, LuaData_Teleport);
|
|
} else if (className == "Player") {
|
|
lua_pushnumber(luaState, LuaData_Player);
|
|
} else if (className == "Monster") {
|
|
lua_pushnumber(luaState, LuaData_Monster);
|
|
} else if (className == "Npc") {
|
|
lua_pushnumber(luaState, LuaData_Npc);
|
|
} else if (className == "Tile") {
|
|
lua_pushnumber(luaState, LuaData_Tile);
|
|
} else {
|
|
lua_pushnumber(luaState, LuaData_Unknown);
|
|
}
|
|
lua_rawseti(luaState, metatable, 't');
|
|
|
|
// pop className, className.metatable
|
|
lua_pop(luaState, 2);
|
|
}
|
|
|
|
void LuaScriptInterface::registerTable(const std::string& tableName)
|
|
{
|
|
// _G[tableName] = {}
|
|
lua_newtable(luaState);
|
|
lua_setglobal(luaState, tableName.c_str());
|
|
}
|
|
|
|
void LuaScriptInterface::registerMethod(const std::string& globalName, const std::string& methodName, lua_CFunction func)
|
|
{
|
|
// globalName.methodName = func
|
|
lua_getglobal(luaState, globalName.c_str());
|
|
lua_pushcfunction(luaState, func);
|
|
lua_setfield(luaState, -2, methodName.c_str());
|
|
|
|
// pop globalName
|
|
lua_pop(luaState, 1);
|
|
}
|
|
|
|
void LuaScriptInterface::registerMetaMethod(const std::string& className, const std::string& methodName, lua_CFunction func)
|
|
{
|
|
// className.metatable.methodName = func
|
|
luaL_getmetatable(luaState, className.c_str());
|
|
lua_pushcfunction(luaState, func);
|
|
lua_setfield(luaState, -2, methodName.c_str());
|
|
|
|
// pop className.metatable
|
|
lua_pop(luaState, 1);
|
|
}
|
|
|
|
void LuaScriptInterface::registerGlobalMethod(const std::string& functionName, lua_CFunction func)
|
|
{
|
|
// _G[functionName] = func
|
|
lua_pushcfunction(luaState, func);
|
|
lua_setglobal(luaState, functionName.c_str());
|
|
}
|
|
|
|
void LuaScriptInterface::registerVariable(const std::string& tableName, const std::string& name, lua_Number value)
|
|
{
|
|
// tableName.name = value
|
|
lua_getglobal(luaState, tableName.c_str());
|
|
setField(luaState, name.c_str(), value);
|
|
|
|
// pop tableName
|
|
lua_pop(luaState, 1);
|
|
}
|
|
|
|
void LuaScriptInterface::registerGlobalVariable(const std::string& name, lua_Number value)
|
|
{
|
|
// _G[name] = value
|
|
lua_pushnumber(luaState, value);
|
|
lua_setglobal(luaState, name.c_str());
|
|
}
|
|
|
|
void LuaScriptInterface::registerGlobalBoolean(const std::string& name, bool value)
|
|
{
|
|
// _G[name] = value
|
|
pushBoolean(luaState, value);
|
|
lua_setglobal(luaState, name.c_str());
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetPlayerFlagValue(lua_State* L)
|
|
{
|
|
//getPlayerFlagValue(cid, flag)
|
|
Player* player = getPlayer(L, 1);
|
|
if (player) {
|
|
PlayerFlags flag = getNumber<PlayerFlags>(L, 2);
|
|
pushBoolean(L, player->hasFlag(flag));
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetPlayerInstantSpellCount(lua_State* L)
|
|
{
|
|
//getPlayerInstantSpellCount(cid)
|
|
Player* player = getPlayer(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, g_spells->getInstantSpellCount(player));
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetPlayerInstantSpellInfo(lua_State* L)
|
|
{
|
|
//getPlayerInstantSpellInfo(cid, index)
|
|
Player* player = getPlayer(L, 1);
|
|
if (!player) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t index = getNumber<uint32_t>(L, 2);
|
|
InstantSpell* spell = g_spells->getInstantSpellByIndex(player, index);
|
|
if (!spell) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_SPELL_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, 0, 6);
|
|
setField(L, "name", spell->getName());
|
|
setField(L, "words", spell->getWords());
|
|
setField(L, "level", spell->getLevel());
|
|
setField(L, "mlevel", spell->getMagicLevel());
|
|
setField(L, "mana", spell->getManaCost(player));
|
|
setField(L, "manapercent", spell->getManaPercent());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
|
|
{
|
|
//doPlayerAddItem(cid, itemid, <optional: default: 1> count/subtype, <optional: default: 1> canDropOnMap)
|
|
//doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
|
|
Player* player = getPlayer(L, 1);
|
|
if (!player) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId = getNumber<uint16_t>(L, 2);
|
|
int32_t count = getNumber<int32_t>(L, 3, 1);
|
|
bool canDropOnMap = getBoolean(L, 4, true);
|
|
uint16_t subType = getNumber<uint16_t>(L, 5, 1);
|
|
|
|
const ItemType& it = Item::items[itemId];
|
|
int32_t itemCount;
|
|
|
|
auto parameters = lua_gettop(L);
|
|
if (parameters > 4) {
|
|
//subtype already supplied, count then is the amount
|
|
itemCount = std::max<int32_t>(1, count);
|
|
} else if (it.hasSubType()) {
|
|
if (it.stackable) {
|
|
itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
|
|
} else {
|
|
itemCount = 1;
|
|
}
|
|
subType = count;
|
|
} else {
|
|
itemCount = std::max<int32_t>(1, count);
|
|
}
|
|
|
|
while (itemCount > 0) {
|
|
uint16_t stackCount = subType;
|
|
if (it.stackable && stackCount > 100) {
|
|
stackCount = 100;
|
|
}
|
|
|
|
Item* newItem = Item::CreateItem(itemId, stackCount);
|
|
if (!newItem) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (it.stackable) {
|
|
subType -= stackCount;
|
|
}
|
|
|
|
ReturnValue ret = g_game.internalPlayerAddItem(player, newItem, canDropOnMap);
|
|
if (ret != RETURNVALUE_NOERROR) {
|
|
delete newItem;
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (--itemCount == 0) {
|
|
if (newItem->getParent()) {
|
|
uint32_t uid = getScriptEnv()->addThing(newItem);
|
|
lua_pushnumber(L, uid);
|
|
return 1;
|
|
} else {
|
|
//stackable item stacked with existing object, newItem will be released
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoTileAddItemEx(lua_State* L)
|
|
{
|
|
//doTileAddItemEx(pos, uid)
|
|
const Position& pos = getPosition(L, 1);
|
|
|
|
Tile* tile = g_game.map.getTile(pos);
|
|
if (!tile) {
|
|
std::ostringstream ss;
|
|
ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
|
|
reportErrorFunc(ss.str());
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t uid = getNumber<uint32_t>(L, 2);
|
|
Item* item = getScriptEnv()->getItemByUID(uid);
|
|
if (!item) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (item->getParent() != VirtualCylinder::virtualCylinder) {
|
|
reportErrorFunc("Item already has a parent");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, g_game.internalAddItem(tile, item));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoCreateItem(lua_State* L)
|
|
{
|
|
//doCreateItem(itemid, <optional> type/count, pos)
|
|
//Returns uid of the created item, only works on tiles.
|
|
const Position& pos = getPosition(L, 3);
|
|
Tile* tile = g_game.map.getTile(pos);
|
|
if (!tile) {
|
|
std::ostringstream ss;
|
|
ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
|
|
reportErrorFunc(ss.str());
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
|
|
int32_t itemCount = 1;
|
|
int32_t subType = 1;
|
|
|
|
uint16_t itemId = getNumber<uint16_t>(L, 1);
|
|
uint32_t count = getNumber<uint32_t>(L, 2, 1);
|
|
|
|
const ItemType& it = Item::items[itemId];
|
|
if (it.hasSubType()) {
|
|
if (it.stackable) {
|
|
itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
|
|
}
|
|
|
|
subType = count;
|
|
} else {
|
|
itemCount = std::max<int32_t>(1, count);
|
|
}
|
|
|
|
while (itemCount > 0) {
|
|
int32_t stackCount = std::min<int32_t>(100, subType);
|
|
Item* newItem = Item::CreateItem(itemId, stackCount);
|
|
if (!newItem) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (it.stackable) {
|
|
subType -= stackCount;
|
|
}
|
|
|
|
ReturnValue ret = g_game.internalAddItem(tile, newItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
|
|
if (ret != RETURNVALUE_NOERROR) {
|
|
delete newItem;
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (--itemCount == 0) {
|
|
if (newItem->getParent()) {
|
|
uint32_t uid = env->addThing(newItem);
|
|
lua_pushnumber(L, uid);
|
|
return 1;
|
|
} else {
|
|
//stackable item stacked with existing object, newItem will be released
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoCreateItemEx(lua_State* L)
|
|
{
|
|
//doCreateItemEx(itemid, <optional> count/subtype)
|
|
//Returns uid of the created item
|
|
uint16_t itemId = getNumber<uint16_t>(L, 1);
|
|
uint32_t count = getNumber<uint32_t>(L, 2, 1);
|
|
|
|
const ItemType& it = Item::items[itemId];
|
|
if (it.stackable && count > 100) {
|
|
reportErrorFunc("Stack count cannot be higher than 100.");
|
|
count = 100;
|
|
}
|
|
|
|
Item* newItem = Item::CreateItem(itemId, count);
|
|
if (!newItem) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
newItem->setParent(VirtualCylinder::virtualCylinder);
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
env->addTempItem(newItem);
|
|
|
|
uint32_t uid = env->addThing(newItem);
|
|
lua_pushnumber(L, uid);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDebugPrint(lua_State* L)
|
|
{
|
|
//debugPrint(text)
|
|
reportErrorFunc(getString(L, -1));
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetWorldTime(lua_State* L)
|
|
{
|
|
//getWorldTime()
|
|
uint32_t time = g_game.getLightHour();
|
|
lua_pushnumber(L, time);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetWorldLight(lua_State* L)
|
|
{
|
|
//getWorldLight()
|
|
LightInfo lightInfo = g_game.getWorldLightInfo();
|
|
lua_pushnumber(L, lightInfo.level);
|
|
lua_pushnumber(L, lightInfo.color);
|
|
return 2;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetWorldUpTime(lua_State* L)
|
|
{
|
|
//getWorldUpTime()
|
|
uint64_t uptime = (OTSYS_TIME() - ProtocolStatus::start) / 1000;
|
|
lua_pushnumber(L, uptime);
|
|
return 1;
|
|
}
|
|
|
|
bool LuaScriptInterface::getArea(lua_State* L, std::list<uint32_t>& list, uint32_t& rows)
|
|
{
|
|
lua_pushnil(L);
|
|
for (rows = 0; lua_next(L, -2) != 0; ++rows) {
|
|
if (!isTable(L, -1)) {
|
|
return false;
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, -2) != 0) {
|
|
if (!isNumber(L, -1)) {
|
|
return false;
|
|
}
|
|
list.push_back(getNumber<uint32_t>(L, -1));
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
return (rows != 0);
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreateCombatArea(lua_State* L)
|
|
{
|
|
//createCombatArea( {area}, <optional> {extArea} )
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
if (env->getScriptId() != EVENT_ID_LOADING) {
|
|
reportErrorFunc("This function can only be used while loading the script.");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t areaId = g_luaEnvironment.createAreaObject(env->getScriptInterface());
|
|
AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
|
|
|
|
int parameters = lua_gettop(L);
|
|
if (parameters >= 2) {
|
|
uint32_t rowsExtArea;
|
|
std::list<uint32_t> listExtArea;
|
|
if (!isTable(L, 2) || !getArea(L, listExtArea, rowsExtArea)) {
|
|
reportErrorFunc("Invalid extended area table.");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
area->setupExtArea(listExtArea, rowsExtArea);
|
|
}
|
|
|
|
uint32_t rowsArea = 0;
|
|
std::list<uint32_t> listArea;
|
|
if (!isTable(L, 1) || !getArea(L, listArea, rowsArea)) {
|
|
reportErrorFunc("Invalid area table.");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
area->setupArea(listArea, rowsArea);
|
|
lua_pushnumber(L, areaId);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoAreaCombatHealth(lua_State* L)
|
|
{
|
|
//doAreaCombatHealth(cid, type, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t areaId = getNumber<uint32_t>(L, 4);
|
|
const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
|
|
if (area || areaId == 0) {
|
|
CombatType_t combatType = getNumber<CombatType_t>(L, 2);
|
|
|
|
CombatParams params;
|
|
params.combatType = combatType;
|
|
params.impactEffect = getNumber<uint8_t>(L, 7);
|
|
|
|
CombatDamage damage;
|
|
damage.origin = getNumber<CombatOrigin>(L, 8, ORIGIN_SPELL);
|
|
damage.type = combatType;
|
|
damage.value = normal_random(getNumber<int32_t>(L, 6), getNumber<int32_t>(L, 5));
|
|
|
|
Combat::doCombatHealth(creature, getPosition(L, 3), area, damage, params);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoTargetCombatHealth(lua_State* L)
|
|
{
|
|
//doTargetCombatHealth(cid, target, type, min, max, effect[, origin = ORIGIN_SPELL])
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = getCreature(L, 2);
|
|
if (!target) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
CombatType_t combatType = getNumber<CombatType_t>(L, 3);
|
|
|
|
CombatParams params;
|
|
params.combatType = combatType;
|
|
params.impactEffect = getNumber<uint8_t>(L, 6);
|
|
|
|
CombatDamage damage;
|
|
damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
|
|
damage.type = combatType;
|
|
damage.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
|
|
|
|
Combat::doCombatHealth(creature, target, damage, params);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoAreaCombatMana(lua_State* L)
|
|
{
|
|
//doAreaCombatMana(cid, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t areaId = getNumber<uint32_t>(L, 3);
|
|
const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
|
|
if (area || areaId == 0) {
|
|
CombatParams params;
|
|
params.impactEffect = getNumber<uint8_t>(L, 6);
|
|
|
|
CombatDamage damage;
|
|
damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
|
|
damage.type = COMBAT_MANADRAIN;
|
|
damage.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
|
|
|
|
Position pos = getPosition(L, 2);
|
|
Combat::doCombatMana(creature, pos, area, damage, params);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoTargetCombatMana(lua_State* L)
|
|
{
|
|
//doTargetCombatMana(cid, target, min, max, effect[, origin = ORIGIN_SPELL)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = getCreature(L, 2);
|
|
if (!target) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
CombatParams params;
|
|
params.impactEffect = getNumber<uint8_t>(L, 5);
|
|
|
|
CombatDamage damage;
|
|
damage.origin = getNumber<CombatOrigin>(L, 6, ORIGIN_SPELL);
|
|
damage.type = COMBAT_MANADRAIN;
|
|
damage.value = normal_random(getNumber<int32_t>(L, 3), getNumber<int32_t>(L, 4));
|
|
|
|
Combat::doCombatMana(creature, target, damage, params);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoAreaCombatCondition(lua_State* L)
|
|
{
|
|
//doAreaCombatCondition(cid, pos, area, condition, effect)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
const Condition* condition = getUserdata<Condition>(L, 4);
|
|
if (!condition) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t areaId = getNumber<uint32_t>(L, 3);
|
|
const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
|
|
if (area || areaId == 0) {
|
|
CombatParams params;
|
|
params.impactEffect = getNumber<uint8_t>(L, 5);
|
|
params.conditionList.emplace_front(condition);
|
|
Combat::doCombatCondition(creature, getPosition(L, 2), area, params);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoTargetCombatCondition(lua_State* L)
|
|
{
|
|
//doTargetCombatCondition(cid, target, condition, effect)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = getCreature(L, 2);
|
|
if (!target) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
const Condition* condition = getUserdata<Condition>(L, 3);
|
|
if (!condition) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
CombatParams params;
|
|
params.impactEffect = getNumber<uint8_t>(L, 4);
|
|
params.conditionList.emplace_front(condition);
|
|
Combat::doCombatCondition(creature, target, params);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoAreaCombatDispel(lua_State* L)
|
|
{
|
|
//doAreaCombatDispel(cid, pos, area, type, effect)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t areaId = getNumber<uint32_t>(L, 3);
|
|
const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
|
|
if (area || areaId == 0) {
|
|
CombatParams params;
|
|
params.impactEffect = getNumber<uint8_t>(L, 5);
|
|
params.dispelType = getNumber<ConditionType_t>(L, 4);
|
|
Combat::doCombatDispel(creature, getPosition(L, 2), area, params);
|
|
|
|
pushBoolean(L, true);
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoTargetCombatDispel(lua_State* L)
|
|
{
|
|
//doTargetCombatDispel(cid, target, type, effect)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = getCreature(L, 2);
|
|
if (!target) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
CombatParams params;
|
|
params.dispelType = getNumber<ConditionType_t>(L, 3);
|
|
params.impactEffect = getNumber<uint8_t>(L, 4);
|
|
Combat::doCombatDispel(creature, target, params);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoChallengeCreature(lua_State* L)
|
|
{
|
|
//doChallengeCreature(cid, target)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = getCreature(L, 2);
|
|
if (!target) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
target->challengeCreature(creature);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaSetCreatureOutfit(lua_State* L)
|
|
{
|
|
//doSetCreatureOutfit(cid, outfit, time)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Outfit_t outfit = getOutfit(L, 2);
|
|
int32_t time = getNumber<int32_t>(L, 3);
|
|
pushBoolean(L, Spell::CreateIllusion(creature, outfit, time) == RETURNVALUE_NOERROR);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaSetMonsterOutfit(lua_State* L)
|
|
{
|
|
//doSetMonsterOutfit(cid, name, time)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
std::string name = getString(L, 2);
|
|
int32_t time = getNumber<int32_t>(L, 3);
|
|
pushBoolean(L, Spell::CreateIllusion(creature, name, time) == RETURNVALUE_NOERROR);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaSetItemOutfit(lua_State* L)
|
|
{
|
|
//doSetItemOutfit(cid, item, time)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t item = getNumber<uint32_t>(L, 2);
|
|
int32_t time = getNumber<int32_t>(L, 3);
|
|
pushBoolean(L, Spell::CreateIllusion(creature, item, time) == RETURNVALUE_NOERROR);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoMoveCreature(lua_State* L)
|
|
{
|
|
//doMoveCreature(cid, direction)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Direction direction = getNumber<Direction>(L, 2);
|
|
if (direction > DIRECTION_LAST) {
|
|
reportErrorFunc("No valid direction");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
ReturnValue ret = g_game.internalMoveCreature(creature, direction, FLAG_NOLIMIT);
|
|
lua_pushnumber(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaIsValidUID(lua_State* L)
|
|
{
|
|
//isValidUID(uid)
|
|
pushBoolean(L, getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1)) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaIsDepot(lua_State* L)
|
|
{
|
|
//isDepot(uid)
|
|
Container* container = getScriptEnv()->getContainerByUID(getNumber<uint32_t>(L, -1));
|
|
pushBoolean(L, container && container->getDepotLocker());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaIsMoveable(lua_State* L)
|
|
{
|
|
//isMoveable(uid)
|
|
//isMovable(uid)
|
|
Thing* thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1));
|
|
pushBoolean(L, thing && thing->isPushable());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoAddContainerItem(lua_State* L)
|
|
{
|
|
//doAddContainerItem(uid, itemid, <optional> count/subtype)
|
|
uint32_t uid = getNumber<uint32_t>(L, 1);
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
Container* container = env->getContainerByUID(uid);
|
|
if (!container) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId = getNumber<uint16_t>(L, 2);
|
|
const ItemType& it = Item::items[itemId];
|
|
|
|
int32_t itemCount = 1;
|
|
int32_t subType = 1;
|
|
uint32_t count = getNumber<uint32_t>(L, 3, 1);
|
|
|
|
if (it.hasSubType()) {
|
|
if (it.stackable) {
|
|
itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
|
|
}
|
|
|
|
subType = count;
|
|
} else {
|
|
itemCount = std::max<int32_t>(1, count);
|
|
}
|
|
|
|
while (itemCount > 0) {
|
|
int32_t stackCount = std::min<int32_t>(100, subType);
|
|
Item* newItem = Item::CreateItem(itemId, stackCount);
|
|
if (!newItem) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (it.stackable) {
|
|
subType -= stackCount;
|
|
}
|
|
|
|
ReturnValue ret = g_game.internalAddItem(container, newItem);
|
|
if (ret != RETURNVALUE_NOERROR) {
|
|
delete newItem;
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (--itemCount == 0) {
|
|
if (newItem->getParent()) {
|
|
lua_pushnumber(L, env->addThing(newItem));
|
|
} else {
|
|
//stackable item stacked with existing object, newItem will be released
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetDepotId(lua_State* L)
|
|
{
|
|
//getDepotId(uid)
|
|
uint32_t uid = getNumber<uint32_t>(L, -1);
|
|
|
|
Container* container = getScriptEnv()->getContainerByUID(uid);
|
|
if (!container) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
DepotLocker* depotLocker = container->getDepotLocker();
|
|
if (!depotLocker) {
|
|
reportErrorFunc("Depot not found");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, depotLocker->getDepotId());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaIsInArray(lua_State* L)
|
|
{
|
|
//isInArray(array, value)
|
|
if (!isTable(L, 1)) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, 1)) {
|
|
if (lua_equal(L, 2, -1) != 0) {
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDoSetCreatureLight(lua_State* L)
|
|
{
|
|
//doSetCreatureLight(cid, lightLevel, lightColor, time)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t level = getNumber<uint16_t>(L, 2);
|
|
uint16_t color = getNumber<uint16_t>(L, 3);
|
|
uint32_t time = getNumber<uint32_t>(L, 4);
|
|
Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8));
|
|
creature->addCondition(condition);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaAddEvent(lua_State* L)
|
|
{
|
|
//addEvent(callback, delay, ...)
|
|
lua_State* globalState = g_luaEnvironment.getLuaState();
|
|
if (!globalState) {
|
|
reportErrorFunc("No valid script interface!");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
} else if (globalState != L) {
|
|
lua_xmove(L, globalState, lua_gettop(L));
|
|
}
|
|
|
|
int parameters = lua_gettop(globalState);
|
|
if (!isFunction(globalState, -parameters)) { //-parameters means the first parameter from left to right
|
|
reportErrorFunc("callback parameter should be a function.");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS) || g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
|
|
std::vector<std::pair<int32_t, LuaDataType>> indexes;
|
|
for (int i = 3; i <= parameters; ++i) {
|
|
if (lua_getmetatable(globalState, i) == 0) {
|
|
continue;
|
|
}
|
|
lua_rawgeti(L, -1, 't');
|
|
|
|
LuaDataType type = getNumber<LuaDataType>(L, -1);
|
|
if (type != LuaData_Unknown && type != LuaData_Tile) {
|
|
indexes.push_back({i, type});
|
|
}
|
|
lua_pop(globalState, 2);
|
|
}
|
|
|
|
if (!indexes.empty()) {
|
|
if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS)) {
|
|
bool plural = indexes.size() > 1;
|
|
|
|
std::string warningString = "Argument";
|
|
if (plural) {
|
|
warningString += 's';
|
|
}
|
|
|
|
for (const auto& entry : indexes) {
|
|
if (entry == indexes.front()) {
|
|
warningString += ' ';
|
|
} else if (entry == indexes.back()) {
|
|
warningString += " and ";
|
|
} else {
|
|
warningString += ", ";
|
|
}
|
|
warningString += '#';
|
|
warningString += std::to_string(entry.first);
|
|
}
|
|
|
|
if (plural) {
|
|
warningString += " are unsafe";
|
|
} else {
|
|
warningString += " is unsafe";
|
|
}
|
|
|
|
reportErrorFunc(warningString);
|
|
}
|
|
|
|
if (g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
|
|
for (const auto& entry : indexes) {
|
|
switch (entry.second) {
|
|
case LuaData_Item:
|
|
case LuaData_Container:
|
|
case LuaData_Teleport: {
|
|
lua_getglobal(globalState, "Item");
|
|
lua_getfield(globalState, -1, "getMovementId");
|
|
break;
|
|
}
|
|
case LuaData_Player:
|
|
case LuaData_Monster:
|
|
case LuaData_Npc: {
|
|
lua_getglobal(globalState, "Creature");
|
|
lua_getfield(globalState, -1, "getId");
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
lua_replace(globalState, -2);
|
|
lua_pushvalue(globalState, entry.first);
|
|
lua_call(globalState, 1, 1);
|
|
lua_replace(globalState, entry.first);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
LuaTimerEventDesc eventDesc;
|
|
for (int i = 0; i < parameters - 2; ++i) { //-2 because addEvent needs at least two parameters
|
|
eventDesc.parameters.push_back(luaL_ref(globalState, LUA_REGISTRYINDEX));
|
|
}
|
|
|
|
uint32_t delay = std::max<uint32_t>(100, getNumber<uint32_t>(globalState, 2));
|
|
lua_pop(globalState, 1);
|
|
|
|
eventDesc.function = luaL_ref(globalState, LUA_REGISTRYINDEX);
|
|
eventDesc.scriptId = getScriptEnv()->getScriptId();
|
|
|
|
auto& lastTimerEventId = g_luaEnvironment.lastEventTimerId;
|
|
eventDesc.eventId = g_scheduler.addEvent(createSchedulerTask(
|
|
delay, std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId)
|
|
));
|
|
|
|
g_luaEnvironment.timerEvents.emplace(lastTimerEventId, std::move(eventDesc));
|
|
lua_pushnumber(L, lastTimerEventId++);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaStopEvent(lua_State* L)
|
|
{
|
|
//stopEvent(eventid)
|
|
lua_State* globalState = g_luaEnvironment.getLuaState();
|
|
if (!globalState) {
|
|
reportErrorFunc("No valid script interface!");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t eventId = getNumber<uint32_t>(L, 1);
|
|
|
|
auto& timerEvents = g_luaEnvironment.timerEvents;
|
|
auto it = timerEvents.find(eventId);
|
|
if (it == timerEvents.end()) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
LuaTimerEventDesc timerEventDesc = std::move(it->second);
|
|
timerEvents.erase(it);
|
|
|
|
g_scheduler.stopEvent(timerEventDesc.eventId);
|
|
luaL_unref(globalState, LUA_REGISTRYINDEX, timerEventDesc.function);
|
|
|
|
for (auto parameter : timerEventDesc.parameters) {
|
|
luaL_unref(globalState, LUA_REGISTRYINDEX, parameter);
|
|
}
|
|
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetCreatureCondition(lua_State* L)
|
|
{
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
ConditionType_t condition = getNumber<ConditionType_t>(L, 2);
|
|
uint32_t subId = getNumber<uint32_t>(L, 3, 0);
|
|
pushBoolean(L, creature->hasCondition(condition, subId));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaSaveServer(lua_State* L)
|
|
{
|
|
g_game.saveGameState();
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCleanMap(lua_State* L)
|
|
{
|
|
lua_pushnumber(L, g_game.map.clean());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaIsInWar(lua_State* L)
|
|
{
|
|
//isInWar(cid, target)
|
|
Player* player = getPlayer(L, 1);
|
|
if (!player) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Player* targetPlayer = getPlayer(L, 2);
|
|
if (!targetPlayer) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
pushBoolean(L, player->isInWar(targetPlayer));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGetWaypointPositionByName(lua_State* L)
|
|
{
|
|
//getWaypointPositionByName(name)
|
|
auto& waypoints = g_game.map.waypoints;
|
|
|
|
auto it = waypoints.find(getString(L, -1));
|
|
if (it != waypoints.end()) {
|
|
pushPosition(L, it->second);
|
|
} else {
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
std::string LuaScriptInterface::escapeString(const std::string& string)
|
|
{
|
|
std::string s = string;
|
|
replaceString(s, "\\", "\\\\");
|
|
replaceString(s, "\"", "\\\"");
|
|
replaceString(s, "'", "\\'");
|
|
replaceString(s, "[[", "\\[[");
|
|
return s;
|
|
}
|
|
|
|
#ifndef LUAJIT_VERSION
|
|
const luaL_Reg LuaScriptInterface::luaBitReg[] = {
|
|
//{"tobit", LuaScriptInterface::luaBitToBit},
|
|
{"bnot", LuaScriptInterface::luaBitNot},
|
|
{"band", LuaScriptInterface::luaBitAnd},
|
|
{"bor", LuaScriptInterface::luaBitOr},
|
|
{"bxor", LuaScriptInterface::luaBitXor},
|
|
{"lshift", LuaScriptInterface::luaBitLeftShift},
|
|
{"rshift", LuaScriptInterface::luaBitRightShift},
|
|
//{"arshift", LuaScriptInterface::luaBitArithmeticalRightShift},
|
|
//{"rol", LuaScriptInterface::luaBitRotateLeft},
|
|
//{"ror", LuaScriptInterface::luaBitRotateRight},
|
|
//{"bswap", LuaScriptInterface::luaBitSwapEndian},
|
|
//{"tohex", LuaScriptInterface::luaBitToHex},
|
|
{nullptr, nullptr}
|
|
};
|
|
|
|
int LuaScriptInterface::luaBitNot(lua_State* L)
|
|
{
|
|
lua_pushnumber(L, ~getNumber<uint32_t>(L, -1));
|
|
return 1;
|
|
}
|
|
|
|
#define MULTIOP(name, op) \
|
|
int LuaScriptInterface::luaBit##name(lua_State* L) \
|
|
{ \
|
|
int n = lua_gettop(L); \
|
|
uint32_t w = getNumber<uint32_t>(L, -1); \
|
|
for (int i = 1; i < n; ++i) \
|
|
w op getNumber<uint32_t>(L, i); \
|
|
lua_pushnumber(L, w); \
|
|
return 1; \
|
|
}
|
|
|
|
MULTIOP(And, &= )
|
|
MULTIOP(Or, |= )
|
|
MULTIOP(Xor, ^= )
|
|
|
|
#define SHIFTOP(name, op) \
|
|
int LuaScriptInterface::luaBit##name(lua_State* L) \
|
|
{ \
|
|
uint32_t n1 = getNumber<uint32_t>(L, 1), n2 = getNumber<uint32_t>(L, 2); \
|
|
lua_pushnumber(L, (n1 op n2)); \
|
|
return 1; \
|
|
}
|
|
|
|
SHIFTOP(LeftShift, << )
|
|
SHIFTOP(RightShift, >> )
|
|
#endif
|
|
|
|
const luaL_Reg LuaScriptInterface::luaConfigManagerTable[] = {
|
|
{"getString", LuaScriptInterface::luaConfigManagerGetString},
|
|
{"getNumber", LuaScriptInterface::luaConfigManagerGetNumber},
|
|
{"getBoolean", LuaScriptInterface::luaConfigManagerGetBoolean},
|
|
{nullptr, nullptr}
|
|
};
|
|
|
|
int LuaScriptInterface::luaConfigManagerGetString(lua_State* L)
|
|
{
|
|
pushString(L, g_config.getString(getNumber<ConfigManager::string_config_t>(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConfigManagerGetNumber(lua_State* L)
|
|
{
|
|
lua_pushnumber(L, g_config.getNumber(getNumber<ConfigManager::integer_config_t>(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConfigManagerGetBoolean(lua_State* L)
|
|
{
|
|
pushBoolean(L, g_config.getBoolean(getNumber<ConfigManager::boolean_config_t>(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
const luaL_Reg LuaScriptInterface::luaDatabaseTable[] = {
|
|
{"query", LuaScriptInterface::luaDatabaseExecute},
|
|
{"asyncQuery", LuaScriptInterface::luaDatabaseAsyncExecute},
|
|
{"storeQuery", LuaScriptInterface::luaDatabaseStoreQuery},
|
|
{"asyncStoreQuery", LuaScriptInterface::luaDatabaseAsyncStoreQuery},
|
|
{"escapeString", LuaScriptInterface::luaDatabaseEscapeString},
|
|
{"escapeBlob", LuaScriptInterface::luaDatabaseEscapeBlob},
|
|
{"lastInsertId", LuaScriptInterface::luaDatabaseLastInsertId},
|
|
{"tableExists", LuaScriptInterface::luaDatabaseTableExists},
|
|
{nullptr, nullptr}
|
|
};
|
|
|
|
int LuaScriptInterface::luaDatabaseExecute(lua_State* L)
|
|
{
|
|
pushBoolean(L, Database::getInstance()->executeQuery(getString(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseAsyncExecute(lua_State* L)
|
|
{
|
|
std::function<void(DBResult_ptr, bool)> callback;
|
|
if (lua_gettop(L) > 1) {
|
|
int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
auto scriptId = getScriptEnv()->getScriptId();
|
|
callback = [ref, scriptId](DBResult_ptr, bool success) {
|
|
lua_State* luaState = g_luaEnvironment.getLuaState();
|
|
if (!luaState) {
|
|
return;
|
|
}
|
|
|
|
if (!LuaScriptInterface::reserveScriptEnv()) {
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
|
|
return;
|
|
}
|
|
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
|
|
pushBoolean(luaState, success);
|
|
auto env = getScriptEnv();
|
|
env->setScriptId(scriptId, &g_luaEnvironment);
|
|
g_luaEnvironment.callFunction(1);
|
|
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
|
|
};
|
|
}
|
|
g_databaseTasks.addTask(getString(L, -1), callback);
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseStoreQuery(lua_State* L)
|
|
{
|
|
if (DBResult_ptr res = Database::getInstance()->storeQuery(getString(L, -1))) {
|
|
lua_pushnumber(L, ScriptEnvironment::addResult(res));
|
|
} else {
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseAsyncStoreQuery(lua_State* L)
|
|
{
|
|
std::function<void(DBResult_ptr, bool)> callback;
|
|
if (lua_gettop(L) > 1) {
|
|
int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
auto scriptId = getScriptEnv()->getScriptId();
|
|
callback = [ref, scriptId](DBResult_ptr result, bool) {
|
|
lua_State* luaState = g_luaEnvironment.getLuaState();
|
|
if (!luaState) {
|
|
return;
|
|
}
|
|
|
|
if (!LuaScriptInterface::reserveScriptEnv()) {
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
|
|
return;
|
|
}
|
|
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
|
|
if (result) {
|
|
lua_pushnumber(luaState, ScriptEnvironment::addResult(result));
|
|
} else {
|
|
pushBoolean(luaState, false);
|
|
}
|
|
auto env = getScriptEnv();
|
|
env->setScriptId(scriptId, &g_luaEnvironment);
|
|
g_luaEnvironment.callFunction(1);
|
|
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
|
|
};
|
|
}
|
|
g_databaseTasks.addTask(getString(L, -1), callback, true);
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseEscapeString(lua_State* L)
|
|
{
|
|
pushString(L, Database::getInstance()->escapeString(getString(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseEscapeBlob(lua_State* L)
|
|
{
|
|
uint32_t length = getNumber<uint32_t>(L, 2);
|
|
pushString(L, Database::getInstance()->escapeBlob(getString(L, 1).c_str(), length));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseLastInsertId(lua_State* L)
|
|
{
|
|
lua_pushnumber(L, Database::getInstance()->getLastInsertId());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaDatabaseTableExists(lua_State* L)
|
|
{
|
|
pushBoolean(L, DatabaseManager::tableExists(getString(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
const luaL_Reg LuaScriptInterface::luaResultTable[] = {
|
|
{"getNumber", LuaScriptInterface::luaResultGetNumber},
|
|
{"getString", LuaScriptInterface::luaResultGetString},
|
|
{"getStream", LuaScriptInterface::luaResultGetStream},
|
|
{"next", LuaScriptInterface::luaResultNext},
|
|
{"free", LuaScriptInterface::luaResultFree},
|
|
{nullptr, nullptr}
|
|
};
|
|
|
|
int LuaScriptInterface::luaResultGetNumber(lua_State* L)
|
|
{
|
|
DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
|
|
if (!res) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
const std::string& s = getString(L, 2);
|
|
lua_pushnumber(L, res->getNumber<int64_t>(s));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaResultGetString(lua_State* L)
|
|
{
|
|
DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
|
|
if (!res) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
const std::string& s = getString(L, 2);
|
|
pushString(L, res->getString(s));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaResultGetStream(lua_State* L)
|
|
{
|
|
DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
|
|
if (!res) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
unsigned long length;
|
|
const char* stream = res->getStream(getString(L, 2), length);
|
|
lua_pushlstring(L, stream, length);
|
|
lua_pushnumber(L, length);
|
|
return 2;
|
|
}
|
|
|
|
int LuaScriptInterface::luaResultNext(lua_State* L)
|
|
{
|
|
DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, -1));
|
|
if (!res) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
pushBoolean(L, res->next());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaResultFree(lua_State* L)
|
|
{
|
|
pushBoolean(L, ScriptEnvironment::removeResult(getNumber<uint32_t>(L, -1)));
|
|
return 1;
|
|
}
|
|
|
|
// Userdata
|
|
int LuaScriptInterface::luaUserdataCompare(lua_State* L)
|
|
{
|
|
// userdataA == userdataB
|
|
pushBoolean(L, getUserdata<void>(L, 1) == getUserdata<void>(L, 2));
|
|
return 1;
|
|
}
|
|
|
|
// _G
|
|
int LuaScriptInterface::luaIsType(lua_State* L)
|
|
{
|
|
// isType(derived, base)
|
|
lua_getmetatable(L, -2);
|
|
lua_getmetatable(L, -2);
|
|
|
|
lua_rawgeti(L, -2, 'p');
|
|
uint_fast8_t parentsB = getNumber<uint_fast8_t>(L, 1);
|
|
|
|
lua_rawgeti(L, -3, 'h');
|
|
size_t hashB = getNumber<size_t>(L, 1);
|
|
|
|
lua_rawgeti(L, -3, 'p');
|
|
uint_fast8_t parentsA = getNumber<uint_fast8_t>(L, 1);
|
|
for (uint_fast8_t i = parentsA; i < parentsB; ++i) {
|
|
lua_getfield(L, -3, "__index");
|
|
lua_replace(L, -4);
|
|
}
|
|
|
|
lua_rawgeti(L, -4, 'h');
|
|
size_t hashA = getNumber<size_t>(L, 1);
|
|
|
|
pushBoolean(L, hashA == hashB);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaRawGetMetatable(lua_State* L)
|
|
{
|
|
// rawgetmetatable(metatableName)
|
|
luaL_getmetatable(L, getString(L, 1).c_str());
|
|
return 1;
|
|
}
|
|
|
|
// os
|
|
int LuaScriptInterface::luaSystemTime(lua_State* L)
|
|
{
|
|
// os.mtime()
|
|
lua_pushnumber(L, OTSYS_TIME());
|
|
return 1;
|
|
}
|
|
|
|
// table
|
|
int LuaScriptInterface::luaTableCreate(lua_State* L)
|
|
{
|
|
// table.create(arrayLength, keyLength)
|
|
lua_createtable(L, getNumber<int32_t>(L, 1), getNumber<int32_t>(L, 2));
|
|
return 1;
|
|
}
|
|
|
|
// Game
|
|
int LuaScriptInterface::luaGameGetSpectators(lua_State* L)
|
|
{
|
|
// Game.getSpectators(position[, multifloor = false[, onlyPlayer = false[, minRangeX = 0[, maxRangeX = 0[, minRangeY = 0[, maxRangeY = 0]]]]]])
|
|
const Position& position = getPosition(L, 1);
|
|
bool multifloor = getBoolean(L, 2, false);
|
|
bool onlyPlayers = getBoolean(L, 3, false);
|
|
int32_t minRangeX = getNumber<int32_t>(L, 4, 0);
|
|
int32_t maxRangeX = getNumber<int32_t>(L, 5, 0);
|
|
int32_t minRangeY = getNumber<int32_t>(L, 6, 0);
|
|
int32_t maxRangeY = getNumber<int32_t>(L, 7, 0);
|
|
|
|
SpectatorVec spectators;
|
|
g_game.map.getSpectators(spectators, position, multifloor, onlyPlayers, minRangeX, maxRangeX, minRangeY, maxRangeY);
|
|
|
|
lua_createtable(L, spectators.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Creature* creature : spectators) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetPlayers(lua_State* L)
|
|
{
|
|
// Game.getPlayers()
|
|
lua_createtable(L, g_game.getPlayersOnline(), 0);
|
|
|
|
int index = 0;
|
|
for (const auto& playerEntry : g_game.getPlayers()) {
|
|
pushUserdata<Player>(L, playerEntry.second);
|
|
setMetatable(L, -1, "Player");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameLoadMap(lua_State* L)
|
|
{
|
|
// Game.loadMap(path)
|
|
const std::string& path = getString(L, 1);
|
|
g_dispatcher.addTask(createTask(std::bind(&Game::loadMap, &g_game, path)));
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetExperienceStage(lua_State* L)
|
|
{
|
|
// Game.getExperienceStage(level)
|
|
uint32_t level = getNumber<uint32_t>(L, 1);
|
|
lua_pushnumber(L, g_game.getExperienceStage(level));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetMonsterCount(lua_State* L)
|
|
{
|
|
// Game.getMonsterCount()
|
|
lua_pushnumber(L, g_game.getMonstersOnline());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetPlayerCount(lua_State* L)
|
|
{
|
|
// Game.getPlayerCount()
|
|
lua_pushnumber(L, g_game.getPlayersOnline());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetNpcCount(lua_State* L)
|
|
{
|
|
// Game.getNpcCount()
|
|
lua_pushnumber(L, g_game.getNpcsOnline());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetTowns(lua_State* L)
|
|
{
|
|
// Game.getTowns()
|
|
const auto& towns = g_game.map.towns.getTowns();
|
|
lua_createtable(L, towns.size(), 0);
|
|
|
|
int index = 0;
|
|
for (auto townEntry : towns) {
|
|
pushUserdata<Town>(L, townEntry.second);
|
|
setMetatable(L, -1, "Town");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetHouses(lua_State* L)
|
|
{
|
|
// Game.getHouses()
|
|
const auto& houses = g_game.map.houses.getHouses();
|
|
lua_createtable(L, houses.size(), 0);
|
|
|
|
int index = 0;
|
|
for (auto houseEntry : houses) {
|
|
pushUserdata<House>(L, houseEntry.second);
|
|
setMetatable(L, -1, "House");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetGameState(lua_State* L)
|
|
{
|
|
// Game.getGameState()
|
|
lua_pushnumber(L, g_game.getGameState());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameSetGameState(lua_State* L)
|
|
{
|
|
// Game.setGameState(state)
|
|
GameState_t state = getNumber<GameState_t>(L, 1);
|
|
g_game.setGameState(state);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetWorldType(lua_State* L)
|
|
{
|
|
// Game.getWorldType()
|
|
lua_pushnumber(L, g_game.getWorldType());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameSetWorldType(lua_State* L)
|
|
{
|
|
// Game.setWorldType(type)
|
|
WorldType_t type = getNumber<WorldType_t>(L, 1);
|
|
g_game.setWorldType(type);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameGetReturnMessage(lua_State* L)
|
|
{
|
|
// Game.getReturnMessage(value)
|
|
ReturnValue value = getNumber<ReturnValue>(L, 1);
|
|
pushString(L, getReturnMessage(value));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameCreateItem(lua_State* L)
|
|
{
|
|
// Game.createItem(itemId[, count[, position]])
|
|
uint16_t count = getNumber<uint16_t>(L, 2, 1);
|
|
uint16_t id;
|
|
if (isNumber(L, 1)) {
|
|
id = getNumber<uint16_t>(L, 1);
|
|
} else {
|
|
id = Item::items.getItemIdByName(getString(L, 1));
|
|
if (id == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
const ItemType& it = Item::items[id];
|
|
if (it.stackable) {
|
|
count = std::min<uint16_t>(count, 100);
|
|
}
|
|
|
|
Item* item = Item::CreateItem(id, count);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (lua_gettop(L) >= 3) {
|
|
const Position& position = getPosition(L, 3);
|
|
Tile* tile = g_game.map.getTile(position);
|
|
if (!tile) {
|
|
delete item;
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
g_game.internalAddItem(tile, item, INDEX_WHEREEVER, FLAG_NOLIMIT);
|
|
} else {
|
|
getScriptEnv()->addTempItem(item);
|
|
item->setParent(VirtualCylinder::virtualCylinder);
|
|
}
|
|
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameCreateContainer(lua_State* L)
|
|
{
|
|
// Game.createContainer(itemId, size[, position])
|
|
uint16_t size = getNumber<uint16_t>(L, 2);
|
|
uint16_t id;
|
|
if (isNumber(L, 1)) {
|
|
id = getNumber<uint16_t>(L, 1);
|
|
} else {
|
|
id = Item::items.getItemIdByName(getString(L, 1));
|
|
if (id == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Container* container = Item::CreateItemAsContainer(id, size);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (lua_gettop(L) >= 3) {
|
|
const Position& position = getPosition(L, 3);
|
|
Tile* tile = g_game.map.getTile(position);
|
|
if (!tile) {
|
|
delete container;
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
g_game.internalAddItem(tile, container, INDEX_WHEREEVER, FLAG_NOLIMIT);
|
|
} else {
|
|
getScriptEnv()->addTempItem(container);
|
|
container->setParent(VirtualCylinder::virtualCylinder);
|
|
}
|
|
|
|
pushUserdata<Container>(L, container);
|
|
setMetatable(L, -1, "Container");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameCreateMonster(lua_State* L)
|
|
{
|
|
// Game.createMonster(monsterName, position[, extended = false[, force = false]])
|
|
Monster* monster = Monster::createMonster(getString(L, 1));
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Position& position = getPosition(L, 2);
|
|
bool extended = getBoolean(L, 3, false);
|
|
bool force = getBoolean(L, 4, false);
|
|
if (g_game.placeCreature(monster, position, extended, force)) {
|
|
pushUserdata<Monster>(L, monster);
|
|
setMetatable(L, -1, "Monster");
|
|
} else {
|
|
delete monster;
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameCreateNpc(lua_State* L)
|
|
{
|
|
// Game.createNpc(npcName, position[, extended = false[, force = false]])
|
|
Npc* npc = Npc::createNpc(getString(L, 1));
|
|
if (!npc) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Position& position = getPosition(L, 2);
|
|
bool extended = getBoolean(L, 3, false);
|
|
bool force = getBoolean(L, 4, false);
|
|
if (g_game.placeCreature(npc, position, extended, force)) {
|
|
pushUserdata<Npc>(L, npc);
|
|
setMetatable(L, -1, "Npc");
|
|
} else {
|
|
delete npc;
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameCreateTile(lua_State* L)
|
|
{
|
|
// Game.createTile(x, y, z[, isDynamic = false])
|
|
// Game.createTile(position[, isDynamic = false])
|
|
Position position;
|
|
bool isDynamic;
|
|
if (isTable(L, 1)) {
|
|
position = getPosition(L, 1);
|
|
isDynamic = getBoolean(L, 2, false);
|
|
} else {
|
|
position.x = getNumber<uint16_t>(L, 1);
|
|
position.y = getNumber<uint16_t>(L, 2);
|
|
position.z = getNumber<uint16_t>(L, 3);
|
|
isDynamic = getBoolean(L, 4, false);
|
|
}
|
|
|
|
Tile* tile = g_game.map.getTile(position);
|
|
if (!tile) {
|
|
if (isDynamic) {
|
|
tile = new DynamicTile(position.x, position.y, position.z);
|
|
} else {
|
|
tile = new StaticTile(position.x, position.y, position.z);
|
|
}
|
|
|
|
g_game.map.setTile(position, tile);
|
|
}
|
|
|
|
pushUserdata(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameStartRaid(lua_State* L)
|
|
{
|
|
// Game.startRaid(raidName)
|
|
const std::string& raidName = getString(L, 1);
|
|
|
|
Raid* raid = g_game.raids.getRaidByName(raidName);
|
|
if (!raid || !raid->isLoaded()) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (g_game.raids.getRunning()) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
g_game.raids.setRunning(raid);
|
|
raid->startRaid();
|
|
lua_pushnumber(L, RETURNVALUE_NOERROR);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGameReload(lua_State* L)
|
|
{
|
|
// Game.reload(reloadType)
|
|
ReloadTypes_t reloadType = getNumber<ReloadTypes_t>(L, 1);
|
|
if (!reloadType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (reloadType == RELOAD_TYPE_GLOBAL) {
|
|
pushBoolean(L, g_luaEnvironment.loadFile("data/global.lua") == 0);
|
|
}
|
|
else {
|
|
pushBoolean(L, g_game.reload(reloadType));
|
|
}
|
|
lua_gc(g_luaEnvironment.getLuaState(), LUA_GCCOLLECT, 0);
|
|
return 1;
|
|
}
|
|
|
|
// Variant
|
|
int LuaScriptInterface::luaVariantCreate(lua_State* L)
|
|
{
|
|
// Variant(number or string or position or thing)
|
|
LuaVariant variant;
|
|
if (isUserdata(L, 2)) {
|
|
if (Thing* thing = getThing(L, 2)) {
|
|
variant.type = VARIANT_TARGETPOSITION;
|
|
variant.pos = thing->getPosition();
|
|
}
|
|
} else if (isTable(L, 2)) {
|
|
variant.type = VARIANT_POSITION;
|
|
variant.pos = getPosition(L, 2);
|
|
} else if (isNumber(L, 2)) {
|
|
variant.type = VARIANT_NUMBER;
|
|
variant.number = getNumber<uint32_t>(L, 2);
|
|
} else if (isString(L, 2)) {
|
|
variant.type = VARIANT_STRING;
|
|
variant.text = getString(L, 2);
|
|
}
|
|
pushVariant(L, variant);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVariantGetNumber(lua_State* L)
|
|
{
|
|
// Variant:getNumber()
|
|
const LuaVariant& variant = getVariant(L, 1);
|
|
if (variant.type == VARIANT_NUMBER) {
|
|
lua_pushnumber(L, variant.number);
|
|
} else {
|
|
lua_pushnumber(L, 0);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVariantGetString(lua_State* L)
|
|
{
|
|
// Variant:getString()
|
|
const LuaVariant& variant = getVariant(L, 1);
|
|
if (variant.type == VARIANT_STRING) {
|
|
pushString(L, variant.text);
|
|
} else {
|
|
pushString(L, std::string());
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVariantGetPosition(lua_State* L)
|
|
{
|
|
// Variant:getPosition()
|
|
const LuaVariant& variant = getVariant(L, 1);
|
|
if (variant.type == VARIANT_POSITION || variant.type == VARIANT_TARGETPOSITION) {
|
|
pushPosition(L, variant.pos);
|
|
} else {
|
|
pushPosition(L, Position());
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Position
|
|
int LuaScriptInterface::luaPositionCreate(lua_State* L)
|
|
{
|
|
// Position([x = 0[, y = 0[, z = 0[, stackpos = 0]]]])
|
|
// Position([position])
|
|
if (lua_gettop(L) <= 1) {
|
|
pushPosition(L, Position());
|
|
return 1;
|
|
}
|
|
|
|
int32_t stackpos;
|
|
if (isTable(L, 2)) {
|
|
const Position& position = getPosition(L, 2, stackpos);
|
|
pushPosition(L, position, stackpos);
|
|
} else {
|
|
uint16_t x = getNumber<uint16_t>(L, 2, 0);
|
|
uint16_t y = getNumber<uint16_t>(L, 3, 0);
|
|
uint8_t z = getNumber<uint8_t>(L, 4, 0);
|
|
stackpos = getNumber<int32_t>(L, 5, 0);
|
|
|
|
pushPosition(L, Position(x, y, z), stackpos);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionAdd(lua_State* L)
|
|
{
|
|
// positionValue = position + positionEx
|
|
int32_t stackpos;
|
|
const Position& position = getPosition(L, 1, stackpos);
|
|
|
|
Position positionEx;
|
|
if (stackpos == 0) {
|
|
positionEx = getPosition(L, 2, stackpos);
|
|
} else {
|
|
positionEx = getPosition(L, 2);
|
|
}
|
|
|
|
pushPosition(L, position + positionEx, stackpos);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionSub(lua_State* L)
|
|
{
|
|
// positionValue = position - positionEx
|
|
int32_t stackpos;
|
|
const Position& position = getPosition(L, 1, stackpos);
|
|
|
|
Position positionEx;
|
|
if (stackpos == 0) {
|
|
positionEx = getPosition(L, 2, stackpos);
|
|
} else {
|
|
positionEx = getPosition(L, 2);
|
|
}
|
|
|
|
pushPosition(L, position - positionEx, stackpos);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionCompare(lua_State* L)
|
|
{
|
|
// position == positionEx
|
|
const Position& positionEx = getPosition(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
pushBoolean(L, position == positionEx);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionGetDistance(lua_State* L)
|
|
{
|
|
// position:getDistance(positionEx)
|
|
const Position& positionEx = getPosition(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
lua_pushnumber(L, std::max<int32_t>(
|
|
std::max<int32_t>(
|
|
std::abs(Position::getDistanceX(position, positionEx)),
|
|
std::abs(Position::getDistanceY(position, positionEx))
|
|
),
|
|
std::abs(Position::getDistanceZ(position, positionEx))
|
|
));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionIsSightClear(lua_State* L)
|
|
{
|
|
// position:isSightClear(positionEx[, sameFloor = true])
|
|
bool sameFloor = getBoolean(L, 3, true);
|
|
const Position& positionEx = getPosition(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
pushBoolean(L, g_game.isSightClear(position, positionEx, sameFloor));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionSendMagicEffect(lua_State* L)
|
|
{
|
|
// position:sendMagicEffect(magicEffect[, player = nullptr])
|
|
SpectatorVec list;
|
|
if (lua_gettop(L) >= 3) {
|
|
Player* player = getPlayer(L, 3);
|
|
if (player) {
|
|
list.insert(player);
|
|
}
|
|
}
|
|
|
|
MagicEffectClasses magicEffect = getNumber<MagicEffectClasses>(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
if (!list.empty()) {
|
|
Game::addMagicEffect(list, position, magicEffect);
|
|
} else {
|
|
g_game.addMagicEffect(position, magicEffect);
|
|
}
|
|
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionSendDistanceEffect(lua_State* L)
|
|
{
|
|
// position:sendDistanceEffect(positionEx, distanceEffect[, player = nullptr])
|
|
SpectatorVec list;
|
|
if (lua_gettop(L) >= 4) {
|
|
Player* player = getPlayer(L, 4);
|
|
if (player) {
|
|
list.insert(player);
|
|
}
|
|
}
|
|
|
|
ShootType_t distanceEffect = getNumber<ShootType_t>(L, 3);
|
|
const Position& positionEx = getPosition(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
if (!list.empty()) {
|
|
Game::addDistanceEffect(list, position, positionEx, distanceEffect);
|
|
} else {
|
|
g_game.addDistanceEffect(position, positionEx, distanceEffect);
|
|
}
|
|
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPositionSendMonsterSay(lua_State * L)
|
|
{
|
|
// position:sendMonsterSay(text)
|
|
const std::string& text = getString(L, 2);
|
|
const Position& position = getPosition(L, 1);
|
|
g_game.addMonsterSayText(position, text);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
// Tile
|
|
int LuaScriptInterface::luaTileCreate(lua_State* L)
|
|
{
|
|
// Tile(x, y, z)
|
|
// Tile(position)
|
|
Tile* tile;
|
|
if (isTable(L, 2)) {
|
|
tile = g_game.map.getTile(getPosition(L, 2));
|
|
} else {
|
|
uint8_t z = getNumber<uint8_t>(L, 4);
|
|
uint16_t y = getNumber<uint16_t>(L, 3);
|
|
uint16_t x = getNumber<uint16_t>(L, 2);
|
|
tile = g_game.map.getTile(x, y, z);
|
|
}
|
|
|
|
if (tile) {
|
|
pushUserdata<Tile>(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetPosition(lua_State* L)
|
|
{
|
|
// tile:getPosition()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (tile) {
|
|
pushPosition(L, tile->getPosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetGround(lua_State* L)
|
|
{
|
|
// tile:getGround()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (tile && tile->getGround()) {
|
|
pushUserdata<Item>(L, tile->getGround());
|
|
setItemMetatable(L, -1, tile->getGround());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetThing(lua_State* L)
|
|
{
|
|
// tile:getThing(index)
|
|
int32_t index = getNumber<int32_t>(L, 2);
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Thing* thing = tile->getThing(index);
|
|
if (!thing) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (Creature* creature = thing->getCreature()) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
} else if (Item* item = thing->getItem()) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetThingCount(lua_State* L)
|
|
{
|
|
// tile:getThingCount()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (tile) {
|
|
lua_pushnumber(L, tile->getThingCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopVisibleThing(lua_State* L)
|
|
{
|
|
// tile:getTopVisibleThing(creature)
|
|
Creature* creature = getCreature(L, 2);
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Thing* thing = tile->getTopVisibleThing(creature);
|
|
if (!thing) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (Creature* visibleCreature = thing->getCreature()) {
|
|
pushUserdata<Creature>(L, visibleCreature);
|
|
setCreatureMetatable(L, -1, visibleCreature);
|
|
} else if (Item* visibleItem = thing->getItem()) {
|
|
pushUserdata<Item>(L, visibleItem);
|
|
setItemMetatable(L, -1, visibleItem);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopTopItem(lua_State* L)
|
|
{
|
|
// tile:getTopTopItem()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = tile->getTopTopItem();
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopDownItem(lua_State* L)
|
|
{
|
|
// tile:getTopDownItem()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = tile->getTopDownItem();
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetFieldItem(lua_State* L)
|
|
{
|
|
// tile:getFieldItem()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = tile->getFieldItem();
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItemById(lua_State* L)
|
|
{
|
|
// tile:getItemById(itemId[, subType = -1])
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
int32_t subType = getNumber<int32_t>(L, 3, -1);
|
|
|
|
Item* item = g_game.findItemOfType(tile, itemId, false, subType);
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItemByType(lua_State* L)
|
|
{
|
|
// tile:getItemByType(itemType)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
bool found;
|
|
|
|
ItemTypes_t itemType = getNumber<ItemTypes_t>(L, 2);
|
|
switch (itemType) {
|
|
case ITEM_TYPE_TELEPORT:
|
|
found = tile->hasFlag(TILESTATE_TELEPORT);
|
|
break;
|
|
case ITEM_TYPE_MAGICFIELD:
|
|
found = tile->hasFlag(TILESTATE_MAGICFIELD);
|
|
break;
|
|
case ITEM_TYPE_MAILBOX:
|
|
found = tile->hasFlag(TILESTATE_MAILBOX);
|
|
break;
|
|
case ITEM_TYPE_BED:
|
|
found = tile->hasFlag(TILESTATE_BED);
|
|
break;
|
|
case ITEM_TYPE_DEPOT:
|
|
found = tile->hasFlag(TILESTATE_DEPOT);
|
|
break;
|
|
default:
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
if (!found) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (Item* item = tile->getGround()) {
|
|
const ItemType& it = Item::items[item->getID()];
|
|
if (it.type == itemType) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if (const TileItemVector* items = tile->getItemList()) {
|
|
for (Item* item : *items) {
|
|
const ItemType& it = Item::items[item->getID()];
|
|
if (it.type == itemType) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItemByTopOrder(lua_State* L)
|
|
{
|
|
// tile:getItemByTopOrder(topOrder)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t topOrder = getNumber<int32_t>(L, 2);
|
|
|
|
Item* item = tile->getItemByTopOrder(topOrder);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItemCountById(lua_State* L)
|
|
{
|
|
// tile:getItemCountById(itemId[, subType = -1])
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t subType = getNumber<int32_t>(L, 3, -1);
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
lua_pushnumber(L, tile->getItemTypeCount(itemId, subType));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetBottomCreature(lua_State* L)
|
|
{
|
|
// tile:getBottomCreature()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Creature* creature = tile->getBottomCreature();
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushUserdata<const Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopCreature(lua_State* L)
|
|
{
|
|
// tile:getTopCreature()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = tile->getTopCreature();
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetBottomVisibleCreature(lua_State* L)
|
|
{
|
|
// tile:getBottomVisibleCreature(creature)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = getCreature(L, 2);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Creature* visibleCreature = tile->getBottomVisibleCreature(creature);
|
|
if (visibleCreature) {
|
|
pushUserdata<const Creature>(L, visibleCreature);
|
|
setCreatureMetatable(L, -1, visibleCreature);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopVisibleCreature(lua_State* L)
|
|
{
|
|
// tile:getTopVisibleCreature(creature)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = getCreature(L, 2);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* visibleCreature = tile->getTopVisibleCreature(creature);
|
|
if (visibleCreature) {
|
|
pushUserdata<Creature>(L, visibleCreature);
|
|
setCreatureMetatable(L, -1, visibleCreature);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItems(lua_State* L)
|
|
{
|
|
// tile:getItems()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
TileItemVector* itemVector = tile->getItemList();
|
|
if (!itemVector) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, itemVector->size(), 0);
|
|
|
|
int index = 0;
|
|
for (Item* item : *itemVector) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetItemCount(lua_State* L)
|
|
{
|
|
// tile:getItemCount()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, tile->getItemCount());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetDownItemCount(lua_State* L)
|
|
{
|
|
// tile:getDownItemCount()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (tile) {
|
|
lua_pushnumber(L, tile->getDownItemCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetTopItemCount(lua_State* L)
|
|
{
|
|
// tile:getTopItemCount()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, tile->getTopItemCount());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetCreatures(lua_State* L)
|
|
{
|
|
// tile:getCreatures()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CreatureVector* creatureVector = tile->getCreatures();
|
|
if (!creatureVector) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, creatureVector->size(), 0);
|
|
|
|
int index = 0;
|
|
for (Creature* creature : *creatureVector) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetCreatureCount(lua_State* L)
|
|
{
|
|
// tile:getCreatureCount()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, tile->getCreatureCount());
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileHasProperty(lua_State* L)
|
|
{
|
|
// tile:hasProperty(property[, item])
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item;
|
|
if (lua_gettop(L) >= 3) {
|
|
item = getUserdata<Item>(L, 3);
|
|
} else {
|
|
item = nullptr;
|
|
}
|
|
|
|
ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
|
|
if (item) {
|
|
pushBoolean(L, tile->hasProperty(item, property));
|
|
} else {
|
|
pushBoolean(L, tile->hasProperty(property));
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetThingIndex(lua_State* L)
|
|
{
|
|
// tile:getThingIndex(thing)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Thing* thing = getThing(L, 2);
|
|
if (thing) {
|
|
lua_pushnumber(L, tile->getThingIndex(thing));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileHasFlag(lua_State* L)
|
|
{
|
|
// tile:hasFlag(flag)
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (tile) {
|
|
tileflags_t flag = getNumber<tileflags_t>(L, 2);
|
|
pushBoolean(L, tile->hasFlag(flag));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileQueryAdd(lua_State* L)
|
|
{
|
|
// tile:queryAdd(thing[, flags])
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Thing* thing = getThing(L, 2);
|
|
if (thing) {
|
|
uint32_t flags = getNumber<uint32_t>(L, 3, 0);
|
|
lua_pushnumber(L, tile->queryAdd(0, *thing, 1, flags));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTileGetHouse(lua_State* L)
|
|
{
|
|
// tile:getHouse()
|
|
Tile* tile = getUserdata<Tile>(L, 1);
|
|
if (!tile) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (HouseTile* houseTile = dynamic_cast<HouseTile*>(tile)) {
|
|
pushUserdata<House>(L, houseTile->getHouse());
|
|
setMetatable(L, -1, "House");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// NetworkMessage
|
|
int LuaScriptInterface::luaNetworkMessageCreate(lua_State* L)
|
|
{
|
|
// NetworkMessage()
|
|
pushUserdata<NetworkMessage>(L, new NetworkMessage);
|
|
setMetatable(L, -1, "NetworkMessage");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageDelete(lua_State* L)
|
|
{
|
|
NetworkMessage** messagePtr = getRawUserdata<NetworkMessage>(L, 1);
|
|
if (messagePtr && *messagePtr) {
|
|
delete *messagePtr;
|
|
*messagePtr = nullptr;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetByte(lua_State* L)
|
|
{
|
|
// networkMessage:getByte()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
lua_pushnumber(L, message->getByte());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetU16(lua_State* L)
|
|
{
|
|
// networkMessage:getU16()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
lua_pushnumber(L, message->get<uint16_t>());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetU32(lua_State* L)
|
|
{
|
|
// networkMessage:getU32()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
lua_pushnumber(L, message->get<uint32_t>());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetU64(lua_State* L)
|
|
{
|
|
// networkMessage:getU64()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
lua_pushnumber(L, message->get<uint64_t>());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetString(lua_State* L)
|
|
{
|
|
// networkMessage:getString()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
pushString(L, message->getString());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageGetPosition(lua_State* L)
|
|
{
|
|
// networkMessage:getPosition()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
pushPosition(L, message->getPosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddByte(lua_State* L)
|
|
{
|
|
// networkMessage:addByte(number)
|
|
uint8_t number = getNumber<uint8_t>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->addByte(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddU16(lua_State* L)
|
|
{
|
|
// networkMessage:addU16(number)
|
|
uint16_t number = getNumber<uint16_t>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->add<uint16_t>(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddU32(lua_State* L)
|
|
{
|
|
// networkMessage:addU32(number)
|
|
uint32_t number = getNumber<uint32_t>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->add<uint32_t>(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddU64(lua_State* L)
|
|
{
|
|
// networkMessage:addU64(number)
|
|
uint64_t number = getNumber<uint64_t>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->add<uint64_t>(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddString(lua_State* L)
|
|
{
|
|
// networkMessage:addString(string)
|
|
const std::string& string = getString(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->addString(string);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddPosition(lua_State* L)
|
|
{
|
|
// networkMessage:addPosition(position)
|
|
const Position& position = getPosition(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->addPosition(position);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddDouble(lua_State* L)
|
|
{
|
|
// networkMessage:addDouble(number)
|
|
double number = getNumber<double>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->addDouble(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddItem(lua_State* L)
|
|
{
|
|
// networkMessage:addItem(item)
|
|
Item* item = getUserdata<Item>(L, 2);
|
|
if (!item) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->addItem(item);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageAddItemId(lua_State* L)
|
|
{
|
|
// networkMessage:addItemId(itemId)
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (!message) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
message->addItemId(itemId);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageReset(lua_State* L)
|
|
{
|
|
// networkMessage:reset()
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->reset();
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageSkipBytes(lua_State* L)
|
|
{
|
|
// networkMessage:skipBytes(number)
|
|
int16_t number = getNumber<int16_t>(L, 2);
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (message) {
|
|
message->skipBytes(number);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNetworkMessageSendToPlayer(lua_State* L)
|
|
{
|
|
// networkMessage:sendToPlayer(player)
|
|
NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
|
|
if (!message) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Player* player = getPlayer(L, 2);
|
|
if (player) {
|
|
player->sendNetworkMessage(*message);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Item
|
|
int LuaScriptInterface::luaItemCreate(lua_State* L)
|
|
{
|
|
// Item(uid)
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
|
|
Item* item = getScriptEnv()->getItemByUID(id);
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemIsItem(lua_State* L)
|
|
{
|
|
// item:isItem()
|
|
pushBoolean(L, getUserdata<const Item>(L, 1) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetParent(lua_State* L)
|
|
{
|
|
// item:getParent()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Cylinder* parent = item->getParent();
|
|
if (!parent) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushCylinder(L, parent);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetTopParent(lua_State* L)
|
|
{
|
|
// item:getTopParent()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Cylinder* topParent = item->getTopParent();
|
|
if (!topParent) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushCylinder(L, topParent);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetId(lua_State* L)
|
|
{
|
|
// item:getId()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getID());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemClone(lua_State* L)
|
|
{
|
|
// item:clone()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* clone = item->clone();
|
|
if (!clone) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
getScriptEnv()->addTempItem(clone);
|
|
clone->setParent(VirtualCylinder::virtualCylinder);
|
|
|
|
pushUserdata<Item>(L, clone);
|
|
setItemMetatable(L, -1, clone);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemSplit(lua_State* L)
|
|
{
|
|
// item:split([count = 1])
|
|
Item** itemPtr = getRawUserdata<Item>(L, 1);
|
|
if (!itemPtr) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = *itemPtr;
|
|
if (!item || !item->isStackable()) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t count = std::min<uint16_t>(getNumber<uint16_t>(L, 2, 1), item->getItemCount());
|
|
uint16_t diff = item->getItemCount() - count;
|
|
|
|
Item* splitItem = item->clone();
|
|
if (!splitItem) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
uint32_t uid = env->addThing(item);
|
|
|
|
Item* newItem = g_game.transformItem(item, item->getID(), diff);
|
|
if (item->isRemoved()) {
|
|
env->removeItemByUID(uid);
|
|
}
|
|
|
|
if (newItem && newItem != item) {
|
|
env->insertItem(uid, newItem);
|
|
}
|
|
|
|
*itemPtr = newItem;
|
|
|
|
splitItem->setParent(VirtualCylinder::virtualCylinder);
|
|
env->addTempItem(splitItem);
|
|
|
|
pushUserdata<Item>(L, splitItem);
|
|
setItemMetatable(L, -1, splitItem);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemRemove(lua_State* L)
|
|
{
|
|
// item:remove([count = -1])
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
int32_t count = getNumber<int32_t>(L, 2, -1);
|
|
pushBoolean(L, g_game.internalRemoveItem(item, count) == RETURNVALUE_NOERROR);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetMovementId(lua_State* L)
|
|
{
|
|
// item:getMovementId()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getMovementId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetActionId(lua_State* L)
|
|
{
|
|
// item:getActionId()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getActionId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemSetActionId(lua_State* L)
|
|
{
|
|
// item:setActionId(actionId)
|
|
uint16_t actionId = getNumber<uint16_t>(L, 2);
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
item->setActionId(actionId);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemSetMovementId(lua_State* L)
|
|
{
|
|
// item:setMovementId(movementId)
|
|
uint16_t movementId = getNumber<uint16_t>(L, 2);
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
item->setMovementID(movementId);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetUniqueId(lua_State * L)
|
|
{
|
|
// item:getUniqueId()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, getScriptEnv()->addThing(item));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetCount(lua_State* L)
|
|
{
|
|
// item:getCount()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getItemCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetCharges(lua_State* L)
|
|
{
|
|
// item:getCharges()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getCharges());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetFluidType(lua_State* L)
|
|
{
|
|
// item:getFluidType()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getFluidType());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetWeight(lua_State* L)
|
|
{
|
|
// item:getWeight()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getWeight());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetSubType(lua_State* L)
|
|
{
|
|
// item:getSubType()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
lua_pushnumber(L, item->getSubType());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetName(lua_State* L)
|
|
{
|
|
// item:getName()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
pushString(L, item->getName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetPluralName(lua_State* L)
|
|
{
|
|
// item:getPluralName()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
pushString(L, item->getPluralName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetArticle(lua_State* L)
|
|
{
|
|
// item:getArticle()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
pushString(L, item->getArticle());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetPosition(lua_State* L)
|
|
{
|
|
// item:getPosition()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
pushPosition(L, item->getPosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetTile(lua_State* L)
|
|
{
|
|
// item:getTile()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Tile* tile = item->getTile();
|
|
if (tile) {
|
|
pushUserdata<Tile>(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemHasAttribute(lua_State* L)
|
|
{
|
|
// item:hasAttribute(key)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
itemAttrTypes attribute;
|
|
if (isNumber(L, 2)) {
|
|
attribute = getNumber<itemAttrTypes>(L, 2);
|
|
} else if (isString(L, 2)) {
|
|
attribute = stringToItemAttribute(getString(L, 2));
|
|
} else {
|
|
attribute = ITEM_ATTRIBUTE_NONE;
|
|
}
|
|
|
|
pushBoolean(L, item->hasAttribute(attribute));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetAttribute(lua_State* L)
|
|
{
|
|
// item:getAttribute(key)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
itemAttrTypes attribute;
|
|
if (isNumber(L, 2)) {
|
|
attribute = getNumber<itemAttrTypes>(L, 2);
|
|
} else if (isString(L, 2)) {
|
|
attribute = stringToItemAttribute(getString(L, 2));
|
|
} else {
|
|
attribute = ITEM_ATTRIBUTE_NONE;
|
|
}
|
|
|
|
if (ItemAttributes::isIntAttrType(attribute)) {
|
|
lua_pushnumber(L, item->getIntAttr(attribute));
|
|
} else if (ItemAttributes::isStrAttrType(attribute)) {
|
|
pushString(L, item->getStrAttr(attribute));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemSetAttribute(lua_State* L)
|
|
{
|
|
// item:setAttribute(key, value)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
itemAttrTypes attribute;
|
|
if (isNumber(L, 2)) {
|
|
attribute = getNumber<itemAttrTypes>(L, 2);
|
|
} else if (isString(L, 2)) {
|
|
attribute = stringToItemAttribute(getString(L, 2));
|
|
} else {
|
|
attribute = ITEM_ATTRIBUTE_NONE;
|
|
}
|
|
|
|
if (ItemAttributes::isIntAttrType(attribute)) {
|
|
item->setIntAttr(attribute, getNumber<int32_t>(L, 3));
|
|
pushBoolean(L, true);
|
|
} else if (ItemAttributes::isStrAttrType(attribute)) {
|
|
item->setStrAttr(attribute, getString(L, 3));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemRemoveAttribute(lua_State* L)
|
|
{
|
|
// item:removeAttribute(key)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
itemAttrTypes attribute;
|
|
if (isNumber(L, 2)) {
|
|
attribute = getNumber<itemAttrTypes>(L, 2);
|
|
} else if (isString(L, 2)) {
|
|
attribute = stringToItemAttribute(getString(L, 2));
|
|
} else {
|
|
attribute = ITEM_ATTRIBUTE_NONE;
|
|
}
|
|
|
|
item->removeAttribute(attribute);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemMoveTo(lua_State* L)
|
|
{
|
|
// item:moveTo(position or cylinder)
|
|
Item** itemPtr = getRawUserdata<Item>(L, 1);
|
|
if (!itemPtr) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = *itemPtr;
|
|
if (!item || item->isRemoved()) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Cylinder* toCylinder;
|
|
if (isUserdata(L, 2)) {
|
|
const LuaDataType type = getUserdataType(L, 2);
|
|
switch (type) {
|
|
case LuaData_Container:
|
|
toCylinder = getUserdata<Container>(L, 2);
|
|
break;
|
|
case LuaData_Player:
|
|
toCylinder = getUserdata<Player>(L, 2);
|
|
break;
|
|
case LuaData_Tile:
|
|
toCylinder = getUserdata<Tile>(L, 2);
|
|
break;
|
|
default:
|
|
toCylinder = nullptr;
|
|
break;
|
|
}
|
|
} else {
|
|
toCylinder = g_game.map.getTile(getPosition(L, 2));
|
|
}
|
|
|
|
if (!toCylinder) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (item->getParent() == toCylinder) {
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
if (item->getParent() == VirtualCylinder::virtualCylinder) {
|
|
pushBoolean(L, g_game.internalAddItem(toCylinder, item) == RETURNVALUE_NOERROR);
|
|
} else {
|
|
Item* moveItem = nullptr;
|
|
ReturnValue ret = g_game.internalMoveItem(item->getParent(), toCylinder, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem, FLAG_NOLIMIT | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE | FLAG_IGNORENOTMOVEABLE);
|
|
if (moveItem) {
|
|
*itemPtr = moveItem;
|
|
}
|
|
pushBoolean(L, ret == RETURNVALUE_NOERROR);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTransform(lua_State* L)
|
|
{
|
|
// item:transform(itemId[, count/subType = -1])
|
|
Item** itemPtr = getRawUserdata<Item>(L, 1);
|
|
if (!itemPtr) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item*& item = *itemPtr;
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int32_t subType = getNumber<int32_t>(L, 3, -1);
|
|
if (item->getID() == itemId && (subType == -1 || subType == item->getSubType())) {
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
const ItemType& it = Item::items[itemId];
|
|
if (it.stackable) {
|
|
subType = std::min<int32_t>(subType, 100);
|
|
}
|
|
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
uint32_t uid = env->addThing(item);
|
|
|
|
Item* newItem = g_game.transformItem(item, itemId, subType);
|
|
if (item->isRemoved()) {
|
|
env->removeItemByUID(uid);
|
|
}
|
|
|
|
if (newItem && newItem != item) {
|
|
env->insertItem(uid, newItem);
|
|
}
|
|
|
|
item = newItem;
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemDecay(lua_State* L)
|
|
{
|
|
// item:decay()
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
g_game.startDecay(item);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemGetDescription(lua_State* L)
|
|
{
|
|
// item:getDescription(distance)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
int32_t distance = getNumber<int32_t>(L, 2);
|
|
pushString(L, item->getDescription(distance));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemHasProperty(lua_State* L)
|
|
{
|
|
// item:hasProperty(property)
|
|
Item* item = getUserdata<Item>(L, 1);
|
|
if (item) {
|
|
ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
|
|
pushBoolean(L, item->hasProperty(property));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Container
|
|
int LuaScriptInterface::luaContainerCreate(lua_State* L)
|
|
{
|
|
// Container(uid)
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
|
|
Container* container = getScriptEnv()->getContainerByUID(id);
|
|
if (container) {
|
|
pushUserdata(L, container);
|
|
setMetatable(L, -1, "Container");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetSize(lua_State* L)
|
|
{
|
|
// container:getSize()
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (container) {
|
|
lua_pushnumber(L, container->size());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetCapacity(lua_State* L)
|
|
{
|
|
// container:getCapacity()
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (container) {
|
|
lua_pushnumber(L, container->capacity());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetEmptySlots(lua_State* L)
|
|
{
|
|
// container:getEmptySlots([recursive = false])
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t slots = container->capacity() - container->size();
|
|
bool recursive = getBoolean(L, 2, false);
|
|
if (recursive) {
|
|
for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
|
|
if (Container* tmpContainer = (*it)->getContainer()) {
|
|
slots += tmpContainer->capacity() - tmpContainer->size();
|
|
}
|
|
}
|
|
}
|
|
lua_pushnumber(L, slots);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetItemHoldingCount(lua_State* L)
|
|
{
|
|
// container:getItemHoldingCount()
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (container) {
|
|
lua_pushnumber(L, container->getItemHoldingCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetItem(lua_State* L)
|
|
{
|
|
// container:getItem(index)
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t index = getNumber<uint32_t>(L, 2);
|
|
Item* item = container->getItemByIndex(index);
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerHasItem(lua_State* L)
|
|
{
|
|
// container:hasItem(item)
|
|
Item* item = getUserdata<Item>(L, 2);
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (container) {
|
|
pushBoolean(L, container->isHoldingItem(item));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerAddItem(lua_State* L)
|
|
{
|
|
// container:addItem(itemId[, count/subType = 1[, index = INDEX_WHEREEVER[, flags = 0]]])
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
uint32_t subType = getNumber<uint32_t>(L, 3, 1);
|
|
|
|
Item* item = Item::CreateItem(itemId, std::min<uint32_t>(subType, 100));
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
|
|
uint32_t flags = getNumber<uint32_t>(L, 5, 0);
|
|
|
|
ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
|
|
if (ret == RETURNVALUE_NOERROR) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
delete item;
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerAddItemEx(lua_State* L)
|
|
{
|
|
// container:addItemEx(item[, index = INDEX_WHEREEVER[, flags = 0]])
|
|
Item* item = getUserdata<Item>(L, 2);
|
|
if (!item) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (item->getParent() != VirtualCylinder::virtualCylinder) {
|
|
reportErrorFunc("Item already has a parent");
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t index = getNumber<int32_t>(L, 3, INDEX_WHEREEVER);
|
|
uint32_t flags = getNumber<uint32_t>(L, 4, 0);
|
|
ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
|
|
if (ret == RETURNVALUE_NOERROR) {
|
|
ScriptEnvironment::removeTempItem(item);
|
|
}
|
|
lua_pushnumber(L, ret);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaContainerGetItemCountById(lua_State* L)
|
|
{
|
|
// container:getItemCountById(itemId[, subType = -1])
|
|
Container* container = getUserdata<Container>(L, 1);
|
|
if (!container) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int32_t subType = getNumber<int32_t>(L, 3, -1);
|
|
lua_pushnumber(L, container->getItemTypeCount(itemId, subType));
|
|
return 1;
|
|
}
|
|
|
|
// Teleport
|
|
int LuaScriptInterface::luaTeleportCreate(lua_State* L)
|
|
{
|
|
// Teleport(uid)
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
|
|
Item* item = getScriptEnv()->getItemByUID(id);
|
|
if (item && item->getTeleport()) {
|
|
pushUserdata(L, item);
|
|
setMetatable(L, -1, "Teleport");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTeleportGetDestination(lua_State* L)
|
|
{
|
|
// teleport:getDestination()
|
|
Teleport* teleport = getUserdata<Teleport>(L, 1);
|
|
if (teleport) {
|
|
pushPosition(L, teleport->getDestPos());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTeleportSetDestination(lua_State* L)
|
|
{
|
|
// teleport:setDestination(position)
|
|
Teleport* teleport = getUserdata<Teleport>(L, 1);
|
|
if (teleport) {
|
|
teleport->setDestPos(getPosition(L, 2));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Creature
|
|
int LuaScriptInterface::luaCreatureCreate(lua_State* L)
|
|
{
|
|
// Creature(id or name or userdata)
|
|
Creature* creature;
|
|
if (isNumber(L, 2)) {
|
|
creature = g_game.getCreatureByID(getNumber<uint32_t>(L, 2));
|
|
} else if (isString(L, 2)) {
|
|
creature = g_game.getCreatureByName(getString(L, 2));
|
|
} else if (isUserdata(L, 2)) {
|
|
LuaDataType type = getUserdataType(L, 2);
|
|
if (type != LuaData_Player && type != LuaData_Monster && type != LuaData_Npc) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
creature = getUserdata<Creature>(L, 2);
|
|
} else {
|
|
creature = nullptr;
|
|
}
|
|
|
|
if (creature) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetEvents(lua_State* L)
|
|
{
|
|
// creature:getEvents(type)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CreatureEventType_t eventType = getNumber<CreatureEventType_t>(L, 2);
|
|
const auto& eventList = creature->getCreatureEvents(eventType);
|
|
lua_createtable(L, eventList.size(), 0);
|
|
|
|
int index = 0;
|
|
for (CreatureEvent* event : eventList) {
|
|
pushString(L, event->getName());
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureRegisterEvent(lua_State* L)
|
|
{
|
|
// creature:registerEvent(name)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
const std::string& name = getString(L, 2);
|
|
pushBoolean(L, creature->registerCreatureEvent(name));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureUnregisterEvent(lua_State* L)
|
|
{
|
|
// creature:unregisterEvent(name)
|
|
const std::string& name = getString(L, 2);
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
pushBoolean(L, creature->unregisterCreatureEvent(name));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureIsRemoved(lua_State* L)
|
|
{
|
|
// creature:isRemoved()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
pushBoolean(L, creature->isRemoved());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureIsCreature(lua_State* L)
|
|
{
|
|
// creature:isCreature()
|
|
pushBoolean(L, getUserdata<const Creature>(L, 1) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureIsInGhostMode(lua_State* L)
|
|
{
|
|
// creature:isInGhostMode()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
pushBoolean(L, creature->isInGhostMode());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureCanSee(lua_State* L)
|
|
{
|
|
// creature:canSee(position)
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
const Position& position = getPosition(L, 2);
|
|
pushBoolean(L, creature->canSee(position));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureCanSeeCreature(lua_State* L)
|
|
{
|
|
// creature:canSeeCreature(creature)
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
const Creature* otherCreature = getCreature(L, 2);
|
|
pushBoolean(L, creature->canSeeCreature(otherCreature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetParent(lua_State* L)
|
|
{
|
|
// creature:getParent()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Cylinder* parent = creature->getParent();
|
|
if (!parent) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushCylinder(L, parent);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetId(lua_State* L)
|
|
{
|
|
// creature:getId()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getID());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetName(lua_State* L)
|
|
{
|
|
// creature:getName()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
pushString(L, creature->getName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetTarget(lua_State* L)
|
|
{
|
|
// creature:getTarget()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* target = creature->getAttackedCreature();
|
|
if (target) {
|
|
pushUserdata<Creature>(L, target);
|
|
setCreatureMetatable(L, -1, target);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetTarget(lua_State* L)
|
|
{
|
|
// creature:setTarget(target)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
Creature* target = getCreature(L, 2);
|
|
pushBoolean(L, creature->setAttackedCreature(target));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetFollowCreature(lua_State* L)
|
|
{
|
|
// creature:getFollowCreature()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* followCreature = creature->getFollowCreature();
|
|
if (followCreature) {
|
|
pushUserdata<Creature>(L, followCreature);
|
|
setCreatureMetatable(L, -1, followCreature);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetFollowCreature(lua_State* L)
|
|
{
|
|
// creature:setFollowCreature(followedCreature)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
Creature* followCreature = getCreature(L, 2);
|
|
pushBoolean(L, creature->setFollowCreature(followCreature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetMaster(lua_State* L)
|
|
{
|
|
// creature:getMaster()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* master = creature->getMaster();
|
|
if (!master) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushUserdata<Creature>(L, master);
|
|
setCreatureMetatable(L, -1, master);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetMaster(lua_State* L)
|
|
{
|
|
// creature:setMaster(master)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* master = getCreature(L, 2);
|
|
if (master) {
|
|
pushBoolean(L, creature->convinceCreature(master));
|
|
} else {
|
|
master = creature->getMaster();
|
|
if (master) {
|
|
master->removeSummon(creature);
|
|
creature->incrementReferenceCounter();
|
|
creature->setDropLoot(true);
|
|
}
|
|
pushBoolean(L, true);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetLight(lua_State* L)
|
|
{
|
|
// creature:getLight()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
LightInfo lightInfo = creature->getCreatureLight();
|
|
lua_pushnumber(L, lightInfo.level);
|
|
lua_pushnumber(L, lightInfo.color);
|
|
return 2;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetLight(lua_State* L)
|
|
{
|
|
// creature:setLight(color, level)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
LightInfo light;
|
|
light.color = getNumber<uint8_t>(L, 2);
|
|
light.level = getNumber<uint8_t>(L, 3);
|
|
creature->setCreatureLight(light);
|
|
g_game.changeLight(creature);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetSpeed(lua_State* L)
|
|
{
|
|
// creature:getSpeed()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getSpeed());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetBaseSpeed(lua_State* L)
|
|
{
|
|
// creature:getBaseSpeed()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getBaseSpeed());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureChangeSpeed(lua_State* L)
|
|
{
|
|
// creature:changeSpeed(delta)
|
|
Creature* creature = getCreature(L, 1);
|
|
if (!creature) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int32_t delta = getNumber<int32_t>(L, 2);
|
|
g_game.changeSpeed(creature, delta);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetDropLoot(lua_State* L)
|
|
{
|
|
// creature:setDropLoot(doDrop)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
creature->setDropLoot(getBoolean(L, 2));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetPosition(lua_State* L)
|
|
{
|
|
// creature:getPosition()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
pushPosition(L, creature->getPosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetTile(lua_State* L)
|
|
{
|
|
// creature:getTile()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Tile* tile = creature->getTile();
|
|
if (tile) {
|
|
pushUserdata<Tile>(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetDirection(lua_State* L)
|
|
{
|
|
// creature:getDirection()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getDirection());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetDirection(lua_State* L)
|
|
{
|
|
// creature:setDirection(direction)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
pushBoolean(L, g_game.internalCreatureTurn(creature, getNumber<Direction>(L, 2)));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetHealth(lua_State* L)
|
|
{
|
|
// creature:getHealth()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getHealth());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureAddHealth(lua_State* L)
|
|
{
|
|
// creature:addHealth(healthChange)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CombatDamage damage;
|
|
damage.value = getNumber<int32_t>(L, 2);
|
|
if (damage.value >= 0) {
|
|
damage.type = COMBAT_HEALING;
|
|
} else {
|
|
damage.type = COMBAT_UNDEFINEDDAMAGE;
|
|
}
|
|
pushBoolean(L, g_game.combatChangeHealth(nullptr, creature, damage));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetMaxHealth(lua_State* L)
|
|
{
|
|
// creature:getMaxHealth()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getMaxHealth());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetMaxHealth(lua_State* L)
|
|
{
|
|
// creature:setMaxHealth(maxHealth)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
creature->healthMax = getNumber<uint32_t>(L, 2);
|
|
creature->health = std::min<int32_t>(creature->health, creature->healthMax);
|
|
g_game.addCreatureHealth(creature);
|
|
|
|
Player* player = creature->getPlayer();
|
|
if (player) {
|
|
player->sendStats();
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetHiddenHealth(lua_State* L)
|
|
{
|
|
// creature:setHiddenHealth(hide)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
creature->setHiddenHealth(getBoolean(L, 2));
|
|
g_game.addCreatureHealth(creature);
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetSkull(lua_State* L)
|
|
{
|
|
// creature:getSkull()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
lua_pushnumber(L, creature->getSkull());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetSkull(lua_State* L)
|
|
{
|
|
// creature:setSkull(skull)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
creature->setSkull(getNumber<Skulls_t>(L, 2));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetOutfit(lua_State* L)
|
|
{
|
|
// creature:getOutfit()
|
|
const Creature* creature = getUserdata<const Creature>(L, 1);
|
|
if (creature) {
|
|
pushOutfit(L, creature->getCurrentOutfit());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSetOutfit(lua_State* L)
|
|
{
|
|
// creature:setOutfit(outfit)
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
creature->defaultOutfit = getOutfit(L, 2);
|
|
g_game.internalCreatureChangeOutfit(creature, creature->defaultOutfit);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetCondition(lua_State* L)
|
|
{
|
|
// creature:getCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0]])
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
|
|
ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
|
|
uint32_t subId = getNumber<uint32_t>(L, 4, 0);
|
|
|
|
Condition* condition = creature->getCondition(conditionType, conditionId, subId);
|
|
if (condition) {
|
|
pushUserdata<Condition>(L, condition);
|
|
setWeakMetatable(L, -1, "Condition");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureAddCondition(lua_State* L)
|
|
{
|
|
// creature:addCondition(condition[, force = false])
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
Condition* condition = getUserdata<Condition>(L, 2);
|
|
if (creature && condition) {
|
|
bool force = getBoolean(L, 3, false);
|
|
pushBoolean(L, creature->addCondition(condition->clone(), force));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureRemoveCondition(lua_State* L)
|
|
{
|
|
// creature:removeCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0[, force = false]]])
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
|
|
ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
|
|
uint32_t subId = getNumber<uint32_t>(L, 4, 0);
|
|
Condition* condition = creature->getCondition(conditionType, conditionId, subId);
|
|
if (condition) {
|
|
bool force = getBoolean(L, 5, true);
|
|
creature->removeCondition(condition, force);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureRemove(lua_State* L)
|
|
{
|
|
// creature:remove()
|
|
Creature** creaturePtr = getRawUserdata<Creature>(L, 1);
|
|
if (!creaturePtr) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = *creaturePtr;
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Player* player = creature->getPlayer();
|
|
if (player) {
|
|
player->kickPlayer(true);
|
|
} else {
|
|
g_game.removeCreature(creature);
|
|
}
|
|
|
|
*creaturePtr = nullptr;
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureTeleportTo(lua_State* L)
|
|
{
|
|
// creature:teleportTo(position[, pushMovement = false])
|
|
bool pushMovement = getBoolean(L, 3, false);
|
|
|
|
const Position& position = getPosition(L, 2);
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Position oldPosition = creature->getPosition();
|
|
if (g_game.internalTeleport(creature, position, pushMovement) != RETURNVALUE_NOERROR) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (!pushMovement) {
|
|
if (oldPosition.x == position.x) {
|
|
if (oldPosition.y < position.y) {
|
|
g_game.internalCreatureTurn(creature, DIRECTION_SOUTH);
|
|
} else {
|
|
g_game.internalCreatureTurn(creature, DIRECTION_NORTH);
|
|
}
|
|
} else if (oldPosition.x > position.x) {
|
|
g_game.internalCreatureTurn(creature, DIRECTION_WEST);
|
|
} else if (oldPosition.x < position.x) {
|
|
g_game.internalCreatureTurn(creature, DIRECTION_EAST);
|
|
}
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureSay(lua_State* L)
|
|
{
|
|
// creature:say(text, type[, ghost = false[, target = nullptr[, position]]])
|
|
int parameters = lua_gettop(L);
|
|
|
|
Position position;
|
|
if (parameters >= 6) {
|
|
position = getPosition(L, 6);
|
|
if (!position.x || !position.y) {
|
|
reportErrorFunc("Invalid position specified.");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Creature* target = nullptr;
|
|
if (parameters >= 5) {
|
|
target = getCreature(L, 5);
|
|
}
|
|
|
|
bool ghost = getBoolean(L, 4, false);
|
|
|
|
SpeakClasses type = getNumber<SpeakClasses>(L, 3);
|
|
const std::string& text = getString(L, 2);
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
SpectatorVec list;
|
|
if (target) {
|
|
list.insert(target);
|
|
}
|
|
|
|
if (position.x != 0) {
|
|
pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list, &position));
|
|
} else {
|
|
pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list));
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetDamageMap(lua_State* L)
|
|
{
|
|
// creature:getDamageMap()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, creature->damageMap.size(), 0);
|
|
for (auto damageEntry : creature->damageMap) {
|
|
lua_createtable(L, 0, 2);
|
|
setField(L, "total", damageEntry.second.total);
|
|
setField(L, "ticks", damageEntry.second.ticks);
|
|
lua_rawseti(L, -2, damageEntry.first);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetSummons(lua_State* L)
|
|
{
|
|
// creature:getSummons()
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, creature->getSummonCount(), 0);
|
|
|
|
int index = 0;
|
|
for (Creature* summon : creature->getSummons()) {
|
|
pushUserdata<Creature>(L, summon);
|
|
setCreatureMetatable(L, -1, summon);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetDescription(lua_State* L)
|
|
{
|
|
// creature:getDescription(distance)
|
|
int32_t distance = getNumber<int32_t>(L, 2);
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (creature) {
|
|
pushString(L, creature->getDescription(distance));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCreatureGetPathTo(lua_State* L)
|
|
{
|
|
// creature:getPathTo(pos[, minTargetDist = 0[, maxTargetDist = 1[, fullPathSearch = true[, clearSight = true[, maxSearchDist = 0]]]]])
|
|
Creature* creature = getUserdata<Creature>(L, 1);
|
|
if (!creature) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Position& position = getPosition(L, 2);
|
|
|
|
FindPathParams fpp;
|
|
fpp.minTargetDist = getNumber<int32_t>(L, 3, 0);
|
|
fpp.maxTargetDist = getNumber<int32_t>(L, 4, 1);
|
|
fpp.fullPathSearch = getBoolean(L, 5, fpp.fullPathSearch);
|
|
fpp.clearSight = getBoolean(L, 6, fpp.clearSight);
|
|
fpp.maxSearchDist = getNumber<int32_t>(L, 7, fpp.maxSearchDist);
|
|
|
|
std::forward_list<Direction> dirList;
|
|
if (creature->getPathTo(position, dirList, fpp)) {
|
|
lua_newtable(L);
|
|
|
|
int index = 0;
|
|
for (Direction dir : dirList) {
|
|
lua_pushnumber(L, dir);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
} else {
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Player
|
|
int LuaScriptInterface::luaPlayerCreate(lua_State* L)
|
|
{
|
|
// Player(id or name or userdata)
|
|
Player* player;
|
|
if (isNumber(L, 2)) {
|
|
player = g_game.getPlayerByID(getNumber<uint32_t>(L, 2));
|
|
} else if (isString(L, 2)) {
|
|
ReturnValue ret = g_game.getPlayerByNameWildcard(getString(L, 2), player);
|
|
if (ret != RETURNVALUE_NOERROR) {
|
|
lua_pushnil(L);
|
|
lua_pushnumber(L, ret);
|
|
return 2;
|
|
}
|
|
} else if (isUserdata(L, 2)) {
|
|
if (getUserdataType(L, 2) != LuaData_Player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
player = getUserdata<Player>(L, 2);
|
|
} else {
|
|
player = nullptr;
|
|
}
|
|
|
|
if (player) {
|
|
pushUserdata<Player>(L, player);
|
|
setMetatable(L, -1, "Player");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerIsPlayer(lua_State* L)
|
|
{
|
|
// player:isPlayer()
|
|
pushBoolean(L, getUserdata<const Player>(L, 1) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetGuid(lua_State* L)
|
|
{
|
|
// player:getGuid()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getGUID());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetIp(lua_State* L)
|
|
{
|
|
// player:getIp()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getIP());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetAccountId(lua_State* L)
|
|
{
|
|
// player:getAccountId()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getAccount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetLastLoginSaved(lua_State* L)
|
|
{
|
|
// player:getLastLoginSaved()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getLastLoginSaved());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetLastLogout(lua_State* L)
|
|
{
|
|
// player:getLastLogout()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getLastLogout());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerHasFlag(lua_State * L)
|
|
{
|
|
// player:hasFlag(flag)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
PlayerFlags flag = getNumber<PlayerFlags>(L, 2);
|
|
pushBoolean(L, player->hasFlag(flag));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetAccountType(lua_State* L)
|
|
{
|
|
// player:getAccountType()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getAccountType());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetAccountType(lua_State* L)
|
|
{
|
|
// player:setAccountType(accountType)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->accountType = getNumber<AccountType_t>(L, 2);
|
|
IOLoginData::setAccountType(player->getAccount(), player->accountType);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetCapacity(lua_State* L)
|
|
{
|
|
// player:getCapacity()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getCapacity());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetCapacity(lua_State* L)
|
|
{
|
|
// player:setCapacity(capacity)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->capacity = getNumber<uint32_t>(L, 2);
|
|
player->sendStats();
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetFreeCapacity(lua_State* L)
|
|
{
|
|
// player:getFreeCapacity()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getFreeCapacity());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetDepotChest(lua_State* L)
|
|
{
|
|
// player:getDepotChest(depotId[, autoCreate = false])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t depotId = getNumber<uint32_t>(L, 2);
|
|
bool autoCreate = getBoolean(L, 3, false);
|
|
DepotLocker* depotLocker = player->getDepotLocker(depotId, autoCreate);
|
|
if (depotLocker) {
|
|
if (!depotLocker->getParent() && player->getTile()) {
|
|
depotLocker->setParent(player->getTile());
|
|
}
|
|
|
|
pushUserdata<Item>(L, depotLocker);
|
|
setItemMetatable(L, -1, depotLocker);
|
|
} else {
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMurderTimestamps(lua_State * L)
|
|
{
|
|
// player:getMurderTimestamps()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_createtable(L, player->murderTimeStamps.size(), 0);
|
|
|
|
uint32_t i = 1;
|
|
for (time_t currentMurderTimestamp : player->murderTimeStamps) {
|
|
lua_pushnumber(L, static_cast<int64_t>(currentMurderTimestamp));
|
|
lua_rawseti(L, -2, ++i);
|
|
}
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetPlayerKillerEnd(lua_State* L)
|
|
{
|
|
// player:getPlayerKillerEnd()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getPlayerKillerEnd());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetPlayerKillerEnd(lua_State* L)
|
|
{
|
|
// player:setPlayerKillerEnd(skullTime)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->setPlayerKillerEnd(getNumber<time_t>(L, 2));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetDeathPenalty(lua_State* L)
|
|
{
|
|
// player:getDeathPenalty()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, static_cast<uint32_t>(player->getLostPercent() * 100));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetExperience(lua_State* L)
|
|
{
|
|
// player:getExperience()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getExperience());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddExperience(lua_State* L)
|
|
{
|
|
// player:addExperience(experience[, sendText = false])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
int64_t experience = getNumber<int64_t>(L, 2);
|
|
bool sendText = getBoolean(L, 3, false);
|
|
player->addExperience(nullptr, experience, sendText);
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveExperience(lua_State* L)
|
|
{
|
|
// player:removeExperience(experience)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
int64_t experience = getNumber<int64_t>(L, 2);
|
|
player->removeExperience(experience);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetLevel(lua_State* L)
|
|
{
|
|
// player:getLevel()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getLevel());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMagicLevel(lua_State* L)
|
|
{
|
|
// player:getMagicLevel()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getMagicLevel());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetBaseMagicLevel(lua_State* L)
|
|
{
|
|
// player:getBaseMagicLevel()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getBaseMagicLevel());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMana(lua_State* L)
|
|
{
|
|
// player:getMana()
|
|
const Player* player = getUserdata<const Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getMana());
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddMana(lua_State* L)
|
|
{
|
|
// player:addMana(manaChange[, animationOnLoss = false])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t manaChange = getNumber<int32_t>(L, 2);
|
|
bool animationOnLoss = getBoolean(L, 3, false);
|
|
if (!animationOnLoss && manaChange < 0) {
|
|
player->changeMana(manaChange);
|
|
}
|
|
else {
|
|
CombatDamage damage;
|
|
damage.value = manaChange;
|
|
damage.origin = ORIGIN_NONE;
|
|
g_game.combatChangeMana(nullptr, player, damage);
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMaxMana(lua_State* L)
|
|
{
|
|
// player:getMaxMana()
|
|
const Player* player = getUserdata<const Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getMaxMana());
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetMaxMana(lua_State* L)
|
|
{
|
|
// player:setMaxMana(maxMana)
|
|
Player* player = getPlayer(L, 1);
|
|
if (player) {
|
|
player->manaMax = getNumber<int32_t>(L, 2);
|
|
player->mana = std::min<int32_t>(player->mana, player->manaMax);
|
|
player->sendStats();
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetManaSpent(lua_State* L)
|
|
{
|
|
// player:getManaSpent()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getSpentMana());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddManaSpent(lua_State* L)
|
|
{
|
|
// player:addManaSpent(amount)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->addManaSpent(getNumber<uint64_t>(L, 2));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetBaseMaxHealth(lua_State* L)
|
|
{
|
|
// player:getBaseMaxHealth()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->healthMax);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetBaseMaxMana(lua_State* L)
|
|
{
|
|
// player:getBaseMaxMana()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->manaMax);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSkillLevel(lua_State* L)
|
|
{
|
|
// player:getSkillLevel(skillType)
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && skillType <= SKILL_LAST) {
|
|
lua_pushnumber(L, player->skills[skillType].level);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetEffectiveSkillLevel(lua_State* L)
|
|
{
|
|
// player:getEffectiveSkillLevel(skillType)
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && skillType <= SKILL_LAST) {
|
|
lua_pushnumber(L, player->getSkillLevel(skillType));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSkillPercent(lua_State* L)
|
|
{
|
|
// player:getSkillPercent(skillType)
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && skillType <= SKILL_LAST) {
|
|
lua_pushnumber(L, player->skills[skillType].percent);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSkillTries(lua_State* L)
|
|
{
|
|
// player:getSkillTries(skillType)
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && skillType <= SKILL_LAST) {
|
|
lua_pushnumber(L, player->skills[skillType].tries);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddSkillTries(lua_State* L)
|
|
{
|
|
// player:addSkillTries(skillType, tries)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
uint64_t tries = getNumber<uint64_t>(L, 3);
|
|
player->addSkillAdvance(skillType, tries);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetItemCount(lua_State* L)
|
|
{
|
|
// player:getItemCount(itemId[, subType = -1])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int32_t subType = getNumber<int32_t>(L, 3, -1);
|
|
lua_pushnumber(L, player->getItemTypeCount(itemId, subType));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetItemById(lua_State* L)
|
|
{
|
|
// player:getItemById(itemId, deepSearch[, subType = -1])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
bool deepSearch = getBoolean(L, 3);
|
|
int32_t subType = getNumber<int32_t>(L, 4, -1);
|
|
|
|
Item* item = g_game.findItemOfType(player, itemId, deepSearch, subType);
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetVocation(lua_State* L)
|
|
{
|
|
// player:getVocation()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushUserdata<Vocation>(L, player->getVocation());
|
|
setMetatable(L, -1, "Vocation");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetVocation(lua_State* L)
|
|
{
|
|
// player:setVocation(id or name or userdata)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Vocation* vocation;
|
|
if (isNumber(L, 2)) {
|
|
vocation = g_vocations.getVocation(getNumber<uint16_t>(L, 2));
|
|
} else if (isString(L, 2)) {
|
|
vocation = g_vocations.getVocation(g_vocations.getVocationId(getString(L, 2)));
|
|
} else if (isUserdata(L, 2)) {
|
|
vocation = getUserdata<Vocation>(L, 2);
|
|
} else {
|
|
vocation = nullptr;
|
|
}
|
|
|
|
if (!vocation) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
player->setVocation(vocation->getId());
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSex(lua_State* L)
|
|
{
|
|
// player:getSex()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getSex());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetSex(lua_State* L)
|
|
{
|
|
// player:setSex(newSex)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
PlayerSex_t newSex = getNumber<PlayerSex_t>(L, 2);
|
|
player->setSex(newSex);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetTown(lua_State* L)
|
|
{
|
|
// player:getTown()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushUserdata<Town>(L, player->getTown());
|
|
setMetatable(L, -1, "Town");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetTown(lua_State* L)
|
|
{
|
|
// player:setTown(town)
|
|
Town* town = getUserdata<Town>(L, 2);
|
|
if (!town) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->setTown(town);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetGuild(lua_State* L)
|
|
{
|
|
// player:getGuild()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Guild* guild = player->getGuild();
|
|
if (!guild) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
pushUserdata<Guild>(L, guild);
|
|
setMetatable(L, -1, "Guild");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetGuild(lua_State* L)
|
|
{
|
|
// player:setGuild(guild)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
player->setGuild(getUserdata<Guild>(L, 2));
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetGuildLevel(lua_State* L)
|
|
{
|
|
// player:getGuildLevel()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && player->getGuild()) {
|
|
lua_pushnumber(L, player->getGuildRank()->level);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetGuildLevel(lua_State* L)
|
|
{
|
|
// player:setGuildLevel(level)
|
|
uint8_t level = getNumber<uint8_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player || !player->getGuild()) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const GuildRank* rank = player->getGuild()->getRankByLevel(level);
|
|
if (!rank) {
|
|
pushBoolean(L, false);
|
|
} else {
|
|
player->setGuildRank(rank);
|
|
pushBoolean(L, true);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetGuildNick(lua_State* L)
|
|
{
|
|
// player:getGuildNick()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushString(L, player->getGuildNick());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetGuildNick(lua_State* L)
|
|
{
|
|
// player:setGuildNick(nick)
|
|
const std::string& nick = getString(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->setGuildNick(nick);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetGroup(lua_State* L)
|
|
{
|
|
// player:getGroup()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushUserdata<Group>(L, player->getGroup());
|
|
setMetatable(L, -1, "Group");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetGroup(lua_State* L)
|
|
{
|
|
// player:setGroup(group)
|
|
Group* group = getUserdata<Group>(L, 2);
|
|
if (!group) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->setGroup(group);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetStamina(lua_State* L)
|
|
{
|
|
// player:getStamina()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getStaminaMinutes());
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetStamina(lua_State* L)
|
|
{
|
|
// player:setStamina(stamina)
|
|
uint16_t stamina = getNumber<uint16_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->staminaMinutes = std::min<uint16_t>(3360, stamina);
|
|
player->sendStats();
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSoul(lua_State* L)
|
|
{
|
|
// player:getSoul()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getSoul());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddSoul(lua_State* L)
|
|
{
|
|
// player:addSoul(soulChange)
|
|
int32_t soulChange = getNumber<int32_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->changeSoul(soulChange);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMaxSoul(lua_State* L)
|
|
{
|
|
// player:getMaxSoul()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player && player->vocation) {
|
|
lua_pushnumber(L, player->vocation->getSoulMax());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetBankBalance(lua_State* L)
|
|
{
|
|
// player:getBankBalance()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getBankBalance());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetBankBalance(lua_State* L)
|
|
{
|
|
// player:setBankBalance(bankBalance)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int64_t balance = getNumber<int64_t>(L, 2);
|
|
if (balance < 0) {
|
|
reportErrorFunc("Invalid bank balance value.");
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
player->setBankBalance(balance);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetStorageValue(lua_State* L)
|
|
{
|
|
// player:getStorageValue(key)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t key = getNumber<uint32_t>(L, 2);
|
|
int32_t value;
|
|
if (player->getStorageValue(key, value)) {
|
|
lua_pushnumber(L, value);
|
|
} else {
|
|
lua_pushnumber(L, 0);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetStorageValue(lua_State* L)
|
|
{
|
|
// player:setStorageValue(key, value)
|
|
int32_t value = getNumber<int32_t>(L, 3);
|
|
uint32_t key = getNumber<uint32_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->addStorageValue(key, value);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddItem(lua_State* L)
|
|
{
|
|
// player:addItem(itemId[, count = 1[, canDropOnMap = true[, subType = 1[, slot = CONST_SLOT_WHEREEVER]]]])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int32_t count = getNumber<int32_t>(L, 3, 1);
|
|
int32_t subType = getNumber<int32_t>(L, 5, 1);
|
|
|
|
const ItemType& it = Item::items[itemId];
|
|
|
|
int32_t itemCount = 1;
|
|
int parameters = lua_gettop(L);
|
|
if (parameters >= 4) {
|
|
itemCount = std::max<int32_t>(1, count);
|
|
} else if (it.hasSubType()) {
|
|
if (it.stackable) {
|
|
itemCount = std::ceil(count / 100.f);
|
|
}
|
|
|
|
subType = count;
|
|
} else {
|
|
itemCount = std::max<int32_t>(1, count);
|
|
}
|
|
|
|
bool hasTable = itemCount > 1;
|
|
if (hasTable) {
|
|
lua_newtable(L);
|
|
} else if (itemCount == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
bool canDropOnMap = getBoolean(L, 4, true);
|
|
slots_t slot = getNumber<slots_t>(L, 6, CONST_SLOT_WHEREEVER);
|
|
for (int32_t i = 1; i <= itemCount; ++i) {
|
|
int32_t stackCount = subType;
|
|
if (it.stackable) {
|
|
stackCount = std::min<int32_t>(stackCount, 100);
|
|
subType -= stackCount;
|
|
}
|
|
|
|
Item* item = Item::CreateItem(itemId, stackCount);
|
|
if (!item) {
|
|
if (!hasTable) {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
ReturnValue ret = g_game.internalPlayerAddItem(player, item, canDropOnMap, slot);
|
|
if (ret != RETURNVALUE_NOERROR) {
|
|
delete item;
|
|
if (!hasTable) {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
if (hasTable) {
|
|
lua_pushnumber(L, i);
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
lua_settable(L, -3);
|
|
} else {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddItemEx(lua_State* L)
|
|
{
|
|
// player:addItemEx(item[, canDropOnMap = false[, index = INDEX_WHEREEVER[, flags = 0]]])
|
|
// player:addItemEx(item[, canDropOnMap = true[, slot = CONST_SLOT_WHEREEVER]])
|
|
Item* item = getUserdata<Item>(L, 2);
|
|
if (!item) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (item->getParent() != VirtualCylinder::virtualCylinder) {
|
|
reportErrorFunc("Item already has a parent");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
bool canDropOnMap = getBoolean(L, 3, false);
|
|
ReturnValue returnValue;
|
|
if (canDropOnMap) {
|
|
slots_t slot = getNumber<slots_t>(L, 4, CONST_SLOT_WHEREEVER);
|
|
returnValue = g_game.internalPlayerAddItem(player, item, true, slot);
|
|
} else {
|
|
int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
|
|
uint32_t flags = getNumber<uint32_t>(L, 5, 0);
|
|
returnValue = g_game.internalAddItem(player, item, index, flags);
|
|
}
|
|
|
|
if (returnValue == RETURNVALUE_NOERROR) {
|
|
ScriptEnvironment::removeTempItem(item);
|
|
}
|
|
lua_pushnumber(L, returnValue);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveItem(lua_State* L)
|
|
{
|
|
// player:removeItem(itemId, count[, subType = -1[, ignoreEquipped = false]])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
uint32_t count = getNumber<uint32_t>(L, 3);
|
|
int32_t subType = getNumber<int32_t>(L, 4, -1);
|
|
bool ignoreEquipped = getBoolean(L, 5, false);
|
|
pushBoolean(L, player->removeItemOfType(itemId, count, subType, ignoreEquipped));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetMoney(lua_State* L)
|
|
{
|
|
// player:getMoney()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getMoney());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddMoney(lua_State* L)
|
|
{
|
|
// player:addMoney(money)
|
|
uint64_t money = getNumber<uint64_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
g_game.addMoney(player, money);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L)
|
|
{
|
|
// player:removeMoney(money)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint64_t money = getNumber<uint64_t>(L, 2);
|
|
pushBoolean(L, g_game.removeMoney(player, money));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerShowTextDialog(lua_State* L)
|
|
{
|
|
// player:showTextDialog(itemId[, text[, canWrite[, length]]])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int32_t length = getNumber<int32_t>(L, 5, -1);
|
|
bool canWrite = getBoolean(L, 4, false);
|
|
std::string text;
|
|
|
|
int parameters = lua_gettop(L);
|
|
if (parameters >= 3) {
|
|
text = getString(L, 3);
|
|
}
|
|
|
|
uint16_t itemId;
|
|
if (isNumber(L, 2)) {
|
|
itemId = getNumber<uint16_t>(L, 2);
|
|
} else {
|
|
itemId = Item::items.getItemIdByName(getString(L, 2));
|
|
if (itemId == 0) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Item* item = Item::CreateItem(itemId);
|
|
if (!item) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (length < 0) {
|
|
length = Item::items[item->getID()].maxTextLen;
|
|
}
|
|
|
|
if (!text.empty()) {
|
|
item->setText(text);
|
|
length = std::max<int32_t>(text.size(), length);
|
|
}
|
|
|
|
item->setParent(player);
|
|
player->setWriteItem(item, length);
|
|
player->sendTextWindow(item, length, canWrite);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSendTextMessage(lua_State* L)
|
|
{
|
|
// player:sendTextMessage(type, text)
|
|
TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->sendTextMessage(message);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSendPrivateMessage(lua_State* L)
|
|
{
|
|
// player:sendPrivateMessage(speaker, text[, type])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Player* speaker = getUserdata<const Player>(L, 2);
|
|
const std::string& text = getString(L, 3);
|
|
SpeakClasses type = getNumber<SpeakClasses>(L, 4, TALKTYPE_PRIVATE);
|
|
player->sendPrivateMessage(speaker, type, text);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerChannelSay(lua_State* L)
|
|
{
|
|
// player:channelSay(speaker, type, text, channelId)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* speaker = getCreature(L, 2);
|
|
SpeakClasses type = getNumber<SpeakClasses>(L, 3);
|
|
const std::string& text = getString(L, 4);
|
|
uint16_t channelId = getNumber<uint16_t>(L, 5);
|
|
player->sendToChannel(speaker, type, text, channelId);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerOpenChannel(lua_State* L)
|
|
{
|
|
// player:openChannel(channelId)
|
|
uint16_t channelId = getNumber<uint16_t>(L, 2);
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
g_game.playerOpenChannel(player->getID(), channelId);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetSlotItem(lua_State* L)
|
|
{
|
|
// player:getSlotItem(slot)
|
|
const Player* player = getUserdata<const Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t slot = getNumber<uint32_t>(L, 2);
|
|
Thing* thing = player->getThing(slot);
|
|
if (!thing) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Item* item = thing->getItem();
|
|
if (item) {
|
|
pushUserdata<Item>(L, item);
|
|
setItemMetatable(L, -1, item);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetParty(lua_State* L)
|
|
{
|
|
// player:getParty()
|
|
const Player* player = getUserdata<const Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Party* party = player->getParty();
|
|
if (party) {
|
|
pushUserdata<Party>(L, party);
|
|
setMetatable(L, -1, "Party");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddOutfit(lua_State* L)
|
|
{
|
|
// player:addOutfit(lookType)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->addOutfit(getNumber<uint16_t>(L, 2), 0);
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddOutfitAddon(lua_State* L)
|
|
{
|
|
// player:addOutfitAddon(lookType, addon)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint16_t lookType = getNumber<uint16_t>(L, 2);
|
|
uint8_t addon = getNumber<uint8_t>(L, 3);
|
|
player->addOutfit(lookType, addon);
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveOutfit(lua_State* L)
|
|
{
|
|
// player:removeOutfit(lookType)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint16_t lookType = getNumber<uint16_t>(L, 2);
|
|
pushBoolean(L, player->removeOutfit(lookType));
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveOutfitAddon(lua_State* L)
|
|
{
|
|
// player:removeOutfitAddon(lookType, addon)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint16_t lookType = getNumber<uint16_t>(L, 2);
|
|
uint8_t addon = getNumber<uint8_t>(L, 3);
|
|
pushBoolean(L, player->removeOutfitAddon(lookType, addon));
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerHasOutfit(lua_State* L)
|
|
{
|
|
// player:hasOutfit(lookType[, addon = 0])
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint16_t lookType = getNumber<uint16_t>(L, 2);
|
|
uint8_t addon = getNumber<uint8_t>(L, 3, 0);
|
|
pushBoolean(L, player->canWear(lookType, addon));
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSendOutfitWindow(lua_State* L)
|
|
{
|
|
// player:sendOutfitWindow()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->sendOutfitWindow();
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetPremiumDays(lua_State* L)
|
|
{
|
|
// player:getPremiumDays()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->premiumDays);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddPremiumDays(lua_State* L)
|
|
{
|
|
// player:addPremiumDays(days)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
|
|
uint16_t days = getNumber<uint16_t>(L, 2);
|
|
int32_t addDays = std::min<int32_t>(0xFFFE - player->premiumDays, days);
|
|
if (addDays > 0) {
|
|
player->setPremiumDays(player->premiumDays + addDays);
|
|
IOLoginData::addPremiumDays(player->getAccount(), addDays);
|
|
}
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemovePremiumDays(lua_State* L)
|
|
{
|
|
// player:removePremiumDays(days)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
|
|
uint16_t days = getNumber<uint16_t>(L, 2);
|
|
int32_t removeDays = std::min<int32_t>(player->premiumDays, days);
|
|
if (removeDays > 0) {
|
|
player->setPremiumDays(player->premiumDays - removeDays);
|
|
IOLoginData::removePremiumDays(player->getAccount(), removeDays);
|
|
}
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerHasBlessing(lua_State* L)
|
|
{
|
|
// player:hasBlessing(blessing)
|
|
uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushBoolean(L, player->hasBlessing(blessing));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerAddBlessing(lua_State* L)
|
|
{
|
|
// player:addBlessing(blessing)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
|
|
if (player->hasBlessing(blessing)) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
player->addBlessing(1 << blessing);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerRemoveBlessing(lua_State* L)
|
|
{
|
|
// player:removeBlessing(blessing)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
|
|
if (!player->hasBlessing(blessing)) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
player->removeBlessing(1 << blessing);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerCanLearnSpell(lua_State* L)
|
|
{
|
|
// player:canLearnSpell(spellName)
|
|
const Player* player = getUserdata<const Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const std::string& spellName = getString(L, 2);
|
|
InstantSpell* spell = g_spells->getInstantSpellByName(spellName);
|
|
if (!spell) {
|
|
reportErrorFunc("Spell \"" + spellName + "\" not found");
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (player->hasFlag(PlayerFlag_IgnoreSpellCheck)) {
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
const auto& vocMap = spell->getVocMap();
|
|
if (vocMap.count(player->getVocationId()) == 0) {
|
|
pushBoolean(L, false);
|
|
} else if (player->getLevel() < spell->getLevel()) {
|
|
pushBoolean(L, false);
|
|
} else if (player->getMagicLevel() < spell->getMagicLevel()) {
|
|
pushBoolean(L, false);
|
|
} else {
|
|
pushBoolean(L, true);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerLearnSpell(lua_State* L)
|
|
{
|
|
// player:learnSpell(spellName)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
const std::string& spellName = getString(L, 2);
|
|
player->learnInstantSpell(spellName);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerForgetSpell(lua_State* L)
|
|
{
|
|
// player:forgetSpell(spellName)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
const std::string& spellName = getString(L, 2);
|
|
player->forgetInstantSpell(spellName);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerHasLearnedSpell(lua_State* L)
|
|
{
|
|
// player:hasLearnedSpell(spellName)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
const std::string& spellName = getString(L, 2);
|
|
pushBoolean(L, player->hasLearnedInstantSpell(spellName));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSave(lua_State* L)
|
|
{
|
|
// player:save()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
player->loginPosition = player->getPosition();
|
|
pushBoolean(L, IOLoginData::savePlayer(player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerIsPzLocked(lua_State* L)
|
|
{
|
|
// player:isPzLocked()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
pushBoolean(L, player->isPzLocked());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetClient(lua_State* L)
|
|
{
|
|
// player:getClient()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_createtable(L, 0, 2);
|
|
setField(L, "version", player->getProtocolVersion());
|
|
setField(L, "os", player->getOperatingSystem());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetHouse(lua_State* L)
|
|
{
|
|
// player:getHouse()
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
House* house = g_game.map.houses.getHouseByPlayerId(player->getGUID());
|
|
if (house) {
|
|
pushUserdata<House>(L, house);
|
|
setMetatable(L, -1, "House");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerSetGhostMode(lua_State* L)
|
|
{
|
|
// player:setGhostMode(enabled)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
bool enabled = getBoolean(L, 2);
|
|
if (player->isInGhostMode() == enabled) {
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
player->switchGhostMode();
|
|
|
|
Tile* tile = player->getTile();
|
|
const Position& position = player->getPosition();
|
|
|
|
SpectatorVec list;
|
|
g_game.map.getSpectators(list, position, true, true);
|
|
for (Creature* spectator : list) {
|
|
Player* tmpPlayer = spectator->getPlayer();
|
|
if (tmpPlayer != player && !tmpPlayer->isAccessPlayer()) {
|
|
if (enabled) {
|
|
tmpPlayer->sendRemoveTileThing(position, tile->getStackposOfCreature(tmpPlayer, player));
|
|
} else {
|
|
tmpPlayer->sendCreatureAppear(player, position, true);
|
|
}
|
|
} else {
|
|
tmpPlayer->sendCreatureChangeVisible(player, !enabled);
|
|
}
|
|
}
|
|
|
|
if (player->isInGhostMode()) {
|
|
for (const auto& it : g_game.getPlayers()) {
|
|
if (!it.second->isAccessPlayer()) {
|
|
it.second->notifyStatusChange(player, VIPSTATUS_OFFLINE);
|
|
}
|
|
}
|
|
IOLoginData::updateOnlineStatus(player->getGUID(), false);
|
|
} else {
|
|
for (const auto& it : g_game.getPlayers()) {
|
|
if (!it.second->isAccessPlayer()) {
|
|
it.second->notifyStatusChange(player, VIPSTATUS_ONLINE);
|
|
}
|
|
}
|
|
IOLoginData::updateOnlineStatus(player->getGUID(), true);
|
|
}
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetContainerId(lua_State* L)
|
|
{
|
|
// player:getContainerId(container)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Container* container = getUserdata<Container>(L, 2);
|
|
if (container) {
|
|
lua_pushnumber(L, player->getContainerID(container));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetContainerById(lua_State* L)
|
|
{
|
|
// player:getContainerById(id)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (!player) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Container* container = player->getContainerByID(getNumber<uint8_t>(L, 2));
|
|
if (container) {
|
|
pushUserdata<Container>(L, container);
|
|
setMetatable(L, -1, "Container");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetContainerIndex(lua_State* L)
|
|
{
|
|
// player:getContainerIndex(id)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
lua_pushnumber(L, player->getContainerIndex(getNumber<uint8_t>(L, 2)));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPlayerGetTotalDamage(lua_State * L)
|
|
{
|
|
// player:getTotalDamage(attackSkill, attackValue, fightMode)
|
|
Player* player = getUserdata<Player>(L, 1);
|
|
if (player) {
|
|
uint32_t attackSkill = getNumber<uint32_t>(L, 2);
|
|
uint32_t attackValue = getNumber<uint32_t>(L, 3);
|
|
fightMode_t fightMode = static_cast<fightMode_t>(getNumber(L, 4, FIGHTMODE_BALANCED));
|
|
|
|
lua_pushnumber(L, Combat::getTotalDamage(attackSkill, attackValue, fightMode));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Monster
|
|
int LuaScriptInterface::luaMonsterCreate(lua_State* L)
|
|
{
|
|
// Monster(id or userdata)
|
|
Monster* monster;
|
|
if (isNumber(L, 2)) {
|
|
monster = g_game.getMonsterByID(getNumber<uint32_t>(L, 2));
|
|
} else if (isUserdata(L, 2)) {
|
|
if (getUserdataType(L, 2) != LuaData_Monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
monster = getUserdata<Monster>(L, 2);
|
|
} else {
|
|
monster = nullptr;
|
|
}
|
|
|
|
if (monster) {
|
|
pushUserdata<Monster>(L, monster);
|
|
setMetatable(L, -1, "Monster");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsMonster(lua_State* L)
|
|
{
|
|
// monster:isMonster()
|
|
pushBoolean(L, getUserdata<const Monster>(L, 1) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetType(lua_State* L)
|
|
{
|
|
// monster:getType()
|
|
const Monster* monster = getUserdata<const Monster>(L, 1);
|
|
if (monster) {
|
|
pushUserdata<MonsterType>(L, monster->mType);
|
|
setMetatable(L, -1, "MonsterType");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetSpawnPosition(lua_State* L)
|
|
{
|
|
// monster:getSpawnPosition()
|
|
const Monster* monster = getUserdata<const Monster>(L, 1);
|
|
if (monster) {
|
|
pushPosition(L, monster->getMasterPos());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsInSpawnRange(lua_State* L)
|
|
{
|
|
// monster:isInSpawnRange([position])
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
pushBoolean(L, monster->isInSpawnRange(lua_gettop(L) >= 2 ? getPosition(L, 2) : monster->getPosition()));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsIdle(lua_State* L)
|
|
{
|
|
// monster:isIdle()
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
pushBoolean(L, monster->getIdleStatus());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterSetIdle(lua_State* L)
|
|
{
|
|
// monster:setIdle(idle)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
monster->setIdle(getBoolean(L, 2));
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsTarget(lua_State* L)
|
|
{
|
|
// monster:isTarget(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
const Creature* creature = getCreature(L, 2);
|
|
pushBoolean(L, monster->isTarget(creature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsOpponent(lua_State* L)
|
|
{
|
|
// monster:isOpponent(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
const Creature* creature = getCreature(L, 2);
|
|
pushBoolean(L, monster->isOpponent(creature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterIsFriend(lua_State* L)
|
|
{
|
|
// monster:isFriend(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
const Creature* creature = getCreature(L, 2);
|
|
pushBoolean(L, monster->isFriend(creature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterAddFriend(lua_State* L)
|
|
{
|
|
// monster:addFriend(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
Creature* creature = getCreature(L, 2);
|
|
monster->addFriend(creature);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterRemoveFriend(lua_State* L)
|
|
{
|
|
// monster:removeFriend(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
Creature* creature = getCreature(L, 2);
|
|
monster->removeFriend(creature);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetFriendList(lua_State* L)
|
|
{
|
|
// monster:getFriendList()
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& friendList = monster->getFriendList();
|
|
lua_createtable(L, friendList.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Creature* creature : friendList) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetFriendCount(lua_State* L)
|
|
{
|
|
// monster:getFriendCount()
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
lua_pushnumber(L, monster->getFriendList().size());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterAddTarget(lua_State* L)
|
|
{
|
|
// monster:addTarget(creature[, pushFront = false])
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = getCreature(L, 2);
|
|
bool pushFront = getBoolean(L, 3, false);
|
|
monster->addTarget(creature, pushFront);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterRemoveTarget(lua_State* L)
|
|
{
|
|
// monster:removeTarget(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
monster->removeTarget(getCreature(L, 2));
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetTargetList(lua_State* L)
|
|
{
|
|
// monster:getTargetList()
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (!monster) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& targetList = monster->getTargetList();
|
|
lua_createtable(L, targetList.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Creature* creature : targetList) {
|
|
pushUserdata<Creature>(L, creature);
|
|
setCreatureMetatable(L, -1, creature);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterGetTargetCount(lua_State* L)
|
|
{
|
|
// monster:getTargetCount()
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
lua_pushnumber(L, monster->getTargetList().size());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterSelectTarget(lua_State* L)
|
|
{
|
|
// monster:selectTarget(creature)
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
Creature* creature = getCreature(L, 2);
|
|
pushBoolean(L, monster->selectTarget(creature));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterSearchTarget(lua_State* L)
|
|
{
|
|
// monster:searchTarget([searchType = TARGETSEARCH_ANY])
|
|
Monster* monster = getUserdata<Monster>(L, 1);
|
|
if (monster) {
|
|
TargetSearchType_t searchType = getNumber<TargetSearchType_t>(L, 2, TARGETSEARCH_ANY);
|
|
pushBoolean(L, monster->searchTarget(searchType));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Npc
|
|
int LuaScriptInterface::luaNpcCreate(lua_State* L)
|
|
{
|
|
// Npc([id or name or userdata])
|
|
Npc* npc;
|
|
if (lua_gettop(L) >= 2) {
|
|
if (isNumber(L, 2)) {
|
|
npc = g_game.getNpcByID(getNumber<uint32_t>(L, 2));
|
|
} else if (isString(L, 2)) {
|
|
npc = g_game.getNpcByName(getString(L, 2));
|
|
} else if (isUserdata(L, 2)) {
|
|
if (getUserdataType(L, 2) != LuaData_Npc) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
npc = getUserdata<Npc>(L, 2);
|
|
} else {
|
|
npc = nullptr;
|
|
}
|
|
} else {
|
|
npc = getScriptEnv()->getNpc();
|
|
}
|
|
|
|
if (npc) {
|
|
pushUserdata<Npc>(L, npc);
|
|
setMetatable(L, -1, "Npc");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNpcIsNpc(lua_State* L)
|
|
{
|
|
// npc:isNpc()
|
|
pushBoolean(L, getUserdata<const Npc>(L, 1) != nullptr);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaNpcSetMasterPos(lua_State* L)
|
|
{
|
|
// npc:setMasterPos(pos[, radius])
|
|
Npc* npc = getUserdata<Npc>(L, 1);
|
|
if (!npc) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const Position& pos = getPosition(L, 2);
|
|
int32_t radius = getNumber<int32_t>(L, 3, 1);
|
|
npc->setMasterPos(pos, radius);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
// Guild
|
|
int LuaScriptInterface::luaGuildCreate(lua_State* L)
|
|
{
|
|
// Guild(id)
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
|
|
Guild* guild = g_game.getGuild(id);
|
|
if (guild) {
|
|
pushUserdata<Guild>(L, guild);
|
|
setMetatable(L, -1, "Guild");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildGetId(lua_State* L)
|
|
{
|
|
// guild:getId()
|
|
Guild* guild = getUserdata<Guild>(L, 1);
|
|
if (guild) {
|
|
lua_pushnumber(L, guild->getId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildGetName(lua_State* L)
|
|
{
|
|
// guild:getName()
|
|
Guild* guild = getUserdata<Guild>(L, 1);
|
|
if (guild) {
|
|
pushString(L, guild->getName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildGetMembersOnline(lua_State* L)
|
|
{
|
|
// guild:getMembersOnline()
|
|
const Guild* guild = getUserdata<const Guild>(L, 1);
|
|
if (!guild) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& members = guild->getMembersOnline();
|
|
lua_createtable(L, members.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Player* player : members) {
|
|
pushUserdata<Player>(L, player);
|
|
setMetatable(L, -1, "Player");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildAddRank(lua_State* L)
|
|
{
|
|
// guild:addRank(id, name, level)
|
|
Guild* guild = getUserdata<Guild>(L, 1);
|
|
if (guild) {
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
const std::string& name = getString(L, 3);
|
|
uint8_t level = getNumber<uint8_t>(L, 4);
|
|
guild->addRank(id, name, level);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildGetRankById(lua_State* L)
|
|
{
|
|
// guild:getRankById(id)
|
|
Guild* guild = getUserdata<Guild>(L, 1);
|
|
if (!guild) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
GuildRank* rank = guild->getRankById(id);
|
|
if (rank) {
|
|
lua_createtable(L, 0, 3);
|
|
setField(L, "id", rank->id);
|
|
setField(L, "name", rank->name);
|
|
setField(L, "level", rank->level);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGuildGetRankByLevel(lua_State* L)
|
|
{
|
|
// guild:getRankByLevel(level)
|
|
const Guild* guild = getUserdata<const Guild>(L, 1);
|
|
if (!guild) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint8_t level = getNumber<uint8_t>(L, 2);
|
|
const GuildRank* rank = guild->getRankByLevel(level);
|
|
if (rank) {
|
|
lua_createtable(L, 0, 3);
|
|
setField(L, "id", rank->id);
|
|
setField(L, "name", rank->name);
|
|
setField(L, "level", rank->level);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Group
|
|
int LuaScriptInterface::luaGroupCreate(lua_State* L)
|
|
{
|
|
// Group(id)
|
|
uint32_t id = getNumber<uint32_t>(L, 2);
|
|
|
|
Group* group = g_game.groups.getGroup(id);
|
|
if (group) {
|
|
pushUserdata<Group>(L, group);
|
|
setMetatable(L, -1, "Group");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetId(lua_State* L)
|
|
{
|
|
// group:getId()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
lua_pushnumber(L, group->id);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetName(lua_State* L)
|
|
{
|
|
// group:getName()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
pushString(L, group->name);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetFlags(lua_State* L)
|
|
{
|
|
// group:getFlags()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
lua_pushnumber(L, group->flags);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetAccess(lua_State* L)
|
|
{
|
|
// group:getAccess()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
pushBoolean(L, group->access);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetMaxDepotItems(lua_State* L)
|
|
{
|
|
// group:getMaxDepotItems()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
lua_pushnumber(L, group->maxDepotItems);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaGroupGetMaxVipEntries(lua_State* L)
|
|
{
|
|
// group:getMaxVipEntries()
|
|
Group* group = getUserdata<Group>(L, 1);
|
|
if (group) {
|
|
lua_pushnumber(L, group->maxVipEntries);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Vocation
|
|
int LuaScriptInterface::luaVocationCreate(lua_State* L)
|
|
{
|
|
// Vocation(id or name)
|
|
uint32_t id;
|
|
if (isNumber(L, 2)) {
|
|
id = getNumber<uint32_t>(L, 2);
|
|
} else {
|
|
id = g_vocations.getVocationId(getString(L, 2));
|
|
}
|
|
|
|
Vocation* vocation = g_vocations.getVocation(id);
|
|
if (vocation) {
|
|
pushUserdata<Vocation>(L, vocation);
|
|
setMetatable(L, -1, "Vocation");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetId(lua_State* L)
|
|
{
|
|
// vocation:getId()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetName(lua_State* L)
|
|
{
|
|
// vocation:getName()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
pushString(L, vocation->getVocName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetDescription(lua_State* L)
|
|
{
|
|
// vocation:getDescription()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
pushString(L, vocation->getVocDescription());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetRequiredSkillTries(lua_State* L)
|
|
{
|
|
// vocation:getRequiredSkillTries(skillType, skillLevel)
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
skills_t skillType = getNumber<skills_t>(L, 2);
|
|
uint16_t skillLevel = getNumber<uint16_t>(L, 3);
|
|
lua_pushnumber(L, vocation->getReqSkillTries(skillType, skillLevel));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetRequiredManaSpent(lua_State* L)
|
|
{
|
|
// vocation:getRequiredManaSpent(magicLevel)
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
uint32_t magicLevel = getNumber<uint32_t>(L, 2);
|
|
lua_pushnumber(L, vocation->getReqMana(magicLevel));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetCapacityGain(lua_State* L)
|
|
{
|
|
// vocation:getCapacityGain()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getCapGain());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetHealthGain(lua_State* L)
|
|
{
|
|
// vocation:getHealthGain()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getHPGain());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetHealthGainTicks(lua_State* L)
|
|
{
|
|
// vocation:getHealthGainTicks()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getHealthGainTicks());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetHealthGainAmount(lua_State* L)
|
|
{
|
|
// vocation:getHealthGainAmount()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getHealthGainAmount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetManaGain(lua_State* L)
|
|
{
|
|
// vocation:getManaGain()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getManaGain());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetManaGainTicks(lua_State* L)
|
|
{
|
|
// vocation:getManaGainTicks()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getManaGainTicks());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetManaGainAmount(lua_State* L)
|
|
{
|
|
// vocation:getManaGainAmount()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getManaGainAmount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetMaxSoul(lua_State* L)
|
|
{
|
|
// vocation:getMaxSoul()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getSoulMax());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetSoulGainTicks(lua_State* L)
|
|
{
|
|
// vocation:getSoulGainTicks()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getSoulGainTicks());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetAttackSpeed(lua_State* L)
|
|
{
|
|
// vocation:getAttackSpeed()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getAttackSpeed());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetBaseSpeed(lua_State* L)
|
|
{
|
|
// vocation:getBaseSpeed()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (vocation) {
|
|
lua_pushnumber(L, vocation->getBaseSpeed());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetDemotion(lua_State* L)
|
|
{
|
|
// vocation:getDemotion()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (!vocation) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t fromId = vocation->getFromVocation();
|
|
if (fromId == VOCATION_NONE) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Vocation* demotedVocation = g_vocations.getVocation(fromId);
|
|
if (demotedVocation && demotedVocation != vocation) {
|
|
pushUserdata<Vocation>(L, demotedVocation);
|
|
setMetatable(L, -1, "Vocation");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaVocationGetPromotion(lua_State* L)
|
|
{
|
|
// vocation:getPromotion()
|
|
Vocation* vocation = getUserdata<Vocation>(L, 1);
|
|
if (!vocation) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint16_t promotedId = g_vocations.getPromotedVocation(vocation->getId());
|
|
if (promotedId == VOCATION_NONE) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Vocation* promotedVocation = g_vocations.getVocation(promotedId);
|
|
if (promotedVocation && promotedVocation != vocation) {
|
|
pushUserdata<Vocation>(L, promotedVocation);
|
|
setMetatable(L, -1, "Vocation");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Town
|
|
int LuaScriptInterface::luaTownCreate(lua_State* L)
|
|
{
|
|
// Town(id or name)
|
|
Town* town;
|
|
if (isNumber(L, 2)) {
|
|
town = g_game.map.towns.getTown(getNumber<uint32_t>(L, 2));
|
|
} else if (isString(L, 2)) {
|
|
town = g_game.map.towns.getTown(getString(L, 2));
|
|
} else {
|
|
town = nullptr;
|
|
}
|
|
|
|
if (town) {
|
|
pushUserdata<Town>(L, town);
|
|
setMetatable(L, -1, "Town");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTownGetId(lua_State* L)
|
|
{
|
|
// town:getId()
|
|
Town* town = getUserdata<Town>(L, 1);
|
|
if (town) {
|
|
lua_pushnumber(L, town->getID());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTownGetName(lua_State* L)
|
|
{
|
|
// town:getName()
|
|
Town* town = getUserdata<Town>(L, 1);
|
|
if (town) {
|
|
pushString(L, town->getName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaTownGetTemplePosition(lua_State* L)
|
|
{
|
|
// town:getTemplePosition()
|
|
Town* town = getUserdata<Town>(L, 1);
|
|
if (town) {
|
|
pushPosition(L, town->getTemplePosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// House
|
|
int LuaScriptInterface::luaHouseCreate(lua_State* L)
|
|
{
|
|
// House(id)
|
|
House* house = g_game.map.houses.getHouse(getNumber<uint32_t>(L, 2));
|
|
if (house) {
|
|
pushUserdata<House>(L, house);
|
|
setMetatable(L, -1, "House");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetId(lua_State* L)
|
|
{
|
|
// house:getId()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetName(lua_State* L)
|
|
{
|
|
// house:getName()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
pushString(L, house->getName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetTown(lua_State* L)
|
|
{
|
|
// house:getTown()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Town* town = g_game.map.towns.getTown(house->getTownId());
|
|
if (town) {
|
|
pushUserdata<Town>(L, town);
|
|
setMetatable(L, -1, "Town");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetExitPosition(lua_State* L)
|
|
{
|
|
// house:getExitPosition()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
pushPosition(L, house->getEntryPosition());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetRent(lua_State* L)
|
|
{
|
|
// house:getRent()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getRent());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetOwnerGuid(lua_State* L)
|
|
{
|
|
// house:getOwnerGuid()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getOwner());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseSetOwnerGuid(lua_State* L)
|
|
{
|
|
// house:setOwnerGuid(guid[, updateDatabase = true])
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
uint32_t guid = getNumber<uint32_t>(L, 2);
|
|
bool updateDatabase = getBoolean(L, 3, true);
|
|
house->setOwner(guid, updateDatabase);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseStartTrade(lua_State* L)
|
|
{
|
|
// house:startTrade(player, tradePartner)
|
|
House* house = getUserdata<House>(L, 1);
|
|
Player* player = getUserdata<Player>(L, 2);
|
|
Player* tradePartner = getUserdata<Player>(L, 3);
|
|
|
|
if (!player || !tradePartner || !house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
if (!Position::areInRange<2, 2, 0>(tradePartner->getPosition(), player->getPosition())) {
|
|
lua_pushnumber(L, RETURNVALUE_TRADEPLAYERFARAWAY);
|
|
return 1;
|
|
}
|
|
|
|
if (house->getOwner() != player->getGUID()) {
|
|
lua_pushnumber(L, RETURNVALUE_YOUDONTOWNTHISHOUSE);
|
|
return 1;
|
|
}
|
|
|
|
if (g_game.map.houses.getHouseByPlayerId(tradePartner->getGUID())) {
|
|
lua_pushnumber(L, RETURNVALUE_TRADEPLAYERALREADYOWNSAHOUSE);
|
|
return 1;
|
|
}
|
|
|
|
if (IOLoginData::hasBiddedOnHouse(tradePartner->getGUID())) {
|
|
lua_pushnumber(L, RETURNVALUE_TRADEPLAYERHIGHESTBIDDER);
|
|
return 1;
|
|
}
|
|
|
|
Item* transferItem = house->getTransferItem();
|
|
if (!transferItem) {
|
|
lua_pushnumber(L, RETURNVALUE_YOUCANNOTTRADETHISHOUSE);
|
|
return 1;
|
|
}
|
|
|
|
transferItem->getParent()->setParent(player);
|
|
if (!g_game.internalStartTrade(player, tradePartner, transferItem)) {
|
|
house->resetTransferItem();
|
|
}
|
|
|
|
lua_pushnumber(L, RETURNVALUE_NOERROR);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetBeds(lua_State* L)
|
|
{
|
|
// house:getBeds()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& beds = house->getBeds();
|
|
lua_createtable(L, beds.size(), 0);
|
|
|
|
int index = 0;
|
|
for (BedItem* bedItem : beds) {
|
|
pushUserdata<Item>(L, bedItem);
|
|
setItemMetatable(L, -1, bedItem);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetBedCount(lua_State* L)
|
|
{
|
|
// house:getBedCount()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getBedCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetDoors(lua_State* L)
|
|
{
|
|
// house:getDoors()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& doors = house->getDoors();
|
|
lua_createtable(L, doors.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Door* door : doors) {
|
|
pushUserdata<Item>(L, door);
|
|
setItemMetatable(L, -1, door);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetDoorCount(lua_State* L)
|
|
{
|
|
// house:getDoorCount()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getDoors().size());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetTiles(lua_State* L)
|
|
{
|
|
// house:getTiles()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const auto& tiles = house->getTiles();
|
|
lua_createtable(L, tiles.size(), 0);
|
|
|
|
int index = 0;
|
|
for (Tile* tile : tiles) {
|
|
pushUserdata<Tile>(L, tile);
|
|
setMetatable(L, -1, "Tile");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetTileCount(lua_State* L)
|
|
{
|
|
// house:getTileCount()
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (house) {
|
|
lua_pushnumber(L, house->getTiles().size());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseGetAccessList(lua_State* L)
|
|
{
|
|
// house:getAccessList(listId)
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
std::string list;
|
|
uint32_t listId = getNumber<uint32_t>(L, 2);
|
|
if (house->getAccessList(listId, list)) {
|
|
pushString(L, list);
|
|
} else {
|
|
pushBoolean(L, false);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaHouseSetAccessList(lua_State* L)
|
|
{
|
|
// house:setAccessList(listId, list)
|
|
House* house = getUserdata<House>(L, 1);
|
|
if (!house) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t listId = getNumber<uint32_t>(L, 2);
|
|
const std::string& list = getString(L, 3);
|
|
house->setAccessList(listId, list);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
// ItemType
|
|
int LuaScriptInterface::luaItemTypeCreate(lua_State* L)
|
|
{
|
|
// ItemType(id or name)
|
|
uint32_t id;
|
|
if (isNumber(L, 2)) {
|
|
id = getNumber<uint32_t>(L, 2);
|
|
} else {
|
|
id = Item::items.getItemIdByName(getString(L, 2));
|
|
}
|
|
|
|
const ItemType& itemType = Item::items[id];
|
|
pushUserdata<const ItemType>(L, &itemType);
|
|
setMetatable(L, -1, "ItemType");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsCorpse(lua_State* L)
|
|
{
|
|
// itemType:isCorpse()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->corpse);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsDoor(lua_State* L)
|
|
{
|
|
// itemType:isDoor()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isDoor());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsContainer(lua_State* L)
|
|
{
|
|
// itemType:isContainer()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isContainer());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsChest(lua_State * L)
|
|
{
|
|
// itemType:isChest()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isChest());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsFluidContainer(lua_State* L)
|
|
{
|
|
// itemType:isFluidContainer()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isFluidContainer());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsMovable(lua_State* L)
|
|
{
|
|
// itemType:isMovable()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->moveable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsRune(lua_State* L)
|
|
{
|
|
// itemType:isRune()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isRune());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsStackable(lua_State* L)
|
|
{
|
|
// itemType:isStackable()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->stackable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsReadable(lua_State* L)
|
|
{
|
|
// itemType:isReadable()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->canReadText);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsWritable(lua_State* L)
|
|
{
|
|
// itemType:isWritable()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->canWriteText);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsMagicField(lua_State* L)
|
|
{
|
|
// itemType:isMagicField()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isMagicField());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsSplash(lua_State* L)
|
|
{
|
|
// itemType:isSplash()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isSplash());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsKey(lua_State* L)
|
|
{
|
|
// itemType:isKey()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->isKey());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsDisguised(lua_State* L)
|
|
{
|
|
// itemType:isDisguised()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->disguise);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsDestroyable(lua_State * L)
|
|
{
|
|
// itemType:isDestroyable()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->destroy);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeIsGroundTile(lua_State * L)
|
|
{
|
|
// itemType:isGroundTile()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->group == ITEM_GROUP_GROUND);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetType(lua_State* L)
|
|
{
|
|
// itemType:getType()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->type);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetId(lua_State* L)
|
|
{
|
|
// itemType:getId()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->id);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetDisguiseId(lua_State * L)
|
|
{
|
|
// itemType:getDisguiseId()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->disguiseId);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetName(lua_State* L)
|
|
{
|
|
// itemType:getName()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushString(L, itemType->name);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetPluralName(lua_State* L)
|
|
{
|
|
// itemType:getPluralName()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushString(L, itemType->getPluralName());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetArticle(lua_State* L)
|
|
{
|
|
// itemType:getArticle()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushString(L, itemType->article);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetDescription(lua_State* L)
|
|
{
|
|
// itemType:getDescription()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushString(L, itemType->description);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetSlotPosition(lua_State *L)
|
|
{
|
|
// itemType:getSlotPosition()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->slotPosition);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetDestroyTarget(lua_State * L)
|
|
{
|
|
// itemType:getDestroyTarget()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->destroyTarget);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetCharges(lua_State* L)
|
|
{
|
|
// itemType:getCharges()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->charges);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetFluidSource(lua_State* L)
|
|
{
|
|
// itemType:getFluidSource()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->fluidSource);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetCapacity(lua_State* L)
|
|
{
|
|
// itemType:getCapacity()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->maxItems);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetWeight(lua_State* L)
|
|
{
|
|
// itemType:getWeight([count = 1])
|
|
uint16_t count = getNumber<uint16_t>(L, 2, 1);
|
|
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (!itemType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint64_t weight = static_cast<uint64_t>(itemType->weight) * std::max<int32_t>(1, count);
|
|
lua_pushnumber(L, weight);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetShootRange(lua_State* L)
|
|
{
|
|
// itemType:getShootRange()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->shootRange);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetAttack(lua_State* L)
|
|
{
|
|
// itemType:getAttack()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->attack);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetDefense(lua_State* L)
|
|
{
|
|
// itemType:getDefense()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->defense);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetArmor(lua_State* L)
|
|
{
|
|
// itemType:getArmor()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->armor);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetWeaponType(lua_State* L)
|
|
{
|
|
// itemType:getWeaponType()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->weaponType);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetTransformEquipId(lua_State* L)
|
|
{
|
|
// itemType:getTransformEquipId()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->transformEquipTo);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetTransformDeEquipId(lua_State* L)
|
|
{
|
|
// itemType:getTransformDeEquipId()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->transformDeEquipTo);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetDecayId(lua_State* L)
|
|
{
|
|
// itemType:getDecayId()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->decayTo);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetNutrition(lua_State* L)
|
|
{
|
|
// itemType:getNutrition()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->nutrition);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeGetRequiredLevel(lua_State* L)
|
|
{
|
|
// itemType:getRequiredLevel()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
lua_pushnumber(L, itemType->minReqLevel);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaItemTypeHasSubType(lua_State* L)
|
|
{
|
|
// itemType:hasSubType()
|
|
const ItemType* itemType = getUserdata<const ItemType>(L, 1);
|
|
if (itemType) {
|
|
pushBoolean(L, itemType->hasSubType());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Combat
|
|
int LuaScriptInterface::luaCombatCreate(lua_State* L)
|
|
{
|
|
// Combat()
|
|
pushUserdata<Combat>(L, g_luaEnvironment.createCombatObject(getScriptEnv()->getScriptInterface()));
|
|
setMetatable(L, -1, "Combat");
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetParameter(lua_State* L)
|
|
{
|
|
// combat:setParameter(key, value)
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (!combat) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CombatParam_t key = getNumber<CombatParam_t>(L, 2);
|
|
uint32_t value;
|
|
if (isBoolean(L, 3)) {
|
|
value = getBoolean(L, 3) ? 1 : 0;
|
|
} else {
|
|
value = getNumber<uint32_t>(L, 3);
|
|
}
|
|
combat->setParam(key, value);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetFormula(lua_State* L)
|
|
{
|
|
// combat:setFormula(type, mina, minb, maxa, maxb)
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (!combat) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
formulaType_t type = getNumber<formulaType_t>(L, 2);
|
|
double mina = getNumber<double>(L, 3);
|
|
double minb = getNumber<double>(L, 4);
|
|
double maxa = getNumber<double>(L, 5);
|
|
double maxb = getNumber<double>(L, 6);
|
|
combat->setPlayerCombatValues(type, mina, minb, maxa, maxb);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetArea(lua_State* L)
|
|
{
|
|
// combat:setArea(area)
|
|
if (getScriptEnv()->getScriptId() != EVENT_ID_LOADING) {
|
|
reportErrorFunc("This function can only be used while loading the script.");
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const AreaCombat* area = g_luaEnvironment.getAreaObject(getNumber<uint32_t>(L, 2));
|
|
if (!area) {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (combat) {
|
|
combat->setArea(new AreaCombat(*area));
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetCondition(lua_State* L)
|
|
{
|
|
// combat:setCondition(condition)
|
|
Condition* condition = getUserdata<Condition>(L, 2);
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (combat && condition) {
|
|
combat->setCondition(condition->clone());
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetCallback(lua_State* L)
|
|
{
|
|
// combat:setCallback(key, function)
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (!combat) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CallBackParam_t key = getNumber<CallBackParam_t>(L, 2);
|
|
if (!combat->setCallback(key)) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
CallBack* callback = combat->getCallback(key);
|
|
if (!callback) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
const std::string& function = getString(L, 3);
|
|
pushBoolean(L, callback->loadCallBack(getScriptEnv()->getScriptInterface(), function));
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatSetOrigin(lua_State* L)
|
|
{
|
|
// combat:setOrigin(origin)
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (combat) {
|
|
combat->setOrigin(getNumber<CombatOrigin>(L, 2));
|
|
pushBoolean(L, true);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaCombatExecute(lua_State* L)
|
|
{
|
|
// combat:execute(creature, variant)
|
|
Combat* combat = getUserdata<Combat>(L, 1);
|
|
if (!combat) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
Creature* creature = getCreature(L, 2);
|
|
|
|
const LuaVariant& variant = getVariant(L, 3);
|
|
switch (variant.type) {
|
|
case VARIANT_NUMBER: {
|
|
Creature* target = g_game.getCreatureByID(variant.number);
|
|
if (!target) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
if (combat->hasArea()) {
|
|
combat->doCombat(creature, target->getPosition());
|
|
} else {
|
|
combat->doCombat(creature, target);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case VARIANT_POSITION: {
|
|
combat->doCombat(creature, variant.pos);
|
|
break;
|
|
}
|
|
|
|
case VARIANT_TARGETPOSITION: {
|
|
if (combat->hasArea()) {
|
|
combat->doCombat(creature, variant.pos);
|
|
} else {
|
|
combat->postCombatEffects(creature, variant.pos);
|
|
g_game.addMagicEffect(variant.pos, CONST_ME_POFF);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case VARIANT_STRING: {
|
|
Player* target = g_game.getPlayerByName(variant.text);
|
|
if (!target) {
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
combat->doCombat(creature, target);
|
|
break;
|
|
}
|
|
|
|
case VARIANT_NONE: {
|
|
reportErrorFunc(getErrorDesc(LUA_ERROR_VARIANT_NOT_FOUND));
|
|
pushBoolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
// Condition
|
|
int LuaScriptInterface::luaConditionCreate(lua_State* L)
|
|
{
|
|
// Condition(conditionType[, conditionId = CONDITIONID_COMBAT])
|
|
ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
|
|
ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
|
|
|
|
Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0);
|
|
if (condition) {
|
|
pushUserdata<Condition>(L, condition);
|
|
setMetatable(L, -1, "Condition");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionDelete(lua_State* L)
|
|
{
|
|
// condition:delete()
|
|
Condition** conditionPtr = getRawUserdata<Condition>(L, 1);
|
|
if (conditionPtr && *conditionPtr) {
|
|
delete *conditionPtr;
|
|
*conditionPtr = nullptr;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetId(lua_State* L)
|
|
{
|
|
// condition:getId()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetSubId(lua_State* L)
|
|
{
|
|
// condition:getSubId()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getSubId());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetType(lua_State* L)
|
|
{
|
|
// condition:getType()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getType());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetIcons(lua_State* L)
|
|
{
|
|
// condition:getIcons()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getIcons());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetEndTime(lua_State* L)
|
|
{
|
|
// condition:getEndTime()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getEndTime());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionClone(lua_State* L)
|
|
{
|
|
// condition:clone()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
pushUserdata<Condition>(L, condition->clone());
|
|
setMetatable(L, -1, "Condition");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionGetTicks(lua_State* L)
|
|
{
|
|
// condition:getTicks()
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
lua_pushnumber(L, condition->getTicks());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionSetTicks(lua_State* L)
|
|
{
|
|
// condition:setTicks(ticks)
|
|
int32_t ticks = getNumber<int32_t>(L, 2);
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (condition) {
|
|
condition->setTicks(ticks);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionSetParameter(lua_State* L)
|
|
{
|
|
// condition:setParameter(key, value)
|
|
Condition* condition = getUserdata<Condition>(L, 1);
|
|
if (!condition) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
ConditionParam_t key = getNumber<ConditionParam_t>(L, 2);
|
|
int32_t value;
|
|
if (isBoolean(L, 3)) {
|
|
value = getBoolean(L, 3) ? 1 : 0;
|
|
} else {
|
|
value = getNumber<int32_t>(L, 3);
|
|
}
|
|
condition->setParam(key, value);
|
|
pushBoolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionSetSpeedDelta(lua_State* L)
|
|
{
|
|
// condition:setSpeedDelta(speedDelta)
|
|
int32_t speedDelta = getNumber<int32_t>(L, 2);
|
|
ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(getUserdata<Condition>(L, 1));
|
|
if (condition) {
|
|
condition->setSpeedDelta(speedDelta);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)
|
|
{
|
|
// condition:setOutfit(outfit)
|
|
// condition:setOutfit(lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet[, lookAddons])
|
|
Outfit_t outfit;
|
|
if (isTable(L, 2)) {
|
|
outfit = getOutfit(L, 2);
|
|
} else {
|
|
outfit.lookAddons = getNumber<uint8_t>(L, 8, outfit.lookAddons);
|
|
outfit.lookFeet = getNumber<uint8_t>(L, 7);
|
|
outfit.lookLegs = getNumber<uint8_t>(L, 6);
|
|
outfit.lookBody = getNumber<uint8_t>(L, 5);
|
|
outfit.lookHead = getNumber<uint8_t>(L, 4);
|
|
outfit.lookType = getNumber<uint8_t>(L, 3);
|
|
outfit.lookTypeEx = getNumber<uint8_t>(L, 2);
|
|
}
|
|
|
|
ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(getUserdata<Condition>(L, 1));
|
|
if (condition) {
|
|
condition->setOutfit(outfit);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaConditionSetTiming(lua_State* L)
|
|
{
|
|
// condition:setTiming(count)
|
|
int32_t count = getNumber<int32_t>(L, 2);
|
|
ConditionDamage* condition = dynamic_cast<ConditionDamage*>(getUserdata<Condition>(L, 1));
|
|
if (condition) {
|
|
if (condition->getType() == CONDITION_POISON) {
|
|
condition->setParam(CONDITION_PARAM_COUNT, 3);
|
|
condition->setParam(CONDITION_PARAM_MAX_COUNT, 3);
|
|
} else if (condition->getType() == CONDITION_FIRE) {
|
|
condition->setParam(CONDITION_PARAM_COUNT, 8);
|
|
condition->setParam(CONDITION_PARAM_MAX_COUNT, 8);
|
|
|
|
count /= 10;
|
|
} else if (condition->getType() == CONDITION_ENERGY) {
|
|
condition->setParam(CONDITION_PARAM_COUNT, 10);
|
|
condition->setParam(CONDITION_PARAM_MAX_COUNT, 10);
|
|
|
|
count /= 20;
|
|
}
|
|
|
|
condition->setParam(CONDITION_PARAM_CYCLE, count);
|
|
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
// MonsterType
|
|
int LuaScriptInterface::luaMonsterTypeCreate(lua_State* L)
|
|
{
|
|
// MonsterType(name)
|
|
MonsterType* monsterType = g_monsters.getMonsterType(getString(L, 2));
|
|
if (monsterType) {
|
|
pushUserdata<MonsterType>(L, monsterType);
|
|
setMetatable(L, -1, "MonsterType");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsAttackable(lua_State* L)
|
|
{
|
|
// monsterType:isAttackable()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.isAttackable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsConvinceable(lua_State* L)
|
|
{
|
|
// monsterType:isConvinceable()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.isConvinceable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsSummonable(lua_State* L)
|
|
{
|
|
// monsterType:isSummonable()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.isSummonable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsIllusionable(lua_State* L)
|
|
{
|
|
// monsterType:isIllusionable()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.isIllusionable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsHostile(lua_State* L)
|
|
{
|
|
// monsterType:isHostile()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.isHostile);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsPushable(lua_State* L)
|
|
{
|
|
// monsterType:isPushable()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.pushable);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeIsHealthShown(lua_State* L)
|
|
{
|
|
// monsterType:isHealthShown()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, !monsterType->info.hiddenHealth);
|
|
}
|
|
else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeCanPushItems(lua_State* L)
|
|
{
|
|
// monsterType:canPushItems()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.canPushItems);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeCanPushCreatures(lua_State* L)
|
|
{
|
|
// monsterType:canPushCreatures()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushBoolean(L, monsterType->info.canPushCreatures);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetName(lua_State* L)
|
|
{
|
|
// monsterType:getName()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushString(L, monsterType->name);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetNameDescription(lua_State* L)
|
|
{
|
|
// monsterType:getNameDescription()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushString(L, monsterType->nameDescription);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetHealth(lua_State* L)
|
|
{
|
|
// monsterType:getHealth()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.health);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetMaxHealth(lua_State* L)
|
|
{
|
|
// monsterType:getMaxHealth()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.healthMax);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetRunHealth(lua_State* L)
|
|
{
|
|
// monsterType:getRunHealth()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.runAwayHealth);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetExperience(lua_State* L)
|
|
{
|
|
// monsterType:getExperience()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.experience);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetCombatImmunities(lua_State* L)
|
|
{
|
|
// monsterType:getCombatImmunities()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.damageImmunities);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetConditionImmunities(lua_State* L)
|
|
{
|
|
// monsterType:getConditionImmunities()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.conditionImmunities);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetAttackList(lua_State* L)
|
|
{
|
|
// monsterType:getAttackList()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, monsterType->info.attackSpells.size(), 0);
|
|
|
|
int index = 0;
|
|
for (const auto& spellBlock : monsterType->info.attackSpells) {
|
|
lua_createtable(L, 0, 8);
|
|
|
|
setField(L, "chance", spellBlock.chance);
|
|
setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
|
|
setField(L, "minCombatValue", spellBlock.minCombatValue);
|
|
setField(L, "maxCombatValue", spellBlock.maxCombatValue);
|
|
setField(L, "range", spellBlock.range);
|
|
pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
|
|
lua_setfield(L, -2, "spell");
|
|
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
|
|
{
|
|
// monsterType:getDefenseList()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, monsterType->info.defenseSpells.size(), 0);
|
|
|
|
|
|
int index = 0;
|
|
for (const auto& spellBlock : monsterType->info.defenseSpells) {
|
|
lua_createtable(L, 0, 8);
|
|
|
|
setField(L, "chance", spellBlock.chance);
|
|
setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
|
|
setField(L, "minCombatValue", spellBlock.minCombatValue);
|
|
setField(L, "maxCombatValue", spellBlock.maxCombatValue);
|
|
setField(L, "range", spellBlock.range);
|
|
pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
|
|
lua_setfield(L, -2, "spell");
|
|
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetElementList(lua_State* L)
|
|
{
|
|
// monsterType:getElementList()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_createtable(L, monsterType->info.elementMap.size(), 0);
|
|
for (const auto& elementEntry : monsterType->info.elementMap) {
|
|
lua_pushnumber(L, elementEntry.second);
|
|
lua_rawseti(L, -2, elementEntry.first);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetVoices(lua_State* L)
|
|
{
|
|
// monsterType:getVoices()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int index = 0;
|
|
lua_createtable(L, monsterType->info.voiceVector.size(), 0);
|
|
for (const auto& voiceBlock : monsterType->info.voiceVector) {
|
|
lua_createtable(L, 0, 2);
|
|
setField(L, "text", voiceBlock.text);
|
|
setField(L, "yellText", voiceBlock.yellText);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L)
|
|
{
|
|
// monsterType:getLoot()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) {
|
|
lua_createtable(L, lootList.size(), 0);
|
|
|
|
int index = 0;
|
|
for (const auto& lootBlock : lootList) {
|
|
lua_createtable(L, 0, 7);
|
|
|
|
setField(L, "itemId", lootBlock.id);
|
|
setField(L, "chance", lootBlock.chance);
|
|
setField(L, "subType", lootBlock.subType);
|
|
setField(L, "maxCount", lootBlock.countmax);
|
|
setField(L, "actionId", lootBlock.actionId);
|
|
setField(L, "text", lootBlock.text);
|
|
|
|
parseLoot(lootBlock.childLoot);
|
|
lua_setfield(L, -2, "childLoot");
|
|
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
};
|
|
parseLoot(monsterType->info.lootItems);
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetCreatureEvents(lua_State* L)
|
|
{
|
|
// monsterType:getCreatureEvents()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int index = 0;
|
|
lua_createtable(L, monsterType->info.scripts.size(), 0);
|
|
for (const std::string& creatureEvent : monsterType->info.scripts) {
|
|
pushString(L, creatureEvent);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetSummonList(lua_State* L)
|
|
{
|
|
// monsterType:getSummonList()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int index = 0;
|
|
lua_createtable(L, monsterType->info.summons.size(), 0);
|
|
for (const auto& summonBlock : monsterType->info.summons) {
|
|
lua_createtable(L, 0, 3);
|
|
setField(L, "name", summonBlock.name);
|
|
setField(L, "chance", summonBlock.chance);
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetMaxSummons(lua_State* L)
|
|
{
|
|
// monsterType:getMaxSummons()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.maxSummons);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetArmor(lua_State* L)
|
|
{
|
|
// monsterType:getArmor()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.armor);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetDefense(lua_State* L)
|
|
{
|
|
// monsterType:getDefense()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.defense);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetOutfit(lua_State* L)
|
|
{
|
|
// monsterType:getOutfit()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
pushOutfit(L, monsterType->info.outfit);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetRace(lua_State* L)
|
|
{
|
|
// monsterType:getRace()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.race);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetCorpseId(lua_State* L)
|
|
{
|
|
// monsterType:getCorpseId()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.lookcorpse);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetManaCost(lua_State* L)
|
|
{
|
|
// monsterType:getManaCost()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.manaCost);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetBaseSpeed(lua_State* L)
|
|
{
|
|
// monsterType:getBaseSpeed()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.baseSpeed);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetLight(lua_State* L)
|
|
{
|
|
// monsterType:getLight()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (!monsterType) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
lua_pushnumber(L, monsterType->info.light.level);
|
|
lua_pushnumber(L, monsterType->info.light.color);
|
|
return 2;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetTargetDistance(lua_State* L)
|
|
{
|
|
// monsterType:getTargetDistance()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.targetDistance);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetChangeTargetChance(lua_State* L)
|
|
{
|
|
// monsterType:getChangeTargetChance()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.changeTargetChance);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed(lua_State* L)
|
|
{
|
|
// monsterType:getChangeTargetSpeed()
|
|
MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
|
|
if (monsterType) {
|
|
lua_pushnumber(L, monsterType->info.changeTargetSpeed);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// Party
|
|
int LuaScriptInterface::luaPartyDisband(lua_State* L)
|
|
{
|
|
// party:disband()
|
|
Party** partyPtr = getRawUserdata<Party>(L, 1);
|
|
if (partyPtr && *partyPtr) {
|
|
Party*& party = *partyPtr;
|
|
party->disband();
|
|
party = nullptr;
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyGetLeader(lua_State* L)
|
|
{
|
|
// party:getLeader()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (!party) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
Player* leader = party->getLeader();
|
|
if (leader) {
|
|
pushUserdata<Player>(L, leader);
|
|
setMetatable(L, -1, "Player");
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartySetLeader(lua_State* L)
|
|
{
|
|
// party:setLeader(player)
|
|
Player* player = getPlayer(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party && player) {
|
|
pushBoolean(L, party->passPartyLeadership(player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyGetMembers(lua_State* L)
|
|
{
|
|
// party:getMembers()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (!party) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int index = 0;
|
|
lua_createtable(L, party->getMemberCount(), 0);
|
|
for (Player* player : party->getMembers()) {
|
|
pushUserdata<Player>(L, player);
|
|
setMetatable(L, -1, "Player");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyGetMemberCount(lua_State* L)
|
|
{
|
|
// party:getMemberCount()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
lua_pushnumber(L, party->getMemberCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyGetInvitees(lua_State* L)
|
|
{
|
|
// party:getInvitees()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
lua_createtable(L, party->getInvitationCount(), 0);
|
|
|
|
int index = 0;
|
|
for (Player* player : party->getInvitees()) {
|
|
pushUserdata<Player>(L, player);
|
|
setMetatable(L, -1, "Player");
|
|
lua_rawseti(L, -2, ++index);
|
|
}
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyGetInviteeCount(lua_State* L)
|
|
{
|
|
// party:getInviteeCount()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
lua_pushnumber(L, party->getInvitationCount());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyAddInvite(lua_State* L)
|
|
{
|
|
// party:addInvite(player)
|
|
Player* player = getPlayer(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party && player) {
|
|
pushBoolean(L, party->invitePlayer(*player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyRemoveInvite(lua_State* L)
|
|
{
|
|
// party:removeInvite(player)
|
|
Player* player = getPlayer(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party && player) {
|
|
pushBoolean(L, party->removeInvite(*player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyAddMember(lua_State* L)
|
|
{
|
|
// party:addMember(player)
|
|
Player* player = getPlayer(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party && player) {
|
|
pushBoolean(L, party->joinParty(*player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyRemoveMember(lua_State* L)
|
|
{
|
|
// party:removeMember(player)
|
|
Player* player = getPlayer(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party && player) {
|
|
pushBoolean(L, party->leaveParty(player));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyIsSharedExperienceActive(lua_State* L)
|
|
{
|
|
// party:isSharedExperienceActive()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
pushBoolean(L, party->isSharedExperienceActive());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyIsSharedExperienceEnabled(lua_State* L)
|
|
{
|
|
// party:isSharedExperienceEnabled()
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
pushBoolean(L, party->isSharedExperienceEnabled());
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartyShareExperience(lua_State* L)
|
|
{
|
|
// party:shareExperience(experience)
|
|
uint64_t experience = getNumber<uint64_t>(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
party->shareExperience(experience, nullptr);
|
|
pushBoolean(L, true);
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int LuaScriptInterface::luaPartySetSharedExperience(lua_State* L)
|
|
{
|
|
// party:setSharedExperience(active)
|
|
bool active = getBoolean(L, 2);
|
|
Party* party = getUserdata<Party>(L, 1);
|
|
if (party) {
|
|
pushBoolean(L, party->setSharedExperience(party->getLeader(), active));
|
|
} else {
|
|
lua_pushnil(L);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
LuaEnvironment::LuaEnvironment() : LuaScriptInterface("Main Interface") {}
|
|
|
|
LuaEnvironment::~LuaEnvironment()
|
|
{
|
|
delete testInterface;
|
|
closeState();
|
|
}
|
|
|
|
bool LuaEnvironment::initState()
|
|
{
|
|
luaState = luaL_newstate();
|
|
if (!luaState) {
|
|
return false;
|
|
}
|
|
|
|
luaL_openlibs(luaState);
|
|
registerFunctions();
|
|
|
|
runningEventId = EVENT_ID_USER;
|
|
return true;
|
|
}
|
|
|
|
bool LuaEnvironment::reInitState()
|
|
{
|
|
// TODO: get children, reload children
|
|
closeState();
|
|
return initState();
|
|
}
|
|
|
|
bool LuaEnvironment::closeState()
|
|
{
|
|
if (!luaState) {
|
|
return false;
|
|
}
|
|
|
|
for (const auto& combatEntry : combatIdMap) {
|
|
clearCombatObjects(combatEntry.first);
|
|
}
|
|
|
|
for (const auto& areaEntry : areaIdMap) {
|
|
clearAreaObjects(areaEntry.first);
|
|
}
|
|
|
|
for (auto& timerEntry : timerEvents) {
|
|
LuaTimerEventDesc timerEventDesc = std::move(timerEntry.second);
|
|
for (int32_t parameter : timerEventDesc.parameters) {
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, parameter);
|
|
}
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
|
|
}
|
|
|
|
combatIdMap.clear();
|
|
areaIdMap.clear();
|
|
timerEvents.clear();
|
|
cacheFiles.clear();
|
|
|
|
lua_close(luaState);
|
|
luaState = nullptr;
|
|
return true;
|
|
}
|
|
|
|
LuaScriptInterface* LuaEnvironment::getTestInterface()
|
|
{
|
|
if (!testInterface) {
|
|
testInterface = new LuaScriptInterface("Test Interface");
|
|
testInterface->initState();
|
|
}
|
|
return testInterface;
|
|
}
|
|
|
|
Combat* LuaEnvironment::getCombatObject(uint32_t id) const
|
|
{
|
|
auto it = combatMap.find(id);
|
|
if (it == combatMap.end()) {
|
|
return nullptr;
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
Combat* LuaEnvironment::createCombatObject(LuaScriptInterface* interface)
|
|
{
|
|
Combat* combat = new Combat;
|
|
combatMap[++lastCombatId] = combat;
|
|
combatIdMap[interface].push_back(lastCombatId);
|
|
return combat;
|
|
}
|
|
|
|
void LuaEnvironment::clearCombatObjects(LuaScriptInterface* interface)
|
|
{
|
|
auto it = combatIdMap.find(interface);
|
|
if (it == combatIdMap.end()) {
|
|
return;
|
|
}
|
|
|
|
for (uint32_t id : it->second) {
|
|
auto itt = combatMap.find(id);
|
|
if (itt != combatMap.end()) {
|
|
delete itt->second;
|
|
combatMap.erase(itt);
|
|
}
|
|
}
|
|
it->second.clear();
|
|
}
|
|
|
|
AreaCombat* LuaEnvironment::getAreaObject(uint32_t id) const
|
|
{
|
|
auto it = areaMap.find(id);
|
|
if (it == areaMap.end()) {
|
|
return nullptr;
|
|
}
|
|
return it->second;
|
|
}
|
|
|
|
uint32_t LuaEnvironment::createAreaObject(LuaScriptInterface* interface)
|
|
{
|
|
areaMap[++lastAreaId] = new AreaCombat;
|
|
areaIdMap[interface].push_back(lastAreaId);
|
|
return lastAreaId;
|
|
}
|
|
|
|
void LuaEnvironment::clearAreaObjects(LuaScriptInterface* interface)
|
|
{
|
|
auto it = areaIdMap.find(interface);
|
|
if (it == areaIdMap.end()) {
|
|
return;
|
|
}
|
|
|
|
for (uint32_t id : it->second) {
|
|
auto itt = areaMap.find(id);
|
|
if (itt != areaMap.end()) {
|
|
delete itt->second;
|
|
areaMap.erase(itt);
|
|
}
|
|
}
|
|
it->second.clear();
|
|
}
|
|
|
|
void LuaEnvironment::executeTimerEvent(uint32_t eventIndex)
|
|
{
|
|
auto it = timerEvents.find(eventIndex);
|
|
if (it == timerEvents.end()) {
|
|
return;
|
|
}
|
|
|
|
LuaTimerEventDesc timerEventDesc = std::move(it->second);
|
|
timerEvents.erase(it);
|
|
|
|
//push function
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
|
|
|
|
//push parameters
|
|
for (auto parameter : boost::adaptors::reverse(timerEventDesc.parameters)) {
|
|
lua_rawgeti(luaState, LUA_REGISTRYINDEX, parameter);
|
|
}
|
|
|
|
//call the function
|
|
if (reserveScriptEnv()) {
|
|
ScriptEnvironment* env = getScriptEnv();
|
|
env->setTimerEvent();
|
|
env->setScriptId(timerEventDesc.scriptId, this);
|
|
callFunction(timerEventDesc.parameters.size());
|
|
} else {
|
|
std::cout << "[Error - LuaScriptInterface::executeTimerEvent] Call stack overflow" << std::endl;
|
|
}
|
|
|
|
//free resources
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
|
|
for (auto parameter : timerEventDesc.parameters) {
|
|
luaL_unref(luaState, LUA_REGISTRYINDEX, parameter);
|
|
}
|
|
}
|