Files
Viano-Core/tests/clientless/test_adventure_equipment_maintenance.py
T
Nico a758239da9
clang PCH / build (push) Canceled after 0s
GCC PCH / build (push) Canceled after 0s
Implement AdventureBot class rotations, group roles and instance encounters
2026-10-28 22:37:18 +01:00

56 lines
4.4 KiB
Python

"""Execute the shared production birth/maintenance equipment eligibility."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
s=(root/'src/server/game/World/AdventureGeneratorMgr.cpp').read_text()
a=s.index(' float EquipmentScore(');b=s.index('{',a);e=b+1;n=1
while n:n+=(s[e]=='{')-(s[e]=='}');e+=1
code=r'''
#include "AdventureGeneratorPolicy.h"
#include <cassert>
#include <cmath>
#include <limits>
using uint32=unsigned;using Archetype=AdventureGeneratorPolicy::Archetype;
enum{CLASS_WARRIOR=1,INVTYPE_2HWEAPON=17,EQUIP_ERR_OK=0,ITEM_FLAG_CONJURED=1,HOLIDAY_NONE=0,ITEM_CLASS_ARMOR=4,
EQUIPMENT_SLOT_NECK=1,EQUIPMENT_SLOT_BACK=14,EQUIPMENT_SLOT_FINGER1=10,EQUIPMENT_SLOT_FINGER2=11,EQUIPMENT_SLOT_TRINKET1=12,EQUIPMENT_SLOT_TRINKET2=13,EQUIPMENT_SLOT_OFFHAND=16,
ITEM_MOD_DODGE_RATING=13,ITEM_MOD_PARRY_RATING=14,ITEM_MOD_MASTERY_RATING=49,ITEM_MOD_STAMINA=7,ITEM_MOD_RESILIENCE_RATING=35,ITEM_MOD_STRENGTH=4,ITEM_MOD_AGILITY=3,ITEM_MOD_INTELLECT=5,ITEM_MOD_ATTACK_POWER=38,ITEM_MOD_RANGED_ATTACK_POWER=39,ITEM_MOD_SPIRIT=6,ITEM_MOD_MANA=0,ITEM_MOD_MANA_REGENERATION=43,ITEM_MOD_SPELL_POWER=45,ITEM_MOD_SPELL_PENETRATION=47,MAX_ITEM_PROTO_STATS=1};
struct Player{unsigned level=60;bool usable=true;unsigned getLevel(){return level;}unsigned CalculateTalentsPoints(){return level>=70?41:26;}template<class T>unsigned CanUseItem(T*){return usable?0:1;}};
struct Effect{unsigned SpellID;};
struct ItemTemplate{
unsigned type=1;unsigned GetInventoryType()const{return type;}bool fits=true;unsigned quality=3,ilevel=80,cls=4,sub=4,flags=0,holiday=0,map=0,duration=0,rep=0,area=0,prop=0,suffix=0;int req=60,stat=4;float value=10;std::vector<Effect>Effects;
int GetRequiredLevel()const{return req;}unsigned GetQuality()const{return quality;}unsigned GetBaseItemLevel()const{return ilevel;}
unsigned GetDuration()const{return duration;}unsigned GetFlags()const{return flags;}unsigned GetRequiredReputationFaction()const{return rep;}unsigned GetArea()const{return area;}unsigned GetMap()const{return map;}unsigned GetHolidayID()const{return holiday;}unsigned GetRandomProperty()const{return prop;}unsigned GetRandomSuffix()const{return suffix;}
unsigned GetClass()const{return cls;}unsigned GetSubClass()const{return sub;}int GetItemStatType(unsigned)const{return stat;}float GetStatValue(unsigned,Player*)const{return value;}
};
bool Slot(ItemTemplate const*i,unsigned,Archetype const&){return i->fits;}
bool UsefulSpell(unsigned id,Archetype const&){return id==42;}
'''+s[a:e]+r'''
int main(){Player p;ItemTemplate item;auto a=AdventureGeneratorPolicy::Archetypes()[0];
auto check=[&]{return EquipmentScore(&p,&item,4,a);};assert(check()==100);
a.Spec=1;item.type=17;assert(!std::isfinite(check()));item.type=1;assert(std::isfinite(check()));a.Spec=0;
item.sub=1;assert(!std::isfinite(check()));item.sub=4; // wearable cloth is wrong for this warrior
item.stat=ITEM_MOD_INTELLECT;assert(!std::isfinite(check()));item.stat=4;
item.Effects={{0xFFFFFFFFu}};assert(!std::isfinite(check()));item.Effects={{42}};assert(std::isfinite(check()));
item.req=61;assert(!std::isfinite(check()));item.req=60;
item.flags=ITEM_FLAG_CONJURED;assert(!std::isfinite(check()));item.flags=0;
item.rep=1;assert(!std::isfinite(check()));item.rep=0;
item.map=719;assert(!std::isfinite(check()));item.map=0;
item.holiday=1;assert(!std::isfinite(check()));item.holiday=0;
p.usable=false;assert(!std::isfinite(check()));p.usable=true;
item.fits=false;assert(!std::isfinite(check()));item.fits=true;
p.level=85;item.req=85;item.ilevel=416;item.quality=3;assert(!std::isfinite(check()));
item.quality=4;assert(std::isfinite(check()));item.ilevel=346;assert(!std::isfinite(check()));item.ilevel=416;
item.quality=5;assert(!std::isfinite(check()));item.quality=4;
a.Spec=2;item.stat=ITEM_MOD_DODGE_RATING;assert(check()==426);
}
'''
# Both birth candidate ranking and retention of already equipped items consume this exact rule.
assert 'EquipmentScore(p,current->GetTemplate(),slot,a)' in s
assert 'auto score=EquipmentScore(p,item,slot,a)' in s
with tempfile.TemporaryDirectory() as d:
p=Path(d);(p/'test.cpp').write_text(code)
subprocess.run(['g++','-std=c++17','-I',str(root/'src/server/game/World'),str(p/'test.cpp'),'-o',str(p/'test')],check=True)
subprocess.run([str(p/'test')],check=True)
print('Production gear maintenance: same birth/retention gate rejects wrong armor/stats, malformed effects, level, temporary, reputation, map, holiday, native-use and slot mismatches passed')