Files
Viano-Core/tests/clientless/test_adventure_pvp.py
T
Nico d6fea6ee68
clang PCH / build (push) Canceled after 0s
GCC PCH / build (push) Canceled after 0s
Add AdventureBot groups, raid preparation and shared travel
Implement native bot recruitment and player admission, leader-owned destinations, intent-specific capacities, preparation scheduling and shared graph and flight travel. Support native group instance visits and separate raid entrances.

Include pending personality-driven faction PvP and solo fleeing, preserving the absolute group fleeing exclusion. Add regression fixtures, migration, documentation and test-server evidence.
2026-10-28 15:00:41 +01:00

68 lines
4.4 KiB
Python

"""Run the production PvP selector against faction, legality and navigation fixtures."""
from pathlib import Path
import subprocess, tempfile
root=Path(__file__).resolve().parents[2]
s=(root/'src/server/game/World/AdventureCombatMgr.cpp').read_text()
a=s.index('Unit* AdventureCombatMgr::PvPTarget');b=s.index('Creature* AdventureCombatMgr::Proactive',a)
code=r'''
#include "AdventureCombatPolicy.h"
#include <cassert>
#include <vector>
#include <unordered_map>
#include <string>
constexpr int ALLIANCE=0,POWER_MANA=0,FACTION_GROUP_MASK_HORDE=4,FACTION_GROUP_MASK_ALLIANCE=2;
struct Player;struct Creature;
struct Faction{unsigned FactionGroup=4;};
struct Guid{int GetCounter(){return 29;}};
struct Unit{unsigned level=60;float distance=10;bool valid=true,hostile=true,reachable=true;Faction faction;
virtual Player* ToPlayer(){return nullptr;}virtual Creature* ToCreature(){return nullptr;}
unsigned getLevel(){return level;}Faction*GetFactionTemplateEntry(){return &faction;}};
struct Creature:Unit{bool controlled=false,elite=false,boss=false;Creature*ToCreature()override{return this;}
bool GetControllingPlayer(){return controlled;}bool isElite(){return elite;}bool isWorldBoss(){return boss;}};
std::vector<Player*> players;std::vector<Creature*> creatures;
struct Player:Unit{int team=1,powerType=1;float health=100;unsigned mana=100;
Player*ToPlayer()override{return this;}int GetTeam(){return team;}Guid GetGUID(){return {};}
float GetHealthPct(){return health;}int GetPowerType(){return powerType;}unsigned GetMaxPower(int){return 100;}unsigned GetPower(int){return mana;}
bool IsHostileTo(Unit*t){return t->hostile;}float GetExactDist(Unit*t){return t->distance;}
void GetPlayerListInGrid(std::vector<Player*>&v,float){v=players;}void GetCreatureListWithEntryInGrid(std::vector<Creature*>&v,int,float){v=creatures;}};
struct Profile{std::unordered_map<std::string,float>Personality{{"adventurousness",1},{"danger_tolerance",1}};}profile;
struct Lua{Profile*GetAdventureProfile(int){return &profile;}}lua;
struct Behavior{std::string intent="adventure";std::string CombatIntent(Player*){return intent;}}behavior;
auto sClientlessLuaEngine=&lua;auto sAdventureBehaviorMgr=&behavior;
float roll=0;float frand(float,float){return roll;}
struct AdventureCombatMgr{bool Valid(Player*,Unit*t,bool)const{return t->valid;}bool Reachable(Player*,Unit*t)const{return t->reachable;}
Unit*PvPTarget(Player*)const;};
'''+s[a:b]+r'''
int main(){
using namespace AdventureCombatPolicy;
assert(PvPLevel(60,55)&&PvPLevel(60,65)&&!PvPLevel(60,54)&&!PvPLevel(60,66));
assert(PvPLevel(1,6)&&!PvPLevel(1,7));
assert(PvPWillingness("rest",1,1)==0&&PvPWillingness("",1,1)==0);
assert(PvPWillingness("adventure",0,1)==0);
assert(PvPWillingness("adventure",1,1)>PvPWillingness("economy",1,1));
Player bot,enemy;bot.team=ALLIANCE;players={&enemy};AdventureCombatMgr mgr;
assert(mgr.PvPTarget(&bot)==&enemy);
for(unsigned level:{54u,66u}){enemy.level=level;assert(!mgr.PvPTarget(&bot));}enemy.level=55;
assert(mgr.PvPTarget(&bot)==&enemy);enemy.level=65;assert(mgr.PvPTarget(&bot)==&enemy);
enemy.distance=50;assert(mgr.PvPTarget(&bot)==&enemy);enemy.distance=50.1;assert(!mgr.PvPTarget(&bot));enemy.distance=10;
enemy.team=ALLIANCE;assert(!mgr.PvPTarget(&bot));enemy.team=1;
enemy.valid=false;assert(!mgr.PvPTarget(&bot));enemy.valid=true;
enemy.reachable=false;assert(!mgr.PvPTarget(&bot));enemy.reachable=true;
enemy.hostile=false;assert(!mgr.PvPTarget(&bot));enemy.hostile=true;
behavior.intent="rest";assert(!mgr.PvPTarget(&bot));behavior.intent="adventure";
bot.health=59;assert(!mgr.PvPTarget(&bot));bot.health=100;
bot.powerType=POWER_MANA;bot.mana=29;assert(!mgr.PvPTarget(&bot));bot.mana=100;
roll=1;assert(!mgr.PvPTarget(&bot));roll=0;
Creature npc;npc.distance=5;creatures={&npc};assert(mgr.PvPTarget(&bot)==&npc);
npc.faction.FactionGroup=8;assert(mgr.PvPTarget(&bot)==&enemy);npc.faction.FactionGroup=4;
npc.elite=true;assert(mgr.PvPTarget(&bot)==&enemy);npc.elite=false;
npc.controlled=true;assert(mgr.PvPTarget(&bot)==&enemy);npc.controlled=false;
npc.level=54;assert(mgr.PvPTarget(&bot)==&enemy);
}
'''
with tempfile.TemporaryDirectory() as d:
src=Path(d)/'pvp.cpp';src.write_text(code);binary=Path(d)/'pvp'
subprocess.run(['g++','-std=c++17','-I'+str(root/'src/server/game/World'),str(src),'-o',str(binary)],check=True)
subprocess.run([str(binary)],check=True)
print('Production PvP selector: level boundaries, radius, factions, native legality, navigation, intent, personality and resources passed.')