106 lines
4.4 KiB
C++
106 lines
4.4 KiB
C++
// B4 adapter: the ServerSystem state `ServerSystem::ProcessTurn` reads and writes <-> our
|
|
// game::sim colony call.
|
|
//
|
|
// The hook (src/shim/hooks/colony_turn.cpp) snapshots a ServerSystem into a ColonySnapshot
|
|
// using only the field offsets in the generated header. This file is the pure half: it turns
|
|
// a snapshot into sim::ColonyTurnState + sim::ColonyTurnInputs and describes both for the
|
|
// trace. It has no OS or game dependencies, so it builds and is unit-tested on the host.
|
|
//
|
|
// INPUT BOUNDARY. `ServerSystem::ProcessTurn` is a dispatcher: most of a colony turn happens
|
|
// in callees this milestone does not model. What our side reproduces is the set of words the
|
|
// dispatcher writes *itself*, plus the two bonus-pool helpers and the system-bonus accrual
|
|
// whose arithmetic game/sim already carries. Everything else -- the plague pass, imperial and
|
|
// civilian growth, the resource debit, the in-orbit refuel, slaves, rebellion, and the morale
|
|
// events the addiction sweep raises -- is an input: those fields are not declared regions, so
|
|
// the harness never compares them, and the trace records them as arguments instead.
|
|
//
|
|
// The one live value our side asks the game for is the imperial carrying capacity, which the
|
|
// accrual reads. `ServerSystem::MaxPop` is read-only, so the hook calls the game's own copy on
|
|
// the live system rather than re-deriving a capacity from species and group tables that this
|
|
// milestone does not model -- the same delegation B3 makes to `TechTree::Cost`.
|
|
#pragma once
|
|
|
|
#include <cstdint>
|
|
|
|
#include "game/sim/colony.h"
|
|
#include "shim/trace/emitter.h"
|
|
|
|
namespace shim::hooks {
|
|
|
|
constexpr int kColonySpeciesSlots = 7;
|
|
|
|
// Everything the adapter needs out of a ServerSystem, its owner and the server.
|
|
struct ColonySnapshot {
|
|
// identity
|
|
std::int32_t systemIndex = 0;
|
|
std::int32_t ownerIndex = -1; // -1 when unowned
|
|
std::int32_t ownerSpecies = -1;
|
|
bool owned = false;
|
|
bool independent = false;
|
|
bool homeSystem = false;
|
|
bool stable = false; // the game's own IsStable verdict
|
|
std::int32_t playerCount = 0;
|
|
std::int32_t currentTurn = 0; // ModCount
|
|
std::int32_t turnAcquired = 0; // TAcq
|
|
|
|
// the mutable colony words the pass owns
|
|
float infra = 0;
|
|
float infraBonus = 0;
|
|
std::int32_t pop = 0;
|
|
std::int32_t popBonus = 0;
|
|
std::int32_t turnsDeveloping = 0;
|
|
std::int32_t totalResources = 0;
|
|
std::uint8_t growthHalted[3] = {0, 0, 0};
|
|
std::uint64_t battles = 0;
|
|
std::uint32_t battlesMask = 0;
|
|
std::uint64_t recon = 0;
|
|
std::uint32_t reconMask = 0;
|
|
|
|
// the addiction sweep's inputs
|
|
std::int32_t addictionStart[kColonySpeciesSlots] = {};
|
|
std::uint8_t civilianPresent[kColonySpeciesSlots] = {};
|
|
std::uint8_t temperance[kColonySpeciesSlots] = {};
|
|
std::int32_t addictionPhase2Start = 0;
|
|
std::int32_t addictionPhase3Start = 0;
|
|
|
|
// measured live rather than re-derived (see the header comment)
|
|
std::int64_t imperialCapacity = 0;
|
|
bool ownerSpeciesEligible = true;
|
|
|
|
// context that is recorded but never compared
|
|
std::int32_t planetSize = 0;
|
|
float suitability = 0;
|
|
std::int32_t resources = 0;
|
|
std::int32_t rebelMask = 0;
|
|
std::int32_t rngLeftIn = 0;
|
|
std::uint32_t fpuControlWord = 0;
|
|
std::int32_t buildQueueDepth = -1;
|
|
};
|
|
|
|
// Pinned: the snapshot is memcpy'd into a declared region, so a padding surprise would shift
|
|
// every field the describer reports (M2's +0x14 lesson).
|
|
static_assert(sizeof(ColonySnapshot) % 8 == 0, "ColonySnapshot has no tail padding surprise");
|
|
|
|
// The tuning keys the modelled steps read. The shim fills these from the loaded globals; a
|
|
// host test fills them directly.
|
|
struct ColonyTuning {
|
|
int SYSTEMBONUS_MINTURNS = 0;
|
|
double SYSTEMBONUS_POPBONUS = 0;
|
|
double SYSTEMBONUS_POPBONUS_INC = 0;
|
|
double SYSTEMBONUS_INFRABONUS = 0;
|
|
double SYSTEMBONUS_INFRABONUS_INC = 0;
|
|
};
|
|
|
|
sots::sim::TuningTable ToTuningTable(const ColonyTuning& t);
|
|
sots::sim::ColonyTurnState ToColonyTurnState(const ColonySnapshot& s);
|
|
sots::sim::ColonyTurnInputs ToColonyTurnInputs(const ColonySnapshot& s);
|
|
|
|
// Write a finished state back over a snapshot, so the hook can lay the result out into the
|
|
// scratch regions field by field.
|
|
void ApplyColonyTurnState(const sots::sim::ColonyTurnState& st, ColonySnapshot& s);
|
|
|
|
// Trace describers.
|
|
trace::Tv DescribeColonySnapshot(const void* data, std::size_t size, unsigned inline_max);
|
|
trace::Tv DescribeMoraleEvents(const sots::sim::ColonyTurnResult& r);
|
|
|
|
} // namespace shim::hooks
|