Files
EscapistsReintroduced/tests/test_hq_radio_node.py
T

44 lines
3.0 KiB
Python

"""Execute physical node validity, including live consciousness during inventory cache lifetime."""
import os,re
from pathlib import Path
from policy_harness import ROOT,run
p=Path(os.environ.get('ERR_NETWORK_SOURCE', ROOT/'addons/ai/Scripts/Game/ERR/ERR_HQNetwork.c'))
s=p.read_text();a=s.index('bool Valid(');b=s.index('{',a);end=b+1;depth=1
while depth:depth+=(s[end]=='{')-(s[end]=='}');end+=1
code=s[a:end].replace('ERR_GameMode factions = ERR_GameMode.Get()', 'ERR_GameMode* factions = ERR_GameMode::Get()')
code=code.replace('ERR_Actors.', 'ERR_Actors::').replace('ERR_HQRadio.', 'ERR_HQRadio::').replace('Group.', 'Group->').replace('factions.', 'factions->')
code=code.replace('GetGame().GetWorld().GetWorldTime()', 'nativeNow')
run(r'''
#include <cassert>
struct SCR_AIGroup{int players=0,faction=1;int GetPlayerCount(bool){return players;}int GetFaction(){return faction;}};
struct IEntity{bool canFight=true;int capability=2;SCR_AIGroup*group=nullptr;};
struct ERR_GameMode{static inline ERR_GameMode*current=nullptr;static ERR_GameMode*Get(){return current;}int EnemyFaction(){return 1;}};
namespace ERR_Actors{bool CanFight(IEntity*a){return a&&a->canFight;}SCR_AIGroup*Group(IEntity*a){return a?a->group:nullptr;}}
namespace ERR_HQRadio{int reads=0;int Capability(IEntity*a){reads++;return a->capability;}}
float nativeNow=0;
struct Node{IEntity*Carrier=nullptr;SCR_AIGroup*Group=nullptr;float m_CheckedAt=-1;int m_LiveCapability=0;
'''+code+r'''
};
int main(){
ERR_GameMode mode;ERR_GameMode::current=&mode;SCR_AIGroup group,other;IEntity actor;actor.group=&group;
Node node;node.Carrier=&actor;node.Group=&group;
assert(node.Valid(true)&&ERR_HQRadio::reads==1);
nativeNow=100;assert(node.Valid()&&ERR_HQRadio::reads==1);
// No cached inventory result can make an incapacitated/dead carrier valid.
actor.canFight=false;nativeNow=200;assert(!node.Valid()&&ERR_HQRadio::reads==1);
actor.canFight=true;assert(node.Valid(true)&&ERR_HQRadio::reads==1);
// Exact original group/faction and absence of player members are always checked live.
actor.group=&other;assert(!node.Valid());actor.group=&group;
group.players=1;assert(!node.Valid());group.players=0;
group.faction=2;assert(!node.Valid());group.faction=1;
ERR_GameMode::current=nullptr;assert(!node.Valid());ERR_GameMode::current=&mode;
// Inventory capability is intentionally sampled at most once per second.
actor.capability=1;nativeNow=999;assert(node.Valid(true));assert(ERR_HQRadio::reads==1);
nativeNow=1000;assert(!node.Valid(true));assert(node.Valid());assert(ERR_HQRadio::reads==2);
actor.capability=0;nativeNow=2000;assert(!node.Valid());assert(ERR_HQRadio::reads==3);
actor.capability=2;nativeNow=1500;assert(node.Valid(true));assert(ERR_HQRadio::reads==4); // rewind refresh
node.Carrier=nullptr;assert(!node.Valid());node.Carrier=&actor;node.Group=nullptr;assert(!node.Valid());
}
''')
print('PASS: actual radio node rejects current incapacitation, death, ownership and faction changes despite cached inventory; one-second capability refresh remains explicit')