From 8be6e5c62826187abbded90085c333f5f01766fc Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Mon, 5 Dec 2022 17:49:14 -0500 Subject: [PATCH 1/3] [Quest API] Add EVENT_LEVEL_DOWN to Perl/Lua. # Perl - Add `EVENT_LEVEL_DOWN`, exports `$levels_lost`. - Add `$levels_gained` export to `EVENT_LEVEL_UP`. # Lua - Add `event_level_down`, exports `e.levels_lost`. - Add `e.levels_gained` export to `event_level_up`. # Notes - Allows operators to perform actions on level down. - Allows operators to tell how many levels were lost or gained in case people are gaining/losing multiple levels and they want to keep track or use this as a mechanic in their code somewhere. --- zone/embparser.cpp | 20 ++++++++- zone/event_codes.h | 1 + zone/exp.cpp | 83 +++++++++++++++++++++++++------------- zone/lua_general.cpp | 3 +- zone/lua_parser.cpp | 5 ++- zone/lua_parser_events.cpp | 24 +++++++++++ zone/lua_parser_events.h | 18 +++++++++ 7 files changed, 122 insertions(+), 32 deletions(-) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index 9fc72dd8bb..d400c75c8a 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -163,7 +163,8 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_TASK_BEFORE_UPDATE", "EVENT_AA_BUY", "EVENT_AA_GAIN", - "EVENT_PAYLOAD" + "EVENT_PAYLOAD", + "EVENT_LEVEL_DOWN" #ifdef BOTS , "EVENT_SPELL_EFFECT_BOT", @@ -1703,6 +1704,7 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "popupid", data); break; } + case EVENT_ENVIRONMENTAL_DAMAGE: { Seperator sep(data); ExportVar(package_name.c_str(), "env_damage", sep.arg[0]); @@ -1845,6 +1847,7 @@ void PerlembParser::ExportEventVariables( } break; } + case EVENT_DROP_ITEM: { ExportVar(package_name.c_str(), "quantity", item_inst->IsStackable() ? item_inst->GetCharges() : 1); ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name); @@ -1853,17 +1856,20 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "slotid", extradata); break; } + case EVENT_SPAWN_ZONE: { ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID()); ExportVar(package_name.c_str(), "spawned_npc_id", mob->GetNPCTypeID()); break; } + case EVENT_USE_SKILL: { Seperator sep(data); ExportVar(package_name.c_str(), "skill_id", sep.arg[0]); ExportVar(package_name.c_str(), "skill_level", sep.arg[1]); break; } + case EVENT_COMBINE_VALIDATE: { Seperator sep(data); ExportVar(package_name.c_str(), "recipe_id", extradata); @@ -1882,6 +1888,7 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "tradeskill_id", tradeskill_id.c_str()); break; } + case EVENT_BOT_COMMAND: { Seperator sep(data); ExportVar(package_name.c_str(), "bot_command", (sep.arg[0] + 1)); @@ -1891,6 +1898,7 @@ void PerlembParser::ExportEventVariables( ExportVar(package_name.c_str(), "langid", extradata); break; } + case EVENT_WARP: { Seperator sep(data); ExportVar(package_name.c_str(), "from_x", sep.arg[0]); @@ -1981,6 +1989,16 @@ void PerlembParser::ExportEventVariables( break; } + case EVENT_LEVEL_UP: { + ExportVar(package_name.c_str(), "levels_gained", data); + break; + } + + case EVENT_LEVEL_DOWN: { + ExportVar(package_name.c_str(), "levels_lost", data); + break; + } + default: { break; } diff --git a/zone/event_codes.h b/zone/event_codes.h index 802f735b7d..482372348f 100644 --- a/zone/event_codes.h +++ b/zone/event_codes.h @@ -107,6 +107,7 @@ typedef enum { EVENT_AA_BUY, EVENT_AA_GAIN, EVENT_PAYLOAD, + EVENT_LEVEL_DOWN, #ifdef BOTS EVENT_SPELL_EFFECT_BOT, EVENT_SPELL_EFFECT_BUFF_TIC_BOT, diff --git a/zone/exp.cpp b/zone/exp.cpp index e191e412c1..98d47b4e44 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -835,55 +835,78 @@ void Client::SetLevel(uint8 set_level, bool command) } auto outapp = new EQApplicationPacket(OP_LevelUpdate, sizeof(LevelUpdate_Struct)); - LevelUpdate_Struct* lu = (LevelUpdate_Struct*)outapp->pBuffer; + auto* lu = (LevelUpdate_Struct *) outapp->pBuffer; lu->level = set_level; - if(m_pp.level2 != 0) + + if (m_pp.level2 != 0) { lu->level_old = m_pp.level2; - else + } else { lu->level_old = level; + } level = set_level; - if(IsRaidGrouped()) { + if (IsRaidGrouped()) { Raid *r = GetRaid(); - if(r){ + if (r) { r->UpdateLevel(GetName(), set_level); } } - if(set_level > m_pp.level2) { - if(m_pp.level2 == 0) + + if (set_level > m_pp.level2) { + if (m_pp.level2 == 0) { m_pp.points += 5; - else + } else { m_pp.points += (5 * (set_level - m_pp.level2)); + } m_pp.level2 = set_level; } - if(set_level > m_pp.level) { - parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0); - /* QS: PlayerLogLevels */ - if (RuleB(QueryServ, PlayerLogLevels)){ - std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, GetZoneID(), GetInstanceID()); + + if (set_level > m_pp.level) { + const auto export_string = fmt::format("{}", (set_level - m_pp.level)); + parse->EventPlayer(EVENT_LEVEL_UP, this, export_string, 0); + + if (RuleB(QueryServ, PlayerLogLevels)) { + const auto event_desc = fmt::format( + "Leveled UP :: to Level:{} from Level:{} in zoneid:{} instid:{}", + set_level, + m_pp.level, + GetZoneID(), + GetInstanceID() + ); QServ->PlayerLogEvent(Player_Log_Levels, CharacterID(), event_desc); } - } - else if (set_level < m_pp.level){ - /* QS: PlayerLogLevels */ - if (RuleB(QueryServ, PlayerLogLevels)){ - std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, GetZoneID(), GetInstanceID()); + } else if (set_level < m_pp.level) { + const auto export_string = fmt::format("{}", (m_pp.level - set_level)); + parse->EventPlayer(EVENT_LEVEL_DOWN, this, export_string, 0); + + if (RuleB(QueryServ, PlayerLogLevels)) { + const auto event_desc = fmt::format( + "Leveled DOWN :: to Level:{} from Level:{} in zoneid:{} instid:{}", + set_level, + m_pp.level, + GetZoneID(), + GetInstanceID() + ); QServ->PlayerLogEvent(Player_Log_Levels, CharacterID(), event_desc); } } m_pp.level = set_level; - if (command){ + + if (command) { m_pp.exp = GetEXPForLevel(set_level); - Message(Chat::Yellow, "Welcome to level %i!", set_level); + Message(Chat::Yellow, fmt::format("Welcome to level {}!", set_level).c_str()); lu->exp = 0; + } else { + const auto temporary_xp = ( + static_cast(m_pp.exp - GetEXPForLevel(GetLevel())) / + static_cast(GetEXPForLevel(GetLevel() + 1) - GetEXPForLevel(GetLevel())) + ); + lu->exp = static_cast(330.0f * temporary_xp); } - else { - float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel())); - lu->exp = (uint32)(330.0f * tmpxp); - } + QueuePacket(outapp); safe_delete(outapp); SendAppearancePacket(AT_WhoLevel, set_level); // who level change @@ -892,16 +915,18 @@ void Client::SetLevel(uint8 set_level, bool command) CalcBonuses(); - if(!RuleB(Character, HealOnLevel)) { + if (!RuleB(Character, HealOnLevel)) { int mhp = CalcMaxHP(); - if(GetHP() > mhp) + if (GetHP() > mhp) { SetHP(mhp); - } - else { + } + } else { SetHP(CalcMaxHP()); // Why not, lets give them a free heal } - if (RuleI(World, PVPMinLevel) > 0 && level >= RuleI(World, PVPMinLevel) && m_pp.pvp == 0) SetPVP(true); + if (RuleI(World, PVPMinLevel) > 0 && level >= RuleI(World, PVPMinLevel) && m_pp.pvp == 0) { + SetPVP(true); + } DoTributeUpdate(); SendHPUpdate(); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 623f90890b..6e324e6ca5 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -4530,7 +4530,8 @@ luabind::scope lua_register_events() { luabind::value("task_before_update", static_cast(EVENT_TASK_BEFORE_UPDATE)), luabind::value("aa_buy", static_cast(EVENT_AA_BUY)), luabind::value("aa_gain", static_cast(EVENT_AA_GAIN)), - luabind::value("payload", static_cast(EVENT_PAYLOAD)) + luabind::value("payload", static_cast(EVENT_PAYLOAD)), + luabind::value("level_down", static_cast(EVENT_LEVEL_DOWN)) ]; } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 9659c0e44b..46d578e3be 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -150,7 +150,8 @@ const char *LuaEvents[_LargestEventID] = { "event_task_before_update", "event_aa_buy", "event_aa_gain", - "event_payload" + "event_payload", + "event_level_down" }; extern Zone *zone; @@ -262,6 +263,8 @@ LuaParser::LuaParser() { PlayerArgumentDispatch[EVENT_AA_BUY] = handle_player_aa_buy; PlayerArgumentDispatch[EVENT_AA_GAIN] = handle_player_aa_gain; PlayerArgumentDispatch[EVENT_PAYLOAD] = handle_player_payload; + PlayerArgumentDispatch[EVENT_LEVEL_UP] = handle_player_level_up; + PlayerArgumentDispatch[EVENT_LEVEL_DOWN] = handle_player_level_down; ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click; ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index c1438e37ab..b5bf0e6097 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -1092,6 +1092,30 @@ void handle_player_aa_gain( lua_setfield(L, -2, "aa_gained"); } +void handle_player_level_up( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushinteger(L, std::stoul(data)); + lua_setfield(L, -2, "levels_gained"); +} + +void handle_player_level_down( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushinteger(L, std::stoul(data)); + lua_setfield(L, -2, "levels_lost"); +} + // Item void handle_item_click( QuestInterface *parse, diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index 49d05ec82f..b811604a14 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -591,6 +591,24 @@ void handle_player_payload( std::vector *extra_pointers ); +void handle_player_level_up( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + +void handle_player_level_down( + QuestInterface *parse, + lua_State* L, + Client* client, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + // Item void handle_item_click( From 12631f479a49371c00c9405da4f0e43b3d2cf892 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Mon, 5 Dec 2022 17:51:34 -0500 Subject: [PATCH 2/3] Update exp.cpp --- zone/exp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zone/exp.cpp b/zone/exp.cpp index 98d47b4e44..df0faf2760 100644 --- a/zone/exp.cpp +++ b/zone/exp.cpp @@ -916,9 +916,9 @@ void Client::SetLevel(uint8 set_level, bool command) CalcBonuses(); if (!RuleB(Character, HealOnLevel)) { - int mhp = CalcMaxHP(); - if (GetHP() > mhp) { - SetHP(mhp); + const auto max_hp = CalcMaxHP(); + if (GetHP() > max_hp) { + SetHP(max_hp); } } else { SetHP(CalcMaxHP()); // Why not, lets give them a free heal From 9ea072a165e4a74e7201abbe02952ec572a72698 Mon Sep 17 00:00:00 2001 From: Kinglykrab Date: Sat, 10 Dec 2022 19:05:51 -0500 Subject: [PATCH 3/3] Update embparser.cpp --- zone/embparser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/zone/embparser.cpp b/zone/embparser.cpp index d400c75c8a..ed0cde2bd8 100644 --- a/zone/embparser.cpp +++ b/zone/embparser.cpp @@ -164,11 +164,10 @@ const char *QuestEventSubroutines[_LargestEventID] = { "EVENT_AA_BUY", "EVENT_AA_GAIN", "EVENT_PAYLOAD", - "EVENT_LEVEL_DOWN" - #ifdef BOTS - , + "EVENT_LEVEL_DOWN", +#ifdef BOTS "EVENT_SPELL_EFFECT_BOT", - "EVENT_SPELL_EFFECT_BUFF_TIC_BOT" + "EVENT_SPELL_EFFECT_BUFF_TIC_BOT", #endif };