diff --git a/zone/bot.cpp b/zone/bot.cpp index adcbbdf4b..19e0a0c67 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -3638,41 +3638,45 @@ uint32 Bot::SpawnedBotCount(const uint32 owner_id, uint8 class_id) { return spawned_bot_count; } -void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) { +void Bot::LevelBotWithClient(Client* c, uint8 new_level, bool send_appearance) { // This essentially performs a '#bot update,' with appearance packets, based on the current methods. - // This should not be called outside of Client::SetEXP() due to it's lack of rule checks. - if (client) { - std::list blist = entity_list.GetBotsByBotOwnerCharacterID(client->CharacterID()); + // This should not be called outside of Client::SetEXP() due to its lack of rule checks. - for (auto biter = blist.begin(); biter != blist.end(); ++biter) { - Bot* bot = *biter; + if (c) { + const auto &l = entity_list.GetBotsByBotOwnerCharacterID(c->CharacterID()); - if (bot && (bot->GetLevel() != client->GetLevel())) { - bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code - bot->CalcBotStats(client->GetBotOption(Client::booStatsUpdate)); + for (const auto &e : l) { + if (e && (e->GetLevel() != c->GetLevel())) { + int levels_change = (new_level - e->GetLevel()); - if (sendlvlapp) { - bot->SendLevelAppearance(); + if (levels_change < 0) { + parse->EventBot(EVENT_LEVEL_DOWN, e, nullptr, std::to_string(std::abs(levels_change)), 0); + } else { + parse->EventBot(EVENT_LEVEL_UP, e, nullptr, std::to_string(levels_change), 0); } - // modified from Client::SetLevel() + + e->SetPetChooser(false); // not sure what this does, but was in bot 'update' code + e->CalcBotStats(c->GetBotOption(Client::booStatsUpdate)); + + if (send_appearance) { + e->SendLevelAppearance(); + } + if (!RuleB(Bots, BotHealOnLevel)) { - int mhp = bot->CalcMaxHP(); - if (bot->GetHP() > mhp) { - bot->SetHP(mhp); + const int64 max_hp = e->CalcMaxHP(); + if (e->GetHP() > max_hp) { + e->SetHP(max_hp); } - } - else { - bot->SetHP(bot->CalcMaxHP()); - bot->SetMana(bot->CalcMaxMana()); + } else { + e->SetHP(e->CalcMaxHP()); + e->SetMana(e->CalcMaxMana()); } - bot->SendHPUpdate(); - bot->SendAppearancePacket(AT_WhoLevel, level, true, true); // who level change - bot->AI_AddBotSpells(bot->GetBotSpellID()); + e->SendHPUpdate(); + e->SendAppearancePacket(AT_WhoLevel, new_level, true, true); // who level change + e->AI_AddBotSpells(e->GetBotSpellID()); } } - - blist.clear(); } } diff --git a/zone/lua_parser.cpp b/zone/lua_parser.cpp index 7869eba9a..24f8e6e8e 100644 --- a/zone/lua_parser.cpp +++ b/zone/lua_parser.cpp @@ -341,6 +341,8 @@ LuaParser::LuaParser() { BotArgumentDispatch[EVENT_UNEQUIP_ITEM_BOT] = handle_bot_equip_item; BotArgumentDispatch[EVENT_DAMAGE_GIVEN] = handle_bot_damage; BotArgumentDispatch[EVENT_DAMAGE_TAKEN] = handle_bot_damage; + BotArgumentDispatch[EVENT_LEVEL_UP] = handle_bot_level_up; + BotArgumentDispatch[EVENT_LEVEL_DOWN] = handle_bot_level_down; #endif L = nullptr; diff --git a/zone/lua_parser_events.cpp b/zone/lua_parser_events.cpp index 969518408..5a71f519e 100644 --- a/zone/lua_parser_events.cpp +++ b/zone/lua_parser_events.cpp @@ -2300,4 +2300,30 @@ void handle_bot_damage( lua_setfield(L, -2, "other"); } +void handle_bot_level_up( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob *init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushinteger(L, Strings::ToInt(data)); + lua_setfield(L, -2, "levels_gained"); +} + +void handle_bot_level_down( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob *init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +) { + lua_pushinteger(L, Strings::ToInt(data)); + lua_setfield(L, -2, "levels_lost"); +} + #endif diff --git a/zone/lua_parser_events.h b/zone/lua_parser_events.h index caca824d2..e7005e1ef 100644 --- a/zone/lua_parser_events.h +++ b/zone/lua_parser_events.h @@ -1055,5 +1055,25 @@ void handle_bot_damage( std::vector *extra_pointers ); +void handle_bot_level_up( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + +void handle_bot_level_down( + QuestInterface *parse, + lua_State* L, + Bot* bot, + Mob* init, + std::string data, + uint32 extra_data, + std::vector *extra_pointers +); + #endif #endif