Files
jakub 6a667d8deb Capture current mission, AI, map and administration development
Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
2026-10-13 22:52:53 +02:00

68 lines
4.8 KiB
Python

"""Production PiP acquisition, fallback and cleanup with native rendering doubled."""
from policy_harness import ROOT, body, run
import re
p=ROOT/'addons/core/Scripts/Game/ERR/00_Core/ERR_ObserverScope.c'
def adapt(s):
s=s.replace('protected ', '').replace('null','nullptr')
for cls in ('SCR_2DPIPSightsComponent','SCR_2DOpticsComponent','SCR_2DPIPSightsComponentClass'):
s=re.sub(r'\b'+cls+r' (?=\w)',cls+'* ',s).replace(cls+'.',cls+'::')
for name in ('pip','m_Optic','data'):
s=s.replace(name+'.',name+'->')
s=s.replace('GetOwner().','GetOwner()->').replace('SCR_Global.', 'SCR_Global::')
s=s.replace('GetGame().GetWorld().GetWorldTime()', 'clockNow')
return s
owned='\n'.join(adapt(body(p,x)) for x in ('bool ERR_ObserverPIPBegin(', 'void ERR_ObserverPIPEnd('))
display='\n'.join(adapt(body(p,x)) for x in ('bool Render(SCR_2DOpticsComponent',))
# Select the display's Close, not the 2D fallback's identically named method.
text=p.read_text();a=text.index('class ERR_ObserverPIPDisplay');close=text.index(' void Close()',a);end=text.index(' void ~',close)
display+='\n'+adapt(text[close:end])
run(r'''
#include <cassert>
using vector=float;float clockNow=1000;
namespace SCR_Global{bool flat=false;bool IsScope2DEnabled(){return flat;}}
struct Owner{bool deleted=false;bool IsDeleted(){return deleted;}};
struct SCR_2DPIPSightsComponentClass{int index=8;int GetCameraIndex(){return index;}static auto Cast(SCR_2DPIPSightsComponentClass*p){return p;}};
struct SCR_2DOpticsComponent{virtual ~SCR_2DOpticsComponent(){};};
struct SCR_2DPIPSightsComponent:SCR_2DOpticsComponent{
bool m_ERRObserverPIPOwned=false,m_bPIPIsEnabled=false,m_PIPCamera=false,m_wRenderTargetTextureWidget=false,m_pMaterial=true;
int m_iReticleScaleIndex=0,m_iReticleColorIndex=1,m_iEdgeMinIndex=2,m_iEdgeMaxIndex=3,m_iVignettePowerIndex=4;
float m_fScopeRadius=.01;inline static bool active=false;bool fail=false,renderWorks=true;int creates=0,destroys=0,renders=0;Owner owner;SCR_2DPIPSightsComponentClass settings;
static auto Cast(SCR_2DOpticsComponent*p){return dynamic_cast<SCR_2DPIPSightsComponent*>(p);}
Owner*GetOwner(){return &owner;}auto GetComponentData(Owner*){return &settings;}static bool IsPIPActive(){return active;}
void Destroy(){destroys++;m_PIPCamera=false;m_wRenderTargetTextureWidget=false;}
void SetPIPEnabled(bool enable){if(enable){creates++;if(fail){m_wRenderTargetTextureWidget=true;return;}m_bPIPIsEnabled=true;m_PIPCamera=true;m_wRenderTargetTextureWidget=true;active=true;}else{Destroy();active=false;m_bPIPIsEnabled=false;}}
bool ERR_ObserverPIPRender(vector*,vector*,float,float,vector,vector,float){renders++;return renderWorks;}
'''+owned+r'''
};
struct Display{
SCR_2DPIPSightsComponent*m_Optic=nullptr,*m_FailedOptic=nullptr;float m_RetryAt=0;
'''+display+r'''
};
int main(){
float camera[4]={};
{SCR_2DPIPSightsComponent optic;Display d;
assert(d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==1&&optic.renders==1);
assert(d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==1);
d.Close();d.Close();assert(optic.destroys==1&&!optic.active&&!optic.m_ERRObserverPIPOwned);}
{SCR_2DPIPSightsComponent a,b;Display d;
assert(d.Render(&a,camera,camera,12,6,0,0,.5));assert(d.Render(&b,camera,camera,12,6,0,0,.5));
assert(a.destroys==1&&b.creates==1);assert(!d.Render(nullptr,camera,camera,12,6,0,0,.5));assert(b.destroys==1);}
{SCR_2DPIPSightsComponent optic;Display d;optic.fail=true;
assert(!d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==1&&optic.destroys==1&&!optic.m_wRenderTargetTextureWidget);
clockNow=2999;assert(!d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==1);
clockNow=3000;optic.fail=false;assert(d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==2);d.Close();}
{SCR_2DPIPSightsComponent optic;Display d;SCR_Global::flat=true;
assert(!d.Render(&optic,camera,camera,12,6,0,0,.5)&&optic.creates==0);SCR_Global::flat=false;
assert(d.Render(&optic,camera,camera,12,6,0,0,.5));SCR_Global::flat=true;
assert(!d.Render(&optic,camera,camera,12,6,0,0,.5)&&optic.destroys==1);SCR_Global::flat=false;}
{SCR_2DPIPSightsComponent optic;Display d;optic.active=true;
assert(!d.Render(&optic,camera,camera,12,6,0,0,.5)&&optic.creates==0&&optic.destroys==0);d.Close();assert(optic.active);optic.active=false;}
{SCR_2DPIPSightsComponent optic;optic.settings.index=0;assert(!optic.ERR_ObserverPIPBegin()&&optic.creates==0);
optic.settings.index=8;optic.m_iReticleScaleIndex=-1;assert(!optic.ERR_ObserverPIPBegin()&&optic.creates==0);}
{SCR_2DPIPSightsComponent optic;Display d;optic.renderWorks=false;
assert(!d.Render(&optic,camera,camera,12,6,0,0,.5));assert(optic.creates==1&&optic.destroys==1&&!optic.active);}
}
''')
print('PASS: production PiP lifecycle preserves other camera owners, retains successful rendering, cleans partial failures/target switches/exits, bounds retries and respects 2D settings')