Skip to content

Instantly share code, notes, and snippets.

@Subv
Created October 17, 2012 22:30
Show Gist options
  • Save Subv/3908751 to your computer and use it in GitHub Desktop.
Save Subv/3908751 to your computer and use it in GitHub Desktop.
#include "Common.h"
#include "LuaEngine.h"
#include "LuaInc.h"
#include "DBCStructure.h"
#include "Config.h"
using namespace luabind;
#define TRY(...) try{__VA_ARGS__} catch(cast_failed &e) { sLog->outString("An exception occurred in LuaBind (cast_failed), message: %s: %s.",e.what(),lua_tostring(m_luaState, -1)); } catch(error& ex) { sLog->outString("An exception occurred in LuaBind (error), message: %s: %s.",ex.what(),lua_tostring(m_luaState, -1)); }
/*void ErrorCallback(lua_State* l)
{
sLog->outString("An exception occurred in LuaBind, message: %s",lua_tostring(l,-1));
set_error_callback(&ErrorCallback);
}
void ErrorCallback2(lua_State* l)
{
sLog->outString("An exception occurred in LuaBind, message: %s", lua_tostring(l,-1));
}*/
void RegisterCreatureEvent(int entry, int type, const char* funcName)
{
LuaScript cls;
cls.type = type;
cls.name = funcName;
CreatureLuaScripts::iterator it = sLua->creaturescripts.find(entry);
if(it != sLua->creaturescripts.end()) // Its already there
{
(*it).second.push_back(cls);
sLua->creaturescripts[entry] = (*it).second;
return;
}
else
{
CreatureLuaEvents cle;
cle.push_back(cls);
sLua->creaturescripts[entry] = cle;
}
}
void RegisterPlayerEvent(int type, const char* funcName)
{
LuaScript crls;
crls.type = uint32(type);
crls.name = funcName;
sLua->InsertPlayerEvent(crls);
sLog->outString("Added function %s for player",funcName);
}
/* Proxies */
void MonsterSay(Creature* cr, const char* text)
{
cr->MonsterSay(text,0,NULL);
}
bool HasAura(Unit* pUnit, uint32 spellid)
{
return pUnit->HasAura(spellid);
}
void SendGossipMenu(Player* plr, uint32 id, uint64 crGUID)
{
plr->PlayerTalkClass->SendGossipMenu(id, crGUID);
}
void add_gossip_item(Player* plr, uint32 icon, const char* item, uint32 def)
{
plr->ADD_GOSSIP_ITEM(icon,item,GOSSIP_SENDER_MAIN,def);
}
LuaEngine::LuaEngine() : m_luaState(NULL) { }
LuaEngine::~LuaEngine()
{
lua_close(m_luaState);
m_file = "";
m_luaState = NULL;
}
void LuaEngine::Initialize()
{
m_luaState = lua_open(); // Create the handle for Lua
int iErr = 0;
if(!m_luaState)
{
sLog->outString("Something wrong happened to the Lua engine");
return;
}
open(m_luaState);
luaL_openlibs(m_luaState); // Opent the correct libraries
m_file = sConfig->GetStringDefault("Lua.FilePath",(const char*)"./LuaScripts.lua"); // The file
AddHooks(); // Call this to add the lua functions -> c++ functions hook
if(luaL_dofile(m_luaState,m_file.c_str()))
{
sLog->outString("Lua engine error: %s",lua_tostring(m_luaState,1));
return;
}
//set_error_callback(&ErrorCallback);
//set_cast_failed_callback(&ErrorCallback2);
sLog->outString("Lua engine initialized!");
}
void LuaEngine::AddHooks()
{
sLog->outString("Initializing hooks");
module(m_luaState)
[
def("RegisterCreatureEvent",&RegisterCreatureEvent),
def("RegisterPlayerEvent",&RegisterPlayerEvent),
def("outString",&LuaHandlers::outString),
def("MonsterSay",&MonsterSay),
def("HasAura",&HasAura)
];
/* Object and WorldObject Class */
module(m_luaState)
[
class_<Object>("Object")
.def((const char*)"GetGUID",&Object::GetGUID)
.def((const char*)"GetGUIDLow",&Object::GetGUIDLow)
.def((const char*)"GetEntry",&Object::GetEntry)
.def((const char*)"GetTypeId",&Object::GetTypeId),
/*.def((const char*)"GetPositionX",&Object::GetPositionX)
.def((const char*)"GetPositionY",&Object::GetPositionY)
.def((const char*)"GetPositionZ",&Object::GetPositionZ)
.def((const char*)"GetOrientation",&Object::GetOrientation)*/
class_<WorldObject,Object>("WorldObject")
.def((const char*)"GetZoneId",&WorldObject::GetZoneId)
.def((const char*)"GetAreaId",&WorldObject::GetAreaId)
.def((const char*)"GetName",&WorldObject::GetName)
.def((const char*)"GetUInt32Value",&WorldObject::GetUInt32Value)
.def((const char*)"GetUInt64Value",&WorldObject::GetUInt64Value)
.def((const char*)"SetUInt64Value",&WorldObject::SetUInt64Value)
.def((const char*)"SetUInt32Value",&WorldObject::SetUInt32Value)
.def((const char*)"GetFloatValue",&WorldObject::GetFloatValue)
.def((const char*)"SetFloatValue",&WorldObject::SetFloatValue)
];
/* Unit Class */
module(m_luaState)
[
class_<Unit,WorldObject>("Unit")
.def((const char*)"GetLevel",&Unit::getLevel)
.def((const char*)"SetLevel",&Unit::SetLevel)
.def((const char*)"GetTotalAttackPowerValue",&Unit::GetTotalAttackPowerValue)
];
/* Player Class */
module(m_luaState)
[
class_<Player,Unit>("Player")
.def((const char*)"TeleportTo",(bool(Player::*)(uint32,float,float,float,float,uint32))&Player::TeleportTo)
.def((const char*)"SendMessageToSet",(void(Player::*)(WorldPacket*,bool))&Player::SendMessageToSet)
.def("SendGossipMenu",&SendGossipMenu)
.def("ADD_GOSSIP_ITEM",&add_gossip_item)
];
/* Creature Class */
module(m_luaState)
[
class_<Creature,Unit>("Creature")
];
/* WorldPacket Class */
module(m_luaState)
[
class_<WorldPacket>("WorldPacket")
.def(constructor<uint32,size_t,bool>())
.def((const char*)"GetOpcode",&WorldPacket::GetOpcode)
.def((const char*)"SetOpcode",&WorldPacket::SetOpcode)
.def((const char*)"WriteInt8",&WorldPacket::WriteInt8)
.def((const char*)"WriteInt16",&WorldPacket::WriteInt16)
.def((const char*)"WriteInt32",&WorldPacket::WriteInt32)
.def((const char*)"WriteInt64",&WorldPacket::WriteInt64)
.def((const char*)"WriteUInt8",&WorldPacket::WriteUInt8)
.def((const char*)"WriteUInt16",&WorldPacket::WriteUInt16)
.def((const char*)"WriteUInt32",&WorldPacket::WriteUInt32)
.def((const char*)"WriteUInt64",&WorldPacket::WriteUInt64)
.def((const char*)"WriteFloat",&WorldPacket::WriteFloat)
.def((const char*)"WriteString",&WorldPacket::WriteString)
.def((const char*)"WriteCString",&WorldPacket::WriteCString)
];
/* SpellEntry struct */
/*module(m_luaState)
[
class_<SpellEntry>("SpellEntry")
.def_readwrite((const char*)"Attributes",&SpellEntry::Attributes)
.def_readwrite((const char*)"AttributesEx",&SpellEntry::AttributesEx)
.def_readwrite((const char*)"AttributesEx2",&SpellEntry::AttributesEx2)
.def_readwrite((const char*)"AttributesEx3",&SpellEntry::AttributesEx3)
.def_readwrite((const char*)"AttributesEx4",&SpellEntry::AttributesEx4)
.def_readwrite((const char*)"AttributesEx5",&SpellEntry::AttributesEx5)
.def_readwrite((const char*)"AttributesEx6",&SpellEntry::AttributesEx6)
.def_readwrite((const char*)"AttributesEx7",&SpellEntry::AttributesEx7)
.def_readwrite((const char*)"AttributesEx8",&SpellEntry::AttributesEx8)
.def_readwrite((const char*)"CastingTimeIndex",&SpellEntry::CastingTimeIndex)
.def_readwrite((const char*)"DurationIndex",&SpellEntry::DurationIndex)
.def_readwrite((const char*)"powerType",&SpellEntry::powerType)
.def_readwrite((const char*)"rangeIndex",&SpellEntry::rangeIndex)
.def_readwrite((const char*)"speed",&SpellEntry::speed)
.def_readwrite((const char*)"SpellVisual",&SpellEntry::SpellVisual)
.def_readwrite((const char*)"SpellIconID",&SpellEntry::SpellIconID)
.def_readwrite((const char*)"activeIconID",&SpellEntry::activeIconID)
.def_readwrite((const char*)"SpellName",&SpellEntry::SpellName)
.def_readwrite((const char*)"Rank",&SpellEntry::Rank)
.def_readwrite((const char*)"SchoolMask",&SpellEntry::SchoolMask)
.def_readwrite((const char*)"runeCostID",&SpellEntry::runeCostID)
.def_readwrite((const char*)"SpellDifficultyId",&SpellEntry::SpellDifficultyId)
.def_readwrite((const char*)"SpellScalingId",&SpellEntry::SpellScalingId)
.def_readwrite((const char*)"SpellAuraOptionsId",&SpellEntry::SpellAuraOptionsId)
.def_readwrite((const char*)"SpellAuraRestrictionsId",&SpellEntry::SpellAuraRestrictionsId)
.def_readwrite((const char*)"SpellCastingRequirementsId",&SpellEntry::SpellCastingRequirementsId)
.def_readwrite((const char*)"SpellCategoriesId",&SpellEntry::SpellCategoriesId)
.def_readwrite((const char*)"SpellClassOptionsId",&SpellEntry::SpellClassOptionsId)
.def_readwrite((const char*)"SpellCooldownsId",&SpellEntry::SpellCooldownsId)
.def_readwrite((const char*)"SpellEquippedItemsId",&SpellEntry::SpellEquippedItemsId)
.def_readwrite((const char*)"SpellInterruptsId",&SpellEntry::SpellInterruptsId)
.def_readwrite((const char*)"SpellLevelsId",&SpellEntry::SpellLevelsId)
.def_readwrite((const char*)"SpellPowerId",&SpellEntry::SpellPowerId)
.def_readwrite((const char*)"SpellReagentsId",&SpellEntry::SpellReagentsId)
.def_readwrite((const char*)"SpellShapeshiftId",&SpellEntry::SpellShapeshiftId)
.def_readwrite((const char*)"SpellTargetRestrictionsId",&SpellEntry::SpellTargetRestrictionsId)
.def_readwrite((const char*)"SpellTotemsId",&SpellEntry::SpellTotemsId)
.def_readwrite((const char*)"StackAmount",&SpellEntry::StackAmount)
.def_readwrite((const char*)"procChance",&SpellEntry::procChance)
.def_readwrite((const char*)"procCharges",&SpellEntry::procCharges)
.def_readwrite((const char*)"procFlags",&SpellEntry::procFlags)
.def_readwrite((const char*)"CasterAuraState",&SpellEntry::CasterAuraState)
.def_readwrite((const char*)"TargetAuraState",&SpellEntry::TargetAuraState)
.def_readwrite((const char*)"CasterAuraStateNot",&SpellEntry::CasterAuraStateNot)
.def_readwrite((const char*)"TargetAuraStateNot",&SpellEntry::TargetAuraStateNot)
.def_readwrite((const char*)"casterAuraSpell",&SpellEntry::casterAuraSpell)
.def_readwrite((const char*)"targetAuraSpell",&SpellEntry::targetAuraSpell)
.def_readwrite((const char*)"excludeCasterAuraSpell",&SpellEntry::excludeCasterAuraSpell)
.def_readwrite((const char*)"excludeTargetAuraSpell",&SpellEntry::excludeTargetAuraSpell)
.def_readwrite((const char*)"FacingCasterFlags",&SpellEntry::FacingCasterFlags)
.def_readwrite((const char*)"AreaGroupId",&SpellEntry::AreaGroupId)
.def_readwrite((const char*)"RequiresSpellFocus",&SpellEntry::RequiresSpellFocus)
.def_readwrite((const char*)"Category",&SpellEntry::Category)
.def_readwrite((const char*)"DmgClass",&SpellEntry::DmgClass)
.def_readwrite((const char*)"Dispel",&SpellEntry::Dispel)
.def_readwrite((const char*)"Mechanic",&SpellEntry::Mechanic)
.def_readwrite((const char*)"PreventionType",&SpellEntry::PreventionType)
.def_readwrite((const char*)"StartRecoveryCategory",&SpellEntry::StartRecoveryCategory)
.def_readwrite((const char*)"SpellFamilyFlags",&SpellEntry::SpellFamilyFlags)
.def_readwrite((const char*)"SpellFamilyName",&SpellEntry::SpellFamilyName)
.def_readwrite((const char*)"CategoryRecoveryTime",&SpellEntry::CategoryRecoveryTime)
.def_readwrite((const char*)"RecoveryTime",&SpellEntry::RecoveryTime)
.def_readwrite((const char*)"StartRecoveryTime",&SpellEntry::StartRecoveryTime)
.def_readwrite((const char*)"Effect",&SpellEntry::Effect)
.def_readwrite((const char*)"EffectValueMultiplier",&SpellEntry::EffectValueMultiplier)
.def_readwrite((const char*)"EffectApplyAuraName",&SpellEntry::EffectApplyAuraName)
.def_readwrite((const char*)"EffectAmplitude",&SpellEntry::EffectAmplitude)
.def_readwrite((const char*)"EffectBasePoints",&SpellEntry::EffectBasePoints)
.def_readwrite((const char*)"EffectBonusCoefficient",&SpellEntry::EffectBonusCoefficient)
.def_readwrite((const char*)"EffectDamageMultiplier",&SpellEntry::EffectDamageMultiplier)
.def_readwrite((const char*)"EffectChainTarget",&SpellEntry::EffectChainTarget)
.def_readwrite((const char*)"EffectDieSides",&SpellEntry::EffectDieSides)
.def_readwrite((const char*)"EffectItemType",&SpellEntry::EffectItemType)
.def_readwrite((const char*)"EffectMechanic",&SpellEntry::EffectMechanic)
.def_readwrite((const char*)"EffectMiscValue",&SpellEntry::EffectMiscValue)
.def_readwrite((const char*)"EffectMiscValueB",&SpellEntry::EffectMiscValueB)
.def_readwrite((const char*)"EffectPointsPerComboPoint",&SpellEntry::EffectPointsPerComboPoint)
.def_readwrite((const char*)"EffectRadiusIndex",&SpellEntry::EffectRadiusIndex)
.def_readwrite((const char*)"EffectRealPointsPerLevel",&SpellEntry::EffectRealPointsPerLevel)
.def_readwrite((const char*)"EffectSpellClassMask",&SpellEntry::EffectSpellClassMask)
.def_readwrite((const char*)"EffectTriggerSpell",&SpellEntry::EffectTriggerSpell)
.def_readwrite((const char*)"EffectImplicitTargetA",&SpellEntry::EffectImplicitTargetA)
.def_readwrite((const char*)"EffectImplicitTargetB",&SpellEntry::EffectImplicitTargetB)
.def_readwrite((const char*)"EquippedItemClass",&SpellEntry::EquippedItemClass)
.def_readwrite((const char*)"EquippedItemInventoryTypeMask",&SpellEntry::EquippedItemInventoryTypeMask)
.def_readwrite((const char*)"EquippedItemSubClassMask",&SpellEntry::EquippedItemSubClassMask)
.def_readwrite((const char*)"AuraInterruptFlags",&SpellEntry::AuraInterruptFlags)
.def_readwrite((const char*)"ChannelInterruptFlags",&SpellEntry::ChannelInterruptFlags)
.def_readwrite((const char*)"InterruptFlags",&SpellEntry::InterruptFlags)
.def_readwrite((const char*)"baseLevel",&SpellEntry::baseLevel)
.def_readwrite((const char*)"maxLevel",&SpellEntry::maxLevel)
.def_readwrite((const char*)"spellLevel",&SpellEntry::spellLevel)
.def_readwrite((const char*)"manaCost",&SpellEntry::manaCost)
.def_readwrite((const char*)"manaCostPerlevel",&SpellEntry::manaCostPerlevel)
.def_readwrite((const char*)"ManaCostPercentage",&SpellEntry::ManaCostPercentage)
.def_readwrite((const char*)"manaPerSecond",&SpellEntry::manaPerSecond)
.def_readwrite((const char*)"Reagent",&SpellEntry::Reagent)
.def_readwrite((const char*)"ReagentCount",&SpellEntry::ReagentCount)
.def_readwrite((const char*)"ct_min",&SpellEntry::ct_min)
.def_readwrite((const char*)"ct_max",&SpellEntry::ct_max)
.def_readwrite((const char*)"ct_max_level",&SpellEntry::ct_max_level)
.def_readwrite((const char*)"SpellScaling_class",&SpellEntry::SpellScaling_class)
.def_readwrite((const char*)"coefMultiplier",&SpellEntry::coefMultiplier)
.def_readwrite((const char*)"coefRandomMultiplier",&SpellEntry::coefRandomMultiplier)
.def_readwrite((const char*)"coefOther",&SpellEntry::coefOther)
.def_readwrite((const char*)"base_coef",&SpellEntry::base_coef)
.def_readwrite((const char*)"base_level_coef",&SpellEntry::base_level_coef)
.def_readwrite((const char*)"Stances",&SpellEntry::Stances)
.def_readwrite((const char*)"StancesNot",&SpellEntry::StancesNot)
.def_readwrite((const char*)"MaxAffectedTargets",&SpellEntry::MaxAffectedTargets)
.def_readwrite((const char*)"MaxTargetLevel",&SpellEntry::MaxTargetLevel)
.def_readwrite((const char*)"TargetCreatureType",&SpellEntry::TargetCreatureType)
.def_readwrite((const char*)"Targets",&SpellEntry::Targets)
.def_readwrite((const char*)"TotemCategory",&SpellEntry::TotemCategory)
.def_readwrite((const char*)"Totem",&SpellEntry::Totem)
];*/
sLog->outString("Hooks initialized");
}
void LuaEngine::Reload()
{
sLog->outString("Re-loading the lua scripts");
lua_close(m_luaState);
playerscripts.clear();
creaturescripts.clear();
m_luaState = lua_open();
if(!m_luaState)
{
sLog->outString("Something wrong happened while reloading the Lua engine");
return;
}
open(m_luaState);
luaL_openlibs(m_luaState); // Opent the correct libraries
AddHooks(); // Call this to add the lua functions -> c++ functions hook
if(luaL_dofile(m_luaState,m_file.c_str()))
{
sLog->outString("Lua engine error: %s",lua_tostring(m_luaState,1));
return;
}
sLog->outString("Lua engine reloaded!");
}
/* Script system hooks */
// Called when a player chats
void LuaEngine::LuaPlayerChat(Player* plr, uint32 type, uint32 lang, std::string msg)
{
TRY(
sLog->outString("Calling LuaPlayerChat");
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerChat)
call_function<void>(m_luaState,(*itr).name,plr,type,lang,msg);
);
}
// Called when a player kills another player in PvP
void LuaEngine::LuaPlayerPvPKill(Player *killer, Player *killed)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerPvPKill)
call_function<void>(m_luaState,(*itr).name,killer,killed);
)
}
// Called when a player kills a creature
void LuaEngine::LuaPlayerCreatureKill(Player* killer, Creature* killed)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerCreatureKill)
call_function<void>(m_luaState,(*itr).name,killer,killed);
)
}
// Called when a creature kills a player
void LuaEngine::LuaPlayerKilledByCreature(Creature* killer, Player* killed)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerKilledByCreature)
call_function<void>(m_luaState,(*itr).name,killer,killed);
)
}
// Called when a player changes its level
void LuaEngine::LuaPlayerLevelChanged(Player* plr, uint8 newlevel)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerLevelChanged)
call_function<void>(m_luaState,(*itr).name,plr,newlevel);
)
}
// Called when a creature engages combat
void LuaEngine::LuaCreatureEnterCombat(Creature* cr, Unit* victim)
{
TRY(
for(CreatureLuaScripts::iterator itr = creaturescripts.begin(); itr != creaturescripts.end(); ++itr)
if((*itr).first == cr->GetEntry())
for(CreatureLuaEvents::iterator it2 = (*itr).second.begin(); it2 != (*itr).second.end(); ++it2)
if((*it2).type == eLuaCreatureEnterCombat)
call_function<void>(m_luaState,(*it2).name,cr,victim);
)
}
// Called when a player opens a gossip window with the creature
bool LuaEngine::LuaCreatureGossipHello(Player* player, Creature* creature)
{
TRY(
for(CreatureLuaScripts::iterator itr = creaturescripts.begin(); itr != creaturescripts.end(); ++itr)
if((*itr).first == creature->GetEntry())
for(CreatureLuaEvents::iterator it2 = (*itr).second.begin(); it2 != (*itr).second.end(); ++it2)
if((*it2).type == eLuaCreatureGossipHello)
{
call_function<void>(m_luaState,(*it2).name,player,creature);
return true;
}
)
return false;
}
// Called when a player resets his talents
void LuaEngine::LuaOnTalentsReset(Player* plr, bool no_cost)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerTalentsReset)
call_function<void>(m_luaState,(*itr).name,plr,no_cost);
)
}
// Called when a player spends talent points
void LuaEngine::LuaOnFreeTalentPointsChanged(Player* plr, uint32 points)
{
TRY(
for(PlayerLuaScripts::iterator itr = playerscripts.begin(); itr != playerscripts.end(); ++itr)
if((*itr).type == eLuaPlayerFreeTalentPointsChanged)
call_function<void>(m_luaState,(*itr).name,plr,points);
)
}
// Called when a creature is hit by a spell
void LuaEngine::LuaCreatureSpellHit(Creature* cr, Unit* caster, SpellEntry const* spellInfo)
{
TRY(
for(CreatureLuaScripts::iterator itr = creaturescripts.begin(); itr != creaturescripts.end(); ++itr)
if((*itr).first == cr->GetEntry())
for(CreatureLuaEvents::iterator it2 = (*itr).second.begin(); it2 != (*itr).second.end(); ++it2)
if((*it2).type == eLuaCreatureSpellHit)
call_function<void>(m_luaState,(*it2).name,caster,spellInfo->Id);
)
}
// Called when a creature hits another with a spell
void LuaEngine::LuaCreatureSpellHitTarget(Creature* cr, Unit* target, SpellEntry const* spellInfo)
{
TRY(
for(CreatureLuaScripts::iterator itr = creaturescripts.begin(); itr != creaturescripts.end(); ++itr)
if((*itr).first == cr->GetEntry())
for(CreatureLuaEvents::iterator it2 = (*itr).second.begin(); it2 != (*itr).second.end(); ++it2)
if((*it2).type == eLuaCreatureSpellHitTarget)
call_function<void>(m_luaState,(*it2).name,target,spellInfo->Id);
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment