Implement AdventureBot profiles, daily planning and population management
This commit is contained in:
1 parent
d6fea6ee68
commit
d3273c677e
61 files changed
+2280
-116
No files matched your search
@@ -8,6 +8,7 @@
|
||||
#include "AdventureInteractionMgr.h"
|
||||
#include "AdventureGroupMgr.h"
|
||||
#include "AdventureGeneratorMgr.h"
|
||||
#include "AdventurePopulationMgr.h"
|
||||
#include "AdventureSupplyMgr.h"
|
||||
#include "AdventureSocialActions.h"
|
||||
#include "Config.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "Random.h"
|
||||
#include <lua.hpp>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
@@ -201,7 +203,7 @@ std::vector<ClientlessWeightedMount> ReadMountDictionary(lua_State* L, int movem
|
||||
{
|
||||
lua_Integer id = lua_tointeger(L, -2);
|
||||
lua_Number weight = lua_tonumber(L, -1);
|
||||
if (id > 0 && id <= 0xFFFFFFFFll && weight > 0.0)
|
||||
if (id > 0 && id <= 0xFFFFFFFFll && std::isfinite(weight) && weight > 0.0 && weight <= 1000000.0)
|
||||
mounts.push_back({ uint32(id), uint32(std::max<lua_Number>(1.0, weight)) });
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
@@ -220,11 +222,13 @@ public:
|
||||
sClientlessLuaEngine->ExecuteAdventureScript(player);
|
||||
sAdventureBehaviorMgr->Online(player);
|
||||
sAdventureSupplyMgr->Online(player);
|
||||
sAdventurePopulationMgr->Online(player);
|
||||
}
|
||||
void OnIntentChanged(Player* player, ClientlessIntent const* intent) override
|
||||
{ sAdventureBehaviorMgr->IntentChanged(player, intent); }
|
||||
void Update(Player* player, uint32 diff) override
|
||||
{
|
||||
sAdventurePopulationMgr->Maintain(player,diff);
|
||||
if(sAdventureSupplyMgr->Update(player,diff,sAdventureCombatMgr->Busy(player)))return;
|
||||
if(!sAdventureCombatMgr->Update(player,diff) && !sAdventureInteractionMgr->Update(player,diff))
|
||||
sAdventureBehaviorMgr->Update(player,diff);
|
||||
@@ -238,7 +242,7 @@ public:
|
||||
void OnDamageTaken(Player* player, Unit* attacker, uint32 damage) override
|
||||
{ sAdventureCombatMgr->DamageTaken(player, attacker, damage); }
|
||||
void OnPlayerLogout(Player* player) override
|
||||
{ sAdventureInteractionMgr->Offline(player); sAdventureSupplyMgr->Offline(player); sAdventureCombatMgr->Offline(player); sAdventureBehaviorMgr->Offline(player); }
|
||||
{ sAdventurePopulationMgr->Offline(player); sAdventureInteractionMgr->Offline(player); sAdventureSupplyMgr->Offline(player); sAdventureCombatMgr->Offline(player); sAdventureBehaviorMgr->Offline(player); }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -394,6 +398,19 @@ bool ClientlessLuaEngine::LoadAdventureProfile(Player* player)
|
||||
profile.HomeRegion = ReadStringField(_state, -1, "home_region");
|
||||
profile.Background = ReadStringField(_state, -1, "background");
|
||||
profile.Vocation = ReadStringField(_state, -1, "vocation");
|
||||
profile.ProfileVersion = uint32(std::clamp(ReadFloatField(_state,-1,"profile_version",0),0.0f,100.0f));
|
||||
profile.Level = uint32(std::clamp(ReadFloatField(_state,-1,"level",0),0.0f,85.0f));
|
||||
profile.Class = uint32(std::clamp(ReadFloatField(_state,-1,"class",0),0.0f,11.0f));
|
||||
profile.Specialization = uint32(std::clamp(ReadFloatField(_state,-1,"specialization",0),0.0f,2.0f));
|
||||
lua_getfield(_state,-1,"seed");
|
||||
if(lua_isinteger(_state,-1)){auto value=lua_tointeger(_state,-1);if(value>=0 && value<=0xFFFFFFFFll)profile.Seed=uint32(value);}
|
||||
lua_pop(_state,1);
|
||||
profile.Role = ReadStringField(_state,-1,"role","damage");
|
||||
if(profile.Role!="tank" && profile.Role!="healer" && profile.Role!="damage")profile.Role="damage";
|
||||
profile.HomeZone = uint32(std::max(0.0f,ReadFloatField(_state,-1,"home_zone",0)));
|
||||
profile.HomeCapital = uint32(std::max(0.0f,ReadFloatField(_state,-1,"home_capital",0)));
|
||||
profile.FavoriteZone = uint32(std::max(0.0f,ReadFloatField(_state,-1,"favorite_zone",0)));
|
||||
profile.FavoriteRegion = ReadStringField(_state,-1,"favorite_region");
|
||||
}
|
||||
lua_pop(_state, 1);
|
||||
|
||||
@@ -408,11 +425,38 @@ bool ClientlessLuaEngine::LoadAdventureProfile(Player* player)
|
||||
profile.GroundMounts = ReadMountDictionary(_state, -1);
|
||||
profile.CanFreeFly = ReadBoolField(_state, -1, "can_free_fly", false);
|
||||
profile.FlightMounts = ReadMountDictionary(_state, -1, "flight_mounts");
|
||||
profile.Companions = ReadMountDictionary(_state,-1,"companions");
|
||||
profile.CompanionSpell = uint32(std::max(0.0f, ReadFloatField(_state, -1, "companion_spell", 0)));
|
||||
profile.CompanionLeashItem = uint32(std::max(0.0f, ReadFloatField(_state, -1, "companion_leash_item", 0)));
|
||||
}
|
||||
lua_pop(_state, 1);
|
||||
|
||||
lua_getfield(_state,rootTable,"inventory");
|
||||
if(lua_istable(_state,-1))
|
||||
{
|
||||
lua_getfield(_state,-1,"keep_items");
|
||||
if(lua_istable(_state,-1))for(size_t i=1;i<=lua_rawlen(_state,-1);++i)
|
||||
{
|
||||
lua_rawgeti(_state,-1,i);auto id=lua_tointeger(_state,-1);
|
||||
if(id>0 && id<=0xFFFFFFFFll)profile.KeepItems.insert(uint32(id));
|
||||
lua_pop(_state,1);
|
||||
}
|
||||
lua_pop(_state,1);
|
||||
}
|
||||
lua_pop(_state,1);
|
||||
lua_getfield(_state,rootTable,"zone_affinity");
|
||||
if(lua_istable(_state,-1))
|
||||
{
|
||||
lua_pushnil(_state);
|
||||
while(lua_next(_state,-2))
|
||||
{
|
||||
auto id=lua_tointeger(_state,-2);auto weight=lua_tonumber(_state,-1);
|
||||
if(lua_isinteger(_state,-2) && lua_isnumber(_state,-1) && id>0 && id<=0xFFFFFFFFll && std::isfinite(weight))
|
||||
profile.ZoneAffinity[uint32(id)]=float(std::clamp(weight,0.0,100.0));
|
||||
lua_pop(_state,1);
|
||||
}
|
||||
}
|
||||
lua_pop(_state,1);
|
||||
profile.Personality = ReadFloatDictionary(_state, rootTable, "personality");
|
||||
profile.RegionAffinity = ReadFloatDictionary(_state, rootTable, "region_affinity");
|
||||
profile.ActivityAffinity = ReadFloatDictionary(_state, rootTable, "activity_affinity");
|
||||
@@ -501,6 +545,18 @@ uint32 ClientlessLuaEngine::SelectGroundMountDisplayId(uint32 characterGuid) con
|
||||
return profile->GroundMounts.back().DisplayId;
|
||||
}
|
||||
|
||||
uint32 ClientlessLuaEngine::SelectCompanionSpell(uint32 guid) const
|
||||
{
|
||||
auto profile=GetAdventureProfile(guid);
|
||||
if(!profile)return 0;
|
||||
uint32 total=0;
|
||||
for(auto const& pet:profile->Companions)total+=pet.Weight;
|
||||
if(!total)return profile->CompanionSpell;
|
||||
auto roll=urand(1,total);
|
||||
for(auto const& pet:profile->Companions){if(roll<=pet.Weight)return pet.DisplayId;roll-=pet.Weight;}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ClientlessLuaEngine::PrepareGroundMount(Player* player, float travelDistance, char const* context)
|
||||
{
|
||||
if (!player || !player->IsInWorld())
|
||||
|
||||
Reference in new issue
Block a user