Improve AI garrisons, player recovery and mission administration

This commit is contained in:
2026-09-24 22:12:45 +02:00
parent 1b1a8b5173
commit 2551d171b3
115 changed files with 3622 additions and 547 deletions
+20 -2
View File
@@ -6,10 +6,10 @@ 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};}
namespace ERR_ObserverReason {enum {NONE,SPENT_LIFE,LATE_EXTRACTION,SPAWN_UNAVAILABLE,UNCONSCIOUS};}
'''+source+'''
int main(){
for(int reason=0;reason<5;reason++)for(bool available:{false,true}){
for(int reason=0;reason<4;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);
@@ -25,6 +25,10 @@ int main(){
bool expected=reason!=0&&(!shown||previous!=reason||oldAvailable!=available);
assert(Refresh(shown,previous,reason,oldAvailable,available)==expected);
}
auto casualty=Message(ERR_ObserverReason::UNCONSCIOUS,true);
assert(casualty.find("Your body remains")!=string::npos&&casualty.find("next round")==string::npos);
assert(casualty.find("/esc spectate next")!=string::npos);
assert(Message(ERR_ObserverReason::UNCONSCIOUS,false).find("No conscious teammate")!=string::npos);
// 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));
@@ -44,3 +48,17 @@ assert commands.index('ERR_CycleObserver(direction);')<commands.index('Rpc(ERR_A
admin=body(ROOT/'addons/core/Scripts/Game/ERR/00_Core/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')
view=body(p,'static bool View(').replace('ERR_ObserverReason.','ERR_ObserverReason::')
run('''#include <cassert>
#include <initializer_list>
namespace ERR_ObserverReason{enum{NONE,SPENT_LIFE,LATE_EXTRACTION,SPAWN_UNAVAILABLE,UNCONSCIOUS};}
'''+view+'''
int main(){
for(int reason=0;reason<5;reason++)for(bool active:{false,true})for(bool alive:{false,true})for(bool conscious:{false,true}){
bool wanted=active&&reason!=0&&(reason==4?(alive&&!conscious):!alive);
assert(View(reason,active,alive,conscious)==wanted);
}
}
''')
print('PASS: actual client camera policy closes immediately on healing or mission end; late unconscious metadata cannot keep the view active')