Ir para conteúdo
  • 0
Entre para seguir isso  
daviqueiroz

Programação Ajuda com funçao getCreatureTarget(cid)

Pergunta

daviqueiroz    0
daviqueiroz

Antes de fazer a sua pergunta, tenha certeza de ter lido as regras da seção e o guia abaixo:

https://forums.otserv.com.br/index.php?/forums/topic/168583-regras-da-seção/

https://forums.otserv.com.br/index.php?/forums/topic/165121-como-fazer-uma-pergunta-ou-o-grande-guia-do-usuário-com-dúvidas/

Descreva em algumas palavras a base utilizada. (Nome do servidor / Nome do cliente / Nome do website / etc.).

Ex: The Forgotten Server 1.3, Versão: 10.98.

Base:

Evolutions 0.7.8 - 7.92:

Qual é a sua pergunta?

Gostaria de adicionar a minha source a função "getCreatureTarget(cid)" – Verifica quem o player está atacando.

luascript.h

 

Spoiler

//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
// Lua script interface
//////////////////////////////////////////////////////////////////////
// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//////////////////////////////////////////////////////////////////////


#ifndef __OTSERV_LUASCRIPT_H__
#define __OTSERV_LUASCRIPT_H__

#include <string>
#include <map>
#include <list>

extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

#include "position.h"
#include "definitions.h"

class Thing;
class Creature;
class Player;
class Item;
class Container;
class AreaCombat;
class Combat;
class Condition;
class Npc;

enum LUA_RET_CODE{
    LUA_NO_ERROR = 0,
    LUA_ERROR = -1,
    LUA_TRUE = 1,
    LUA_FALSE = 0,
    LUA_NULL = 0,
};

enum LuaVariantType_t{    
    VARIANT_NONE = 0,
    VARIANT_NUMBER,
    VARIANT_POSITION,
    VARIANT_TARGETPOSITION,
    VARIANT_STRING,
};

struct LuaVariant{
    LuaVariant()
    {
        type = VARIANT_NONE;
        text = "";
        pos.x = 0;
        pos.y = 0;
        pos.z = 0;
        pos.stackpos = 0;
        number = 0;
    }

    LuaVariantType_t type;
    std::string text;
    PositionEx pos;
    uint32_t number;
};

class LuaScriptInterface;
class Game;
class Npc;

class ScriptEnviroment
{
public:
    ScriptEnviroment();
    ~ScriptEnviroment();

    void resetEnv();
    void resetCallback() {m_callbackId = 0;}

    void setScriptId(int32_t scriptId, LuaScriptInterface* scriptInterface)
        {m_scriptId = scriptId; m_interface = scriptInterface;}
    bool setCallbackId(int32_t callbackId, LuaScriptInterface* scriptInterface);
    void setEventDesc(const std::string& desc) {m_eventdesc = desc;}
    
    std::string getEventDesc() {return m_eventdesc;}
    int32_t getScriptId() {return m_scriptId;}
    int32_t getCallbackId() {return m_callbackId;}
    LuaScriptInterface* getScriptInterface() {return m_interface;}
    
    void setTimerEvent() {m_timerEvent = true;}
    void resetTimerEvent() {m_timerEvent = false;}

    void getEventInfo(int32_t& scriptId, std::string& desc, LuaScriptInterface*& scriptInterface, int32_t& callbackId, bool& timerEvent);

    static void addUniqueThing(Thing* thing);
    uint32_t addThing(Thing* thing);
    
    void addGlobalStorageValue(const uint32_t key, const int32_t value);
    bool getGlobalStorageValue(const uint32_t key, int32_t& value) const;

    void setRealPos(const Position& realPos) {m_realPos = realPos;}
    Position getRealPos() {return m_realPos;}

    void setNpc(Npc* npc) {m_curNpc = npc;}
    Npc* getNpc() const {return m_curNpc;}

    Thing* getThingByUID(uint32_t uid);
    Item* getItemByUID(uint32_t uid);
    Container* getContainerByUID(uint32_t uid);
    Creature* getCreatureByUID(uint32_t uid);
    Player* getPlayerByUID(uint32_t uid);

    uint32_t addCombatArea(AreaCombat* area);
    AreaCombat* getCombatArea(uint32_t areaId) const;

    uint32_t addCombatObject(Combat* combat);
    const Combat* getCombatObject(uint32_t combatId) const;
    Combat* getCombatObject(uint32_t combatId);

    uint32_t addConditionObject(Condition* condition);
    const Condition* getConditionObject(uint32_t conditionId) const;
    Condition* getConditionObject(uint32_t conditionId);

private:
    typedef std::map<int32_t, Thing*> ThingMap;
    typedef std::vector<const LuaVariant*> VariantVector;
    typedef std::map<uint32_t, int32_t> StorageMap;
    typedef std::map<uint32_t, AreaCombat*> AreaMap;
    typedef std::map<uint32_t, Combat*> CombatMap;
    typedef std::map<uint32_t, Condition*> ConditionMap;

    //script file id
    int32_t m_scriptId;
    int32_t m_callbackId;
    bool m_timerEvent;
    LuaScriptInterface* m_interface;
    //script event desc
    std::string m_eventdesc;

    static StorageMap m_globalStorageMap;
    //unique id map
    static ThingMap m_globalMap;
    
    Position m_realPos;
    
    //item/creature map
    int32_t m_lastUID;
    ThingMap m_localMap;
    
    //area map
    uint32_t m_lastAreaId;
    static AreaMap m_areaMap;

    //combat map
    uint32_t m_lastCombatId;
    static CombatMap m_combatMap;

    //condition map
    uint32_t m_lastConditionId;
    static ConditionMap m_conditionMap;

    //for npc scripts
    Npc* m_curNpc;
};

class Position;

enum PlayerInfo_t{
    PlayerInfoFood,
    PlayerInfoAccess,
    PlayerInfoLevel,
    PlayerInfoMagLevel,
    PlayerInfoMana,
    PlayerInfoHealth,
    PlayerInfoName,
    PlayerInfoPosition,
    PlayerInfoVocation,
    PlayerInfoMasterPos,
    PlayerInfoSoul,
    PlayerInfoFreeCap,
    PlayerInfoGuildId,
    PlayerInfoGuildName,
    PlayerInfoGuildRank,
    PlayerInfoGuildNick,
    PlayerInfoSex,
    PlayerInfoLookDirection,
    PlayerInfoTown,
    PlayerInfoGUID
};

#define reportErrorFunc(a)  reportError(__FUNCTION__, a)

enum ErrorCode_t{
    LUA_ERROR_PLAYER_NOT_FOUND,
    LUA_ERROR_CREATURE_NOT_FOUND,
    LUA_ERROR_ITEM_NOT_FOUND,
    LUA_ERROR_THING_NOT_FOUND,
    LUA_ERROR_TILE_NOT_FOUND,
    LUA_ERROR_HOUSE_NOT_FOUND,
    LUA_ERROR_COMBAT_NOT_FOUND,
    LUA_ERROR_CONDITION_NOT_FOUND,
    LUA_ERROR_AREA_NOT_FOUND,
    LUA_ERROR_CONTAINER_NOT_FOUND,
    LUA_ERROR_VARIANT_NOT_FOUND,
    LUA_ERROR_VARIANT_UNKNOWN
};


class LuaScriptInterface
{
public:
    LuaScriptInterface(std::string interfaceName);
    virtual ~LuaScriptInterface();

    virtual bool initState();
    bool reInitState();

    int32_t loadFile(const std::string& file, Npc* npc = NULL);
    const std::string& getFileById(int32_t scriptId);

    int32_t getEvent(const std::string& eventName);

    static ScriptEnviroment* getScriptEnv(){
        assert(m_scriptEnvIndex >= 0 && m_scriptEnvIndex < 16);
        return &m_scriptEnv[m_scriptEnvIndex];
    }
    
    static bool reserveScriptEnv(){
        ++m_scriptEnvIndex;
        if(m_scriptEnvIndex < 15){
            return true;
        }
        else{
            --m_scriptEnvIndex;
            return false;
        }
    }
    
    static void releaseScriptEnv(){
        if(m_scriptEnvIndex >= 0){
            m_scriptEnv[m_scriptEnvIndex].resetEnv();
            --m_scriptEnvIndex;
        }
    }

    static void reportError(const char* function, const std::string& error_desc);

    std::string getInterfaceName() {return m_interfaceName;}
    const std::string& getLastLuaError() const {return m_lastLuaError;}
    void dumpLuaStack();

    lua_State* getLuaState() {return m_luaState;}

    bool pushFunction(int32_t functionId);

    int32_t callFunction(uint32_t nParams);

    //push/pop common structures
    static void pushThing(lua_State *L, Thing* thing, uint32_t thingid);
    static void pushVariant(lua_State *L, const LuaVariant& var);
    static void pushPosition(lua_State *L, const PositionEx& position);
    static void pushPosition(lua_State *L, const Position& position, uint32_t stackpos);
        
    static LuaVariant popVariant(lua_State *L);
    static void popPosition(lua_State *L, PositionEx& position);
    static void popPosition(lua_State *L, Position& position, uint32_t& stackpos);
    static uint32_t popNumber(lua_State *L);
    static double popFloatNumber(lua_State *L);
    static const char* popString(lua_State *L);

    static int32_t getField(lua_State *L, const char *key);
    static void setField(lua_State *L, const char* index, uint32_t val);
    static void setField(lua_State *L, const char* index, const std::string& val);

protected:
    virtual bool closeState();

    virtual void registerFunctions();

    static std::string getErrorDesc(ErrorCode_t code);
    static bool getArea(lua_State *L, std::list<uint32_t>& list, uint32_t& rows);

    //lua functions
    static int luaDoRemoveItem(lua_State *L);
    static int luaDoFeedPlayer(lua_State *L);
    static int luaDoSendCancel(lua_State *L);
    static int luaDoSendDefaultCancel(lua_State *L);
    static int luaDoTeleportThing(lua_State *L);
    static int luaDoTransformItem(lua_State *L);
    static int luaDoSendMagicEffect(lua_State *L);
    static int luaDoChangeTypeItem(lua_State *L);
    static int luaDoSendAnimatedText(lua_State *L);
    static int luaDoShowTextWindow(lua_State *L);
    static int luaDoShowTextDialog(lua_State *L);
    static int luaDoDecayItem(lua_State *L);
    static int luaDoCreateItem(lua_State *L);
    static int luaDoSummonCreature(lua_State *L);
    static int luaDoMoveCreature(lua_State *L);

    static int luaDoPlayerSay(lua_State *L);
    static int luaDoPlayerAddSkillTry(lua_State *L);
    static int luaDoPlayerAddHealth(lua_State *L);
    static int luaDoPlayerAddMana(lua_State *L);
    static int luaDoPlayerSoul(lua_State *L);
    static int luaDoPlayerAddItem(lua_State *L);
    static int luaDoPlayerSendTextMessage(lua_State *L);
    static int luaDoPlayerRemoveMoney(lua_State *L);
    static int luaDoPlayerSetMasterPos(lua_State *L);
    static int luaDoPlayerSetTown(lua_State *L);
    static int luaDoPlayerSetVocation(lua_State *L);
    static int luaDoPlayerRemoveItem(lua_State *L);
    static int luaDoPlayerAddSoul(lua_State *L);
    static int luaDoPlayerAddExp(lua_State *L);
    //static int luaDoPlayerSetGuildId(lua_State *L);
    static int luaDoPlayerSetGuildRank(lua_State *L);
    static int luaDoPlayerSetGuildNick(lua_State *L);
    static int luaDoSetCreatureLight(lua_State *L);

    //get item info
    static int luaGetItemRWInfo(lua_State *L);
    static int luaGetThingfromPos(lua_State *L);
    static int luaGetThing(lua_State *L);
    static int luaGetThingPos(lua_State *L);
    //set item
    static int luaDoSetItemActionId(lua_State *L);
    static int luaDoSetItemText(lua_State *L);
    static int luaDoSetItemSpecialDescription(lua_State *L);

    //get tile info
    static int luaGetTilePzInfo(lua_State *L);
    static int luaGetTileHouseInfo(lua_State *L);
    //houses
    static int luaGetHouseOwner(lua_State *L);
    static int luaGetHouseName(lua_State *L);
    static int luaGetHouseEntry(lua_State *L);
    static int luaGetHouseRent(lua_State *L);
    static int luaGetHouseTown(lua_State *L);
    static int luaGetHouseAccessList(lua_State *L);
    static int luaGetHouseByPlayerGUID(lua_State *L);
    static int luaSetHouseOwner(lua_State *L);
    static int luaSetHouseAccessList(lua_State *L);

    //get player info functions
    static int luaGetPlayerFood(lua_State *L);
    static int luaGetPlayerAccess(lua_State *L);
    static int luaGetPlayerLevel(lua_State *L);
    static int luaGetPlayerMagLevel(lua_State *L);
    static int luaGetPlayerMana(lua_State *L);
    static int luaGetPlayerHealth(lua_State *L);
    static int luaGetPlayerName(lua_State *L);
    static int luaGetPlayerPosition(lua_State *L);
    static int luaGetPlayerSkill(lua_State *L);
    static int luaGetPlayerVocation(lua_State *L);
    static int luaGetPlayerMasterPos(lua_State *L);
    static int luaGetPlayerTown(lua_State *L);
    static int luaGetPlayerItemCount(lua_State *L);
    static int luaGetPlayerSoul(lua_State *L);
    static int luaGetPlayerFreeCap(lua_State *L);
    static int luaGetPlayerLight(lua_State *L);
    static int luaGetPlayerSlotItem(lua_State *L);
    static int luaGetPlayerDepotItems(lua_State *L);
    static int luaGetPlayerSex(lua_State *L);
    static int luaGetPlayerLookDir(lua_State *L);

    static int luaGetPlayerStorageValue(lua_State *L);
    static int luaSetPlayerStorageValue(lua_State *L);
    
    static int luaGetGlobalStorageValue(lua_State *L);
    static int luaSetGlobalStorageValue(lua_State *L);
    
    static int luaDoPlayerAddOutfit(lua_State *L);
    static int luaDoPlayerRemOutfit(lua_State *L);

    static int luaGetWorldType(lua_State *L);
    static int luaGetWorldTime(lua_State *L);
    static int luaGetWorldLight(lua_State *L);
    static int luaGetWorldCreatures(lua_State *L);
    static int luaGetWorldUpTime(lua_State *L);

    //type validation
    static int luaIsPlayer(lua_State *L);
    static int luaIsCreature(lua_State *L);
    static int luaIsContainer(lua_State *L);
    static int luaIsMoveable(lua_State *L);
    
    static int luaGetPlayerByName(lua_State *L);
    static int luaRegisterCreature(lua_State *L);
    
    //container
    static int luaGetContainerSize(lua_State *L);
    static int luaGetContainerCap(lua_State *L);
    static int luaGetContainerItem(lua_State *L);
    static int luaDoAddContainerItem(lua_State *L);

    //
    static int luaCreateCombatObject(lua_State *L);
    static int luaCreateCombatArea(lua_State *L);
    static int luaSetCombatArea(lua_State *L);
    static int luaSetCombatCondition(lua_State *L);
    static int luaSetCombatParam(lua_State *L);
    static int luaCreateConditionObject(lua_State *L);
    static int luaSetConditionParam(lua_State *L);
    static int luaAddDamageCondition(lua_State *L);
    static int luaAddOutfitCondition(lua_State *L);

    static int luaSetCombatCallBack(lua_State *L);
    static int luaSetCombatFormula(lua_State *L);
    static int luaSetConditionFormula(lua_State *L);
    static int luaDoCombat(lua_State *L);

    static int luaDoAreaCombatHealth(lua_State *L);
    static int luaDoTargetCombatHealth(lua_State *L);

    //
    static int luaDoAreaCombatMana(lua_State *L);
    static int luaDoTargetCombatMana(lua_State *L);

    static int luaDoAreaCombatCondition(lua_State *L);
    static int luaDoTargetCombatCondition(lua_State *L);

    static int luaDoAreaCombatDispel(lua_State *L);
    static int luaDoTargetCombatDispel(lua_State *L);

    static int luaDoChallengeCreature(lua_State *L);
    static int luaDoConvinceCreature(lua_State *L);

    static int luaNumberToVariant(lua_State *L);
    static int luaStringToVariant(lua_State *L);
    static int luaPositionToVariant(lua_State *L);
    static int luaTargetPositionToVariant(lua_State *L);

    static int luaVariantToNumber(lua_State *L);
    static int luaVariantToString(lua_State *L);
    static int luaVariantToPosition(lua_State *L);

    static int luaDoChangeSpeed(lua_State *L);

    static int luaSetCreatureOutfit(lua_State *L);
    static int luaGetCreatureOutfit(lua_State *L);
    static int luaSetMonsterOutfit(lua_State *L);
    static int luaSetItemOutfit(lua_State *L);
    static int luaGetCreaturePosition(lua_State *L);
    static int luaGetCreatureName(lua_State *L);

    static int luaIsItemStackable(lua_State *L);
    static int luaIsItemRune(lua_State *L);
    static int luaIsItemDoor(lua_State *L);
    static int luaIsItemContainer(lua_State *L);
    static int luaIsItemFluidContainer(lua_State *L);
    static int luaGetItemName(lua_State *L);

    #ifdef __XID_CVS_MODS__
    static int luaGetPlayerSkull(lua_State *L);
    static int luaGetPlayerConditionTicks(lua_State *L);
    #endif

    #ifdef __XID_SEPERATE_ADDONS__
    static int luaDoPlayerAddAddon(lua_State* L);
    static int luaGetPlayerOutfitAddon(lua_State* L);
    #endif

    #ifdef __XID_BUY_SELL__
    static int luaGetItemStackable(lua_State *L);
    #endif

    #ifdef __XID_PREMIUM_SYSTEM__
    static int luaIsPremium(lua_State *L);
    static int luaBuyPremium(lua_State *L);
    #endif

    #ifdef __YUR_GUILD_SYSTEM__
    static int luaFoundNewGuild(lua_State* L);
    static int luaGetPlayerGuildStatus(lua_State* L);
    static int luaSetPlayerGuildStatus(lua_State* L);
    static int luaGetPlayerGuildName(lua_State* L);
    static int luaSetPlayerGuild(lua_State* L);
    static int luaClearPlayerGuild(lua_State* L);
    static int luaSetPlayerGuildNick(lua_State* L);
    #endif

    #ifdef __XID_LEARN_SPELLS__
    static int luaDoPlayerLearnSpell(lua_State* L);
    #endif

    #ifdef __XID_BLESS_SYSTEM__
    static int luaDoPlayerAddBlessing(lua_State* L);
    static int luaGetPlayerBlessing(lua_State* L);
    #endif

    static int luaDebugPrint(lua_State *L);
    static int luaIsInArray(lua_State *L);
    static int luaAddEvent(lua_State *L);
    static int luaStopEvent(lua_State *L);

    static int luaGetDataDirectory(lua_State *L);
    //

    static int internalGetPlayerInfo(lua_State *L, PlayerInfo_t info);

    lua_State* m_luaState;
    std::string m_lastLuaError;
private:

    static ScriptEnviroment m_scriptEnv[16];
    static int32_t m_scriptEnvIndex;

    int32_t m_runningEventId;
    std::string m_loadingFile;

    //script file cache
    typedef std::map<int32_t , std::string> ScriptsCache;
    ScriptsCache m_cacheFiles;

    //events information
    struct LuaTimerEventDesc{
        int32_t scriptId;
        int function;
        int parameter;
    };
    uint32_t m_lastEventTimerId;
    typedef std::map<uint32_t , LuaTimerEventDesc > LuaTimerEvents;
    LuaTimerEvents m_timerEvents;
    
    void executeTimerEvent(uint32_t eventIndex);

    std::string m_interfaceName;
};

#endif
 

luascript.cpp

 

Spoiler

//////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
//////////////////////////////////////////////////////////////////////
// Lua script interface
//////////////////////////////////////////////////////////////////////
// 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include <string>
#include <iostream>
#include <sstream>

#include "luascript.h"
#include "player.h"
#include "item.h"
#include "game.h"
#include "house.h"
#include "housetile.h"
#include "status.h"
#include "combat.h"
#include "spells.h"
#include "condition.h"
#include "monsters.h"
#include "baseevents.h"
#include "town.h"
#include "ioplayer.h"
#include "configmanager.h"

extern Game g_game;
extern Monsters g_monsters;
extern ConfigManager g_config;

enum{
    EVENT_ID_LOADING = 1,
    EVENT_ID_USER = 1000,
};

ScriptEnviroment::ThingMap ScriptEnviroment::m_globalMap;
ScriptEnviroment::AreaMap ScriptEnviroment::m_areaMap;
ScriptEnviroment::CombatMap ScriptEnviroment::m_combatMap;
ScriptEnviroment::ConditionMap ScriptEnviroment::m_conditionMap;
ScriptEnviroment::StorageMap ScriptEnviroment::m_globalStorageMap;

ScriptEnviroment::ScriptEnviroment()
{
    resetEnv();
    m_lastUID = 70000;
    m_lastAreaId = 0;
    m_lastCombatId = 0;
    m_lastConditionId = 0;
}

ScriptEnviroment::~ScriptEnviroment()
{
    //
}

void ScriptEnviroment::resetEnv()
{
    m_scriptId = 0;
    m_callbackId = 0;
    m_timerEvent = false;
    m_interface = NULL;
    m_localMap.clear();

    m_realPos.x = 0;
    m_realPos.y = 0;
    m_realPos.z = 0;
}

bool ScriptEnviroment::setCallbackId(int32_t callbackId, LuaScriptInterface* scriptInterface)
{
    if(m_callbackId == 0){
        m_callbackId = callbackId;
        m_interface = scriptInterface;
        return true;
    }
    else{
        //nested callbacks are not allowed
        if(m_interface){
            m_interface->reportError(__FUNCTION__, "Nested callbacks!");
        }
        return false;
    }
}

void ScriptEnviroment::getEventInfo(int32_t& scriptId, std::string& desc, LuaScriptInterface*& scriptInterface, int32_t& callbackId, bool& timerEvent)
{
    scriptId = m_scriptId;
    desc = m_eventdesc;
    scriptInterface = m_interface;
    callbackId = m_callbackId;
    timerEvent = m_timerEvent;
}

void ScriptEnviroment::addUniqueThing(Thing* thing)
{
    Item* item = thing->getItem();
    if(item && item->getUniqueId() != 0 ){
        int32_t uid = item->getUniqueId();
        
        Thing* tmp = m_globalMap[uid];
        if(!tmp){
            m_globalMap[uid] = thing;
        }
        else{
            std::cout << "Duplicate uniqueId " <<  uid << std::endl;
        }
    }
}

uint32_t ScriptEnviroment::addThing(Thing* thing)
{
    if(thing){
        ThingMap::iterator it;
        for(it = m_localMap.begin(); it != m_localMap.end(); ++it){
            if(it->second == thing){
                return it->first;
            }
        }
    
        uint32_t newUid;
        if(Creature* creature = thing->getCreature()){
            newUid = creature->getID();
        }
        else{
            if(Item* item = thing->getItem()){
                uint32_t uid = item->getUniqueId();
                if(uid && item->getTile() == item->getParent()){
                    m_localMap[uid] = thing;
                    return uid;
                }
            }
        
            ++m_lastUID;
            if(m_lastUID > 0xFFFFFF)
                m_lastUID = 70000;
        
            while(m_localMap[m_lastUID]){
                ++m_lastUID;
            }
            newUid = m_lastUID;
        }
    
        m_localMap[newUid] = thing;
        return newUid;
    }
    else{
        return 0;
    }
}
    
Thing* ScriptEnviroment::getThingByUID(uint32_t uid)
{
    Thing* tmp = m_localMap[uid];
    if(tmp && !tmp->isRemoved()){
        return tmp;
    }
    tmp = m_globalMap[uid];
    if(tmp && !tmp->isRemoved()){
        return tmp;
    }
    if(uid >= 0x10000000){ //is a creature id
        tmp = g_game.getCreatureByID(uid);
        if(tmp && !tmp->isRemoved()){
            m_localMap[uid] = tmp;
            return tmp;
        }
    }
    return NULL;
}

Item* ScriptEnviroment::getItemByUID(uint32_t uid)
{
    Thing* tmp = getThingByUID(uid);
    if(tmp){
        if(Item* item = tmp->getItem())
            return item;
    }
    return NULL;
}

Container* ScriptEnviroment::getContainerByUID(uint32_t uid)
{
    Item* tmp = getItemByUID(uid);
    if(tmp){
        if(Container* container = tmp->getContainer())
            return container;
    }
    return NULL;
}

Creature* ScriptEnviroment::getCreatureByUID(uint32_t uid)
{
    Thing* tmp = getThingByUID(uid);
    if(tmp){
        if(Creature* creature = tmp->getCreature())
            return creature;
    }
    return NULL;
}

Player* ScriptEnviroment::getPlayerByUID(uint32_t uid)
{
    Thing* tmp = getThingByUID(uid);
    if(tmp){
        if(Creature* creature = tmp->getCreature())
            if(Player* player = creature->getPlayer())
                return player;
    }
    return NULL;
}

uint32_t ScriptEnviroment::addCombatArea(AreaCombat* area)
{
    uint32_t newAreaId = m_lastAreaId + 1;
    m_areaMap[newAreaId] = area;
    
    m_lastAreaId++;
    return newAreaId;
}

AreaCombat* ScriptEnviroment::getCombatArea(uint32_t areaId) const
{
    AreaMap::const_iterator it = m_areaMap.find(areaId);
    if(it != m_areaMap.end()){
        return it->second;
    }

    return NULL;
}

uint32_t ScriptEnviroment::addCombatObject(Combat* combat)
{
    uint32_t newCombatId = m_lastCombatId + 1;
    m_combatMap[newCombatId] = combat;
    
    m_lastCombatId++;
    return newCombatId;
}

const Combat* ScriptEnviroment::getCombatObject(uint32_t combatId) const
{
    CombatMap::iterator it = m_combatMap.find(combatId);
    if(it != m_combatMap.end()){
        return it->second;
    }

    return NULL;
}

Combat* ScriptEnviroment::getCombatObject(uint32_t combatId)
{
    CombatMap::iterator it = m_combatMap.find(combatId);
    if(it != m_combatMap.end()){
        return it->second;
    }

    return NULL;
}

uint32_t ScriptEnviroment::addConditionObject(Condition* condition)
{
    uint32_t newConditionId = m_lastConditionId + 1;
    m_conditionMap[newConditionId] = condition;
    
    m_lastConditionId++;
    return m_lastConditionId;
}

const Condition* ScriptEnviroment::getConditionObject(uint32_t conditionId) const
{
    ConditionMap::iterator it = m_conditionMap.find(conditionId);
    if(it != m_conditionMap.end()){
        return it->second;
    }

    return NULL;
}

Condition* ScriptEnviroment::getConditionObject(uint32_t conditionId)
{
    ConditionMap::iterator it = m_conditionMap.find(conditionId);
    if(it != m_conditionMap.end()){
        return it->second;
    }

    return NULL;
}

void ScriptEnviroment::addGlobalStorageValue(const uint32_t key, const int32_t value)
{
    m_globalStorageMap[key] = value;
}

bool ScriptEnviroment::getGlobalStorageValue(const uint32_t key, int32_t& value) const
{
    StorageMap::const_iterator it;
    it = m_globalStorageMap.find(key);
    if(it != m_globalStorageMap.end()){
        value = it->second;
        return true;
    }
    else{
        value = 0;
        return false;
    }
}

std::string LuaScriptInterface::getErrorDesc(ErrorCode_t code){
    switch(code){
    case LUA_ERROR_PLAYER_NOT_FOUND:
        return "Player not found";
        break;
    case LUA_ERROR_CREATURE_NOT_FOUND:
        return "Creature not found";
        break;
    case LUA_ERROR_ITEM_NOT_FOUND:
        return "Item not found";
        break;
    case LUA_ERROR_THING_NOT_FOUND:
        return "Thing not found";
        break;
    case LUA_ERROR_TILE_NOT_FOUND:
        return "Tile not found";
        break;
    case LUA_ERROR_HOUSE_NOT_FOUND:
        return "House not found";
        break;
    case LUA_ERROR_COMBAT_NOT_FOUND:
        return "Combat not found";
        break;
    case LUA_ERROR_CONDITION_NOT_FOUND:
        return "Condition not found";
        break;
    case LUA_ERROR_AREA_NOT_FOUND:
        return "Area not found";
        break;
    case LUA_ERROR_CONTAINER_NOT_FOUND:
        return "Container not found";
        break;
    case LUA_ERROR_VARIANT_NOT_FOUND:
        return "Variant not found";
    case LUA_ERROR_VARIANT_UNKNOWN:
        return "Unknown variant type";
        break;
    default:
        return "Wrong error code!";
        break;
    };
}

ScriptEnviroment LuaScriptInterface::m_scriptEnv[16];
int32_t LuaScriptInterface::m_scriptEnvIndex = -1;

LuaScriptInterface::LuaScriptInterface(std::string interfaceName)
{
    m_luaState = NULL;
    m_interfaceName = interfaceName;
    m_lastEventTimerId = 1000;
}

LuaScriptInterface::~LuaScriptInterface()
{
    closeState();
}
    
bool LuaScriptInterface::reInitState()
{
    closeState();
    return initState();
}

void LuaScriptInterface::dumpLuaStack()
{
    int a = lua_gettop(m_luaState);
    std::cout <<  "stack size: " << a << std::endl;
    for(int i = 1; i <= a ; ++i){
        std::cout << lua_typename(m_luaState, lua_type(m_luaState,-i)) << " " << lua_topointer(m_luaState, -i) << std::endl;
    }
}

int32_t LuaScriptInterface::loadFile(const std::string& file, Npc* npc /* = NULL*/)
{
    //loads file as a chunk at stack top
    int ret = luaL_loadfile(m_luaState, file.c_str());
    if(ret != 0){
        m_lastLuaError = popString(m_luaState);
        return -1;
    }
    //check that it is loaded as a function
    if(lua_isfunction(m_luaState, -1) == 0){
        return -1;
    }
    
    m_loadingFile = file;
    this->reserveScriptEnv();
    ScriptEnviroment* env = this->getScriptEnv();
    env->setScriptId(EVENT_ID_LOADING, this);
    env->setNpc(npc);
    
    //execute it
    ret = lua_pcall(m_luaState, 0, 0, 0);
    if(ret != 0){
        reportError(NULL, std::string(popString(m_luaState)));
        this->releaseScriptEnv();
        return -1;
    }
    
    this->releaseScriptEnv();
    return 0;
}

int32_t LuaScriptInterface::getEvent(const std::string& eventName)
{
    //get our events table
    lua_getfield(m_luaState, LUA_REGISTRYINDEX, "EVENTS");
    if(lua_istable(m_luaState, -1) == 0){
        lua_pop(m_luaState, 1);
        return -1;
    }
    //get current event function pointer
    lua_getglobal(m_luaState, eventName.c_str());
    if(lua_isfunction(m_luaState, -1) == 0){
        lua_pop(m_luaState, 1);
        return -1;
    }
    //save in our events table
    lua_pushnumber(m_luaState, m_runningEventId);
    lua_pushvalue(m_luaState, -2);
    lua_rawset(m_luaState, -4);
    lua_pop(m_luaState, 2);
    //reset global value of this event
    lua_pushnil(m_luaState);
    lua_setglobal(m_luaState, eventName.c_str());

    m_cacheFiles[m_runningEventId] = m_loadingFile + ":" + eventName;
    ++m_runningEventId;
    return m_runningEventId - 1;
}

const std::string& LuaScriptInterface::getFileById(int32_t scriptId)
{
    static std::string unk = "(Unknown scriptfile)";
    if(scriptId != EVENT_ID_LOADING){
        ScriptsCache::iterator it = m_cacheFiles.find(scriptId);
        if(it != m_cacheFiles.end()){
            return it->second;
        }
        else{
            return unk;
        }
    }
    else{
        return m_loadingFile;
    }
}

void LuaScriptInterface::reportError(const char* function, const std::string& error_desc)
{
    ScriptEnviroment* env = getScriptEnv();
    int32_t scriptId;
    int32_t callbackId;
    bool timerEvent;
    std::string event_desc;
    LuaScriptInterface* scriptInterface;
    env->getEventInfo(scriptId, event_desc, 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;
    }
    std::cout << event_desc << std::endl;
    if(function)
        std::cout << function << "(). ";
    std::cout << error_desc << std::endl;
}

bool LuaScriptInterface::pushFunction(int32_t functionId)
{
    lua_getfield(m_luaState, LUA_REGISTRYINDEX, "EVENTS");
    if(lua_istable(m_luaState, -1) != 0){
        lua_pushnumber(m_luaState, functionId);
        lua_rawget(m_luaState, -2);
        lua_remove(m_luaState, -2);
        if(lua_isfunction(m_luaState, -1) != 0){
            return true;
        }
    }
    return false;
}

bool LuaScriptInterface::initState()
{
    m_luaState = luaL_newstate();
    if(!m_luaState){
        return false;
    }
    luaopen_base(m_luaState);
    luaopen_table(m_luaState);
    luaopen_os(m_luaState);
    luaopen_string(m_luaState);
    luaopen_math(m_luaState);
    //luaL_openlibs(m_luaState);
    
    std::string datadir = g_config.getString(ConfigManager::DATA_DIRECTORY);
    
    if(loadFile(std::string(datadir + "global.lua")) == -1){
        std::cout << "Warning: [LuaScriptInterface::initState] Can not load " << datadir << "global.lua." << std::endl;
    }

    registerFunctions();
    
    lua_newtable(m_luaState);
    lua_setfield(m_luaState, LUA_REGISTRYINDEX, "EVENTS");
    
    m_runningEventId = EVENT_ID_USER;
    return true;
}

bool LuaScriptInterface::closeState()
{
    m_cacheFiles.clear();
    
    LuaTimerEvents::iterator it;
    for(it = m_timerEvents.begin(); it != m_timerEvents.end(); ++it){
        luaL_unref(m_luaState, LUA_REGISTRYINDEX, it->second.parameter);
        luaL_unref(m_luaState, LUA_REGISTRYINDEX, it->second.function);
    }
    m_timerEvents.clear();
    
    lua_close(m_luaState);
    return true;
}

void LuaScriptInterface::executeTimerEvent(uint32_t eventIndex)
{
    OTSYS_THREAD_LOCK_CLASS lockClass(g_game.gameLock, "LuaScriptInterface::executeTimerEvent()");
    LuaTimerEvents::iterator it = m_timerEvents.find(eventIndex);
    if(it != m_timerEvents.end()){
        //push function
        lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, it->second.function);
        
        //push parameters
        lua_rawgeti(m_luaState, LUA_REGISTRYINDEX, it->second.parameter);
        
        //call the function
        if(reserveScriptEnv()){
            ScriptEnviroment* env = getScriptEnv();
            env->setTimerEvent();
            env->setScriptId(it->second.scriptId, this);
            callFunction(1);
            releaseScriptEnv();
        }
        else{
            std::cout << "[Error] Call stack overflow. LuaScriptInterface::executeTimerEvent" << std::endl;
        }
        
        //free resources
        luaL_unref(m_luaState, LUA_REGISTRYINDEX, it->second.parameter);
        luaL_unref(m_luaState, LUA_REGISTRYINDEX, it->second.function);
        m_timerEvents.erase(it);
    }    
}

int32_t LuaScriptInterface::callFunction(uint32_t nParams)
{
    int32_t result = LUA_NO_ERROR;

    int size0 = lua_gettop(m_luaState);
    if(lua_pcall(m_luaState, nParams, 1, 0) != 0){
        LuaScriptInterface::reportError(NULL, std::string(LuaScriptInterface::popString(m_luaState)));
        result = LUA_ERROR;
    }
    else{
        result = (int32_t)LuaScriptInterface::popNumber(m_luaState);
    }

    if((lua_gettop(m_luaState) + (int)nParams  + 1) != size0){
        LuaScriptInterface::reportError(NULL, "Stack size changed!");
    }

    return result;
}

void LuaScriptInterface::pushVariant(lua_State *L, const LuaVariant& var)
{
    lua_newtable(L);
    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:
        {
                lua_pushstring(L, "pos");
                pushPosition(L, var.pos);
                lua_settable(L, -3);
                break;
        }
        case VARIANT_NONE:
            break;
     }
}

void LuaScriptInterface::pushThing(lua_State *L, Thing* thing, uint32_t thingid)
{
    lua_newtable(L);
    if(thing && thing->getItem()){    
        const Item* item = thing->getItem();
        setField(L, "uid", thingid);
        setField(L, "itemid", item->getID());

        if(item->hasSubType())
            setField(L, "type", item->getItemCountOrSubtype());
        else
            setField(L, "type", 0);

        setField(L, "actionid", item->getActionId());
    }
    else if(thing && thing->getCreature()){
        const Creature* creature = thing->getCreature();
        setField(L, "uid", thingid);
        setField(L, "itemid", 1);
        char type;
        if(creature->getPlayer()){
            type = 1;
        }
        else if(creature->getMonster()){
            type = 2;
        }
        else{//npc
            type = 3;
        }    
        setField(L, "type", type);
        setField(L, "actionid", 0);
    }    
    else{
        setField(L, "uid", 0);
        setField(L, "itemid", 0);
        setField(L, "type", 0);
        setField(L, "actionid", 0);
    }
}

void LuaScriptInterface::pushPosition(lua_State *L, const PositionEx& position)
{
    lua_newtable(L);
    setField(L, "z", position.z);
    setField(L, "y", position.y);
    setField(L, "x", position.x);
    setField(L, "stackpos", position.stackpos);
}

void LuaScriptInterface::pushPosition(lua_State *L, const Position& position, uint32_t stackpos)
{
    lua_newtable(L);
    setField(L, "z", position.z);
    setField(L, "y", position.y);
    setField(L, "x", position.x);
    setField(L, "stackpos", stackpos);
}

LuaVariant LuaScriptInterface::popVariant(lua_State *L)
{
    uint32_t type = getField(L, "type");

    LuaVariant var;
    var.type = (LuaVariantType_t)type;

    switch(type){
        case VARIANT_NUMBER:
        {
            var.number = getField(L, "number");
            break;
        }

        case VARIANT_STRING:
        {
            var.text = getField(L, "string");
            break;
        }

        case VARIANT_POSITION:
        case VARIANT_TARGETPOSITION:
        {
            lua_pushstring(L, "pos");
            lua_gettable(L, -2);
            popPosition(L, var.pos);
            break;
        }

        default:
        {
            var.type = VARIANT_NONE;
            break;
        }
    }
    
    lua_pop(L, 1); //table
    
    return var;
}

void LuaScriptInterface::popPosition(lua_State *L, PositionEx& position)
{
    position.z = getField(L, "z");
    position.y = getField(L, "y");
    position.x = getField(L, "x");
    position.stackpos = getField(L, "stackpos");

    lua_pop(L, 1); //table
}

void LuaScriptInterface::popPosition(lua_State *L, Position& position, uint32_t& stackpos)
{
    position.z = getField(L, "z");
    position.y = getField(L, "y");
    position.x = getField(L, "x");
    stackpos = getField(L, "stackpos");
    lua_pop(L, 1); //table
}

uint32_t LuaScriptInterface::popNumber(lua_State *L)
{
    lua_pop(L,1);
    return (uint32_t)lua_tonumber(L, 0);
}

double LuaScriptInterface::popFloatNumber(lua_State *L)
{
    lua_pop(L,1);
    return (double)lua_tonumber(L, 0);
}

const char* LuaScriptInterface::popString(lua_State *L)
{
    lua_pop(L,1);
    return lua_tostring(L, 0);
}
    
int32_t LuaScriptInterface::getField(lua_State *L, const char *key)
{
    int32_t result;
    lua_pushstring(L, key);
    lua_gettable(L, -2);  // get table[key]
    result = (int32_t)lua_tonumber(L, -1);
    lua_pop(L, 1);  // remove number and key
    return result;
}

void LuaScriptInterface::setField(lua_State *L, const char* index, uint32_t val)
{
    lua_pushstring(L, index);
    lua_pushnumber(L, (double)val);
    lua_settable(L, -3);
}
    
void LuaScriptInterface::setField(lua_State *L, const char* index, const std::string& val)
{
    lua_pushstring(L, index);
    lua_pushstring(L, val.c_str());
    lua_settable(L, -3);
}

void LuaScriptInterface::registerFunctions()
{
    //lua_register(L, "name", C_function);
    
    //getPlayerFood(uid)
    lua_register(m_luaState, "getPlayerFood", LuaScriptInterface::luaGetPlayerFood);
    //getPlayerHealth(uid)    
    lua_register(m_luaState, "getPlayerHealth", LuaScriptInterface::luaGetPlayerHealth);
    //getPlayerMana(uid)
    lua_register(m_luaState, "getPlayerMana", LuaScriptInterface::luaGetPlayerMana);
    //getPlayerLevel(uid)
    lua_register(m_luaState, "getPlayerLevel", LuaScriptInterface::luaGetPlayerLevel);
    //getPlayerMagLevel(uid)
    lua_register(m_luaState, "getPlayerMagLevel", LuaScriptInterface::luaGetPlayerMagLevel);
    //getPlayerName(uid)
    lua_register(m_luaState, "getPlayerName", LuaScriptInterface::luaGetPlayerName);
    //getPlayerAccess(uid)
    lua_register(m_luaState, "getPlayerAccess", LuaScriptInterface::luaGetPlayerAccess);
    //getPlayerPosition(uid)
    lua_register(m_luaState, "getPlayerPosition", LuaScriptInterface::luaGetPlayerPosition);
    //getPlayerSkill(uid,skillid)
    lua_register(m_luaState, "getPlayerSkill", LuaScriptInterface::luaGetPlayerSkill);
    //getPlayerMasterPos(cid)
    lua_register(m_luaState, "getPlayerMasterPos", LuaScriptInterface::luaGetPlayerMasterPos);
    //getPlayerTown(cid)
    lua_register(m_luaState, "getPlayerTown", LuaScriptInterface::luaGetPlayerTown);
    //getPlayerVocation(cid)
    lua_register(m_luaState, "getPlayerVocation", LuaScriptInterface::luaGetPlayerVocation);
    //getPlayerItemCount(cid,itemid)
    lua_register(m_luaState, "getPlayerItemCount", LuaScriptInterface::luaGetPlayerItemCount);
    //getPlayerSoul(cid)
    lua_register(m_luaState, "getPlayerSoul", LuaScriptInterface::luaGetPlayerSoul);
    //getPlayerFreeCap(cid)
    lua_register(m_luaState, "getPlayerFreeCap", LuaScriptInterface::luaGetPlayerFreeCap);
    //getPlayerLight(cid)
    lua_register(m_luaState, "getPlayerLight", LuaScriptInterface::luaGetPlayerLight);
    //getPlayerSlotItem(cid, slot)
    lua_register(m_luaState, "getPlayerSlotItem", LuaScriptInterface::luaGetPlayerSlotItem);
    //getPlayerDepotItems(uid, depotid)
    lua_register(m_luaState, "getPlayerDepotItems", LuaScriptInterface::luaGetPlayerDepotItems);    
    //getPlayerSex(cid)
    lua_register(m_luaState, "getPlayerSex", LuaScriptInterface::luaGetPlayerSex);
    //getPlayerLookDir(cid)
    lua_register(m_luaState, "getPlayerLookDir", LuaScriptInterface::luaGetPlayerLookDir);
    
    //getPlayerStorageValue(uid,valueid)
    lua_register(m_luaState, "getPlayerStorageValue", LuaScriptInterface::luaGetPlayerStorageValue);
    //setPlayerStorageValue(uid,valueid, newvalue)
    lua_register(m_luaState, "setPlayerStorageValue", LuaScriptInterface::luaSetPlayerStorageValue);
    
    //getGlobalStorageValue(valueid)
    lua_register(m_luaState, "getGlobalStorageValue", LuaScriptInterface::luaGetGlobalStorageValue);
    //setGlobalStorageValue(valueid, newvalue)
    lua_register(m_luaState, "setGlobalStorageValue", LuaScriptInterface::luaSetGlobalStorageValue);
    
    //getTilePzInfo(pos) 1 is pz. 0 no pz.
    lua_register(m_luaState, "getTilePzInfo", LuaScriptInterface::luaGetTilePzInfo);
    //getTileHouseInfo(pos). 0 no house. != 0 house id
    lua_register(m_luaState, "getTileHouseInfo", LuaScriptInterface::luaGetTileHouseInfo);
    
    //getItemRWInfo(uid)
    lua_register(m_luaState, "getItemRWInfo", LuaScriptInterface::luaGetItemRWInfo);
    //getThingfromPos(pos)
    lua_register(m_luaState, "getThingfromPos", LuaScriptInterface::luaGetThingfromPos);
    //getThing(uid)
    lua_register(m_luaState, "getThing", LuaScriptInterface::luaGetThing);
    //getThingPos(uid)
    lua_register(m_luaState, "getThingPos", LuaScriptInterface::luaGetThingPos);
    
    //doRemoveItem(uid,n)
    lua_register(m_luaState, "doRemoveItem", LuaScriptInterface::luaDoRemoveItem);
    //doPlayerFeed(uid,food)
    lua_register(m_luaState, "doPlayerFeed", LuaScriptInterface::luaDoFeedPlayer);    
    //doPlayerSendCancel(uid,text)
    lua_register(m_luaState, "doPlayerSendCancel", LuaScriptInterface::luaDoSendCancel);
    //doPlayerSendDefaultCancel(uid, ReturnValue)
    lua_register(m_luaState, "doPlayerSendDefaultCancel", LuaScriptInterface::luaDoSendDefaultCancel);
    //doTeleportThing(uid,newpos)
    lua_register(m_luaState, "doTeleportThing", LuaScriptInterface::luaDoTeleportThing);
    //doTransformItem(uid,toitemid)
    lua_register(m_luaState, "doTransformItem", LuaScriptInterface::luaDoTransformItem);
    //doPlayerSay(uid,text,type)
    lua_register(m_luaState, "doPlayerSay", LuaScriptInterface::luaDoPlayerSay);
    //doSendMagicEffect(position,type)
    lua_register(m_luaState, "doSendMagicEffect", LuaScriptInterface::luaDoSendMagicEffect);
    //doChangeTypeItem(uid,new_type)
    lua_register(m_luaState, "doChangeTypeItem", LuaScriptInterface::luaDoChangeTypeItem);
    //doSetItemActionId(uid,actionid)
    lua_register(m_luaState, "doSetItemActionId", LuaScriptInterface::luaDoSetItemActionId);
    //doSetItemText(uid,text)
    lua_register(m_luaState, "doSetItemText", LuaScriptInterface::luaDoSetItemText);
    //doSetItemSpecialDescription(uid,desc)
    lua_register(m_luaState, "doSetItemSpecialDescription", LuaScriptInterface::luaDoSetItemSpecialDescription);
    //doSendAnimatedText(position,text,color)
    lua_register(m_luaState, "doSendAnimatedText", LuaScriptInterface::luaDoSendAnimatedText);
    //doPlayerAddSkillTry(cid,skillid,n)
    lua_register(m_luaState, "doPlayerAddSkillTry", LuaScriptInterface::luaDoPlayerAddSkillTry);
    //doPlayerAddHealth(cid,health)
    lua_register(m_luaState, "doPlayerAddHealth", LuaScriptInterface::luaDoPlayerAddHealth);
    //doCreatureAddHealth(cid,health)
    lua_register(m_luaState, "doCreatureAddHealth", LuaScriptInterface::luaDoPlayerAddHealth);
    //doPlayerAddMana(cid,mana)
    lua_register(m_luaState, "doPlayerAddMana", LuaScriptInterface::luaDoPlayerAddMana);
    //doPlayerAddSoul(cid,soul)
    lua_register(m_luaState, "doPlayerAddSoul", LuaScriptInterface::luaDoPlayerAddSoul);
    //doPlayerAddItem(cid,itemid,count or type) . returns uid of the created item
    lua_register(m_luaState, "doPlayerAddItem", LuaScriptInterface::luaDoPlayerAddItem);
    //doPlayerSendTextMessage(cid,MessageClasses,message)
    lua_register(m_luaState, "doPlayerSendTextMessage", LuaScriptInterface::luaDoPlayerSendTextMessage);
    //doPlayerRemoveMoney(cid,money)
    lua_register(m_luaState, "doPlayerRemoveMoney", LuaScriptInterface::luaDoPlayerRemoveMoney);
    //doShowTextWindow(cid,maxlen,canWrite)    
    lua_register(m_luaState, "doShowTextWindow", LuaScriptInterface::luaDoShowTextWindow);    
    //doShowTextDialog(cid,itemid,text)    
    lua_register(m_luaState, "doShowTextDialog", LuaScriptInterface::luaDoShowTextDialog);    
    //doDecayItem(uid)
    lua_register(m_luaState, "doDecayItem", LuaScriptInterface::luaDoDecayItem);
    //doCreateItem(itemid,type or count,position) .only working on ground. returns uid of the created item
    lua_register(m_luaState, "doCreateItem", LuaScriptInterface::luaDoCreateItem);
    //doSummonCreature(name, position)
    lua_register(m_luaState, "doSummonCreature", LuaScriptInterface::luaDoSummonCreature);
    //doMoveCreature(cid, direction)
    lua_register(m_luaState, "doMoveCreature", LuaScriptInterface::luaDoMoveCreature);
    //doPlayerSetMasterPos(cid,pos)
    lua_register(m_luaState, "doPlayerSetMasterPos", LuaScriptInterface::luaDoPlayerSetMasterPos);
    //doPlayerSetTown(cid,townid)
    lua_register(m_luaState, "doPlayerSetTown", LuaScriptInterface::luaDoPlayerSetTown);
    //doPlayerSetVocation(cid,voc)
    lua_register(m_luaState, "doPlayerSetVocation", LuaScriptInterface::luaDoPlayerSetVocation);
    //doPlayerRemoveItem(cid,itemid,count)
    lua_register(m_luaState, "doPlayerRemoveItem", LuaScriptInterface::luaDoPlayerRemoveItem);
    //doPlayerAddExp(cid,exp)
    lua_register(m_luaState, "doPlayerAddExp", LuaScriptInterface::luaDoPlayerAddExp);
    //doPlayerSetGuildId(cid, id)
    //lua_register(m_luaState, "doPlayerSetGuildId", LuaScriptInterface::luaDoPlayerSetGuildId);
    //doPlayerSetGuildRank(cid, rank)
    lua_register(m_luaState, "doPlayerSetGuildRank", LuaScriptInterface::luaDoPlayerSetGuildRank);
    //doPlayerSetGuildNick(cid, nick)
    lua_register(m_luaState, "doPlayerSetGuildNick", LuaScriptInterface::luaDoPlayerSetGuildNick);
    //doPlayerAddOutfit(cid,looktype,addons)
    lua_register(m_luaState, "doPlayerAddOutfit", LuaScriptInterface::luaDoPlayerAddOutfit);
    //doPlayerRemOutfit(cid,looktype,addons)
    lua_register(m_luaState, "doPlayerRemOutfit", LuaScriptInterface::luaDoPlayerRemOutfit);    
    //doSetCreatureLight(cid, lightLevel, lightColor, time)
    lua_register(m_luaState, "doSetCreatureLight", LuaScriptInterface::luaDoSetCreatureLight);
    
    //isPlayer(cid)
    lua_register(m_luaState, "isPlayer", LuaScriptInterface::luaIsPlayer);
    //isCreature(cid)
    lua_register(m_luaState, "isCreature", LuaScriptInterface::luaIsCreature);
    //isContainer(uid)
    lua_register(m_luaState, "isContainer", LuaScriptInterface::luaIsContainer);
    //isMoveable(uid)
    lua_register(m_luaState, "isMoveable", LuaScriptInterface::luaIsMoveable);

    //getPlayerByName(name)
    lua_register(m_luaState, "getPlayerByName", LuaScriptInterface::luaGetPlayerByName);
    //registerCreature(cid)
    lua_register(m_luaState, "registerCreature", LuaScriptInterface::luaRegisterCreature);

    //getContainerSize(uid)
    lua_register(m_luaState, "getContainerSize", LuaScriptInterface::luaGetContainerSize);
    //getContainerCap(uid)
    lua_register(m_luaState, "getContainerCap", LuaScriptInterface::luaGetContainerCap);
    //getContainerItem(uid, slot)
    lua_register(m_luaState, "getContainerItem", LuaScriptInterface::luaGetContainerItem);
    //doAddContainerItem(uid, itemid, count or subtype)
    lua_register(m_luaState, "doAddContainerItem", LuaScriptInterface::luaDoAddContainerItem);
    
    //getHouseOwner(houseid)
    lua_register(m_luaState, "getHouseOwner", LuaScriptInterface::luaGetHouseOwner);
    //getHouseName(houseid)
    lua_register(m_luaState, "getHouseName", LuaScriptInterface::luaGetHouseName);
    //getHouseEntry(houseid)
    lua_register(m_luaState, "getHouseEntry", LuaScriptInterface::luaGetHouseEntry);
    //getHouseRent(houseid)
    lua_register(m_luaState, "getHouseRent", LuaScriptInterface::luaGetHouseRent);
    //getHouseTown(houseid)
    lua_register(m_luaState, "getHouseTown", LuaScriptInterface::luaGetHouseTown);
    //getHouseAccessList(houseod, listid)
    lua_register(m_luaState, "getHouseAccessList", LuaScriptInterface::luaGetHouseAccessList);
    //getHouseByPlayerName(playername)
    lua_register(m_luaState, "getHouseByPlayerName", LuaScriptInterface::luaGetHouseByPlayerGUID);
    //setHouseAccessList(houseid, listid, listtext)
    lua_register(m_luaState, "setHouseAccessList", LuaScriptInterface::luaSetHouseAccessList);
    //setHouseOwner(houseid, ownerGUID)
    lua_register(m_luaState, "setHouseOwner", LuaScriptInterface::luaSetHouseOwner);
    
    //getWorldType()
    lua_register(m_luaState, "getWorldType", LuaScriptInterface::luaGetWorldType);
    //getWorldTime()
    lua_register(m_luaState, "getWorldTime", LuaScriptInterface::luaGetWorldTime);
    //getWorldLight()
    lua_register(m_luaState, "getWorldLight", LuaScriptInterface::luaGetWorldLight);
    //getWorldCreatures(type) 0 players, 1 monsters, 2 npcs, 3 all
    lua_register(m_luaState, "getWorldCreatures", LuaScriptInterface::luaGetWorldCreatures);
    //getWorldUpTime()
    lua_register(m_luaState, "getWorldUpTime", LuaScriptInterface::luaGetWorldUpTime);
    
    //createCombatArea( {area}, {extArea} )
    lua_register(m_luaState, "createCombatArea", LuaScriptInterface::luaCreateCombatArea);

    //createConditionObject(type)
    lua_register(m_luaState, "createConditionObject", LuaScriptInterface::luaCreateConditionObject);

    //setCombatArea(combat, area)
    lua_register(m_luaState, "setCombatArea", LuaScriptInterface::luaSetCombatArea);

    //setCombatCondition(combat, condition)
    lua_register(m_luaState, "setCombatCondition", LuaScriptInterface::luaSetCombatCondition);

    //setCombatParam(combat, key, value)
    lua_register(m_luaState, "setCombatParam", LuaScriptInterface::luaSetCombatParam);
    
    //setConditionParam(condition, key, value)
    lua_register(m_luaState, "setConditionParam", LuaScriptInterface::luaSetConditionParam);

    //addDamageCondition(condition, key, rounds, time, value)
    lua_register(m_luaState, "addDamageCondition", LuaScriptInterface::luaAddDamageCondition);

    //addOutfitCondition(condition, lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet)
    lua_register(m_luaState, "addOutfitCondition", LuaScriptInterface::luaAddOutfitCondition);

    //setCombatCallBack(combat, key, function_name)
    lua_register(m_luaState, "setCombatCallback", LuaScriptInterface::luaSetCombatCallBack);

    //setCombatFormula(combat, type, mina, minb, maxa, maxb)
    lua_register(m_luaState, "setCombatFormula", LuaScriptInterface::luaSetCombatFormula);

    //setConditionFormula(combat, mina, minb, maxa, maxb)
    lua_register(m_luaState, "setConditionFormula", LuaScriptInterface::luaSetConditionFormula);

    //doCombat(cid, combat, param)
    lua_register(m_luaState, "doCombat", LuaScriptInterface::luaDoCombat);

    //createCombatObject()
    lua_register(m_luaState, "createCombatObject", LuaScriptInterface::luaCreateCombatObject);

    //doAreaCombatHealth(cid, type, pos, area, min, max, effect)
    lua_register(m_luaState, "doAreaCombatHealth", LuaScriptInterface::luaDoAreaCombatHealth);

    //doTargetCombatHealth(cid, target, type, min, max, effect)
    lua_register(m_luaState, "doTargetCombatHealth", LuaScriptInterface::luaDoTargetCombatHealth);

    //doAreaCombatMana(cid, pos, area, min, max, effect)
    lua_register(m_luaState, "doAreaCombatMana", LuaScriptInterface::luaDoAreaCombatMana);

    //doTargetCombatMana(cid, target, min, max, effect)
    lua_register(m_luaState, "doTargetCombatMana", LuaScriptInterface::luaDoTargetCombatMana);

    //doAreaCombatCondition(cid, pos, area, condition, effect)
    lua_register(m_luaState, "doAreaCombatCondition", LuaScriptInterface::luaDoAreaCombatCondition);

    //doTargetCombatCondition(cid, target, condition, effect)
    lua_register(m_luaState, "doTargetCombatCondition", LuaScriptInterface::luaDoTargetCombatCondition);

    //doAreaCombatDispel(cid, pos, area, type, effect)
    lua_register(m_luaState, "doAreaCombatDispel", LuaScriptInterface::luaDoAreaCombatDispel);

    //doTargetCombatDispel(cid, target, type, effect)
    lua_register(m_luaState, "doTargetCombatDispel", LuaScriptInterface::luaDoTargetCombatDispel);

    //doChallengeCreature(cid, target)
    lua_register(m_luaState, "doChallengeCreature", LuaScriptInterface::luaDoChallengeCreature);

    //doConvinceCreature(cid, target)
    lua_register(m_luaState, "doConvinceCreature", LuaScriptInterface::luaDoConvinceCreature);

    //numberToVariant(number)
    lua_register(m_luaState, "numberToVariant", LuaScriptInterface::luaNumberToVariant);

    //stringToVariant(string)
    lua_register(m_luaState, "stringToVariant", LuaScriptInterface::luaStringToVariant);

    //positionToVariant(pos)
    lua_register(m_luaState, "positionToVariant", LuaScriptInterface::luaPositionToVariant);

    //targetPositionToVariant(pos)
    lua_register(m_luaState, "targetPositionToVariant", LuaScriptInterface::luaTargetPositionToVariant);

    //variantToNumber(var)
    lua_register(m_luaState, "variantToNumber", LuaScriptInterface::luaVariantToNumber);

    //variantToString(var)
    lua_register(m_luaState, "variantToString", LuaScriptInterface::luaVariantToString);

    //variantToPosition(var)
    lua_register(m_luaState, "variantToPosition", LuaScriptInterface::luaVariantToPosition);

    //doChangeSpeed(cid, delta)
    lua_register(m_luaState, "doChangeSpeed", LuaScriptInterface::luaDoChangeSpeed);

    //doSetMonsterOutfit(cid, name, time)
    lua_register(m_luaState, "doSetMonsterOutfit", LuaScriptInterface::luaSetMonsterOutfit);
    //doSetItemOutfit(cid, item, time)
    lua_register(m_luaState, "doSetItemOutfit", LuaScriptInterface::luaSetItemOutfit);
    //doSetCreatureOutfit(cid, outfit, time)
    lua_register(m_luaState, "doSetCreatureOutfit", LuaScriptInterface::luaSetCreatureOutfit);
    //getCreatureOutfit(cid)
    lua_register(m_luaState, "getCreatureOutfit", LuaScriptInterface::luaGetCreatureOutfit);
    //getCreaturePosition(cid)
    lua_register(m_luaState, "getCreaturePosition", LuaScriptInterface::luaGetCreaturePosition);
    //getCreatureName(cid)
    lua_register(m_luaState, "getCreatureName", LuaScriptInterface::luaGetCreatureName);

    //isItemStackable(itemid)
    lua_register(m_luaState, "isItemStackable", LuaScriptInterface::luaIsItemStackable);
    //isItemRune(itemid)
    lua_register(m_luaState, "isItemRune", LuaScriptInterface::luaIsItemRune);
    //isItemDoor(itemid)
    lua_register(m_luaState, "isItemDoor", LuaScriptInterface::luaIsItemDoor);
    //isItemContainer(itemid)
    lua_register(m_luaState, "isItemContainer", LuaScriptInterface::luaIsItemContainer);
    //isItemFluidContainer(itemid)
    lua_register(m_luaState, "isItemFluidContainer", LuaScriptInterface::luaIsItemFluidContainer);
    //getItemName(itemid)
    lua_register(m_luaState, "getItemName", LuaScriptInterface::luaGetItemName);

    #ifdef __XID_CVS_MODS__
    //getPlayerSkull(cid)
    lua_register(m_luaState, "getPlayerSkull", LuaScriptInterface::luaGetPlayerSkull);
    //getPlayerConditionTicks(cid, conditionid)
    lua_register(m_luaState, "getPlayerConditionTicks", LuaScriptInterface::luaGetPlayerConditionTicks);
    #endif

    #ifdef __XID_SEPERATE_ADDONS__
    //doPlayerAddAddon(cid, looktype, addon)
    lua_register(m_luaState, "doPlayerAddAddon", LuaScriptInterface::luaDoPlayerAddAddon);
    //getPlayerOutfitAddon(cid, looktype)
    lua_register(m_luaState, "getPlayerOutfitAddon", LuaScriptInterface::luaGetPlayerOutfitAddon);
    #endif

    #ifdef __XID_BUY_SELL__
    //getItemStackable(itemid)
    lua_register(m_luaState, "getItemStackable", LuaScriptInterface::luaGetItemStackable);
    #endif

    #ifdef __XID_PREMIUM_SYSTEM__
    //isPremium(cid)
    lua_register(m_luaState, "isPremium", LuaScriptInterface::luaIsPremium);
    //buyPrem(cid, days)
    lua_register(m_luaState, "addPremium", LuaScriptInterface::luaBuyPremium);
    #endif

    #ifdef __YUR_GUILD_SYSTEM__
    //foundNewGuild(guildname)
    lua_register(m_luaState, "foundNewGuild", LuaScriptInterface::luaFoundNewGuild);
    //getPlayerGuildStatus(name)
    lua_register(m_luaState, "getPlayerGuildStatus", LuaScriptInterface::luaGetPlayerGuildStatus);
    //setPlayerGuildStatus(guildstatus, name)
    lua_register(m_luaState, "setPlayerGuildStatus", LuaScriptInterface::luaSetPlayerGuildStatus);
    //getPlayerGuildName(name)
    lua_register(m_luaState, "getPlayerGuildName", LuaScriptInterface::luaGetPlayerGuildName);
    //setPlayerGuild(name, guildstatus, guilrank, guildname)
    lua_register(m_luaState, "setPlayerGuild", LuaScriptInterface::luaSetPlayerGuild);
    //clearPlayerGuild(name)
    lua_register(m_luaState, "clearPlayerGuild", LuaScriptInterface::luaClearPlayerGuild);
    //setPlayerGuildNick(name, guildnick)
    lua_register(m_luaState, "setPlayerGuildNick", LuaScriptInterface::luaSetPlayerGuildNick);
    //setPlayerGuildTitle(name, guildnick)
    lua_register(m_luaState, "setPlayerGuildTitle", LuaScriptInterface::luaSetPlayerGuildNick);
    #endif

    #ifdef __XID_LEARN_SPELLS__
    //doPlayerLearnSpell(cid, spellname)
    lua_register(m_luaState, "doPlayerLearnSpell", LuaScriptInterface::luaDoPlayerLearnSpell);
    #endif
    
    #ifdef __XID_BLESS_SYSTEM__
    //doPlayerAddBlesing(cid, blessid)
    lua_register(m_luaState, "doPlayerAddBlessing", LuaScriptInterface::luaDoPlayerAddBlessing);
    //getPlayerBlessing(cid, blessid)
    lua_register(m_luaState, "getPlayerBlessing", LuaScriptInterface::luaGetPlayerBlessing);    
    #endif

    //debugPrint(text)
    lua_register(m_luaState, "debugPrint", LuaScriptInterface::luaDebugPrint);
    //isInArray(array, value)
    lua_register(m_luaState, "isInArray", LuaScriptInterface::luaIsInArray);
    
    //addEvent(callback, delay, parameter)
    lua_register(m_luaState, "addEvent", LuaScriptInterface::luaAddEvent);
    //stopEvent(eventid)
    lua_register(m_luaState, "stopEvent", LuaScriptInterface::luaStopEvent);

    //getDataDir()
    lua_register(m_luaState, "getDataDir", LuaScriptInterface::luaGetDataDirectory);
}


int LuaScriptInterface::internalGetPlayerInfo(lua_State *L, PlayerInfo_t info)
{
    uint32_t cid = popNumber(L);
    ScriptEnviroment* env = getScriptEnv();
    int32_t value;
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        const Tile *tile;
        Position pos;
        uint32_t stackpos;
        switch(info){
        case PlayerInfoAccess:
            value = player->getAccessLevel();
            break;        
        case PlayerInfoLevel:
            value = player->level;
            break;
        case PlayerInfoMagLevel:
            value = player->magLevel;
            break;
        case PlayerInfoMana:
            value = player->mana;
            break;
        case PlayerInfoHealth:
            value = player->health;
            break;
        case PlayerInfoName:
            lua_pushstring(L, player->name.c_str());
            return 1;
            break;
        case PlayerInfoPosition:            
            pos = player->getPosition();
            tile = player->getTile();
            if(tile){
                stackpos = player->getParent()->__getIndexOfThing(player);
            }
            else{
                stackpos = 0;
            }
            pushPosition(L, pos, stackpos);
            return 1;
            break;
        case PlayerInfoMasterPos:
            pos = player->masterPos;
            pushPosition(L, pos, 0);
            return 1;
            break;
        case PlayerInfoFood:
        {
            //value = player->food/1000;
            value = 0;

            Condition* condition = player->getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT);
            if(condition){
                value = condition->getTicks() / 1000;
            }
            else{
                value = 0;
            }
            break;
        }
        case PlayerInfoVocation:
            value = player->getVocationId();
            break;
        case PlayerInfoSoul:
            value = player->getPlayerInfo(PLAYERINFO_SOUL);
            break;
        case PlayerInfoFreeCap:
            value = (int)player->getFreeCapacity();
            break;
        case PlayerInfoSex:
            value = player->getSex();
            break;
        case PlayerInfoLookDirection:
            value = player->getDirection();
            break;
        case PlayerInfoTown:
            value = player->getTown();
            break;
        case PlayerInfoGUID:
            value = player->getGUID();
            break;
        default:
            std::string error_str = "Unknown player info. info = " + info;
            reportErrorFunc(error_str);
            value = 0;
            break;        
        }
        lua_pushnumber(L,value);
        return 1;
    }
    else{
        std::stringstream error_str;
        error_str << "Player not found. info = " << info;
        reportErrorFunc(error_str.str());
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }        
    
    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}
//getPlayer[Info](uid)
int LuaScriptInterface::luaGetPlayerFood(lua_State *L){    
    return internalGetPlayerInfo(L, PlayerInfoFood);}
    
int LuaScriptInterface::luaGetPlayerAccess(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoAccess);}
    
int LuaScriptInterface::luaGetPlayerLevel(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoLevel);}
    
int LuaScriptInterface::luaGetPlayerMagLevel(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoMagLevel);}
    
int LuaScriptInterface::luaGetPlayerMana(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoMana);}

int LuaScriptInterface::luaGetPlayerHealth(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoHealth);}
    
int LuaScriptInterface::luaGetPlayerName(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoName);}
    
int LuaScriptInterface::luaGetPlayerPosition(lua_State *L){    
    return internalGetPlayerInfo(L, PlayerInfoPosition);}
    
int LuaScriptInterface::luaGetPlayerVocation(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoVocation);}

int LuaScriptInterface::luaGetPlayerMasterPos(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoMasterPos);}

int LuaScriptInterface::luaGetPlayerSoul(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoSoul);}

int LuaScriptInterface::luaGetPlayerFreeCap(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoFreeCap);}

int LuaScriptInterface::luaGetPlayerSex(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoSex);}

int LuaScriptInterface::luaGetPlayerLookDir(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoLookDirection);}

int LuaScriptInterface::luaGetPlayerTown(lua_State *L){
    return internalGetPlayerInfo(L, PlayerInfoTown);}
//

int LuaScriptInterface::luaDoRemoveItem(lua_State *L)
{    
    //doRemoveItem(uid,n)
    char n = (char)popNumber(L);    
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        g_game.internalRemoveItem(item, n);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerRemoveItem(lua_State *L)
{
    //doPlayerRemoveItem(cid,itemid,count)
    uint32_t count = popNumber(L);
    uint16_t itemId = (uint16_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        if(g_game.removeItemOfType(player, itemId, count)){
            lua_pushnumber(L, LUA_TRUE);
        }
        else{
            lua_pushnumber(L, LUA_FALSE);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoFeedPlayer(lua_State *L)
{    
    //doFeedPlayer(uid,food)
    int32_t food = (int32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->addDefaultRegeneration(food * 1000);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSendCancel(lua_State *L)
{    
    //doSendCancel(uid,text)
    const char * text = popString(L);
    uint32_t cid = popNumber(L);    
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        player->sendCancel(text);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSendDefaultCancel(lua_State *L)
{    
    //doPlayerSendDefaultCancel(uid, ReturnValue)
    ReturnValue ret = (ReturnValue)popNumber(L);    
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        player->sendCancelMessage(ret);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaDoTeleportThing(lua_State *L)
{
    //doTeleportThing(uid,newpos)
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    uint32_t uid = popNumber(L);    
    
    ScriptEnviroment* env = getScriptEnv();
    
    Thing* tmp = env->getThingByUID(uid);
    if(tmp){
        if(g_game.internalTeleport(tmp,(Position&)pos) == RET_NOERROR){
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            reportErrorFunc("Can not teleport thing.");
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

    
int LuaScriptInterface::luaDoTransformItem(lua_State *L)
{
    //doTransformItem(uid,toitemid)    
    uint16_t toId = (uint16_t)popNumber(L);    
    uint32_t uid = popNumber(L);    
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        g_game.transformItem(item, toId);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerSay(lua_State *L)
{
    //doPlayerSay(uid,text,type)
    uint32_t type = popNumber(L);    
    const char * text = popString(L);
    uint32_t cid = popNumber(L);
                    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        g_game.internalCreatureSay(player,(SpeakClasses)type,std::string(text));
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSendMagicEffect(lua_State *L)
{
    //doSendMagicEffect(position,type)
    uint32_t type = popNumber(L);    
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    
    ScriptEnviroment* env = getScriptEnv();
    
    SpectatorVec list;
    SpectatorVec::iterator it;

    if(pos.x == 0xFFFF){
        pos = env->getRealPos();
    }
    
    g_game.addMagicEffect(pos, type);
    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}

int LuaScriptInterface::luaDoChangeTypeItem(lua_State *L)
{
    //doChangeTypeItem(uid,new_type)
    int32_t subtype = (int32_t)popNumber(L);    
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        g_game.transformItem(item, item->getID(), subtype);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaDoPlayerAddSkillTry(lua_State *L)
{
    //doPlayerAddSkillTry(uid,skillid,n)
    uint32_t n = popNumber(L);
    uint32_t skillid = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->addSkillAdvance((skills_t)skillid, n);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaDoPlayerAddHealth(lua_State *L)
{
    //doPlayerAddHealth(uid,health)
    //doCreatureAddHealth(uid,health)
    int32_t healthChange = (int32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Creature* creature = env->getCreatureByUID(cid);
    if(creature){
        if(healthChange >= 0){
            g_game.combatChangeHealth(COMBAT_HEALING, NULL, creature, healthChange);
        }
        else{
            g_game.combatChangeHealth(COMBAT_UNDEFINEDDAMAGE, NULL, creature, healthChange);
        }

        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerAddMana(lua_State *L)
{
    //doPlayerAddMana(uid,mana)
    int32_t manaChange = (int32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        g_game.combatChangeMana(NULL, player, manaChange);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerAddItem(lua_State *L)
{
    //doPlayerAddItem(uid,itemid,count or type)
    uint32_t count = popNumber(L);
    uint32_t itemId = (uint32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(!player){
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    const ItemType& it = Item::items[itemId];
    if(it.stackable && count > 100){
        count = 100;
    }

    Item* newItem = Item::CreateItem(itemId, count);

    if(!newItem){
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    //internalPlayerAddItem(L, player, itemId, count);
    ReturnValue ret = g_game.internalPlayerAddItem(player, newItem);

    if(ret != RET_NOERROR){
        delete newItem;
        reportErrorFunc("Could not add item");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    if(newItem->getParent()){
        uint32_t uid = env->addThing((Thing*)newItem);
        lua_pushnumber(L, uid);
    }
    else{
        //stackable item stacked with existing object, newItem will be released
        lua_pushnumber(L, LUA_NULL);
    }

    return 1;
}

int LuaScriptInterface::luaDoPlayerSendTextMessage(lua_State *L)
{    
    //doPlayerSendTextMessage(uid,MessageClasses,message)
    const char * text = popString(L);
    uint32_t messageClass = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        player->sendTextMessage((MessageClasses)messageClass,text);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }        
    return 1;
}

int LuaScriptInterface::luaDoSendAnimatedText(lua_State *L)
{    
    //doSendAnimatedText(position,text,color)
    uint32_t color = popNumber(L);
    const char * text = popString(L);
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    
    ScriptEnviroment* env = getScriptEnv();
    
    SpectatorVec list;
    SpectatorVec::iterator it;

    if(pos.x == 0xFFFF){
        pos = env->getRealPos();
    }
    
    g_game.addAnimatedText(pos, color, text);
    return 1;
}

int LuaScriptInterface::luaGetPlayerSkill(lua_State *L)
{
    //getPlayerSkill(uid,skillid)
    uint32_t skillid = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        if(skillid <= 6){
            uint32_t value = player->skills[skillid][SKILL_LEVEL];
            lua_pushnumber(L, value);
        }
        else{
            reportErrorFunc("No valid skillId");
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoShowTextWindow(lua_State *L)
{
    //doShowTextWindow(uid,maxlen,canWrite)
    popNumber(L);
    popNumber(L);
    popNumber(L);
    reportErrorFunc("Deprecated function.");
    lua_pushnumber(L, LUA_ERROR);
    return 1;
}

int LuaScriptInterface::luaDoShowTextDialog(lua_State *L)
{
    //doShowTextDialog(cid, itemid, text)
    const char * text = popString(L);
    uint32_t itemid = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->sendTextWindow(itemid, text);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetItemRWInfo(lua_State *L)
{
    //getItemRWInfo(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Item* item = env->getItemByUID(uid);
    if(item){
        uint32_t rwflags = 0;
        if(item->isReadable())
            rwflags |= 1;

        if(item->canWriteText()){
            rwflags |= 2;
        }

        lua_pushnumber(L, rwflags);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoDecayItem(lua_State *L)
{
    //doDecayItem(uid)
    //Note: to stop decay set decayTo = 0 in items.otb
    uint32_t uid = popNumber(L);    
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        g_game.startDecay(item);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetThingfromPos(lua_State *L)
{
    //getThingfromPos(pos)
    //Note: 
    //    stackpos = 255. Get the top thing(item moveable or creature).
    //    stackpos = 254. Get MagicFieldtItem
    //    stackpos = 253. Get Creature
    
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Tile* tile = g_game.map->getTile(pos);    
    Thing *thing = NULL;
    
    if(tile){
        if(stackpos == 255){
            thing = tile->getTopCreature();
            
            if(thing == NULL){
                Item* item = tile->getTopDownItem();
                if(item && !item->isNotMoveable())
                    thing = item;
            }
        }
        else if(stackpos == 254){
            thing = tile->getFieldItem();
        }
        else if(stackpos == 253){
            thing = tile->getTopCreature();
        }
        else{
            thing = tile->__getThing(stackpos);
        }
        
        if(thing){
            uint32_t thingid = env->addThing(thing);
            pushThing(L, thing, thingid);
        }
        else{
            pushThing(L, NULL, 0);
        }
        return 1;
        
    }//if(tile)
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_TILE_NOT_FOUND));
        pushThing(L, NULL, 0);
        return 1;
    }
}

int LuaScriptInterface::luaDoCreateItem(lua_State *L)
{
    //doCreateItem(itemid,type or count,position) only working on ground. returns uid of the created item
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    uint32_t count = popNumber(L);
    uint32_t itemId = (uint32_t)popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Tile* tile = g_game.map->getTile(pos);
    if(!tile){
        reportErrorFunc(getErrorDesc(LUA_ERROR_TILE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    const ItemType& it = Item::items[itemId];
    if(it.stackable && count > 100){
        count = 100;
    }

    Item* newItem = Item::CreateItem(itemId, count);
    
    ReturnValue ret = g_game.internalAddItem(tile, newItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
    if(ret != RET_NOERROR){
        delete newItem;
        reportErrorFunc("Can not add Item");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    if(newItem->getParent()){
        uint32_t uid = env->addThing(newItem);
        lua_pushnumber(L, uid);
    }
    else{
        //stackable item stacked with existing object, newItem will be released
        lua_pushnumber(L, LUA_NULL);
    }
    return 1;
}

int LuaScriptInterface::luaGetPlayerStorageValue(lua_State *L)
{
    //getPlayerStorageValue(cid,valueid)
    uint32_t key = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        int32_t value;
        if(player->getStorageValue(key, value)){
            lua_pushnumber(L, value);
        }
        else{
            lua_pushnumber(L, -1);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetPlayerStorageValue(lua_State *L)
{
    //setPlayerStorageValue(cid,valueid, newvalue)
    int32_t value = (int32_t)popNumber(L);
    uint32_t key = popNumber(L);
    uint32_t cid = popNumber(L);
    if(IS_IN_KEYRANGE(key, RESERVED_RANGE)){
        std::stringstream error_str;
        error_str << "Accesing to reserverd range: "  << key;
        reportErrorFunc(error_str.str());
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->addStorageValue(key,value);
        lua_pushnumber(L, 0);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSetItemActionId(lua_State *L)
{
    //doSetItemActionId(uid,actionid)
    uint32_t actionid = popNumber(L);    
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);    
    if(item){
        item->setActionId(actionid);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSetItemText(lua_State *L)
{
    //doSetItemText(uid,text)
    const char *text = popString(L);
    uint32_t uid = popNumber(L);    
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        std::string str(text);
        item->setText(str);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSetItemSpecialDescription(lua_State *L)
{
    //doSetItemSpecialDescription(uid,desc)
    const char *desc = popString(L);
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Item* item = env->getItemByUID(uid);
    if(item){
        std::string str(desc);
        item->setSpecialDescription(str);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetTilePzInfo(lua_State *L)
{
    //getTilePzInfo(pos)
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    
    Tile *tile = g_game.map->getTile(pos);
    
    if(tile){
        if(tile->isPz()){
            lua_pushnumber(L, LUA_TRUE);
        }
        else{
            lua_pushnumber(L, LUA_FALSE);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_TILE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetTileHouseInfo(lua_State *L)
{
    //getTileHouseInfo(pos)
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    
    Tile *tile = g_game.map->getTile(pos);
    if(tile){
        if(HouseTile* houseTile = dynamic_cast<HouseTile*>(tile)){
            House* house = houseTile->getHouse();
            if(house){
                lua_pushnumber(L, house->getHouseId());
            }
            else{
                lua_pushnumber(L, LUA_NULL);
            }
        }
        else{
            lua_pushnumber(L, LUA_NULL);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_TILE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaDoSummonCreature(lua_State *L){
    //doSummonCreature(name, position)
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    const char *name = popString(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Monster* monster = Monster::createMonster(name);

    if(!monster){
        std::string error_str = (std::string)"Monster name(" + name + (std::string)") not found";
        reportErrorFunc(error_str);
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    if(!g_game.placeCreature((Position&)pos, monster)){
        delete monster;
        std::string error_str = (std::string)"Can not summon monster: " + name;
        reportErrorFunc(error_str);
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    uint32_t cid = env->addThing((Thing*)monster);
    
    lua_pushnumber(L, cid);
    return 1;    
}


int LuaScriptInterface::luaDoPlayerRemoveMoney(lua_State *L)
{
    //doPlayerRemoveMoney(cid,money)
    uint32_t money = popNumber(L);
    uint32_t cid = popNumber(L);    
                    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        if(g_game.removeMoney(player, money)){
            lua_pushnumber(L, LUA_TRUE);
        }
        else{
            lua_pushnumber(L, LUA_FALSE);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerSetMasterPos(lua_State *L)
{
    //doPlayerSetMasterPos(cid,pos)
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    popNumber(L);
    
    reportErrorFunc("Deprecated function. Use doPlayerSetTown");
    lua_pushnumber(L, LUA_ERROR);
    return 1;
}

int LuaScriptInterface::luaDoPlayerSetTown(lua_State *L)
{
    //doPlayerSetTown(cid,towind)
    uint32_t townid = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        Town* town = Towns::getInstance().getTown(townid);
        if(town){
            player->masterPos = town->getTemplePosition();
            player->setTown(townid);
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            reportErrorFunc("Not found townid");
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerSetVocation(lua_State *L)
{
    //doPlayerSetVocation(cid,voc)
    uint32_t voc = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->setVocation(voc);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaDebugPrint(lua_State *L)
{
    //debugPrint(text)
    const char * text = popString(L);
    reportErrorFunc(std::string(text));
    return 0;
}

int LuaScriptInterface::luaDoPlayerAddSoul(lua_State *L)
{
    //doPlayerAddSoul(cid,soul)
    int32_t addsoul = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->changeSoul(addsoul);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }        
    return 1;
}

int LuaScriptInterface::luaGetPlayerItemCount(lua_State *L)
{
    //getPlayerItemCount(cid,itemid)
    uint32_t itemId = (uint32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        uint32_t n = player->__getItemTypeCount(itemId);
        lua_pushnumber(L, n);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaGetHouseOwner(lua_State *L)
{
    //getHouseOwner(houseid)
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        std::string owner = house->getHouseOwner();
        lua_pushstring(L, owner.c_str());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetHouseName(lua_State *L)
{
    //getHouseName(houseid)
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        lua_pushstring(L, house->getName().c_str());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaGetHouseEntry(lua_State *L)
{
    //getHouseEntry(houseid)
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        pushPosition(L, house->getEntryPosition(), 0);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaGetHouseRent(lua_State *L)
{
    //getHouseRent(houseid)
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        lua_pushnumber(L, house->getRent());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaGetHouseTown(lua_State *L)
{
    //getHouseTown(houseid)
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        lua_pushnumber(L, house->getTownId());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnil(L);
    }
    return 1;
}

int LuaScriptInterface::luaGetHouseAccessList(lua_State *L)
{
    //getHouseAccessList(houseid, listid)
    uint32_t listid = popNumber(L);
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        std::string list;
        if(house->getAccessList(listid, list)){
            lua_pushstring(L, list.c_str());
        }
        else{
            reportErrorFunc("No valid listid.");
            lua_pushnil(L);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnil(L);
    }
    return 1;
}

int  LuaScriptInterface::luaGetHouseByPlayerGUID(lua_State *L)
{
    //getHouseByPlayerName(playername)
    std::string name = popString(L);
    
    House* house = Houses::getInstance().getHouseByPlayerName(name);
    if(house){
        lua_pushnumber(L, house->getHouseId());
    }
    else{
        lua_pushnil(L);
    }
    
    return 1;
}

int LuaScriptInterface::luaSetHouseAccessList(lua_State *L)
{
    //setHouseAccessList(houseid, listid, listtext)
    std::string list = popString(L);
    uint32_t listid = popNumber(L);
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        house->setAccessList(listid, list);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetHouseOwner(lua_State *L)
{
    //setHouseOwner(houseid, owner)
    std::string owner = popString(L);
    uint32_t houseid = popNumber(L);
    
    House* house = Houses::getInstance().getHouse(houseid);
    if(house){
        house->setHouseOwner(owner);
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_HOUSE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}


int LuaScriptInterface::luaGetWorldType(lua_State *L)
{
    //getWorldType()
    switch(g_game.getWorldType()){
    case WORLD_TYPE_NO_PVP:
        lua_pushnumber(L, 1);
        break;
    case WORLD_TYPE_PVP:
        lua_pushnumber(L, 2);
        break;
    case WORLD_TYPE_PVP_ENFORCED:
        lua_pushnumber(L, 3);
        break;
    default:
        lua_pushnumber(L, LUA_ERROR);
        break;
    }
    return 1;
}

int LuaScriptInterface::luaGetWorldTime(lua_State *L)
{
    //getWorldTime()
    uint32_t time = g_game.light_hour;
    lua_pushnumber(L, time);
    return 1;
}

int LuaScriptInterface::luaGetWorldLight(lua_State *L)
{
    //getWorldLight()
    uint32_t level = g_game.lightlevel;
    lua_pushnumber(L, level);
    lua_pushnumber(L, 0xD7);//color
    return 2;
}

int LuaScriptInterface::luaGetWorldCreatures(lua_State *L)
{
    //getWorldCreatures(type) 0 players, 1 monsters, 2 npcs, 3 all
    uint32_t type = popNumber(L);
    uint32_t value;
    switch(type){
    case 0:
        value = g_game.getPlayersOnline();
        break;
    case 1:
        value = g_game.getMonstersOnline();
        break;
    case 2:
        value = g_game.getNpcsOnline();
        break;
    case 3:
        value = g_game.getCreaturesOnline();
        break;
    default:
        reportErrorFunc("Wrong creature type.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
        break;
    }
    lua_pushnumber(L, value);
    return 1;
}

int LuaScriptInterface::luaGetWorldUpTime(lua_State *L)
{
    //getWorldUpTime()
    uint32_t uptime = 0;

    Status* status = Status::instance();
    if(status){
        uptime = (OTSYS_TIME() - status->start)/1000;
    }

    lua_pushnumber(L, uptime);
    return 1;
}

int LuaScriptInterface::luaGetPlayerLight(lua_State *L)
{
    //getPlayerLight(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        LightInfo lightInfo;
        player->getCreatureLight(lightInfo);
        lua_pushnumber(L, lightInfo.level);
        lua_pushnumber(L, lightInfo.color);//color
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    return 2;
}

int LuaScriptInterface::luaDoPlayerAddExp(lua_State *L)
{
    //doPlayerAddExp(cid,exp)
    int32_t exp = (int32_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        if(exp > 0){
            player->addExperience(exp);
            lua_pushnumber(L, LUA_TRUE);
        }
        else{
            lua_pushnumber(L, LUA_FALSE);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetPlayerSlotItem(lua_State *L)
{
    //getPlayerSlotItem(cid, slot)
    uint32_t slot = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    const Player* player = env->getPlayerByUID(cid);
    if(player){
        Thing* thing = player->__getThing(slot);
        if(thing){
            uint32_t uid = env->addThing(thing);
            pushThing(L, thing, uid);
        }
        else{
            pushThing(L, NULL, 0);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        pushThing(L, NULL, 0);
    }
    return 1;
}

int LuaScriptInterface::luaGetThing(lua_State *L)
{
    //getThing(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Thing* thing = env->getThingByUID(uid);
    if(thing){
        pushThing(L, thing, uid);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND));
        pushThing(L, NULL, 0);
    }
    return 1;
}

int LuaScriptInterface::luaGetThingPos(lua_State *L)
{
    //getThingPos(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Thing* thing = env->getThingByUID(uid);
    Position pos(0, 0, 0);
    if(thing){
        pos = thing->getPosition();
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_THING_NOT_FOUND));
    }
    
    pushPosition(L, pos, 0);
    return 1;
}

int LuaScriptInterface::luaCreateCombatObject(lua_State *L)
{
    //createCombatObject()

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Combat* combat = new Combat;

    if(combat){
        uint32_t newCombatId = env->addCombatObject(combat);
        lua_pushnumber(L, newCombatId);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

bool LuaScriptInterface::getArea(lua_State *L, std::list<uint32_t>& list, uint32_t& rows)
{
    rows = 0;
    uint32_t i = 0, j = 0;
    lua_pushnil(L);  // first key //

    while(lua_next(L, -2) != 0){
        lua_pushnil(L);
        while(lua_next(L, -2) != 0){
            list.push_back((uint32_t)lua_tonumber(L, -1));
            
            lua_pop(L, 1);  // removes `value'; keeps `key' for next iteration //
            j++;
        }

        ++rows;
        
        j = 0;
        lua_pop(L, 1);  // removes `value'; keeps `key' for next iteration //
        i++;
    }
    
    lua_pop(L, 1);
    return (rows != 0);
}

int LuaScriptInterface::luaCreateCombatArea(lua_State *L)
{
    //createCombatArea( {area}, {extArea} )

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    int32_t parameters = lua_gettop(L);

    AreaCombat* area = new AreaCombat;

    if(parameters > 1){
        //has extra parameter with diagonal area information

        uint32_t rowsExtArea;
        std::list<uint32_t> listExtArea;
        getArea(L, listExtArea, rowsExtArea);
        
        /*setup all possible rotations*/
        area->setupExtArea(listExtArea, rowsExtArea);
    }

    uint32_t rowsArea = 0;
    std::list<uint32_t> listArea;
    getArea(L, listArea, rowsArea);

    /*setup all possible rotations*/
    area->setupArea(listArea, rowsArea);

    uint32_t newAreaId = env->addCombatArea(area);

    lua_pushnumber(L, newAreaId);
    return 1;
}

int LuaScriptInterface::luaCreateConditionObject(lua_State *L)
{
    //createConditionObject(type)

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    ConditionType_t type = (ConditionType_t)popNumber(L);

    Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, type, 0, 0);
    if(condition){
        uint32_t newConditionId = env->addConditionObject(condition);
        lua_pushnumber(L, newConditionId);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaSetCombatArea(lua_State *L)
{
    //setCombatArea(combat, area)

    uint32_t areaId = popNumber(L);
    uint32_t combatId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Combat* combat = env->getCombatObject(combatId);

    if(!combat){
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    const AreaCombat* area = env->getCombatArea(areaId);
    if(!area){
        reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    combat->setArea(area);

    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}

int LuaScriptInterface::luaSetCombatCondition(lua_State *L)
{
    //setCombatCondition(combat, condition)

    uint32_t conditionId = popNumber(L);
    uint32_t combatId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Combat* combat = env->getCombatObject(combatId);

    if(!combat){
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    const Condition* condition = env->getConditionObject(conditionId);
    if(!condition){
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    combat->setCondition(condition);

    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}

int LuaScriptInterface::luaSetCombatParam(lua_State *L)
{
    //setCombatParam(combat, key, value)
    
    uint32_t value = popNumber(L);
    CombatParam_t key = (CombatParam_t)popNumber(L);
    uint32_t combatId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Combat* combat = env->getCombatObject(combatId);

    if(combat){
        combat->setParam(key, value);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetConditionParam(lua_State *L)
{
    //setConditionParam(condition, key, value)

    int32_t value = (int32_t)popNumber(L);
    ConditionParam_t key = (ConditionParam_t)popNumber(L);
    uint32_t conditionId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Condition* condition = env->getConditionObject(conditionId);

    if(condition){
        condition->setParam(key, value);
        lua_pushnumber(L, LUA_NO_ERROR);        
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaAddDamageCondition(lua_State *L)
{
    //addDamageCondition(condition, rounds, time, value)

    int32_t value = (int32_t)popNumber(L);
    int32_t time = (int32_t)popNumber(L);
    int32_t rounds  = (int32_t)popNumber(L);
    uint32_t conditionId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    ConditionDamage* condition = dynamic_cast<ConditionDamage*>(env->getConditionObject(conditionId));

    if(condition){
        condition->addDamage(rounds, time, value);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaAddOutfitCondition(lua_State *L)
{
    //addOutfitCondition(condition, lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet)

    Outfit_t outfit;
    outfit.lookFeet = popNumber(L);
    outfit.lookLegs = popNumber(L);
    outfit.lookBody = popNumber(L);
    outfit.lookHead = popNumber(L);
    outfit.lookType = popNumber(L);
    outfit.lookTypeEx = popNumber(L);
    uint32_t conditionId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(env->getConditionObject(conditionId));

    if(condition){
        condition->addOutfit(outfit);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetCombatCallBack(lua_State *L)
{
    //setCombatCallBack(combat, key, function_name)

    const char* function = popString(L);
    std::string function_str(function);
    CallBackParam_t key = (CallBackParam_t)popNumber(L);
    uint32_t combatId = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    
    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    Combat* combat = env->getCombatObject(combatId);

    if(!combat){
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    LuaScriptInterface* scriptInterface = env->getScriptInterface();
    
    combat->setCallback(key);
    CallBack* callback = combat->getCallback(key);
    if(!callback){
        std::stringstream ss;
        ss << (uint32_t)key << " is not a valid callback key";
        reportError(__FUNCTION__, ss.str());
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    if(!callback->loadCallBack(scriptInterface, function_str)){
        reportError(__FUNCTION__, "Can not load callback");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}

int LuaScriptInterface::luaSetCombatFormula(lua_State *L)
{
    //setCombatFormula(combat, type, mina, minb, maxa, maxb)

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    double maxb = popFloatNumber(L);
    double maxa = popFloatNumber(L);
    double minb = popFloatNumber(L);
    double mina = popFloatNumber(L);

    formulaType_t type = (formulaType_t)popNumber(L);
    uint32_t combatId = popNumber(L);

    Combat* combat = env->getCombatObject(combatId);

    if(combat){
        combat->setPlayerCombatValues(type, mina, minb, maxa, maxb);
        
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetConditionFormula(lua_State *L)
{
    //setConditionFormula(condition, mina, minb, maxa, maxb)

    ScriptEnviroment* env = getScriptEnv();

    if(env->getScriptId() != EVENT_ID_LOADING){
        reportError(__FUNCTION__, "This function can only be used while loading the script.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    double maxb = popFloatNumber(L);
    double maxa = popFloatNumber(L);
    double minb = popFloatNumber(L);
    double mina = popFloatNumber(L);

    uint32_t conditionId = popNumber(L);

    ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(env->getConditionObject(conditionId));
    
    if(condition){
        condition->setFormulaVars(mina, minb, maxa, maxb);

        lua_pushnumber(L, LUA_NO_ERROR);    
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoCombat(lua_State *L)
{
    //doCombat(cid, combat, param)

    ScriptEnviroment* env = getScriptEnv();
    
    LuaVariant var = popVariant(L);
    uint32_t combatId = (uint32_t)popNumber(L);
    uint32_t cid = (uint32_t)popNumber(L);
    
    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    const Combat* combat = env->getCombatObject(combatId);

    if(!combat){
        reportErrorFunc(getErrorDesc(LUA_ERROR_COMBAT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    if(var.type == VARIANT_NONE){
        reportErrorFunc(getErrorDesc(LUA_ERROR_VARIANT_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    switch(var.type){
        case VARIANT_NUMBER:
        {
            Creature* target = g_game.getCreatureByID(var.number);

            if(!target){
                lua_pushnumber(L, LUA_ERROR);
                return 1;
            }

            if(combat->hasArea()){
                combat->doCombat(creature, target->getPosition());
                //std::cout << "Combat->hasArea()" << std::endl;
            }
            else{
                combat->doCombat(creature, target);
            }
            break;
        }

        case VARIANT_POSITION:
        {
            combat->doCombat(creature, var.pos);
            break;
        }

        case VARIANT_TARGETPOSITION:
        {
            if(combat->hasArea()){
                combat->doCombat(creature, var.pos);
            }
            else{
                combat->postCombatEffects(creature, var.pos);
                g_game.addMagicEffect(var.pos, NM_ME_PUFF);
            }
            break;
        }

        case VARIANT_STRING:
        {
            Player* target = g_game.getPlayerByName(var.text);
            if(!target){
                lua_pushnumber(L, LUA_ERROR);
                return 1;
            }

            combat->doCombat(creature, target);
            break;
        }

        default:
        {
            reportErrorFunc(getErrorDesc(LUA_ERROR_VARIANT_UNKNOWN));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
            break;
        }
    }

    lua_pushnumber(L, LUA_NO_ERROR);
    return 1;
}

int LuaScriptInterface::luaDoAreaCombatHealth(lua_State *L)
{
    //doAreaCombatHealth(cid, type, pos, area, min, max, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    int32_t maxChange = (int32_t)popNumber(L);
    int32_t minChange = (int32_t)popNumber(L);
    uint32_t areaId = popNumber(L);
    
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);

    CombatType_t combatType = (CombatType_t)popNumber(L);
    uint32_t cid = (uint32_t)popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    const AreaCombat* area = env->getCombatArea(areaId);
    if(area || areaId == 0){
        CombatParams params;
        params.combatType = combatType;
        params.impactEffect = effect;
        Combat::doCombatHealth(creature, pos, area, minChange, maxChange, params);

        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaDoTargetCombatHealth(lua_State *L)
{
    //doTargetCombatHealth(cid, target, type, min, max, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    int32_t maxChange = (int32_t)popNumber(L);
    int32_t minChange = (int32_t)popNumber(L);
    CombatType_t combatType = (CombatType_t)popNumber(L);
    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        CombatParams params;
        params.combatType = combatType;
        params.impactEffect = effect;
        Combat::doCombatHealth(creature, target, minChange, maxChange, params);

        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoAreaCombatMana(lua_State *L)
{
    //doAreaCombatMana(cid, pos, area, min, max, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    int32_t maxChange = (int32_t)popNumber(L);
    int32_t minChange = (int32_t)popNumber(L);
    uint32_t areaId = popNumber(L);

    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);

    uint32_t cid = (uint32_t)popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    const AreaCombat* area = env->getCombatArea(areaId);
    if(area || areaId == 0){
        CombatParams params;
        params.impactEffect = effect;
        Combat::doCombatMana(creature, pos, area, minChange, maxChange, params);
        
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoTargetCombatMana(lua_State *L)
{
    //doTargetCombatMana(cid, target, min, max, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    int32_t maxChange = (int32_t)popNumber(L);
    int32_t minChange = (int32_t)popNumber(L);
    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        CombatParams params;
        params.impactEffect = effect;
        Combat::doCombatMana(creature, target, minChange, maxChange, params);
        
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoAreaCombatCondition(lua_State *L)
{
    //doAreaCombatCondition(cid, pos, area, condition, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    uint32_t conditionId = popNumber(L);
    uint32_t areaId = popNumber(L);
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    uint32_t cid = (uint32_t)popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);
        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    const Condition* condition = env->getConditionObject(conditionId);
    if(condition){
        
        const AreaCombat* area = env->getCombatArea(areaId);
        
        if(area || areaId == 0){
            CombatParams params;
            params.impactEffect = effect;
            params.condition = condition;
            Combat::doCombatCondition(creature, pos, area, params);
            
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoTargetCombatCondition(lua_State *L)
{
    //doTargetCombatCondition(cid, target, condition, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    uint32_t conditionId = popNumber(L);
    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;

    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        const Condition* condition = env->getConditionObject(conditionId);
        if(condition){
            CombatParams params;
            params.impactEffect = effect;
            params.condition = condition;
            Combat::doCombatCondition(creature, target, params);
            
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoAreaCombatDispel(lua_State *L)
{
    //doAreaCombatDispel(cid, pos, area, type, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    ConditionType_t dispelType = (ConditionType_t)popNumber(L);
    uint32_t areaId = popNumber(L);
    Position pos;
    uint32_t stackpos;
    popPosition(L, pos, stackpos);
    uint32_t cid = (uint32_t)popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;
    
    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    const AreaCombat* area = env->getCombatArea(areaId);
    if(area || areaId == 0){
        CombatParams params;
        params.impactEffect = effect;
        params.dispelType = dispelType;
        Combat::doCombatDispel(creature, pos, area, params);

        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoTargetCombatDispel(lua_State *L)
{
    //doTargetCombatDispel(cid, target, type, effect)

    uint8_t effect = (uint8_t)popNumber(L);
    ConditionType_t dispelType = (ConditionType_t)popNumber(L);
    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = NULL;

    if(cid != 0){
        creature = env->getCreatureByUID(cid);

        if(!creature){
            reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        CombatParams params;
        params.impactEffect = effect;
        params.dispelType = dispelType;
        Combat::doCombatDispel(creature, target, params);

        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaDoChallengeCreature(lua_State *L)
{
    //doChallengeCreature(cid, target)

    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(!creature){
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        target->challengeCreature(creature);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaDoConvinceCreature(lua_State *L)
{
    //doConvinceCreature(cid, target)

    uint32_t targetCid = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(!creature){
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    Creature* target = env->getCreatureByUID(targetCid);
    if(target){
        target->convinceCreature(creature);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaNumberToVariant(lua_State *L)
{
    //numberToVariant(number)

    LuaVariant var;
    var.type = VARIANT_NUMBER;
    var.number = popNumber(L);

    LuaScriptInterface::pushVariant(L, var);
    return 1;
}

int LuaScriptInterface::luaStringToVariant(lua_State *L)
{
    //stringToVariant(string)
    LuaVariant var;
    var.type = VARIANT_STRING;
    var.text = popString(L);

    LuaScriptInterface::pushVariant(L, var);
    return 1;
}

int LuaScriptInterface::luaPositionToVariant(lua_State *L)
{
    //positionToVariant(pos)

    LuaVariant var;
    var.type = VARIANT_POSITION;
    popPosition(L, var.pos);

    LuaScriptInterface::pushVariant(L, var);
    return 1;
}

int LuaScriptInterface::luaTargetPositionToVariant(lua_State *L)
{
    //targetPositionToVariant(pos)

    LuaVariant var;
    var.type = VARIANT_TARGETPOSITION;
    popPosition(L, var.pos);

    LuaScriptInterface::pushVariant(L, var);
    return 1;
}

int LuaScriptInterface::luaVariantToNumber(lua_State *L)
{
    //variantToNumber(var)

    LuaVariant var = popVariant(L);

    uint32_t number = 0;
    if(var.type == VARIANT_NUMBER){
        number = var.number;
    }

    lua_pushnumber(L, number);
    return 1;
}

int LuaScriptInterface::luaVariantToString(lua_State *L)
{
    //variantToString(var)

    LuaVariant var = popVariant(L);

    std::string text = "";
    if(var.type == VARIANT_STRING){
        text = var.text;
    }

    lua_pushstring(L, text.c_str());
    return 1;
}

int LuaScriptInterface::luaVariantToPosition(lua_State *L)
{
    //luaVariantToPosition(var)

    LuaVariant var = popVariant(L);

    PositionEx pos(0, 0, 0, 0);
    if(var.type == VARIANT_POSITION || var.type == VARIANT_TARGETPOSITION){
        pos = var.pos;
    }

    pushPosition(L, pos, pos.stackpos);
    return 1;
}

int LuaScriptInterface::luaDoChangeSpeed(lua_State *L)
{
    //doChangeSpeed(cid, delta)

    int32_t delta = (int32_t)popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(creature){
        g_game.changeSpeed(creature, delta);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetCreatureOutfit(lua_State *L)
{
    //doSetCreatureOutfit(cid, outfit, time)

    int32_t time = (int32_t)popNumber(L);
    Outfit_t outfit;
    outfit.lookType = getField(L, "lookType");
    outfit.lookHead = getField(L, "lookHead");
    outfit.lookBody = getField(L, "lookBody");
    outfit.lookLegs = getField(L, "lookLegs");
    outfit.lookFeet = getField(L, "lookFeet");
    outfit.lookAddons = getField(L, "lookAddons");
    lua_pop(L, 1);

    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(creature){
        ReturnValue ret = Spell::CreateIllusion(creature, outfit, time);
        if(ret == RET_NOERROR){
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetCreatureOutfit(lua_State *L)
{
    //getCreatureOutfit(cid)

    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(creature){
        const Outfit_t outfit = creature->getCurrentOutfit();

        lua_newtable(L);
        setField(L, "lookType", outfit.lookType);
        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);

        return 1;
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaSetMonsterOutfit(lua_State *L)
{
    //doSetMonsterOutfit(cid, name, time)

    int32_t time = (int32_t)popNumber(L);
    std::string name = popString(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(creature){
        ReturnValue ret = Spell::CreateIllusion(creature, name, time);
        if(ret == RET_NOERROR){
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaSetItemOutfit(lua_State *L)
{
    //doSetItemOutfit(cid, item, time)

    int32_t time = (int32_t)popNumber(L);
    uint32_t item = (uint32_t)popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();

    Creature* creature = env->getCreatureByUID(cid);

    if(creature){
        ReturnValue ret = Spell::CreateIllusion(creature, item, time);
        if(ret == RET_NOERROR){
            lua_pushnumber(L, LUA_NO_ERROR);
        }
        else{
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetGlobalStorageValue(lua_State *L)
{
    //getGlobalStorageValue(valueid)
    uint32_t key = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    int32_t value;
    if(env->getGlobalStorageValue(key, value)){
        lua_pushnumber(L, value);
    }
    else{
        lua_pushnumber(L, -1);
    }
    return 1;
}

int LuaScriptInterface::luaSetGlobalStorageValue(lua_State *L)
{
    //setGlobalStorageValue(valueid, newvalue)
    int32_t value = (int32_t)popNumber(L);
    uint32_t key = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    env->addGlobalStorageValue(key,value);
    lua_pushnumber(L,0);
    return 1;
}

int LuaScriptInterface::luaGetPlayerDepotItems(lua_State *L)
{
    //getPlayerDepotItems(cid, depotid)
    uint32_t depotid = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        const Depot* depot = player->getDepot(depotid, true);
        if(depot){
            lua_pushnumber(L, depot->getItemHoldingCount());
        }
        else{
            reportErrorFunc("Depot not found");
            lua_pushnumber(L, LUA_ERROR);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerSetGuildRank(lua_State *L)
{
    //doPlayerSetGuildRank(cid, rank)
    const char* rank = popString(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->setGuildRank(std::string(rank));
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerSetGuildNick(lua_State *L)
{
    //doPlayerSetGuildNick(cid, nick)
    const char* nick = popString(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->setGuildNick(std::string(nick));
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoMoveCreature(lua_State *L)
{
    //doMoveCreature(cid, direction)
    uint32_t direction = popNumber(L);
    uint32_t cid = popNumber(L);
    
    switch(direction){
        case NORTH:
        case SOUTH:
        case WEST:
        case EAST:
        case SOUTHWEST:
        case NORTHWEST:
        case NORTHEAST:
        case SOUTHEAST:
            break;
        default:
            reportErrorFunc("No valid direction");
            lua_pushnumber(L, LUA_ERROR);
            return 1;
    }
    
    ScriptEnviroment* env = getScriptEnv();
    
    Creature* creature = env->getCreatureByUID(cid);
    if(creature){
        ReturnValue ret = g_game.internalMoveCreature(creature, (Direction)direction, true);
        lua_pushnumber(L, ret);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaIsPlayer(lua_State *L)
{
    //isPlayer(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(env->getPlayerByUID(cid)){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsCreature(lua_State *L)
{
    //isCreature(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(env->getCreatureByUID(cid)){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsContainer(lua_State *L)
{
    //isContainer(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(env->getContainerByUID(uid)){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}
    
int LuaScriptInterface::luaIsMoveable(lua_State *L)
{
    //isMoveable(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Thing* thing = env->getThingByUID(uid);
    
    if(thing && thing->isPushable()){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }

    return 1;
}

int LuaScriptInterface::luaGetPlayerByName(lua_State *L)
{
    //getPlayerByName(name)
    const char* name = popString(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(Player* player = g_game.getPlayerByName(name)){
        uint32_t cid = env->addThing(player);
        lua_pushnumber(L, cid);
    }
    else{
        lua_pushnumber(L, LUA_NULL);
    }
    return 1;
    
}

int LuaScriptInterface::luaRegisterCreature(lua_State *L)
{
    //registerCreature(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Creature* creature = g_game.getCreatureByID(cid);
    uint32_t newcid;
    if(creature){
        newcid = env->addThing(creature);
    }
    else{
        newcid = 0;
    }

    lua_pushnumber(L, newcid);
    return 1;
}

int LuaScriptInterface::luaGetContainerSize(lua_State *L)
{
    //getContainerSize(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(Container* container = env->getContainerByUID(uid)){
        lua_pushnumber(L, container->size());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetContainerCap(lua_State *L)
{
    //getContainerCap(uid)
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(Container* container = env->getContainerByUID(uid)){
        lua_pushnumber(L, container->capacity());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetContainerItem(lua_State *L)
{
    //getContainerItem(uid, slot)
    uint32_t slot = popNumber(L);
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    if(Container* container = env->getContainerByUID(uid)){
        Item* item = container->getItem(slot);
        if(item){
            uint32_t uid = env->addThing(item);
            pushThing(L, item, uid);
        }
        else{
            pushThing(L, NULL, 0);
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
        pushThing(L, NULL, 0);
    }
    return 1;
    
}

int LuaScriptInterface::luaDoAddContainerItem(lua_State *L)
{
    //doAddContainerItem(uid, itemid, count or subtype)
    uint32_t count = popNumber(L);
    uint16_t itemId = (uint16_t)popNumber(L);
    uint32_t uid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Container* container = env->getContainerByUID(uid);
        if(container){
        const ItemType& it = Item::items[itemId];
        if(it.stackable && count > 100){
            count = 100;
        }

        Item* newItem = Item::CreateItem(itemId, count);

        ReturnValue ret = g_game.internalAddItem(container, newItem);
        if(ret != RET_NOERROR){
            delete newItem;
            reportErrorFunc("Could not add item");
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
        
        if(newItem->getParent()){
            uint32_t new_uid = env->addThing((Thing*)newItem);
            lua_pushnumber(L, new_uid);
            return 1;
        }
        else{
            //stackable item stacked with existing object, newItem will be released
            lua_pushnumber(L, LUA_NULL);
            return 1;
        }
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
}

int LuaScriptInterface::luaIsInArray(lua_State *L)
{
    //isInArray(array, value)
    int32_t value = (int32_t)popNumber(L);
    if(lua_istable(L, -1) == 0){
        lua_pop(L, 1);
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    int i = 1;
    while(1){
        lua_pushnumber(L, i);
        lua_gettable(L, -2);
        if(lua_isnil(L, -1) == 1){
            lua_pop(L, 2);
            lua_pushnumber(L, LUA_FALSE);
            return 1;
        }
        else if(lua_isnumber(L, -1) == 1){
            int32_t array_value = (int32_t)popNumber(L);
            if(array_value == value){
                lua_pop(L, 1);
                lua_pushnumber(L, LUA_TRUE);
                return 1;
            }
        }
        else{
            lua_pop(L, 2);
            lua_pushnumber(L, LUA_ERROR);
            return 1;
        }
        ++i;
    }
}

int LuaScriptInterface::luaDoPlayerAddOutfit(lua_State *L)
{
    //doPlayerAddOutfit(cid, looktype, addon)
    int addon = (int)popNumber(L);
    int looktype = (int)popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->addOutfit(looktype, addon);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoPlayerRemOutfit(lua_State *L)
{
    //doPlayerRemOutfit(cid, looktype, addon)
    int addon = (int)popNumber(L);
    int looktype = (int)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    if(player){
        player->remOutfit(looktype, addon);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaDoSetCreatureLight(lua_State *L)
{
    //doSetCreatureLight(cid, lightLevel, lightColor, time)
    uint32_t time = popNumber(L);
    uint8_t color = (uint8_t)popNumber(L);
    uint8_t level = (uint8_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Creature* creature = env->getCreatureByUID(cid);
    if(creature){
        Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8));
        
        creature->addCondition(condition);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetCreaturePosition(lua_State *L)
{
    //getCreaturePosition(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Creature* creature = env->getCreatureByUID(cid);
    if(creature){
        Position pos = creature->getPosition();
        pushPosition(L, pos, 0);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaGetCreatureName(lua_State *L)
{
    //getCreatureName(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    
    Creature* creature = env->getCreatureByUID(cid);
    if(creature){
        lua_pushstring(L, creature->getName().c_str());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    return 1;
}

int LuaScriptInterface::luaIsItemStackable(lua_State *L)
{
    //isItemStackable(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    if(it.stackable){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsItemRune(lua_State *L)
{
    //isItemRune(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    if(it.isRune()){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsItemDoor(lua_State *L)
{
    //isItemDoor(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    if(it.isDoor()){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsItemContainer(lua_State *L)
{
    //isItemContainer(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    if(it.isContainer()){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaIsItemFluidContainer(lua_State *L)
{
    //isItemFluidContainer(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    if(it.isFluidContainer()){
        lua_pushnumber(L, LUA_TRUE);
    }
    else{
        lua_pushnumber(L, LUA_FALSE);
    }
    return 1;
}

int LuaScriptInterface::luaGetItemName(lua_State *L)
{
    //getItemName(itemid)
    uint32_t itemid = popNumber(L);
    const ItemType& it = Item::items[itemid];
    lua_pushstring(L, it.name.c_str());
    return 1;
}

int LuaScriptInterface::luaAddEvent(lua_State *L)
{
    //addEvent(callback, delay, parameter)    
    ScriptEnviroment* env = getScriptEnv();
    
    LuaScriptInterface* script_interface = env->getScriptInterface();
    if(!script_interface){
        reportError(__FUNCTION__, "No valid script interface!");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }
    
    if(lua_isfunction(L, -3) == 0){
        reportError(__FUNCTION__, "callback parameter should be a function.");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    LuaTimerEventDesc eventDesc;
    eventDesc.parameter = luaL_ref(L, LUA_REGISTRYINDEX);
    uint32_t delay = popNumber(L);
    if(delay < 100){
        delay = 100;
    }
    eventDesc.function = luaL_ref(L, LUA_REGISTRYINDEX);
    
    eventDesc.scriptId = env->getScriptId();
    
    script_interface->m_lastEventTimerId++;
    script_interface->m_timerEvents[script_interface->m_lastEventTimerId] = eventDesc;
    
    g_game.addEvent(makeTask(delay, boost::bind(&LuaScriptInterface::executeTimerEvent, script_interface, script_interface->m_lastEventTimerId)));
    
    lua_pushnumber(L, script_interface->m_lastEventTimerId);
    return 1;
}

int LuaScriptInterface::luaStopEvent(lua_State *L)
{
    //stopEvent(eventid)
    uint32_t eventId = popNumber(L);
    ScriptEnviroment* env = getScriptEnv();
    
    LuaScriptInterface* script_interface = env->getScriptInterface();
    if(!script_interface){
        reportError(__FUNCTION__, "No valid script interface!");
        lua_pushnumber(L, LUA_ERROR);
        return 1;
    }

    LuaTimerEvents::iterator it = script_interface->m_timerEvents.find(eventId);
    if(it != script_interface->m_timerEvents.end()){
        luaL_unref(script_interface->m_luaState, LUA_REGISTRYINDEX, it->second.parameter);
        luaL_unref(script_interface->m_luaState, LUA_REGISTRYINDEX, it->second.function);
        script_interface->m_timerEvents.erase(it);
        lua_pushnumber(L, LUA_NO_ERROR);
    }
    else{
        lua_pushnumber(L, LUA_ERROR);
    }
    
    return 1;
}

int LuaScriptInterface::luaGetDataDirectory(lua_State *L)
{
    //getDataDir()
    std::string datadir = g_config.getString(ConfigManager::DATA_DIRECTORY);
    lua_pushstring(L, datadir.c_str());
    return 1;
}

#ifdef __XID_CVS_MODS__
int LuaScriptInterface::luaGetPlayerSkull(lua_State *L)
{
    //getPlayerSkull(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        lua_pushnumber(L, (int)player->getSkull());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    
    return 1;
}

int LuaScriptInterface::luaGetPlayerConditionTicks(lua_State *L)
{
    //getPlayerConditionTicks(cid, conditionid)
    ConditionType_t conditionType;
    uint32_t conditionTicks = 0;
    
    conditionType = (ConditionType_t)popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        if(Condition* condition = player->getCondition(conditionType, CONDITIONID_DEFAULT)){
            conditionTicks = condition->getTicks() / 1000;
        }
        
        lua_pushnumber(L, conditionTicks);
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    
    return 1;
}
#endif

#ifdef __XID_SEPERATE_ADDONS__
int LuaScriptInterface::luaDoPlayerAddAddon(lua_State* L)
{
    uint32_t addon = popNumber(L);
    uint32_t lookType = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        player->addAddon(lookType, addon);
        lua_pushnumber(L, LUA_NO_ERROR);
    }           
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}

int LuaScriptInterface::luaGetPlayerOutfitAddon(lua_State* L)
{
    uint32_t lookType = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        lua_pushnumber(L, player->getOutfitAddon(lookType));
    }           
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}
#endif

#ifdef __XID_BUY_SELL__
int LuaScriptInterface::luaGetItemStackable(lua_State *L)
{
    //getItemStackable(id)
    int id = popNumber(L);
    if(Item::items[id].stackable || Item::items[id].isRune())
        lua_pushboolean(L, 1);
    else
        lua_pushboolean(L, 0);
    
    return 1;
}
#endif

#ifdef __XID_PREMIUM_SYSTEM__
int LuaScriptInterface::luaIsPremium(lua_State *L)
{
    //isPremium(cid)
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        lua_pushboolean(L, player->isPremium());
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    
    return 1;
}

int LuaScriptInterface::luaBuyPremium(lua_State *L)
{
    int days = popNumber(L);
    uint32_t cid = popNumber(L);

    int premiumTime = days * 86400;
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        g_game.savePremium(player, premiumTime, false);
        lua_pushnumber(L, LUA_NO_ERROR);
    }           
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}
#endif

#ifdef __YUR_GUILD_SYSTEM__
int LuaScriptInterface::luaFoundNewGuild(lua_State* L)
{
    const char* gname = popString(L);
    if(gname)
        lua_pushnumber(L, Guilds::AddNewGuild(gname));
    else
        lua_pushnumber(L, -1);

    return 1;
}

int LuaScriptInterface::luaGetPlayerGuildStatus(lua_State* L)
{
    const char* name = popString(L);
    lua_pushnumber(L, Guilds::GetGuildStatus(name));
    
    return 1;
}

int LuaScriptInterface::luaSetPlayerGuildStatus(lua_State* L)
{
    int gstat = popNumber(L);
    const char* name = popString(L);

    Guilds::SetGuildStatus(std::string(name), (gstat_t)gstat);
    if(Player* player = g_game.getPlayerByName(name)){
        Guilds::ReloadGuildInfo(player);
    }

    return 0;
}

int LuaScriptInterface::luaGetPlayerGuildName(lua_State* L)
{
    const char* name = popString(L);
    lua_pushstring(L, Guilds::GetGuildName(name).c_str());
    
    return 1;
}

int LuaScriptInterface::luaSetPlayerGuild(lua_State* L)
{
    const char* gname = popString(L);
    const char* grank = popString(L);
    int gstat = popNumber(L);
    const char* name = popString(L);

    Guilds::SetGuildInfo(name, (gstat_t)gstat, grank, gname);
    if(Player* player = g_game.getPlayerByName(name))
        Guilds::ReloadGuildInfo(player);
            
    return 0;
}

int LuaScriptInterface::luaClearPlayerGuild(lua_State* L)
{
    const char* name = popString(L);

    Guilds::ClearGuildInfo(name);
    if(Player* player = g_game.getPlayerByName(name))
        Guilds::ReloadGuildInfo(player);

    return 0;
}

int LuaScriptInterface::luaSetPlayerGuildNick(lua_State* L)
{
    const char* nick = popString(L);
    const char* name = popString(L);
    
    Guilds::SetGuildNick(name, nick);
    if(Player* player = g_game.getPlayerByName(name))
        Guilds::ReloadGuildInfo(player);

    return 0;
}
#endif

#ifdef __XID_LEARN_SPELLS__
int LuaScriptInterface::luaDoPlayerLearnSpell(lua_State* L)
{
    const char* spell = popString(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        if(!player->knowsSpell(spell)){
            player->learnSpell(spell);
            lua_pushnumber(L, LUA_TRUE);
        }
        else{ 
            lua_pushnumber(L, LUA_TRUE);
        }
    }           
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }

    return 1;
}
#endif

#ifdef __XID_BLESS_SYSTEM__
int LuaScriptInterface::luaDoPlayerAddBlessing(lua_State* L)
{
    //doPlayerAddBlessing(cid, blessid)
    int32_t blessId = popNumber(L);
    uint32_t cid = popNumber(L);

    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        player->addBlessing(blessId);
        g_game.addMagicEffect(player->getPosition(), NM_ME_MAGIC_POISON);
        
        lua_pushnumber(L, LUA_NO_ERROR);
    }           
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_FALSE);
    }

    return 1;
}

int LuaScriptInterface::luaGetPlayerBlessing(lua_State *L)
{
    //getPlayerBlessing(cid, blessid)
    uint32_t blessId = popNumber(L);
    uint32_t cid = popNumber(L);
    
    ScriptEnviroment* env = getScriptEnv();
    Player* player = env->getPlayerByUID(cid);
    
    if(player){
        lua_pushboolean(L, player->getBlessing(blessId));
    }
    else{
        reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
        lua_pushnumber(L, LUA_ERROR);
    }
    
    return 1;
}
#endif
 

 

Editado por daviqueiroz

Compartilhar este post


Link para o post
Compartilhar em outros sites

2 respostass a esta questão

Recommended Posts

  • 0
daviqueiroz    0
daviqueiroz

@Gengo funcionou muito obrigado Reputado +1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×