#!/usr/bin/env python3 """PORT missing AVA2 biology stats into unused points (no packet-size change). Existing non-biology monster bonuses keep the current server's combat rule. """ from pathlib import Path import sys source=Path(sys.argv[1]) def edit(name, marker, replacement, tag): p=source/name;s=p.read_bytes() if tag.encode() not in s: if s.count(marker.encode())!=1:raise ValueError('source mismatch: '+name) p.write_bytes(s.replace(marker.encode(),replacement.encode())) edit('char.h','\tPOINT_MELEE_MAGIC_ATT_BONUS_PER = 132,', '\tPOINT_MELEE_MAGIC_ATT_BONUS_PER = 132,\n\t// PORT AVA2 biology points, within the existing 255-point packet.\n\tPOINT_ATTBONUS_STONE = 240,\n\tPOINT_ATTBONUS_BOSS = 241,\n\tPOINT_RESIST_HUMAN = 220,','PORT AVA2 biology points') edit('char.cpp','\t\tcase POINT_ATTBONUS_MONSTER:', '\t\t// PORT AVA2 biology points\n\t\tcase POINT_ATTBONUS_STONE:\n\t\tcase POINT_ATTBONUS_BOSS:\n\t\tcase POINT_RESIST_HUMAN:\n\t\tcase POINT_ATTBONUS_MONSTER:', 'PORT AVA2 biology points') p=source/'battle.cpp';s=p.read_bytes() if b'PORT AVA2 biology combat' not in s: start=s.index(b'int CalcAttBonus(');end=s.index(b'\nint ',start+1) body=s[start:end] body=body.replace(b'\tif (pkVictim->IsNPC())',b''' // PORT AVA2 biology combat: stone bonus precedes race modifiers, as upstream. if (pkVictim->IsStone()) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_STONE)) / 100; \tif (pkVictim->IsNPC())''',1) marker=b'\t\tiAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_MONSTER)) / 100;' assert body.count(marker)==1 body=body.replace(marker,b''' if (pkVictim->GetMobRank() >= MOB_RANK_BOSS && !pkVictim->IsStone()) iAtk += (iAtk * pkAttacker->GetPoint(POINT_ATTBONUS_BOSS)) / 100; int monsterBonus = pkAttacker->GetPoint(POINT_ATTBONUS_MONSTER); if (pkVictim->GetMobRank() >= MOB_RANK_BOSS) { CAffect* research = pkAttacker->FindAffect(AFFECT_COLLECT, POINT_ATTBONUS_MONSTER); if (research) monsterBonus -= research->lApplyValue; } iAtk += (iAtk * monsterBonus) / 100;''') body=body.replace(b'\treturn iAtk;',b''' if (pkAttacker->IsNPC() && pkVictim->IsPC() && pkAttacker->IsRaceFlag(RACE_FLAG_HUMAN)) iAtk -= (iAtk * 30 * pkVictim->GetPoint(POINT_RESIST_HUMAN)) / 10000; if (pkAttacker->IsPC() && pkVictim->IsPC()) iAtk -= (iAtk * pkVictim->GetPoint(POINT_RESIST_HUMAN)) / 100; \treturn iAtk;''',1) s=s[:start]+body+s[end:] if b'#include "affect.h"' not in s:s=s.replace(b'#include "char.h"',b'#include "char.h"\n#include "affect.h"') p.write_bytes(s)