Files
metin2-client/tools/server/biolog/tests/test_combat.py
T

53 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""Compile the actual patched CalcAttBonus and assert the biology bonuses in real arithmetic."""
from pathlib import Path
import re,subprocess,sys,tempfile
source=Path(sys.argv[1]).read_bytes().decode('latin1');start=source.index('int CalcAttBonus(');end=source.index('\nvoid Item_GetDamage',start);body=source[start:end]
assert 'PORT AVA2 biology combat' in body
names=sorted(set(re.findall(r'\b(?:POINT_|RACE_FLAG_|JOB_|UNIQUE_ITEM_)[A-Z_0-9]+',body)))
code=r'''
#include <map>
#include <set>
#include <cassert>
#include <cstdio>
NAMES
enum {MOB_RANK_BOSS=4,AFFECT_COLLECT=515};
struct CAffect {int lApplyValue;};
struct Character {
bool pc=true,stone=false;int rank=1,job=-1;
std::map<int,int> points;std::set<int> races;CAffect research{0};
bool IsPC(){return pc;}bool IsNPC(){return !pc;}bool IsStone(){return stone;}
int GetPoint(int n){return points[n];}int GetJob(){return job;}int GetMobRank(){return rank;}
int GetMarriageBonus(int){return 0;}bool IsRaceFlag(int n){return races.count(n);}
CAffect* FindAffect(int,int){return research.lApplyValue?&research:nullptr;}
};
struct CHARACTER_MANAGER {
static CHARACTER_MANAGER& instance(){static CHARACTER_MANAGER m;return m;}
int GetMobDamageRate(Character*){return 100;}
};
typedef Character* LPCHARACTER;
BODY
int main(){
Character attacker,victim;victim.pc=false;victim.stone=true;
attacker.points[POINT_ATTBONUS_STONE]=10;
assert(CalcAttBonus(&attacker,&victim,1000)==1100);
victim.stone=false;victim.rank=MOB_RANK_BOSS;attacker.points.clear();attacker.points[POINT_ATTBONUS_BOSS]=6;
assert(CalcAttBonus(&attacker,&victim,1000)==1060);
// AVA2's research monster bonus excludes bosses; unrelated existing equipment still applies.
attacker.points.clear();attacker.points[POINT_ATTBONUS_MONSTER]=15;attacker.research.lApplyValue=5;
assert(CalcAttBonus(&attacker,&victim,1000)==1100);
victim.rank=1;assert(CalcAttBonus(&attacker,&victim,1000)==1150);
attacker.points.clear();attacker.research.lApplyValue=0;victim.pc=true;victim.points[POINT_RESIST_HUMAN]=10;
assert(CalcAttBonus(&attacker,&victim,1000)==900);
attacker.pc=false;attacker.races.insert(RACE_FLAG_HUMAN);
assert(CalcAttBonus(&attacker,&victim,1000)==970);
attacker.races.clear();assert(CalcAttBonus(&attacker,&victim,1000)==1000);
std::puts("PASS: patched combat applies stone/boss bonuses, excludes research monster bonus on bosses, and applies PvP/NPC human resistance");
}
'''
code=code.replace('NAMES','enum {'+', '.join([names[0]+'=1']+names[1:])+'};').replace('BODY',body)
with tempfile.TemporaryDirectory(prefix='bio-combat-') as folder:
folder=Path(folder);(folder/'test.cpp').write_text(code)
subprocess.run(['c++','-std=c++17',str(folder/'test.cpp'),'-o',str(folder/'test')],check=True)
subprocess.run([str(folder/'test')],check=True)