diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 50a810e4d..a8b45001b 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -33,6 +33,7 @@ SET(zone_sources loottables.cpp lua_client.cpp lua_entity.cpp + lua_item.cpp lua_mob.cpp lua_npc.cpp lua_parser.cpp @@ -116,6 +117,7 @@ SET(zone_headers horse.h lua_client.h lua_entity.h + lua_item.h lua_mob.h lua_npc.h lua_parser.h diff --git a/zone/attack.cpp b/zone/attack.cpp index a0716be5b..88a471791 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -1425,7 +1425,12 @@ void Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ if(dead) return; //cant die more than once... - if(parse->EventPlayer(EVENT_DEATH, this, "", 0) == 1) { + if(!spell) + spell = SPELL_UNKNOWN; + + char buffer[48] = { 0 }; + snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast(attack_skill)); + if(parse->EventPlayer(EVENT_DEATH, this, buffer, 0) != 0) { return; } @@ -1437,7 +1442,6 @@ void Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ // #1: Send death packet to everyone // uint8 killed_level = GetLevel(); - if(!spell) spell = SPELL_UNKNOWN; SendLogoutPackets(); @@ -2044,7 +2048,10 @@ void NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_ski Mob *oos = nullptr; if(killerMob) { Mob *oos = killerMob->GetOwnerOrSelf(); - if(parse->EventNPC(EVENT_DEATH, this, oos, "", 0) != 0) + + char buffer[32] = { 0 }; + snprintf(buffer, 31, "%d %d %d", damage, spell, static_cast(attack_skill)); + if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0) { return; } diff --git a/zone/bot.cpp b/zone/bot.cpp index 47f974444..8c8ab64af 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -6212,36 +6212,6 @@ void Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, SkillType attack_ bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE); - //if (give_exp_client && !IsCorpse() && MerchantType == 0) - //{ - // Group *kg = entity_list.GetGroupByClient(give_exp_client); - // Raid *kr = entity_list.GetRaidByClient(give_exp_client); - - // if(!kr && give_exp_client->IsClient() && give_exp_client->GetBotRaidID() > 0) { - // BotRaids *br = entity_list.GetBotRaidByMob(give_exp_client->CastToMob()); - // if(br) { - // if(!IsLdonTreasure) - // br->SplitExp((EXP_FORMULA), this); - - // if(br->GetBotMainTarget() == this) - // br->SetBotMainTarget(nullptr); - - // /* Send the EVENT_KILLED_MERIT event for all raid members */ - // if(br->BotRaidGroups[0]) { - // for(int j=0; jBotRaidGroups[0]->members[j] && br->BotRaidGroups[0]->members[j]->IsClient()) { - // parse->Event(EVENT_KILLED_MERIT, GetNPCTypeID(), "killed", this, br->BotRaidGroups[0]->members[j]); - // if(RuleB(TaskSystem, EnableTaskSystem)) { - // br->BotRaidGroups[0]->members[j]->CastToClient()->UpdateTasksOnKill(GetNPCTypeID()); - // } - // } - // } - // } - // } - // } - //} - - //corpse->Depop(); if(entity_list.GetCorpseByID(GetID())) entity_list.GetCorpseByID(GetID())->Depop(); diff --git a/zone/client.cpp b/zone/client.cpp index c2cbad7ed..147bd80f7 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -1076,7 +1076,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s Mob *targ = GetTarget(); if(targ->GetAppearance() != eaDead) - targ->FaceTarget(targ); + targ->FaceTarget(this); parse->EventNPC(EVENT_SAY, targ->CastToNPC(), this, message, language); } } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index f9323376c..69966fd49 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -3266,7 +3266,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app) { Mob *targ = GetTarget(); if(targ->GetAppearance() != eaDead) - targ->FaceTarget(targ); + targ->FaceTarget(this); parse->EventNPC(EVENT_SAY, GetTarget()->CastToNPC(), this, response.c_str(), 0); parse->EventPlayer(EVENT_SAY, this, response.c_str(), 0); } @@ -6301,7 +6301,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app) } char buf[20]; - snprintf(buf, 19, "%u %u", cd->doorid, zone->GetInstanceVersion()); + snprintf(buf, 19, "%u", cd->doorid); buf[19] = '\0'; parse->EventPlayer(EVENT_CLICKDOOR, this, buf, 0); @@ -9629,8 +9629,9 @@ void Client::CompleteConnect() parse->EventPlayer(EVENT_ENTERZONE, this, "", 0); + //This sub event is for if a player logs in for the first time since entering world. if(firstlogon == 1) - parse->EventPlayer(EVENT_CONNECT, this, "", 0); //This sub event is for if a player logs in for the first time since entering world. + parse->EventPlayer(EVENT_CONNECT, this, "", 0); if(zone) { @@ -10665,8 +10666,8 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) { break; } - char *buf = 0; - MakeAnyLenString(&buf, "%d", prs->popupid); + char buf[16]; + sprintf(buf, "%d\0", prs->popupid); parse->EventPlayer(EVENT_POPUP_RESPONSE, this, buf, 0); @@ -10674,8 +10675,6 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) { if(Target && Target->IsNPC()) { parse->EventNPC(EVENT_POPUP_RESPONSE, Target->CastToNPC(), this, buf, 0); } - - safe_delete_array(buf); } void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app) { diff --git a/zone/embparser.cpp b/zone/embparser.cpp index eddf2d6ac..d157ce0e2 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -1141,9 +1141,8 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID } case EVENT_CLICKDOOR: { - Seperator sep(data); - ExportVar(package_name.c_str(), "doorid", sep.arg[0]); - ExportVar(package_name.c_str(), "version", sep.arg[1]); + ExportVar(package_name.c_str(), "doorid", data); + ExportVar(package_name.c_str(), "version", zone->GetInstanceVersion()); break; } diff --git a/zone/lua_item.cpp b/zone/lua_item.cpp new file mode 100644 index 000000000..228d211a8 --- /dev/null +++ b/zone/lua_item.cpp @@ -0,0 +1,14 @@ +#ifdef LUA_EQEMU + +#include "masterentity.h" +#include "lua_item.h" + +bool Lua_Item::Null() { + return d_ == nullptr; +} + +bool Lua_Item::Valid() { + return d_ != nullptr; +} + +#endif diff --git a/zone/lua_item.h b/zone/lua_item.h new file mode 100644 index 000000000..d4b385a5a --- /dev/null +++ b/zone/lua_item.h @@ -0,0 +1,29 @@ +#ifndef EQEMU_LUA_ITEM_H +#define EQEMU_LUA_ITEM_H +#ifdef LUA_EQEMU + +class ItemInst; + +class Lua_Item +{ +public: + Lua_Item() { d_ = nullptr; } + Lua_Item(ItemInst *d) { d_ = d; } + virtual ~Lua_Item() { } + + operator ItemInst* () { + if(d_) { + return reinterpret_cast(d_); + } + + return nullptr; + } + + bool Null(); + bool Valid(); + + void *d_; +}; + +#endif +#endif diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 40701cdc2..135fa8049 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -2,18 +2,22 @@ #include "lua_parser.h" #include +#include #include #include "lua.hpp" #include #include +#include "../common/seperator.h" #include "masterentity.h" #include "lua_entity.h" #include "lua_mob.h" #include "lua_client.h" #include "lua_npc.h" #include "lua_trade.h" +#include "lua_item.h" +#include "zone.h" const char *LuaEvents[_LargestEventID] = { "event_say", @@ -77,6 +81,8 @@ const char *LuaEvents[_LargestEventID] = { "event_duel_lose" }; +extern Zone *zone; + LuaParser::LuaParser() { } @@ -132,7 +138,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M try { lua_getfield(L, LUA_GLOBALSINDEX, sub_name); - //push self + //always push self Lua_NPC l_npc(npc); luabind::object l_npc_o = luabind::object(L, l_npc); l_npc_o.push(L); @@ -140,32 +146,36 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M int arg_count = 1; int ret_count = 1; - if(init) { - Lua_Mob l_mob(init); - luabind::object l_mob_o = luabind::object(L, l_mob); - l_mob_o.push(L); - ++arg_count; - } - + //push arguments based on event switch(evt) { case EVENT_SAY: case EVENT_AGGRO_SAY: case EVENT_PROXIMITY_SAY: { + //client + Lua_Client l_client(reinterpret_cast(init)); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + //text lua_pushstring(L, data.c_str()); - + //language lua_pushinteger(L, extra_data); - - arg_count += 2; + + arg_count += 3; break; } - + case EVENT_ITEM: { + //client + Lua_Client l_client(reinterpret_cast(init)); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + + //trade Lua_Trade trade; std::stringstream ident; ident << npc->GetNPCTypeID(); - //std::string identifier = std::string(itoa(npc->GetNPCTypeID())); trade.item1_ = std::stoul(GetVar("item1." + ident.str())); trade.item2_ = std::stoul(GetVar("item2." + ident.str())); trade.item3_ = std::stoul(GetVar("item3." + ident.str())); @@ -185,48 +195,123 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M luabind::object l_trade_o = luabind::object(L, trade); l_trade_o.push(L); + + arg_count += 2; + break; + } + + case EVENT_HP: { + if(extra_data == 1) { + lua_pushinteger(L, -1); + lua_pushinteger(L, std::stoi(data)); + } + else + { + lua_pushinteger(L, std::stoi(data)); + lua_pushinteger(L, -1); + } + + arg_count += 2; + break; + } + + case EVENT_ATTACK: + case EVENT_AGGRO: + case EVENT_TARGET_CHANGE: + case EVENT_CAST_ON: { + //mob + Lua_Mob l_mob(init); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); arg_count += 1; break; } - case EVENT_HP: { - if(extra_data == 1) { - lua_pushstring(L, "-1"); - lua_pushstring(L, data.c_str()); - } - else - { - lua_pushstring(L, data.c_str()); - lua_pushstring(L, "-1"); - } - - arg_count += 2; - break; - } - - case EVENT_WAYPOINT_ARRIVE: - case EVENT_WAYPOINT_DEPART: - case EVENT_TIMER: - case EVENT_SIGNAL: - case EVENT_COMBAT: - case EVENT_CAST_ON: - case EVENT_TASKACCEPTED: - case EVENT_POPUP_RESPONSE: - case EVENT_HATE_LIST: { - lua_pushstring(L, data.c_str()); + case EVENT_KILLED_MERIT: + case EVENT_SLAY: + case EVENT_ENTER: + case EVENT_EXIT: + case EVENT_TASKACCEPTED: { + //client + Lua_Client l_client(reinterpret_cast(init)); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); arg_count += 1; break; } case EVENT_NPC_SLAY: { - lua_pushinteger(L, init->GetNPCTypeID()); + //npc + Lua_NPC l_npc(reinterpret_cast(init)); + luabind::object l_npc_o = luabind::object(L, l_npc); + l_npc_o.push(L); arg_count += 1; break; } + case EVENT_POPUP_RESPONSE: + case EVENT_WAYPOINT_ARRIVE: + case EVENT_WAYPOINT_DEPART: { + //client + Lua_Client l_client(reinterpret_cast(init)); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + + //id + lua_pushinteger(L, std::stoi(data)); + + arg_count += 2; + break; + } + + case EVENT_HATE_LIST: + case EVENT_COMBAT: { + //mob + Lua_Mob l_mob(init); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + + //joined + lua_pushboolean(L, std::stoi(data) == 0 ? false : true); + + arg_count += 2; + break; + } + + case EVENT_SIGNAL: { + //id + lua_pushinteger(L, std::stoi(data)); + + arg_count += 1; + break; + } + + case EVENT_TIMER: { + //id + lua_pushstring(L, data.c_str()); + + arg_count += 1; + break; + } + + case EVENT_DEATH: { + //mob + Lua_Mob l_mob(init); + luabind::object l_mob_o = luabind::object(L, l_mob); + l_mob_o.push(L); + + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushinteger(L, std::stoi(sep.arg[2])); + + arg_count += 4; + break; + } + } if(lua_pcall(L, arg_count, ret_count, 0)) { @@ -248,10 +333,161 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M } int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { - return 0; + if(evt >= _LargestEventID) { + return 0; + } + + if(!client) { + return 0; + } + + if(!PlayerHasQuestSub(LuaEvents[evt])) { + return 0; + } + + return _EventPlayer("player", evt, client, data, extra_data); } int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data) { + if(evt >= _LargestEventID) { + return 0; + } + + if(!client) { + return 0; + } + + if(!GlobalPlayerHasQuestSub(LuaEvents[evt])) { + return 0; + } + + return _EventPlayer("global_player", evt, client, data, extra_data); +} + +int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data) { + const char *sub_name = LuaEvents[evt]; + + lua_State *L = nullptr; + auto iter = states_.find(package_name); + if(iter == states_.end()) { + return 0; + } + L = iter->second; + + try { + lua_getfield(L, LUA_GLOBALSINDEX, sub_name); + + //push self + Lua_Client l_client(client); + luabind::object l_client_o = luabind::object(L, l_client); + l_client_o.push(L); + int arg_count = 1; + int ret_count = 1; + + switch(evt) { + case EVENT_DEATH: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushinteger(L, std::stoi(sep.arg[2])); + lua_pushinteger(L, std::stoi(sep.arg[3])); + + arg_count += 4; + break; + } + + case EVENT_SAY: { + lua_pushstring(L, data.c_str()); + lua_pushinteger(L, extra_data); + + arg_count += 2; + break; + } + + case EVENT_DISCOVER_ITEM: + case EVENT_FISH_SUCCESS: + case EVENT_FORAGE_SUCCESS: { + lua_pushinteger(L, extra_data); + + arg_count += 1; + break; + } + + case EVENT_CLICK_OBJECT: + case EVENT_CLICKDOOR: + case EVENT_SIGNAL: + case EVENT_POPUP_RESPONSE: + case EVENT_PLAYER_PICKUP: + case EVENT_CAST: + case EVENT_TASK_FAIL: + case EVENT_ZONE: { + lua_pushinteger(L, std::stoi(data)); + + arg_count += 1; + break; + } + + case EVENT_TIMER: { + lua_pushstring(L, data.c_str()); + + arg_count += 1; + break; + } + + case EVENT_DUEL_WIN: + case EVENT_DUEL_LOSE: { + lua_pushstring(L, data.c_str()); + lua_pushinteger(L, extra_data); + arg_count += 2; + break; + } + + case EVENT_LOOT: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushstring(L, sep.arg[2]); + + arg_count += 3; + break; + } + + case EVENT_TASK_STAGE_COMPLETE: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + + arg_count += 2; + break; + } + + case EVENT_TASK_COMPLETE: { + Seperator sep(data.c_str()); + lua_pushinteger(L, std::stoi(sep.arg[0])); + lua_pushinteger(L, std::stoi(sep.arg[1])); + lua_pushinteger(L, std::stoi(sep.arg[2])); + + arg_count += 3; + break; + } + + } + + if(lua_pcall(L, arg_count, ret_count, 0)) { + printf("Error: %s\n", lua_tostring(L, -1)); + return 0; + } + + if(lua_isnumber(L, -1)) { + int ret = static_cast(lua_tointeger(L, -1)); + return ret; + } + + } catch(std::exception &ex) { + printf("%s\n", ex.what()); + return 0; + } + return 0; } @@ -373,12 +609,47 @@ void LuaParser::LoadScript(std::string filename, std::string package_name) { lua_State *L = luaL_newstate(); luaL_openlibs(L); - //lua_pushnil(L); - //lua_setglobal(L, "os"); - // + lua_pushnil(L); + lua_setglobal(L, "os"); + //lua_pushnil(L); //lua_setglobal(L, "io"); + lua_getglobal(L, "package"); + lua_getfield(L, -1, "path"); + char module_path[1024]; + snprintf(module_path, 1024, "%s;%s", lua_tostring(L,-1), "quests/plugins/?.lua"); + lua_pop(L, 1); + lua_pushstring(L, module_path); + lua_setfield(L, -2, "path"); + lua_pop(L, 1); + + //load init + FILE *f = fopen("quests/templates/script_init.lua", "r"); + if(f) { + fclose(f); + + if(luaL_dofile(L, "quests/templates/script_init.lua")) { + printf("Lua Error in Global Init: %s\n", lua_tostring(L, -1)); + lua_close(L); + return; + } + } + + //zone init - always loads after global + std::string zone_script = "quests/" + std::string(zone->GetShortName()); + zone_script += "/script_init.lua"; + f = fopen(zone_script.c_str(), "r"); + if(f) { + fclose(f); + + if(luaL_dofile(L, zone_script.c_str())) { + printf("Lua Error in Zone Init: %s\n", lua_tostring(L, -1)); + lua_close(L); + return; + } + } + MapFunctions(L); if(luaL_dofile(L, filename.c_str())) { @@ -622,7 +893,12 @@ void LuaParser::MapFunctions(lua_State *L) { .def_readwrite("platinum", &Lua_Trade::platinum_) .def_readwrite("gold", &Lua_Trade::gold_) .def_readwrite("silver", &Lua_Trade::silver_) - .def_readwrite("copper", &Lua_Trade::copper_) + .def_readwrite("copper", &Lua_Trade::copper_), + + luabind::class_("Item") + .def(luabind::constructor<>()) + .property("null", &Lua_Entity::Null) + .property("valid", &Lua_Entity::Valid) ]; } catch(std::exception &ex) { diff --git a/zone/lua_parser.h b/zone/lua_parser.h index 4d055aa7e..c27cb9f0f 100644 --- a/zone/lua_parser.h +++ b/zone/lua_parser.h @@ -45,6 +45,7 @@ public: private: int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data); + int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data); void LoadScript(std::string filename, std::string package_name); bool HasFunction(std::string function, std::string package_name); void ClearStates(); diff --git a/zone/merc.cpp b/zone/merc.cpp index 6f7c8142f..a7ba09f34 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4805,37 +4805,6 @@ void Merc::Death(Mob* killerMob, int32 damage, uint16 spell, SkillType attack_sk bool IsLdonTreasure = (this->GetClass() == LDON_TREASURE); - //if (give_exp_client && !IsCorpse() && MerchantType == 0) - //{ - // Group *kg = entity_list.GetGroupByClient(give_exp_client); - // Raid *kr = entity_list.GetRaidByClient(give_exp_client); - - // if(!kr && give_exp_client->IsClient() && give_exp_client->GetBotRaidID() > 0) { - // BotRaids *br = entity_list.GetBotRaidByMob(give_exp_client->CastToMob()); - // if(br) { - // if(!IsLdonTreasure) - // br->SplitExp((EXP_FORMULA), this); - - // if(br->GetBotMainTarget() == this) - // br->SetBotMainTarget(nullptr); - - // /* Send the EVENT_KILLED_MERIT event for all raid members */ - // if(br->BotRaidGroups[0]) { - // for(int j=0; jBotRaidGroups[0]->members[j] && br->BotRaidGroups[0]->members[j]->IsClient()) { - // parse->Event(EVENT_KILLED_MERIT, GetNPCTypeID(), "killed", this, br->BotRaidGroups[0]->members[j]); - // if(RuleB(TaskSystem, EnableTaskSystem)) { - // br->BotRaidGroups[0]->members[j]->CastToClient()->UpdateTasksOnKill(GetNPCTypeID()); - // } - // } - // } - // } - // } - // } - //} - - //corpse->Depop(); - //no corpse, no exp if we're a merc. We'll suspend instead, since that's what live does. I'm not actually sure live supports 'depopping' merc corpses. if(entity_list.GetCorpseByID(GetID())) entity_list.GetCorpseByID(GetID())->Depop(); diff --git a/zone/mob.cpp b/zone/mob.cpp index 6782a8826..a3fb6191b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -2817,9 +2817,9 @@ void Mob::SetTarget(Mob* mob) { target = mob; entity_list.UpdateHoTT(this); if(IsNPC()) - parse->EventNPC(EVENT_TARGET_CHANGE, CastToNPC(), mob, "", 0); //parse->Event(EVENT_TARGET_CHANGE, this->GetNPCTypeID(), 0, this->CastToNPC(), mob); + parse->EventNPC(EVENT_TARGET_CHANGE, CastToNPC(), mob, "", 0); else if (IsClient()) - parse->EventPlayer(EVENT_TARGET_CHANGE, CastToClient(), "", 0); //parse->Event(EVENT_TARGET_CHANGE, 0, "", (NPC*)nullptr, this->CastToClient()); + parse->EventPlayer(EVENT_TARGET_CHANGE, CastToClient(), "", 0); if(IsPet() && GetOwner() && GetOwner()->IsClient()) GetOwner()->CastToClient()->UpdateXTargetType(MyPetTarget, mob); diff --git a/zone/spells.cpp b/zone/spells.cpp index af27d92fa..3c310ab37 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -1211,10 +1211,6 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot, this->CastToClient()->CheckSongSkillIncrease(spell_id); this->CastToClient()->MemorizeSpell(slot, spell_id, memSpellSpellbar); } - // go again in 6 seconds - //this is handled with bardsong_timer - // DoCastSpell(casting_spell_id, casting_spell_targetid, casting_spell_slot, 6000, casting_spell_mana); - mlog(SPELLS__CASTING, "Bard song %d should be started", spell_id); } else