Validate independent packed addons and complete physical mortar salvos
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
"""Execute the actual spectator message/refresh policy; no native UI claim."""
|
||||
from policy_harness import ROOT,body,run
|
||||
p=ROOT/'addons/core/Scripts/Game/ERR/ERR_Observer.c'
|
||||
source=body(p,'static string Message(')+'\n'+body(p,'static bool Refresh(')
|
||||
source=source.replace('ERR_ObserverReason.','ERR_ObserverReason::')
|
||||
run('''#include <cassert>
|
||||
#include <string>
|
||||
using string=std::string;
|
||||
namespace ERR_ObserverReason {enum {NONE,SPENT_LIFE,LATE_EXTRACTION,SPAWN_UNAVAILABLE};}
|
||||
'''+source+'''
|
||||
int main(){
|
||||
for(int reason=0;reason<5;reason++)for(bool available:{false,true}){
|
||||
auto message=Message(reason,available);
|
||||
if(reason==0){assert(message.empty());continue;}
|
||||
assert(message.find("next round")!=string::npos);
|
||||
assert((message.find("/esc spectate next")!=string::npos)==available);
|
||||
assert((message.find("/esc spectate previous")!=string::npos)==available);
|
||||
assert((message.find("No survivor is currently available")!=string::npos)==!available);
|
||||
assert((message.find("when one becomes available")!=string::npos)==!available);
|
||||
}
|
||||
assert(Message(1,true).find("life for this round has been used")!=string::npos);
|
||||
assert(Message(2,true).find("Extraction has started")!=string::npos);
|
||||
assert(Message(3,true).find("could not be spawned")!=string::npos);
|
||||
for(bool shown:{false,true})for(int previous=0;previous<5;previous++)for(int reason=0;reason<5;reason++)for(bool oldAvailable:{false,true})for(bool available:{false,true}){
|
||||
bool expected=reason!=0&&(!shown||previous!=reason||oldAvailable!=available);
|
||||
assert(Refresh(shown,previous,reason,oldAvailable,available)==expected);
|
||||
}
|
||||
// Stable monitoring must not repeat. Availability and reason changes do refresh.
|
||||
assert(!Refresh(true,1,1,true,true));assert(Refresh(true,1,1,true,false));
|
||||
assert(Refresh(true,1,1,false,true));assert(Refresh(true,1,2,true,true));
|
||||
// Camera close/reopen resets shown; missing hint manager must not consume it.
|
||||
assert(Refresh(false,1,1,true,true));assert(Refresh(false,1,1,false,false));
|
||||
}
|
||||
''')
|
||||
monitor=body(p,'protected void ERR_UpdateObserverClient(')
|
||||
assert 'bool survivorAvailable = m_ERRObservedId != RplId.Invalid();' in monitor
|
||||
assert 'if (!hints) return;' in monitor
|
||||
assert monitor.index('if (!hints) return;')<monitor.index('hints.ShowCustom(')<monitor.index('m_ERRObserverReady = true;')
|
||||
assert 'm_ERRShownObserverReason = m_ERRObserverReason;' in monitor and 'm_ERRShownObserverAvailable = survivorAvailable;' in monitor
|
||||
assert 'm_ERRObserverReady = false;' in body(p,'protected void ERR_CloseObserverCamera(')
|
||||
assert 'CallLater' not in monitor, 'No additional timer belongs to guidance'
|
||||
commands=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_PlayerAdminCommands.c','protected void ERR_OnCommand(')
|
||||
assert commands.index('ERR_CycleObserver(direction);')<commands.index('Rpc(ERR_Request, arguments);')
|
||||
admin=body(ROOT/'addons/core/Scripts/Game/ERR/ERR_AdminService.c','void Execute(')
|
||||
assert 'if (!authorized) { replies.Insert("Administrator access required."); return; }' in admin
|
||||
print('PASS: actual reason/availability guidance and refresh matrix; no-target copy omits cycling, hint retry retained, existing command/admin paths unchanged; native UI pending')
|
||||
Reference in New Issue
Block a user