mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +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
|
||||
};
|
||||
|
||||
enum ScribeSpellActions
|
||||
{
|
||||
Scribe,
|
||||
Memorize,
|
||||
Unmemorize
|
||||
};
|
||||
|
||||
#endif /*COMMON_EQ_CONSTANTS_H*/
|
||||
|
||||
@ -2783,18 +2783,64 @@ void Client::GMKill() {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing, uint32 reduction){
|
||||
if (slot < 0 || slot >= EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
void Client::MemorizeSpell(uint32 slot, uint32 spell_id, uint32 scribing, uint32 reduction){
|
||||
if (
|
||||
!EQ::ValueWithin(
|
||||
slot,
|
||||
0,
|
||||
(EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize - 1)
|
||||
)
|
||||
) {
|
||||
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;
|
||||
}
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
||||
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
||||
mss->scribing=scribing;
|
||||
mss->slot=slot;
|
||||
mss->spell_id=spellid;
|
||||
|
||||
auto* mss = (MemorizeSpell_Struct*) outapp->pBuffer;
|
||||
|
||||
mss->scribing = scribing;
|
||||
mss->slot = slot;
|
||||
mss->spell_id = spell_id;
|
||||
mss->reduction = reduction;
|
||||
|
||||
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);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@ -932,7 +932,7 @@ public:
|
||||
inline uint32 GetAAPercent() const { return m_epp.perAA; }
|
||||
void SetAATitle(std::string title);
|
||||
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
|
||||
void UseAugmentContainer(int container_slot);
|
||||
|
||||
@ -179,6 +179,10 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_ITEM_CLICK_CAST_CLIENT",
|
||||
"EVENT_DESTROY_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
|
||||
"EVENT_SPELL_EFFECT_BOT",
|
||||
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
||||
@ -2160,6 +2164,19 @@ void PerlembParser::ExportEventVariables(
|
||||
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: {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -124,6 +124,10 @@ typedef enum {
|
||||
EVENT_ITEM_CLICK_CAST_CLIENT,
|
||||
EVENT_DESTROY_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
|
||||
EVENT_SPELL_EFFECT_BOT,
|
||||
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
||||
|
||||
@ -3,18 +3,18 @@
|
||||
|
||||
void command_unscribespell(Client *c, const Seperator *sep)
|
||||
{
|
||||
int arguments = sep->argnum;
|
||||
const auto arguments = sep->argnum;
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
auto target = c;
|
||||
auto t = c;
|
||||
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)) {
|
||||
c->Message(
|
||||
@ -29,16 +29,16 @@ void command_unscribespell(Client *c, const Seperator *sep)
|
||||
|
||||
auto spell_name = GetSpellName(spell_id);
|
||||
|
||||
if (target->HasSpellScribed(spell_id)) {
|
||||
target->UnscribeSpellBySpellID(spell_id);
|
||||
if (t->HasSpellScribed(spell_id)) {
|
||||
t->UnscribeSpellBySpellID(spell_id);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Unscribing {} ({}) for {}.",
|
||||
"Unscribing {} ({}) from {}.",
|
||||
spell_name,
|
||||
spell_id,
|
||||
c->GetTargetDescription(target)
|
||||
c->GetTargetDescription(t, TargetDescriptionType::LCSelf)
|
||||
).c_str()
|
||||
);
|
||||
} else {
|
||||
@ -46,8 +46,8 @@ void command_unscribespell(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} {} not have {} ({}) scribed.",
|
||||
c->GetTargetDescription(target),
|
||||
c == target ? "do" : "does",
|
||||
c->GetTargetDescription(t, TargetDescriptionType::UCYou),
|
||||
c == t ? "do" : "does",
|
||||
spell_name,
|
||||
spell_id
|
||||
).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_cast_client", static_cast<int>(EVENT_ITEM_CLICK_CAST_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_cast_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;
|
||||
@ -292,6 +296,10 @@ LuaParser::LuaParser() {
|
||||
PlayerArgumentDispatch[EVENT_DESTROY_ITEM_CLIENT] = handle_player_destroy_item;
|
||||
PlayerArgumentDispatch[EVENT_TARGET_CHANGE] = handle_player_target_change;
|
||||
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_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
|
||||
void handle_item_click(
|
||||
QuestInterface *parse,
|
||||
|
||||
@ -734,6 +734,15 @@ void handle_player_drop_item(
|
||||
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
|
||||
void handle_item_click(
|
||||
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);
|
||||
m_pp.mem_spells[slot] = 0xFFFFFFFF;
|
||||
|
||||
database.DeleteCharacterMemorizedSpell(CharacterID(), m_pp.mem_spells[slot], slot);
|
||||
|
||||
if(update_client) {
|
||||
if (update_client) {
|
||||
MemorizeSpell(slot, m_pp.mem_spells[slot], memSpellForget);
|
||||
}
|
||||
|
||||
m_pp.mem_spells[slot] = UINT32_MAX;
|
||||
}
|
||||
|
||||
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 (m_pp.spell_book[slot] != 0xFFFFFFFF) {
|
||||
if (m_pp.spell_book[slot] != UINT32_MAX) {
|
||||
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)
|
||||
{
|
||||
if (slot >= EQ::spells::SPELLBOOK_SIZE || slot < 0) {
|
||||
if (!EQ::ValueWithin(slot, 0, (EQ::spells::SPELLBOOK_SIZE - 1))) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogSpells("Spell [{}] erased from spell book slot [{}]", m_pp.spell_book[slot], slot);
|
||||
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
||||
|
||||
if (!defer_save) {
|
||||
database.DeleteCharacterSpell(CharacterID(), m_pp.spell_book[slot], slot);
|
||||
}
|
||||
|
||||
if (update_client && slot < EQ::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize) {
|
||||
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
||||
DeleteSpell_Struct *del = (DeleteSpell_Struct *) outapp->pBuffer;
|
||||
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
||||
auto* del = (DeleteSpell_Struct *) outapp->pBuffer;
|
||||
|
||||
del->spell_slot = slot;
|
||||
del->success = 1;
|
||||
del->success = 1;
|
||||
|
||||
QueuePacket(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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user