rename blueprint to schematic
This commit is contained in:
@@ -358,17 +358,17 @@ ShipsConfig ConfigLoader::loadShips(const std::string& path)
|
||||
def.id = requireString(mt["id"], file, elemPath + ".id");
|
||||
def.availableFromStart = requireBool(mt["available_from_start"], file, elemPath + ".available_from_start");
|
||||
|
||||
// Blueprint
|
||||
// Schematic
|
||||
{
|
||||
const std::string bpPath = elemPath + ".blueprint";
|
||||
const toml::table& bpTable = requireTable(mt["blueprint"], file, bpPath);
|
||||
const std::string bpPath = elemPath + ".schematic";
|
||||
const toml::table& bpTable = requireTable(mt["schematic"], file, bpPath);
|
||||
toml::table& bpMt = const_cast<toml::table&>(bpTable);
|
||||
|
||||
const toml::array& materials = requireArray(bpMt["materials"], file, bpPath + ".materials");
|
||||
def.blueprint.materials = parseIngredients(materials, file, bpPath + ".materials");
|
||||
def.blueprint.playerProductionLevel = static_cast<int>(requireInt(
|
||||
def.schematic.materials = parseIngredients(materials, file, bpPath + ".materials");
|
||||
def.schematic.playerProductionLevel = static_cast<int>(requireInt(
|
||||
bpMt["player_production_level"], file, bpPath + ".player_production_level"));
|
||||
def.blueprint.productionTimeSeconds = requireDouble(
|
||||
def.schematic.productionTimeSeconds = requireDouble(
|
||||
bpMt["production_time_seconds"], file, bpPath + ".production_time_seconds");
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#include "Formula.h"
|
||||
#include "RecipesConfig.h" // for RecipeIngredient
|
||||
|
||||
// Build materials and initial per-blueprint production level
|
||||
// (REQ-BLD-SHIPYARD, REQ-DEF-BLUEPRINT-DROP).
|
||||
struct ShipBlueprint
|
||||
// Build materials and initial per-schematic production level
|
||||
// (REQ-BLD-SHIPYARD, REQ-DEF-SCHEMATIC-DROP).
|
||||
struct ShipSchematic
|
||||
{
|
||||
std::vector<RecipeIngredient> materials;
|
||||
int playerProductionLevel;
|
||||
@@ -65,7 +65,7 @@ struct ShipDef
|
||||
std::string id;
|
||||
bool availableFromStart;
|
||||
|
||||
ShipBlueprint blueprint;
|
||||
ShipSchematic schematic;
|
||||
ShipThreat threat;
|
||||
ShipHealth health;
|
||||
ShipMovement movement;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// Emitted in tick step 9 (Deaths & loot) when a destroyed enemy-defence-station
|
||||
// set awards a blueprint (REQ-DEF-BLUEPRINT-DROP). The UI renders a toast
|
||||
// (REQ-UI-BLUEPRINT-TOAST); wasNewUnlock chooses between the "unlocked" and
|
||||
// "level -> N" wording.
|
||||
struct BlueprintDropEvent
|
||||
{
|
||||
std::string blueprintId; // matches ShipDef::id in the config.
|
||||
int newLevel;
|
||||
bool wasNewUnlock;
|
||||
};
|
||||
@@ -9,7 +9,7 @@ SET(HDRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Port.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/MovementIntent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/FireEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BlueprintDropEvent.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SchematicDropEvent.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
|
||||
14
src/lib/core/SchematicDropEvent.h
Normal file
14
src/lib/core/SchematicDropEvent.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
// Emitted in tick step 9 (Deaths & loot) when a destroyed enemy-defence-station
|
||||
// set awards a schematic (REQ-DEF-SCHEMATIC-DROP). The UI renders a toast
|
||||
// (REQ-UI-SCHEMATIC-TOAST); wasNewUnlock chooses between the "unlocked" and
|
||||
// "level -> N" wording.
|
||||
struct SchematicDropEvent
|
||||
{
|
||||
std::string schematicId; // matches ShipDef::id in the config.
|
||||
int newLevel;
|
||||
bool wasNewUnlock;
|
||||
};
|
||||
@@ -111,7 +111,7 @@ void BuildingSystem::initShipyardBuffers(Building& b) const
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (const RecipeIngredient& ing : def->blueprint.materials)
|
||||
for (const RecipeIngredient& ing : def->schematic.materials)
|
||||
{
|
||||
const ItemType type{ing.item};
|
||||
b.inputBuffer.counts[type] = 0;
|
||||
@@ -666,7 +666,7 @@ void BuildingSystem::tickShipyardProduction(Tick currentTick)
|
||||
|
||||
// Idle: check if all materials are available to start a new cycle.
|
||||
bool inputsOk = true;
|
||||
for (const RecipeIngredient& ing : shipDef->blueprint.materials)
|
||||
for (const RecipeIngredient& ing : shipDef->schematic.materials)
|
||||
{
|
||||
const ItemType type{ing.item};
|
||||
const std::map<ItemType, int>::const_iterator it =
|
||||
@@ -684,7 +684,7 @@ void BuildingSystem::tickShipyardProduction(Tick currentTick)
|
||||
}
|
||||
|
||||
// Consume materials and start the production cycle.
|
||||
for (const RecipeIngredient& ing : shipDef->blueprint.materials)
|
||||
for (const RecipeIngredient& ing : shipDef->schematic.materials)
|
||||
{
|
||||
building.inputBuffer.counts[ItemType{ing.item}] -= ing.amount;
|
||||
}
|
||||
@@ -692,7 +692,7 @@ void BuildingSystem::tickShipyardProduction(Tick currentTick)
|
||||
Production prod;
|
||||
prod.recipeId = building.recipeId;
|
||||
prod.completesAt = currentTick
|
||||
+ secondsToTicks(shipDef->blueprint.productionTimeSeconds);
|
||||
+ secondsToTicks(shipDef->schematic.productionTimeSeconds);
|
||||
building.production = std::move(prod);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
// unknown ids.
|
||||
int demolish(EntityId id);
|
||||
|
||||
// Set the recipe (or blueprint id for shipyard) on a building or queued
|
||||
// Set the recipe (or schematic id for shipyard) on a building or queued
|
||||
// construction site. Clears both buffers on an operational building.
|
||||
void setRecipe(EntityId id, const std::string& recipeId);
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ struct Ship
|
||||
float maxHp;
|
||||
float speedPerTick; // pre-evaluated from speedFormula / kTickRateHz
|
||||
int level;
|
||||
std::string blueprintId;
|
||||
std::string schematicId;
|
||||
|
||||
bool isEnemy = false; // true for enemy-faction ships (used by behavior systems)
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ ShipSystem::ShipSystem(const GameConfig& config,
|
||||
{
|
||||
}
|
||||
|
||||
const ShipDef* ShipSystem::findShipDef(const std::string& blueprintId) const
|
||||
const ShipDef* ShipSystem::findShipDef(const std::string& schematicId) const
|
||||
{
|
||||
for (const ShipDef& def : m_config.ships.ships)
|
||||
{
|
||||
if (def.id == blueprintId)
|
||||
if (def.id == schematicId)
|
||||
{
|
||||
return &def;
|
||||
}
|
||||
@@ -30,10 +30,10 @@ const ShipDef* ShipSystem::findShipDef(const std::string& blueprintId) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EntityId ShipSystem::spawn(const std::string& blueprintId, int level, QVector2D position,
|
||||
EntityId ShipSystem::spawn(const std::string& schematicId, int level, QVector2D position,
|
||||
bool isEnemy)
|
||||
{
|
||||
const ShipDef* def = findShipDef(blueprintId);
|
||||
const ShipDef* def = findShipDef(schematicId);
|
||||
assert(def != nullptr);
|
||||
|
||||
const double x = static_cast<double>(level);
|
||||
@@ -48,7 +48,7 @@ EntityId ShipSystem::spawn(const std::string& blueprintId, int level, QVector2D
|
||||
def->movement.speedFormula.evaluate(x))
|
||||
/ static_cast<float>(kTickRateHz);
|
||||
ship.level = level;
|
||||
ship.blueprintId = blueprintId;
|
||||
ship.schematicId = schematicId;
|
||||
ship.isEnemy = isEnemy;
|
||||
ship.intent = MovementIntent{0, QVector2D(0.0f, 0.0f)};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
std::function<EntityId()> allocateId);
|
||||
|
||||
// isEnemy defaults to false; set true for enemy-faction ships (step 7 wave spawning).
|
||||
EntityId spawn(const std::string& blueprintId, int level, QVector2D position,
|
||||
EntityId spawn(const std::string& schematicId, int level, QVector2D position,
|
||||
bool isEnemy = false);
|
||||
void despawn(EntityId id);
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
bool damageShip(EntityId id, float amount);
|
||||
|
||||
private:
|
||||
const ShipDef* findShipDef(const std::string& blueprintId) const;
|
||||
const ShipDef* findShipDef(const std::string& schematicId) const;
|
||||
|
||||
// True if the entity identified by id is alive and within range of ship.
|
||||
// Searches both the ship list and (for buildings) the supplied BuildingSystem.
|
||||
|
||||
@@ -30,9 +30,9 @@ Simulation::Simulation(GameConfig config, unsigned int seed)
|
||||
[this]() { return allocateId(); },
|
||||
[this](int amount) { m_buildingBlocksStock += amount; },
|
||||
[this](const std::string& id, QVector2D pos) {
|
||||
const std::map<std::string, BlueprintState>::const_iterator it =
|
||||
m_blueprintLevels.find(id);
|
||||
if (it == m_blueprintLevels.end() || !it->second.unlocked)
|
||||
const std::map<std::string, SchematicState>::const_iterator it =
|
||||
m_schematicLevels.find(id);
|
||||
if (it == m_schematicLevels.end() || !it->second.unlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -44,13 +44,13 @@ Simulation::Simulation(GameConfig config, unsigned int seed)
|
||||
m_waveSystem = std::make_unique<WaveSystem>(m_config, m_rng);
|
||||
m_combatSystem = std::make_unique<CombatSystem>(m_config);
|
||||
|
||||
// Initialize blueprint unlock state.
|
||||
// Initialize schematic unlock state.
|
||||
for (const ShipDef& def : m_config.ships.ships)
|
||||
{
|
||||
BlueprintState state;
|
||||
SchematicState state;
|
||||
state.unlocked = def.availableFromStart;
|
||||
state.level = def.availableFromStart ? def.blueprint.playerProductionLevel : 0;
|
||||
m_blueprintLevels[def.id] = state;
|
||||
state.level = def.availableFromStart ? def.schematic.playerProductionLevel : 0;
|
||||
m_schematicLevels[def.id] = state;
|
||||
}
|
||||
|
||||
placeInitialStructures();
|
||||
@@ -82,7 +82,7 @@ void Simulation::reset(unsigned int seed)
|
||||
m_currentEnemyStationIds[0] = kInvalidEntityId;
|
||||
m_currentEnemyStationIds[1] = kInvalidEntityId;
|
||||
m_fireEvents.clear();
|
||||
m_blueprintDropEvents.clear();
|
||||
m_schematicDropEvents.clear();
|
||||
|
||||
m_beltSystem = BeltSystem(m_config.world.beltSpeedTilesPerSecond);
|
||||
m_buildingSystem = std::make_unique<BuildingSystem>(
|
||||
@@ -91,9 +91,9 @@ void Simulation::reset(unsigned int seed)
|
||||
[this]() { return allocateId(); },
|
||||
[this](int amount) { m_buildingBlocksStock += amount; },
|
||||
[this](const std::string& id, QVector2D pos) {
|
||||
const std::map<std::string, BlueprintState>::const_iterator it =
|
||||
m_blueprintLevels.find(id);
|
||||
if (it == m_blueprintLevels.end() || !it->second.unlocked)
|
||||
const std::map<std::string, SchematicState>::const_iterator it =
|
||||
m_schematicLevels.find(id);
|
||||
if (it == m_schematicLevels.end() || !it->second.unlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -105,13 +105,13 @@ void Simulation::reset(unsigned int seed)
|
||||
m_waveSystem = std::make_unique<WaveSystem>(m_config, m_rng);
|
||||
m_combatSystem = std::make_unique<CombatSystem>(m_config);
|
||||
|
||||
m_blueprintLevels.clear();
|
||||
m_schematicLevels.clear();
|
||||
for (const ShipDef& def : m_config.ships.ships)
|
||||
{
|
||||
BlueprintState state;
|
||||
SchematicState state;
|
||||
state.unlocked = def.availableFromStart;
|
||||
state.level = def.availableFromStart ? def.blueprint.playerProductionLevel : 0;
|
||||
m_blueprintLevels[def.id] = state;
|
||||
state.level = def.availableFromStart ? def.schematic.playerProductionLevel : 0;
|
||||
m_schematicLevels[def.id] = state;
|
||||
}
|
||||
|
||||
placeInitialStructures();
|
||||
@@ -290,7 +290,7 @@ void Simulation::tickDeathsAndLoot()
|
||||
// Look up scrap drop amount from config.
|
||||
for (const ShipDef& def : m_config.ships.ships)
|
||||
{
|
||||
if (def.id == s->blueprintId && def.loot.scrapDrop > 0)
|
||||
if (def.id == s->schematicId && def.loot.scrapDrop > 0)
|
||||
{
|
||||
const Tick despawnAt = m_currentTick
|
||||
+ secondsToTicks(m_config.world.scrapDespawnSeconds);
|
||||
@@ -366,11 +366,11 @@ void Simulation::tickDeathsAndLoot()
|
||||
{
|
||||
m_waveSystem->applyPush();
|
||||
placeEnemyStationSet(m_waveSystem->generation());
|
||||
awardBlueprintDrop();
|
||||
awardSchematicDrop();
|
||||
}
|
||||
}
|
||||
|
||||
void Simulation::awardBlueprintDrop()
|
||||
void Simulation::awardSchematicDrop()
|
||||
{
|
||||
std::vector<std::string> ids;
|
||||
ids.reserve(m_config.ships.ships.size());
|
||||
@@ -382,16 +382,16 @@ void Simulation::awardBlueprintDrop()
|
||||
std::uniform_int_distribution<int> dist(0, static_cast<int>(ids.size()) - 1);
|
||||
const std::string chosen = ids[static_cast<std::size_t>(dist(m_rng))];
|
||||
|
||||
BlueprintState& state = m_blueprintLevels.at(chosen);
|
||||
SchematicState& state = m_schematicLevels.at(chosen);
|
||||
const bool wasNew = !state.unlocked;
|
||||
state.unlocked = true;
|
||||
state.level += 1;
|
||||
|
||||
BlueprintDropEvent evt;
|
||||
evt.blueprintId = chosen;
|
||||
SchematicDropEvent evt;
|
||||
evt.schematicId = chosen;
|
||||
evt.newLevel = state.level;
|
||||
evt.wasNewUnlock = wasNew;
|
||||
m_blueprintDropEvents.push_back(evt);
|
||||
m_schematicDropEvents.push_back(evt);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -405,10 +405,10 @@ std::vector<FireEvent> Simulation::drainFireEvents()
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<BlueprintDropEvent> Simulation::drainBlueprintDropEvents()
|
||||
std::vector<SchematicDropEvent> Simulation::drainSchematicDropEvents()
|
||||
{
|
||||
std::vector<BlueprintDropEvent> result;
|
||||
result.swap(m_blueprintDropEvents);
|
||||
std::vector<SchematicDropEvent> result;
|
||||
result.swap(m_schematicDropEvents);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -436,22 +436,22 @@ double Simulation::threatLevel() const
|
||||
return m_waveSystem->threatLevel();
|
||||
}
|
||||
|
||||
int Simulation::blueprintLevel(const std::string& shipId) const
|
||||
int Simulation::schematicLevel(const std::string& shipId) const
|
||||
{
|
||||
const std::map<std::string, BlueprintState>::const_iterator it =
|
||||
m_blueprintLevels.find(shipId);
|
||||
if (it == m_blueprintLevels.end())
|
||||
const std::map<std::string, SchematicState>::const_iterator it =
|
||||
m_schematicLevels.find(shipId);
|
||||
if (it == m_schematicLevels.end())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return it->second.level;
|
||||
}
|
||||
|
||||
bool Simulation::isBlueprintUnlocked(const std::string& shipId) const
|
||||
bool Simulation::isSchematicUnlocked(const std::string& shipId) const
|
||||
{
|
||||
const std::map<std::string, BlueprintState>::const_iterator it =
|
||||
m_blueprintLevels.find(shipId);
|
||||
if (it == m_blueprintLevels.end())
|
||||
const std::map<std::string, SchematicState>::const_iterator it =
|
||||
m_schematicLevels.find(shipId);
|
||||
if (it == m_schematicLevels.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <QPoint>
|
||||
|
||||
#include "BeltSystem.h"
|
||||
#include "BlueprintDropEvent.h"
|
||||
#include "SchematicDropEvent.h"
|
||||
#include "BuildingType.h"
|
||||
#include "EntityId.h"
|
||||
#include "FireEvent.h"
|
||||
@@ -44,17 +44,17 @@ public:
|
||||
// internal queue. Call once per rendered frame (REQ-SHP-FIRING-BEAM).
|
||||
std::vector<FireEvent> drainFireEvents();
|
||||
|
||||
// Returns all blueprint drop events since the last drain.
|
||||
std::vector<BlueprintDropEvent> drainBlueprintDropEvents();
|
||||
// Returns all schematic drop events since the last drain.
|
||||
std::vector<SchematicDropEvent> drainSchematicDropEvents();
|
||||
|
||||
Tick currentTick() const;
|
||||
int buildingBlocksStock() const;
|
||||
bool isGameOver() const;
|
||||
double threatLevel() const;
|
||||
|
||||
// Blueprint state queries.
|
||||
int blueprintLevel(const std::string& shipId) const;
|
||||
bool isBlueprintUnlocked(const std::string& shipId) const;
|
||||
// Schematic state queries.
|
||||
int schematicLevel(const std::string& shipId) const;
|
||||
bool isSchematicUnlocked(const std::string& shipId) const;
|
||||
|
||||
// Checks affordability, deducts building blocks, and places the building.
|
||||
// Returns the new entity id, or kInvalidEntityId if blocks are insufficient.
|
||||
@@ -85,8 +85,8 @@ private:
|
||||
// Tick step 9: remove dead ships and buildings, drop scrap, handle push.
|
||||
void tickDeathsAndLoot();
|
||||
|
||||
// Award a random blueprint drop (REQ-DEF-BLUEPRINT-DROP) and emit the event.
|
||||
void awardBlueprintDrop();
|
||||
// Award a random schematic drop (REQ-DEF-SCHEMATIC-DROP) and emit the event.
|
||||
void awardSchematicDrop();
|
||||
|
||||
GameConfig m_config;
|
||||
std::mt19937 m_rng;
|
||||
@@ -102,13 +102,13 @@ private:
|
||||
EntityId m_playerStation2Id;
|
||||
EntityId m_currentEnemyStationIds[2];
|
||||
|
||||
// Blueprint unlock state (REQ-DEF-BLUEPRINT-DROP).
|
||||
struct BlueprintState
|
||||
// Schematic unlock state (REQ-DEF-SCHEMATIC-DROP).
|
||||
struct SchematicState
|
||||
{
|
||||
bool unlocked;
|
||||
int level;
|
||||
};
|
||||
std::map<std::string, BlueprintState> m_blueprintLevels;
|
||||
std::map<std::string, SchematicState> m_schematicLevels;
|
||||
|
||||
BeltSystem m_beltSystem;
|
||||
std::unique_ptr<BuildingSystem> m_buildingSystem;
|
||||
@@ -118,5 +118,5 @@ private:
|
||||
std::unique_ptr<CombatSystem> m_combatSystem;
|
||||
|
||||
std::vector<FireEvent> m_fireEvents;
|
||||
std::vector<BlueprintDropEvent> m_blueprintDropEvents;
|
||||
std::vector<SchematicDropEvent> m_schematicDropEvents;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ void WaveSystem::tickWaveScheduler(Tick currentTick, ShipSystem& ships,
|
||||
{
|
||||
if (currentTick >= entry.spawnAt)
|
||||
{
|
||||
ships.spawn(entry.blueprintId, entry.level, entry.position,
|
||||
ships.spawn(entry.schematicId, entry.level, entry.position,
|
||||
/*isEnemy=*/true);
|
||||
}
|
||||
else
|
||||
@@ -90,7 +90,7 @@ std::vector<WaveSystem::SpawnEntry> WaveSystem::composeWave(Tick currentTick,
|
||||
// Build eligible ship list with their costs at the current level.
|
||||
struct EligibleShip
|
||||
{
|
||||
std::string blueprintId;
|
||||
std::string schematicId;
|
||||
double cost;
|
||||
};
|
||||
std::vector<EligibleShip> eligible;
|
||||
@@ -100,7 +100,7 @@ std::vector<WaveSystem::SpawnEntry> WaveSystem::composeWave(Tick currentTick,
|
||||
if (cost > 0.0)
|
||||
{
|
||||
EligibleShip es;
|
||||
es.blueprintId = def.id;
|
||||
es.schematicId = def.id;
|
||||
es.cost = cost;
|
||||
eligible.push_back(es);
|
||||
}
|
||||
@@ -151,7 +151,7 @@ std::vector<WaveSystem::SpawnEntry> WaveSystem::composeWave(Tick currentTick,
|
||||
budget -= chosen.cost;
|
||||
|
||||
SpawnEntry entry;
|
||||
entry.blueprintId = chosen.blueprintId;
|
||||
entry.schematicId = chosen.schematicId;
|
||||
entry.level = shipLevel;
|
||||
entry.spawnAt = 0; // set below after all picks are done
|
||||
entry.position = QVector2D(xDist(m_rng),
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
private:
|
||||
struct SpawnEntry
|
||||
{
|
||||
std::string blueprintId;
|
||||
std::string schematicId;
|
||||
int level;
|
||||
Tick spawnAt;
|
||||
QVector2D position;
|
||||
|
||||
Reference in New Issue
Block a user