mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 14:41:28 +00:00
[Quest API] Add Memorize and Scribe Spell Events to Perl/Lua (#3363)
* [Quest API] Add Memorize and Scribe Spell Events to Perl/Lua # Perl - Add `EVENT_MEMORIZE_SPELL`. - Add `EVENT_UNMEMORIZE_SPELL`. - Add `EVENT_SCRIBE_SPELL`. - Add `EVENT_UNSCRIBE_SPELL`. # Lua - Add `event_memorize_spell`. - Add `event_unmemorize_spell`. - Add `event_scribe_spell`. - Add `event_unscribe_spell`. # Notes - Allows operators to perform events on memorization, unmemorization, scribe, or unscribe. - Cleaned up target description messages for `#unscribespell`. * Update client.cpp
This commit is contained in:
parent
67fdc75df3
commit
50db7637aa
@ -1045,4 +1045,11 @@ enum ResurrectionActions
|
|||||||
Accept
|
Accept
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ScribeSpellActions
|
||||||
|
{
|
||||||
|
Scribe,
|
||||||
|
Memorize,
|
||||||
|
Unmemorize
|
||||||
|
};
|
||||||
|
|
||||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||||
|
|||||||
@ -2783,18 +2783,64 @@ void Client::GMKill() {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing, uint32 reduction){
|
void Client::MemorizeSpell(uint32 slot, uint32 spell_id, uint32 scribing, uint32 reduction){
|
||||||
if (slot < 0 || slot >= EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
if (
|
||||||
|
!EQ::ValueWithin(
|
||||||
|
slot,
|
||||||
|
0,
|
||||||
|
(EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize - 1)
|
||||||
|
)
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
if ((spellid < 3 || spellid > EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellIdMax) && spellid != 0xFFFFFFFF)
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!EQ::ValueWithin(
|
||||||
|
spell_id,
|
||||||
|
3,
|
||||||
|
EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellIdMax
|
||||||
|
) &&
|
||||||
|
spell_id != UINT32_MAX
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
||||||
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
|
||||||
mss->scribing=scribing;
|
auto* mss = (MemorizeSpell_Struct*) outapp->pBuffer;
|
||||||
mss->slot=slot;
|
|
||||||
mss->spell_id=spellid;
|
mss->scribing = scribing;
|
||||||
|
mss->slot = slot;
|
||||||
|
mss->spell_id = spell_id;
|
||||||
mss->reduction = reduction;
|
mss->reduction = reduction;
|
||||||
|
|
||||||
outapp->priority = 5;
|
outapp->priority = 5;
|
||||||
|
|
||||||
|
if (
|
||||||
|
parse->PlayerHasQuestSub(EVENT_SCRIBE_SPELL) ||
|
||||||
|
parse->PlayerHasQuestSub(EVENT_MEMORIZE_SPELL) ||
|
||||||
|
parse->PlayerHasQuestSub(EVENT_UNMEMORIZE_SPELL)
|
||||||
|
) {
|
||||||
|
const auto export_string = fmt::format("{} {}", slot, spell_id);
|
||||||
|
|
||||||
|
if (
|
||||||
|
scribing == ScribeSpellActions::Memorize &&
|
||||||
|
parse->PlayerHasQuestSub(EVENT_MEMORIZE_SPELL)
|
||||||
|
) {
|
||||||
|
parse->EventPlayer(EVENT_MEMORIZE_SPELL, this, export_string, 0);
|
||||||
|
} else if (
|
||||||
|
scribing == ScribeSpellActions::Unmemorize &&
|
||||||
|
parse->PlayerHasQuestSub(EVENT_UNMEMORIZE_SPELL)
|
||||||
|
) {
|
||||||
|
parse->EventPlayer(EVENT_UNMEMORIZE_SPELL, this, export_string, 0);
|
||||||
|
} else if (
|
||||||
|
scribing == ScribeSpellActions::Scribe &&
|
||||||
|
parse->PlayerHasQuestSub(EVENT_SCRIBE_SPELL)
|
||||||
|
) {
|
||||||
|
parse->EventPlayer(EVENT_SCRIBE_SPELL, this, export_string, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -932,7 +932,7 @@ public:
|
|||||||
inline uint32 GetAAPercent() const { return m_epp.perAA; }
|
inline uint32 GetAAPercent() const { return m_epp.perAA; }
|
||||||
void SetAATitle(std::string title);
|
void SetAATitle(std::string title);
|
||||||
void SetTitleSuffix(std::string suffix);
|
void SetTitleSuffix(std::string suffix);
|
||||||
void MemorizeSpell(uint32 slot, uint32 spellid, uint32 scribing, uint32 reduction = 0);
|
void MemorizeSpell(uint32 slot, uint32 spell_id, uint32 scribing, uint32 reduction = 0);
|
||||||
|
|
||||||
// Item methods
|
// Item methods
|
||||||
void UseAugmentContainer(int container_slot);
|
void UseAugmentContainer(int container_slot);
|
||||||
|
|||||||
@ -179,6 +179,10 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_ITEM_CLICK_CAST_CLIENT",
|
"EVENT_ITEM_CLICK_CAST_CLIENT",
|
||||||
"EVENT_DESTROY_ITEM_CLIENT",
|
"EVENT_DESTROY_ITEM_CLIENT",
|
||||||
"EVENT_DROP_ITEM_CLIENT",
|
"EVENT_DROP_ITEM_CLIENT",
|
||||||
|
"EVENT_MEMORIZE_SPELL",
|
||||||
|
"EVENT_UNMEMORIZE_SPELL",
|
||||||
|
"EVENT_SCRIBE_SPELL",
|
||||||
|
"EVENT_UNSCRIBE_SPELL",
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
"EVENT_SPELL_EFFECT_BOT",
|
"EVENT_SPELL_EFFECT_BOT",
|
||||||
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
||||||
@ -2160,6 +2164,19 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EVENT_MEMORIZE_SPELL:
|
||||||
|
case EVENT_UNMEMORIZE_SPELL:
|
||||||
|
case EVENT_SCRIBE_SPELL:
|
||||||
|
case EVENT_UNSCRIBE_SPELL: {
|
||||||
|
Seperator sep(data);
|
||||||
|
ExportVar(package_name.c_str(), "slot_id", sep.arg[0]);
|
||||||
|
ExportVar(package_name.c_str(), "spell_id", sep.arg[1]);
|
||||||
|
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[1]))) {
|
||||||
|
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[1])]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,6 +124,10 @@ typedef enum {
|
|||||||
EVENT_ITEM_CLICK_CAST_CLIENT,
|
EVENT_ITEM_CLICK_CAST_CLIENT,
|
||||||
EVENT_DESTROY_ITEM_CLIENT,
|
EVENT_DESTROY_ITEM_CLIENT,
|
||||||
EVENT_DROP_ITEM_CLIENT,
|
EVENT_DROP_ITEM_CLIENT,
|
||||||
|
EVENT_MEMORIZE_SPELL,
|
||||||
|
EVENT_UNMEMORIZE_SPELL,
|
||||||
|
EVENT_SCRIBE_SPELL,
|
||||||
|
EVENT_UNSCRIBE_SPELL,
|
||||||
// Add new events before these or Lua crashes
|
// Add new events before these or Lua crashes
|
||||||
EVENT_SPELL_EFFECT_BOT,
|
EVENT_SPELL_EFFECT_BOT,
|
||||||
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
||||||
|
|||||||
@ -3,18 +3,18 @@
|
|||||||
|
|
||||||
void command_unscribespell(Client *c, const Seperator *sep)
|
void command_unscribespell(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
int arguments = sep->argnum;
|
const auto arguments = sep->argnum;
|
||||||
if (!arguments || !sep->IsNumber(1)) {
|
if (!arguments || !sep->IsNumber(1)) {
|
||||||
c->Message(Chat::White, "Usage: #unscribespell [Spell ID] - Unscribe a spell from your or your target's spell book by Spell ID");
|
c->Message(Chat::White, "Usage: #unscribespell [Spell ID] - Unscribe a spell from your or your target's spell book by Spell ID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto target = c;
|
auto t = c;
|
||||||
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) {
|
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM()) {
|
||||||
target = c->GetTarget()->CastToClient();
|
t = c->GetTarget()->CastToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 spell_id = EQ::Clamp(Strings::ToInt(sep->arg[1]), 0, 65535);
|
const uint16 spell_id = EQ::Clamp(Strings::ToInt(sep->arg[1]), 0, 65535);
|
||||||
|
|
||||||
if (!IsValidSpell(spell_id)) {
|
if (!IsValidSpell(spell_id)) {
|
||||||
c->Message(
|
c->Message(
|
||||||
@ -29,16 +29,16 @@ void command_unscribespell(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
auto spell_name = GetSpellName(spell_id);
|
auto spell_name = GetSpellName(spell_id);
|
||||||
|
|
||||||
if (target->HasSpellScribed(spell_id)) {
|
if (t->HasSpellScribed(spell_id)) {
|
||||||
target->UnscribeSpellBySpellID(spell_id);
|
t->UnscribeSpellBySpellID(spell_id);
|
||||||
|
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Unscribing {} ({}) for {}.",
|
"Unscribing {} ({}) from {}.",
|
||||||
spell_name,
|
spell_name,
|
||||||
spell_id,
|
spell_id,
|
||||||
c->GetTargetDescription(target)
|
c->GetTargetDescription(t, TargetDescriptionType::LCSelf)
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -46,8 +46,8 @@ void command_unscribespell(Client *c, const Seperator *sep)
|
|||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} {} not have {} ({}) scribed.",
|
"{} {} not have {} ({}) scribed.",
|
||||||
c->GetTargetDescription(target),
|
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||||
c == target ? "do" : "does",
|
c == t ? "do" : "does",
|
||||||
spell_name,
|
spell_name,
|
||||||
spell_id
|
spell_id
|
||||||
).c_str()
|
).c_str()
|
||||||
|
|||||||
@ -5474,7 +5474,11 @@ luabind::scope lua_register_events() {
|
|||||||
luabind::value("item_click_client", static_cast<int>(EVENT_ITEM_CLICK_CLIENT)),
|
luabind::value("item_click_client", static_cast<int>(EVENT_ITEM_CLICK_CLIENT)),
|
||||||
luabind::value("item_click_cast_client", static_cast<int>(EVENT_ITEM_CLICK_CAST_CLIENT)),
|
luabind::value("item_click_cast_client", static_cast<int>(EVENT_ITEM_CLICK_CAST_CLIENT)),
|
||||||
luabind::value("destroy_item_client", static_cast<int>(EVENT_DESTROY_ITEM_CLIENT)),
|
luabind::value("destroy_item_client", static_cast<int>(EVENT_DESTROY_ITEM_CLIENT)),
|
||||||
luabind::value("drop_item_client", static_cast<int>(EVENT_DROP_ITEM_CLIENT))
|
luabind::value("drop_item_client", static_cast<int>(EVENT_DROP_ITEM_CLIENT)),
|
||||||
|
luabind::value("memorize_spell", static_cast<int>(EVENT_MEMORIZE_SPELL)),
|
||||||
|
luabind::value("unmemorize_spell", static_cast<int>(EVENT_UNMEMORIZE_SPELL)),
|
||||||
|
luabind::value("scribe_spell", static_cast<int>(EVENT_SCRIBE_SPELL)),
|
||||||
|
luabind::value("unscribe_spell", static_cast<int>(EVENT_UNSCRIBE_SPELL))
|
||||||
)];
|
)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -164,7 +164,11 @@ const char *LuaEvents[_LargestEventID] = {
|
|||||||
"event_item_click_client",
|
"event_item_click_client",
|
||||||
"event_item_click_cast_client",
|
"event_item_click_cast_client",
|
||||||
"event_destroy_item_client",
|
"event_destroy_item_client",
|
||||||
"event_drop_item_client"
|
"event_drop_item_client",
|
||||||
|
"event_memorize_spell",
|
||||||
|
"event_unmemorize_spell",
|
||||||
|
"event_scribe_spell",
|
||||||
|
"event_unscribe_spell"
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
@ -292,6 +296,10 @@ LuaParser::LuaParser() {
|
|||||||
PlayerArgumentDispatch[EVENT_DESTROY_ITEM_CLIENT] = handle_player_destroy_item;
|
PlayerArgumentDispatch[EVENT_DESTROY_ITEM_CLIENT] = handle_player_destroy_item;
|
||||||
PlayerArgumentDispatch[EVENT_TARGET_CHANGE] = handle_player_target_change;
|
PlayerArgumentDispatch[EVENT_TARGET_CHANGE] = handle_player_target_change;
|
||||||
PlayerArgumentDispatch[EVENT_DROP_ITEM_CLIENT] = handle_player_drop_item;
|
PlayerArgumentDispatch[EVENT_DROP_ITEM_CLIENT] = handle_player_drop_item;
|
||||||
|
PlayerArgumentDispatch[EVENT_MEMORIZE_SPELL] = handle_player_memorize_scribe_spell;
|
||||||
|
PlayerArgumentDispatch[EVENT_UNMEMORIZE_SPELL] = handle_player_memorize_scribe_spell;
|
||||||
|
PlayerArgumentDispatch[EVENT_SCRIBE_SPELL] = handle_player_memorize_scribe_spell;
|
||||||
|
PlayerArgumentDispatch[EVENT_UNSCRIBE_SPELL] = handle_player_memorize_scribe_spell;
|
||||||
|
|
||||||
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
||||||
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
||||||
|
|||||||
@ -1411,6 +1411,35 @@ void handle_player_target_change(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_player_memorize_scribe_spell(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
lua_pushnumber(L, Strings::ToUnsignedInt(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "slot_id");
|
||||||
|
|
||||||
|
lua_pushnumber(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "spell_id");
|
||||||
|
|
||||||
|
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[1]))) {
|
||||||
|
Lua_Spell l_spell(&spells[Strings::ToUnsignedInt(sep.arg[1])]);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
lua_setfield(L, -2, "spell");
|
||||||
|
} else {
|
||||||
|
Lua_Spell l_spell(nullptr);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
lua_setfield(L, -2, "spell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
void handle_item_click(
|
void handle_item_click(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
|
|||||||
@ -734,6 +734,15 @@ void handle_player_drop_item(
|
|||||||
std::vector<std::any> *extra_pointers
|
std::vector<std::any> *extra_pointers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void handle_player_memorize_scribe_spell(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Client* client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
// Item
|
// Item
|
||||||
void handle_item_click(
|
void handle_item_click(
|
||||||
QuestInterface *parse,
|
QuestInterface *parse,
|
||||||
|
|||||||
@ -5521,13 +5521,14 @@ void Client::UnmemSpell(int slot, bool update_client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogSpells("Spell [{}] forgotten from slot [{}]", m_pp.mem_spells[slot], slot);
|
LogSpells("Spell [{}] forgotten from slot [{}]", m_pp.mem_spells[slot], slot);
|
||||||
m_pp.mem_spells[slot] = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
database.DeleteCharacterMemorizedSpell(CharacterID(), m_pp.mem_spells[slot], slot);
|
database.DeleteCharacterMemorizedSpell(CharacterID(), m_pp.mem_spells[slot], slot);
|
||||||
|
|
||||||
if(update_client) {
|
if (update_client) {
|
||||||
MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget);
|
MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pp.mem_spells[slot] = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UnmemSpellBySpellID(int32 spell_id)
|
void Client::UnmemSpellBySpellID(int32 spell_id)
|
||||||
@ -5599,7 +5600,7 @@ void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client, bool def
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update_client) {
|
if (update_client) {
|
||||||
if (m_pp.spell_book[slot] != 0xFFFFFFFF) {
|
if (m_pp.spell_book[slot] != UINT32_MAX) {
|
||||||
UnscribeSpell(slot, update_client, defer_save);
|
UnscribeSpell(slot, update_client, defer_save);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5619,25 +5620,33 @@ void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client, bool def
|
|||||||
|
|
||||||
void Client::UnscribeSpell(int slot, bool update_client, bool defer_save)
|
void Client::UnscribeSpell(int slot, bool update_client, bool defer_save)
|
||||||
{
|
{
|
||||||
if (slot >= EQ::spells::SPELLBOOK_SIZE || slot < 0) {
|
if (!EQ::ValueWithin(slot, 0, (EQ::spells::SPELLBOOK_SIZE - 1))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSpells("Spell [{}] erased from spell book slot [{}]", m_pp.spell_book[slot], slot);
|
LogSpells("Spell [{}] erased from spell book slot [{}]", m_pp.spell_book[slot], slot);
|
||||||
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
if (!defer_save) {
|
if (!defer_save) {
|
||||||
database.DeleteCharacterSpell(CharacterID(), m_pp.spell_book[slot], slot);
|
database.DeleteCharacterSpell(CharacterID(), m_pp.spell_book[slot], slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update_client && slot < EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize) {
|
if (update_client && slot < EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize) {
|
||||||
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
||||||
DeleteSpell_Struct *del = (DeleteSpell_Struct *) outapp->pBuffer;
|
auto* del = (DeleteSpell_Struct *) outapp->pBuffer;
|
||||||
|
|
||||||
del->spell_slot = slot;
|
del->spell_slot = slot;
|
||||||
del->success = 1;
|
del->success = 1;
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parse->PlayerHasQuestSub(EVENT_UNSCRIBE_SPELL)) {
|
||||||
|
const auto export_string = fmt::format("{} {}", slot, m_pp.spell_book[slot]);
|
||||||
|
parse->EventPlayer(EVENT_UNSCRIBE_SPELL, this, export_string, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pp.spell_book[slot] = UINT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UnscribeSpellAll(bool update_client)
|
void Client::UnscribeSpellAll(bool update_client)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user