88 lines
3.9 KiB
C++
88 lines
3.9 KiB
C++
// The byte-level adapter between a live `ServerPlayer` and game/effects' PlayerEconomyState,
|
|
// plus the region table and struct describers the B2 hook declares.
|
|
//
|
|
// Split out of the hook (as B1 split `budget_inputs`) so that every offset, every float32
|
|
// round-trip and every field the tech-effect callback writes can be exercised on the host
|
|
// against a synthetic player buffer, without the game and without a VM window. The hook
|
|
// itself then only has to resolve the tech id and delegate to the game's tech tree.
|
|
//
|
|
// The regions do not cover the whole object: they are exactly the field groups the callback
|
|
// writes, one region each, so a divergence names the field. `Views` is the indirection that
|
|
// lets the same code run against the scratch copies (compare mode) and against the live
|
|
// object (replace mode).
|
|
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
#include "game/effects/tech_effects.h"
|
|
#include "game/sim/species.h"
|
|
#include "shim/trace/tracer.h"
|
|
|
|
namespace shim::hooks::techfx {
|
|
|
|
enum RegionId {
|
|
R_SUIT = 0, // SuitTol, MaxOH
|
|
R_RESMOD, // ResMod
|
|
R_ABILITIES, // RebAI .. harcc
|
|
R_MODIFIERS, // pddm .. CstT
|
|
R_MASKS, // design-option masks A / B
|
|
R_TRANSLATION, // sticky translation mask
|
|
R_VACCINES, // HasVac, HasImm, NPTrk
|
|
R_RESEARCH_TARGET, // ResT
|
|
R_NODEBORE_PTR, // pointer to the node-bore block
|
|
R_INCMOD, // IncMod
|
|
R_CAPTURE, // cdp
|
|
R_SPECIES_FLAGS, // flags[7] + count
|
|
R_ROLL, // pending plague-cure roll + AIRebellion*
|
|
R_NODEBORE, // the 3-word node-bore block itself (behind R_NODEBORE_PTR)
|
|
R_RNG, // the strategic Mars::RNG object (behind player+8 -> server+0x16c)
|
|
kRegionCount
|
|
};
|
|
|
|
struct RegionDef {
|
|
const char* name;
|
|
std::uint32_t off; // from the ServerPlayer base; meaningless for R_NODEBORE
|
|
std::size_t size;
|
|
trace::Tv (*describe)(const void* data, std::size_t size, unsigned inline_max);
|
|
};
|
|
|
|
extern const RegionDef kRegions[kRegionCount];
|
|
|
|
// The last byte the region table reaches, for one readability check up front.
|
|
std::size_t PlayerSpan();
|
|
|
|
// Where each region's bytes live for this call. A null entry means "not present": only
|
|
// R_NODEBORE is ever legitimately null (no bore drive researched yet).
|
|
struct Views {
|
|
void* base[kRegionCount] = {};
|
|
// The generator's live address, for the describer's next-pointer arithmetic: `next` is a
|
|
// heap address, so it is reported as its index into mt, which is what it means and what
|
|
// survives being rewritten by a reimplementation.
|
|
void* liveRng = nullptr;
|
|
|
|
// Point every region at its offset inside a live (or synthetic) player object, and
|
|
// R_NODEBORE at whatever the block pointer holds.
|
|
static Views OverPlayer(void* player);
|
|
};
|
|
|
|
// Seed our model from the pre-call field values. `species` is read from the live object by
|
|
// the caller because no region covers it (the callback never writes it).
|
|
sots::effects::PlayerEconomyState ReadPlayerState(const Views& v, sots::sim::Species species);
|
|
|
|
// Write back exactly the words the callback writes. The node-bore block is only written
|
|
// where it already exists.
|
|
void WritePlayerState(const Views& v, const sots::effects::PlayerEconomyState& s);
|
|
|
|
// The callback's first act when the completing definition is the current research target:
|
|
// clear the target and the pending-roll byte. Returns whether the roll was pending (the
|
|
// roll itself draws randomness, so a differential run reports it instead of running it).
|
|
bool ClearResearchTargetIfMatched(const Views& v, const void* def);
|
|
|
|
// The two design-option masks, written straight into R_MASKS.
|
|
void WriteDesignOptionMasks(const Views& v, std::uint32_t a, std::uint32_t b);
|
|
|
|
// The describer needs the live generator address; set it before a snapshot is described.
|
|
void SetLiveRngBase(const void* p);
|
|
|
|
} // namespace shim::hooks::techfx
|