53 lines
2.7 KiB
Python
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)
|