"""Execute opt-in diagnostic helper/wrappers with transparent native superclass doubles.""" import os,re from pathlib import Path from policy_harness import ROOT,body,run p=Path(os.environ.get('ERR_NATIVE_RANDOM_RADIUS_SOURCE',ROOT/'addons/core/Scripts/Game/ERR/40_Chat/ERR_NativeRandomRadiusTrace.c')) source=p.read_text() assert '#ifdef WORKBENCH' in source and source.rstrip().endswith('#endif') # The diagnosis must not repair/clamp/reroll values or bypass native execution. for token in ('Math.Clamp','GenerateRandomPointInRadius(', 'SetVariableOut(', 'SetOrigin(', 'CallLater(', 'Math.Random'): assert token not in source,token def adapt(s): s=s.replace('override ','').replace('protected ','').replace('out vector','vector&') s=s.replace('AIAgent owner','AIAgent* owner').replace('IEntity controlledEntity','Entity* controlledEntity') for name in ('owner','controlledEntity'):s=s.replace(name+'.',name+'->') for name in ('ERR_NativeRandomRadiusTrace','ENodeResult','System','Debug','string','vector'):s=s.replace(name+'.',name+'::') s=s.replace('null','nullptr').replace('Node node','Node* node').replace('node.','node->') s=re.sub(r'\b(bool|int|float) (\w+);',r'\1 \2{};',s) return s helper=adapt(body(p,'class ERR_NativeRandomRadiusTrace')).replace('class ERR_','struct ERR_').replace('static bool s_','static inline bool s_').replace('static int s_','static inline int s_')+';' classes={'SCR_AIGetRandomPoint':'PointBase','SCR_AIGetRandomLookPosition':'LookBase','SCR_AICalculateNextCombatMovePos':'CombatBase','SCR_AIGetRandomPointWithExclude':'ExcludeBase','SCR_RecoilCameraShakeParams':'RecoilBase'} wrappers=[] for cls,base in classes.items(): raw=body(p,'modded class '+cls) assert raw.count('super.')==1,(cls,'must call superclass exactly once') code=adapt(raw).replace('modded class '+cls,'struct '+cls+' : '+base).replace('super.',base+'::')+';' wrappers.append(code) run(r''' #include #include #include #include struct string:std::string{using std::string::string;templatestatic string Format(const char*s,T...){return s;}}; struct vector{float x=0,y=0,z=0;vector()=default;vector(float a,float b,float c):x(a),y(b),z(c){}bool operator==(vector b)const{return x==b.x&&y==b.y&&z==b.z;}static float Distance(vector a,vector b){return std::sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));}float Length()const{return Distance(*this,{});}static const vector Zero;};const vector vector::Zero{}; struct Entity{vector position;int reads=0;vector GetOrigin(){reads++;return position;}}; struct AIAgent{Entity*entity=nullptr;int reads=0;Entity*GetControlledEntity(){reads++;return entity;}}; enum class ENodeResult{FAIL,SUCCESS,RUNNING}; struct System{static inline bool present=false;static inline string value="";static inline int reads=0;static bool GetCLIParam(const char*,string&v){reads++;v=value;return present;}}; struct Debug{static inline int dumps=0;static void DumpStack(){dumps++;}}; struct Row{int count;string context;AIAgent*owner;float inner,outer;string details,stack;};std::vector rows; void PrintFormat(const char*,int count,string context,AIAgent*owner,float inner,float outer,string details,string stack){rows.push_back({count,context,owner,inner,outer,details,stack});} struct Node{int stackReads=0;void GetCallstackStr(string&out){stackReads++;out="native-tree-context";}}; struct SimBase:Node{int supers=0;AIAgent*lastOwner=nullptr;float lastDt=-1;ENodeResult next=ENodeResult::SUCCESS;vector output{19,23,29};void called(AIAgent*o,float dt){supers++;lastOwner=o;lastDt=dt;output={31,37,41};}}; struct PointBase:SimBase{float m_ExclusionRadius=7,m_Radius=9,innerAfter=0,outerAfter=0;ENodeResult EOnTaskSimulate(AIAgent*o,float dt){called(o,dt);m_ExclusionRadius=innerAfter;m_Radius=outerAfter;return next;}}; struct LookBase:SimBase{float m_fTangent=.5;static inline string PORT_IN_POS="InPos";bool hasInput=true;vector input;int inputReads=0;bool GetVariableIn(string,vector&v){inputReads++;v=input;return hasInput;}ENodeResult EOnTaskSimulate(AIAgent*o,float dt){called(o,dt);return next;}}; struct CombatBase:Node{int supers=0;float lastDistance=-1;vector lastCenter,output{43,47,53};vector RandomizeDestinationPos(float distance,vector centerPos){supers++;lastDistance=distance;lastCenter=centerPos;return output;}}; struct ExcludeBase:Node{int supers=0;bool result=true;vector output{59,61,67},lastInput,lastOrigin,lastExclude;float lastRadius=-1,lastExcludeRadius=-1;int lastIterations=-1;bool FindPosition2D(vector&randomPos,vector randomSphereOrigin,float randomSphereRadius,vector excludeSphereOrigin=vector::Zero,float excludeRadius=0,int iterationCount=50){supers++;lastInput=randomPos;lastOrigin=randomSphereOrigin;lastRadius=randomSphereRadius;lastExclude=excludeSphereOrigin;lastExcludeRadius=excludeRadius;lastIterations=iterationCount;randomPos=output;return result;}}; struct RecoilBase{int supers=0;vector lastMin,lastMax,output{71,73,79};bool lastUniform=false;vector RandomVectorSphere(vector min,vector max,bool uniform=true){supers++;lastMin=min;lastMax=max;lastUniform=uniform;return output;}}; '''+helper+'\n'.join(wrappers)+r''' void reset(bool enabled){ERR_NativeRandomRadiusTrace::s_Checked=false;ERR_NativeRandomRadiusTrace::s_Enabled=false;ERR_NativeRandomRadiusTrace::s_Count=0;System::present=enabled;System::value=enabled?"1":"";System::reads=0;Debug::dumps=0;rows.clear();} void count(int n){assert((int)rows.size()==n&&Debug::dumps==n&&ERR_NativeRandomRadiusTrace::s_Count==n);} int main(){ Entity actor;AIAgent owner;owner.entity=&actor; // Disabled diagnostics are transparent even when every radius is zero. reset(false);SCR_AIGetRandomPoint point;SCR_AIGetRandomLookPosition look;SCR_AICalculateNextCombatMovePos combat;SCR_AIGetRandomPointWithExclude exclude;SCR_RecoilCameraShakeParams recoil;vector pos{1,2,3},center{4,5,6}; assert(point.EOnTaskSimulate(&owner,.25)==ENodeResult::SUCCESS&&point.supers==1&&point.output==vector(31,37,41)); assert(look.EOnTaskSimulate(&owner,.5)==ENodeResult::SUCCESS&&look.supers==1&&look.output==vector(31,37,41)); assert(!owner.reads&&!actor.reads&&!look.inputReads); assert(combat.RandomizeDestinationPos(0,center)==combat.output&&combat.supers==1&&combat.lastCenter==center&&combat.lastDistance==0); assert(exclude.FindPosition2D(pos,center,0,center,0,0)&&pos==exclude.output&&exclude.supers==1&&exclude.lastInput==vector(1,2,3)); assert(recoil.RandomVectorSphere({}, {},false)==recoil.output&&recoil.supers==1&&!recoil.lastUniform);count(0);assert(System::reads==1&&!point.stackReads&&!look.stackReads&&!combat.stackReads&&!exclude.stackReads); System::present=true;System::value="1";point.EOnTaskSimulate(&owner,1);count(0);assert(System::reads==1); // cached disabled flag for(const char*flag:{"0","true","","2"}){reset(true);System::value=flag;assert(!ERR_NativeRandomRadiusTrace::CanTrace());count(0);} // Point uses actual post-super fields, only on success, with exact owner/result. reset(true);point.innerAfter=point.outerAfter=0;point.next=ENodeResult::FAIL;int calls=point.supers;assert(point.EOnTaskSimulate(&owner,.75)==ENodeResult::FAIL&&point.supers==calls+1);count(0); point.next=ENodeResult::RUNNING;assert(point.EOnTaskSimulate(&owner,.8)==ENodeResult::RUNNING);count(0); point.next=ENodeResult::SUCCESS;point.m_Radius=10;point.m_ExclusionRadius=2;assert(point.EOnTaskSimulate(&owner,.9)==ENodeResult::SUCCESS);count(1);assert(point.stackReads==1&&rows.back().stack=="native-tree-context");assert(rows.back().owner==&owner&&point.lastOwner==&owner&&point.lastDt==.9f); point.outerAfter=.001;point.EOnTaskSimulate(&owner,1);count(1);point.outerAfter=0;point.innerAfter=.001;point.EOnTaskSimulate(&owner,1);count(1); // Look observes only native-valid controlled entity/input, preserves failures. reset(true);owner.reads=actor.reads=0;look.inputReads=0;actor.position={1,2,3};look.input=actor.position;look.next=ENodeResult::RUNNING;calls=look.supers; assert(look.EOnTaskSimulate(&owner,1)==ENodeResult::RUNNING&&look.supers==calls+1);count(1);assert(owner.reads==1&&actor.reads==1&&look.inputReads==1); look.input={2,2,3};look.EOnTaskSimulate(&owner,1);count(1);look.m_fTangent=0;look.EOnTaskSimulate(&owner,1);count(2); look.hasInput=false;look.next=ENodeResult::FAIL;assert(look.EOnTaskSimulate(&owner,1)==ENodeResult::FAIL);count(2);look.hasInput=true;owner.entity=nullptr;look.EOnTaskSimulate(&owner,1);count(2);owner.entity=&actor; // Combat calls native randomization once with unmodified arguments/result. reset(true);calls=combat.supers;assert(combat.RandomizeDestinationPos(0,center)==combat.output&&combat.supers==calls+1);count(1); assert(combat.RandomizeDestinationPos(1,center)==combat.output&&combat.lastDistance==1);count(1);combat.RandomizeDestinationPos(-1,center);count(1); // Exclusion native branch: same centers uses exclusion radius even at0iterations; // different centers withpositiveexclusion loops only wheniterations>0. reset(true);pos={8,9,10};calls=exclude.supers;exclude.result=false; assert(!exclude.FindPosition2D(pos,center,0,center,0,0)&&exclude.supers==calls+1&&pos==exclude.output&&exclude.lastInput==vector(8,9,10));count(1); exclude.FindPosition2D(pos,center,0,center,1,50);count(1); vector different{11,12,13};exclude.FindPosition2D(pos,center,0,different,1,0);count(1); exclude.FindPosition2D(pos,center,0,different,1,-1);count(1); exclude.FindPosition2D(pos,center,0,different,1,1);count(2); exclude.FindPosition2D(pos,center,0,different,0,0);count(3); exclude.FindPosition2D(pos,center,.001,different,0,1);count(3); exclude.FindPosition2D(pos,center,0,different,1.e-9f,0);count(3); // native inner is tiny positive, notzero assert(exclude.lastOrigin==center&&exclude.lastExclude==different&&exclude.lastRadius==0&&exclude.lastExcludeRadius==1.e-9f&&exclude.lastIterations==0); // Recoil values, uniform flag, result and one native draw remain untouched. reset(true);calls=recoil.supers;assert(recoil.RandomVectorSphere({},{},false)==recoil.output&&recoil.supers==calls+1&&!recoil.lastUniform);count(1);assert(rows.back().stack.empty()); recoil.RandomVectorSphere({.001,0,0},{},true);count(1);recoil.RandomVectorSphere({},{0,0,.001},true);count(1);assert(recoil.lastMin==vector::Zero&&recoil.lastMax==vector(0,0,.001)&&recoil.lastUniform); // Shared cap includes allwrappers and prevents further observational inputreads. reset(true);for(int i=0;i<20;i++)combat.RandomizeDestinationPos(0,center);count(16);for(int i=0;i<16;i++)assert(rows[i].count==i+1);assert(System::reads==1); int ownerReads=owner.reads,positionReads=actor.reads,inputReads=look.inputReads;calls=look.supers;look.EOnTaskSimulate(&owner,1);assert(look.supers==calls+1&&owner.reads==ownerReads&&actor.reads==positionReads&&look.inputReads==inputReads);count(16); point.innerAfter=point.outerAfter=0;point.next=ENodeResult::SUCCESS;calls=point.supers;point.EOnTaskSimulate(&owner,1);assert(point.supers==calls+1);count(16); calls=exclude.supers;exclude.FindPosition2D(pos,center,0,center,0,0);assert(exclude.supers==calls+1&&pos==exclude.output);count(16); calls=recoil.supers;recoil.RandomVectorSphere({},{});assert(recoil.supers==calls+1);count(16); } ''') print('PASS: actual five random-radius diagnostic wrappers, disabled transparency, cached opt-in, exact zero and exclusion branch, native arguments/returns/outarg preservation, single superclass call and shared16-log cap')