Core Modules (game-agnostic, reusable for WarFactory): - ResourceModule: Inventory, crafting system (465 lines) - StorageModule: Save/load with pub/sub state collection (424 lines) - CombatModule: Combat resolver, damage/armor/morale (580 lines) - EventModule: JSON event scripting with choices/outcomes (651 lines) MC-Specific Modules: - GameModule v2: State machine + event subscriptions (updated) - TrainBuilderModule: 3 wagons, 2-axis balance, performance malus (530 lines) - ExpeditionModule: A→B expeditions, team management, events integration (641 lines) Features: - All modules hot-reload compatible (state preservation) - Pure pub/sub architecture (zero direct coupling) - 7 config files (resources, storage, combat, events, train, expeditions) - 7 test suites (GameModuleTest: 12/12 PASSED) - CMakeLists.txt updated for all modules + tests Total: ~3,500 lines of production code + comprehensive tests 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
183 lines
6.2 KiB
C++
183 lines
6.2 KiB
C++
#pragma once
|
|
|
|
#include <grove/IModule.h>
|
|
#include <grove/IIO.h>
|
|
#include <grove/JsonDataNode.h>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <unordered_map>
|
|
#include <memory>
|
|
|
|
/**
|
|
* ExpeditionModule - Mobile Command expedition system
|
|
*
|
|
* This is an MC-SPECIFIC module that manages expeditions from the train to various
|
|
* destinations. Unlike core modules, this contains Mobile Command specific logic
|
|
* for expeditions, drones, human teams, and scavenging missions.
|
|
*
|
|
* Responsibilities:
|
|
* - Launch expeditions with team composition (humans + drones)
|
|
* - Track expedition progress (A->B movement)
|
|
* - Trigger random events during travel
|
|
* - Handle destination arrival and scavenging
|
|
* - Return to base with loot and casualties
|
|
* - Fully decoupled via pub/sub (no direct module references)
|
|
*
|
|
* Communication:
|
|
* - Publishes: expedition:* topics for state changes
|
|
* - Subscribes: expedition:request_start, event:*, resource:craft_complete
|
|
* - Forwards combat events to CombatModule via pub/sub
|
|
* - Forwards random events to EventModule via pub/sub
|
|
*/
|
|
|
|
namespace mc {
|
|
|
|
/**
|
|
* Team member data structure (MC-SPECIFIC: human crew member)
|
|
*/
|
|
struct TeamMember {
|
|
std::string id; // Unique identifier
|
|
std::string name; // Display name
|
|
std::string role; // leader, soldier, engineer, medic
|
|
int health; // 0-100
|
|
int experience; // Skill level
|
|
|
|
TeamMember() : health(100), experience(0) {}
|
|
};
|
|
|
|
/**
|
|
* Drone data structure (MC-SPECIFIC: aerial/ground drone)
|
|
*/
|
|
struct Drone {
|
|
std::string type; // recon, combat, cargo
|
|
int count; // Number of drones
|
|
bool operational; // All functional?
|
|
|
|
Drone() : count(0), operational(true) {}
|
|
};
|
|
|
|
/**
|
|
* Destination data structure (MC-SPECIFIC: expedition target)
|
|
*/
|
|
struct Destination {
|
|
std::string id; // Unique destination ID
|
|
std::string type; // urban_ruins, military_depot, village, etc.
|
|
int distance; // Distance in meters
|
|
int dangerLevel; // 1-5 danger rating
|
|
std::string lootPotential; // low, medium, high
|
|
float travelSpeed; // m/s travel speed
|
|
std::string description; // Display text
|
|
|
|
Destination() : distance(0), dangerLevel(1), travelSpeed(30.0f) {}
|
|
};
|
|
|
|
/**
|
|
* Expedition supplies (MC-SPECIFIC: resources allocated)
|
|
*/
|
|
struct ExpeditionSupplies {
|
|
int fuel;
|
|
int ammunition;
|
|
int food;
|
|
int medicalSupplies;
|
|
|
|
ExpeditionSupplies() : fuel(0), ammunition(0), food(0), medicalSupplies(0) {}
|
|
};
|
|
|
|
/**
|
|
* Active expedition state (MC-SPECIFIC: ongoing expedition)
|
|
*/
|
|
struct Expedition {
|
|
std::string id; // Unique expedition ID
|
|
std::vector<TeamMember> team; // Human team members
|
|
std::vector<Drone> drones; // Drones assigned
|
|
Destination destination; // Target destination
|
|
ExpeditionSupplies supplies; // Allocated supplies
|
|
float progress; // 0.0 to 1.0 (A->B progress)
|
|
float elapsedTime; // Time since departure (seconds)
|
|
bool atDestination; // Reached target?
|
|
bool returning; // On return journey?
|
|
|
|
Expedition() : progress(0.0f), elapsedTime(0.0f), atDestination(false), returning(false) {}
|
|
};
|
|
|
|
/**
|
|
* ExpeditionModule implementation
|
|
*/
|
|
class ExpeditionModule : public grove::IModule {
|
|
public:
|
|
ExpeditionModule();
|
|
~ExpeditionModule() override;
|
|
|
|
// IModule interface
|
|
void setConfiguration(const grove::IDataNode& config, grove::IIO* io, grove::ITaskScheduler* scheduler) override;
|
|
void process(const grove::IDataNode& input) override;
|
|
void shutdown() override;
|
|
std::unique_ptr<grove::IDataNode> getState() override;
|
|
void setState(const grove::IDataNode& state) override;
|
|
const grove::IDataNode& getConfiguration() override;
|
|
std::unique_ptr<grove::IDataNode> getHealthStatus() override;
|
|
std::string getType() const override;
|
|
bool isIdle() const override;
|
|
|
|
private:
|
|
// Configuration loading
|
|
void loadDestinations(const grove::IDataNode& config);
|
|
void loadExpeditionRules(const grove::IDataNode& config);
|
|
|
|
// Event subscription setup
|
|
void setupEventSubscriptions();
|
|
|
|
// Message processing
|
|
void processMessages();
|
|
|
|
// Event handlers
|
|
void onExpeditionRequestStart(const grove::IDataNode& data);
|
|
void onResourceCraftComplete(const grove::IDataNode& data);
|
|
void onEventOutcome(const grove::IDataNode& data);
|
|
void onCombatEnded(const grove::IDataNode& data);
|
|
|
|
// Expedition management
|
|
bool startExpedition(const std::string& destinationId,
|
|
const std::vector<TeamMember>& team,
|
|
const std::vector<Drone>& drones,
|
|
const ExpeditionSupplies& supplies);
|
|
void updateProgress(Expedition& expedition, float deltaTime);
|
|
void checkForRandomEvents(Expedition& expedition);
|
|
void handleDestinationArrival(Expedition& expedition);
|
|
void returnToBase(Expedition& expedition);
|
|
void distributeRewards(const Expedition& expedition);
|
|
|
|
// Team/drone management
|
|
bool assignTeam(const std::vector<std::string>& humanIds, const std::vector<std::string>& droneTypes);
|
|
void updateAvailableHumans();
|
|
void updateAvailableDrones(const std::string& droneType, int count);
|
|
|
|
// Utility methods
|
|
Destination* findDestination(const std::string& destinationId);
|
|
std::string generateExpeditionId();
|
|
void publishExpeditionState(const Expedition& expedition);
|
|
|
|
private:
|
|
// Services
|
|
grove::IIO* m_io = nullptr;
|
|
grove::ITaskScheduler* m_scheduler = nullptr;
|
|
|
|
// Configuration
|
|
std::unique_ptr<grove::JsonDataNode> m_config;
|
|
std::unordered_map<std::string, Destination> m_destinations;
|
|
int m_maxActiveExpeditions = 1;
|
|
float m_eventProbability = 0.3f;
|
|
float m_suppliesConsumptionRate = 1.0f;
|
|
bool m_debugMode = false;
|
|
|
|
// State
|
|
std::vector<Expedition> m_activeExpeditions;
|
|
std::unordered_map<std::string, TeamMember> m_availableHumans;
|
|
std::unordered_map<std::string, int> m_availableDrones; // type -> count
|
|
int m_nextExpeditionId = 1;
|
|
int m_totalExpeditionsCompleted = 0;
|
|
float m_totalTimeElapsed = 0.0f;
|
|
};
|
|
|
|
} // namespace mc
|