85 lines
5.2 KiB
Python
85 lines
5.2 KiB
Python
"""Run actual shared objective selection and map grid methods; no native UI claim."""
|
|
from policy_harness import ROOT, body, run
|
|
|
|
source = ROOT / 'addons/core/Scripts/Game/ERR/ERR_ObjectiveText.c'
|
|
s = body(source, 'protected static string PhaseDescription(')
|
|
s = s.replace('protected ', '').replace('ERR_GameMode mode,', 'ERR_GameMode* mode,')
|
|
s = s.replace('ERR_Phase phase', 'int phase').replace('mode.', 'mode->')
|
|
s = s.replace('array<ERR_LocationComponent>', 'std::vector<ERR_LocationComponent*>')
|
|
s = s.replace('foreach (ERR_LocationComponent location : locations)', 'for (ERR_LocationComponent* location : locations)')
|
|
s = s.replace('location.', 'location->').replace('null', 'nullptr')
|
|
s = s.replace('bool roughRadio;', 'bool roughRadio = false;') # Enforce default initialization
|
|
s = s.replace('.IsEmpty()', '.empty()').replace('string.Format(', 'Format(')
|
|
for scope in ('ERR_Phase', 'ERR_LocationKind', 'Math'):
|
|
s = s.replace(scope + '.', scope + '::')
|
|
coordinate = body(ROOT / 'addons/core/Scripts/Game/ERR/ERR_DiscoveryMap.c', 'static int Coordinate(').replace('Math.', 'Math::')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <cmath>
|
|
using string = std::string;
|
|
namespace ERR_Phase {enum {PREPARING,PRISON,RADIO_SEARCH,RADIO_DEFENCE,EXTRACTION,VICTORY,DEFEAT};}
|
|
namespace ERR_LocationKind {enum {PRISON,RADIO,EXTRACTION,OUTPOST,DEPOT};}
|
|
namespace Math {float Ceil(float v){return std::ceil(v);}float Floor(float v){return std::floor(v);}float Round(float v){return std::round(v);}}
|
|
struct ERR_LocationComponent {int kind,knowledge;int Kind(){return kind;}int Knowledge(){return knowledge;}};
|
|
struct ERR_GameMode {
|
|
int phase=ERR_Phase::RADIO_SEARCH;string error;bool occupied=false;
|
|
std::vector<ERR_LocationComponent*> locations;
|
|
int Phase(){return phase;}string PreparationError(){return error;}
|
|
void Locations(std::vector<ERR_LocationComponent*>& result){result=locations;}
|
|
int RadioFeedback(){return 7;}int DefenceSecondsRemaining(){return 30;}
|
|
bool DefenceOccupied(){return occupied;}float EscapeRadius(){return 9000;}
|
|
};
|
|
string Format(string value,int){return value;}
|
|
string RadioFeedbackMessage(int value){assert(value==7);return "radio feedback boundary";}
|
|
string Extraction(float value){assert(value==9000);return "extraction boundary";}
|
|
struct Actual {
|
|
''' + s + '\n' + coordinate + r'''
|
|
};
|
|
bool has(string text,string part){return text.find(part)!=string::npos;}
|
|
int main(){
|
|
ERR_GameMode mode;ERR_LocationComponent radio{ERR_LocationKind::RADIO,0};
|
|
mode.locations={&radio};
|
|
string unknown=Actual::PhaseDescription(&mode,true);
|
|
assert(has(unknown,"Choose either marked supply cache")&&!has(unknown,"Intel recovered"));
|
|
radio.knowledge=1;
|
|
string rough=Actual::PhaseDescription(&mode,true);
|
|
assert(rough!=unknown&&has(rough,"Intel recovered")&&has(rough,"500 m search square"));
|
|
assert(has(rough,"carried field map")&&has(rough,"different intelligence folder"));
|
|
assert(has(rough,"already recovered cannot provide another clue"));
|
|
assert(Actual::PhaseDescription(&mode,false)==rough); // Same task and guide copy.
|
|
for(int i=0;i<10;i++) assert(Actual::PhaseDescription(&mode,true)==rough);
|
|
radio.knowledge=2;
|
|
string exact=Actual::PhaseDescription(&mode,true);
|
|
assert(exact!=rough&&has(exact,"identified on your map")&&has(exact,"Contact extraction HQ"));
|
|
ERR_LocationComponent roughRadio{ERR_LocationKind::RADIO,1};
|
|
ERR_LocationComponent depot{ERR_LocationKind::DEPOT,1};
|
|
mode.locations={nullptr,&roughRadio,&depot,&radio};
|
|
assert(Actual::PhaseDescription(&mode,true)==exact);
|
|
mode.locations={&radio,&depot,&roughRadio,nullptr};
|
|
assert(Actual::PhaseDescription(&mode,true)==exact);
|
|
radio.knowledge=0;mode.locations={&depot,nullptr,&radio};
|
|
assert(Actual::PhaseDescription(&mode,true)==unknown);
|
|
mode.locations={};assert(Actual::PhaseDescription(&mode,true)==unknown);
|
|
mode.locations={&roughRadio};assert(Actual::PhaseDescription(&mode,true)==rough);
|
|
// Exact production grid dimensions agree with the player-facing 500 m claim.
|
|
assert(Actual::Coordinate(6500.0f,1)==6750);
|
|
assert(Actual::Coordinate(6999.9f,1)==6750);
|
|
assert(Actual::Coordinate(7000.0f,1)==7250);
|
|
assert(Actual::Coordinate(-.1f,1)==-250);
|
|
assert(Actual::Coordinate(6501.4f,2)==6501);
|
|
assert(Actual::PhaseDescription(nullptr,true).empty());
|
|
mode.phase=ERR_Phase::PREPARING;assert(has(Actual::PhaseDescription(&mode,true),"Preparing mission"));
|
|
mode.error="bad";assert(has(Actual::PhaseDescription(&mode,true),"could not start"));
|
|
mode.phase=ERR_Phase::PRISON;assert(has(Actual::PhaseDescription(&mode,true),"Pick the gate lock"));
|
|
mode.phase=ERR_Phase::RADIO_DEFENCE;assert(has(Actual::PhaseDescription(&mode,true),"interrupted"));
|
|
mode.occupied=true;assert(has(Actual::PhaseDescription(&mode,true),"in progress"));
|
|
assert(Actual::PhaseDescription(&mode,false)=="radio feedback boundary");
|
|
mode.phase=ERR_Phase::EXTRACTION;assert(Actual::PhaseDescription(&mode,true)=="extraction boundary");
|
|
mode.phase=ERR_Phase::VICTORY;assert(Actual::PhaseDescription(&mode,true).empty());
|
|
mode.phase=ERR_Phase::DEFEAT;assert(Actual::PhaseDescription(&mode,true).empty());
|
|
}
|
|
''')
|
|
print('PASS: actual rough-intel objective selection, exact precedence, source grid dimensions and unchanged other-phase dispatch; native UI pending')
|