project-mobile-command/src/modules/mc_specific/ExpeditionModule.h
StillHammer 0953451fea Implement 7 modules: 4 core (game-agnostic) + 3 MC-specific
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>
2025-12-02 16:40:54 +08:00

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