Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
96 lines
5.8 KiB
Python
96 lines
5.8 KiB
Python
"""Run actual shared objective selection and map grid methods; no native UI claim."""
|
|
from policy_harness import ROOT, body, run
|
|
from pathlib import Path
|
|
import os
|
|
|
|
source = Path(os.environ.get('ERR_OBJECTIVE_TEXT_SOURCE', ROOT / 'addons/core/Scripts/Game/ERR/00_Core/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', 'ERR_RadioFeedback', 'Math'):
|
|
s = s.replace(scope + '.', scope + '::')
|
|
coordinate = body(ROOT / 'addons/core/Scripts/Game/ERR/00_Core/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_RadioFeedback {enum {INACTIVE,WAITING,TRANSMITTING,INTERRUPTED};}
|
|
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 PickupStage(){return 0;}
|
|
int startMode=0;int StartMode(){return startMode;}
|
|
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 clue site")&&!has(unknown,"Intel recovered"));
|
|
mode.startMode=1;string crash=Actual::PhaseDescription(&mode,true);
|
|
assert(has(crash,"salvage backpack at the crash site")&&has(crash,unknown)&&!has(crash,"inside the prison"));
|
|
assert(Actual::PhaseDescription(&mode,false)==crash);mode.startMode=0;
|
|
radio.knowledge=1;
|
|
string rough=Actual::PhaseDescription(&mode,true);
|
|
assert(rough!=unknown&&has(rough,"Intel recovered")&&has(rough,"question mark"));
|
|
assert(!has(rough,"search square")&&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')
|
|
|
|
assert "smoke" in body(source,"static string Extraction(")
|
|
assert "kilometres from the prison:" not in body(source,"static string Extraction(")
|