#pragma once #include #include "cpputils/unique_ptr.hpp" #include "entities/game_object.hpp" #include "levels/goal.hpp" #include "levels/level.hpp" #include "levels/scene.hpp" #include "levels/progression.hpp" #include "utils/globals.hpp" namespace Nimbin { class CelebrationSystem; class HintSystem; class ParticleSystem; class Plate; class WordAiSystem; struct GameContext; namespace Level { struct StepLedger { DynArray buttons_pressed; DynArray ai_defeated; DynArray picked_up; bool compile_ok {false}; bool dropped {false}; bool shot {false}; void clear() { buttons_pressed.clear(); ai_defeated .clear(); picked_up .clear(); compile_ok = false; dropped = false; shot = false; } }; struct StepPlate { Plate* plate; std::string tag; }; class Director { DynArray _step_plates; DynArray _step_scenery; StepLedger _ledger; cpputils::unique_ptr _runner; double _step_age { 0.0 }; mutable const Level::Step* _detail_built_for { nullptr }; mutable DynArray _detail_tokens; void spawn_Grants (GameContext& ctx); void setup_Scene (GameContext& ctx, const Scene::Data& scene); void teardown_Scene(GameContext& ctx); Goal::Context build_GoalCtx (const GameContext& ctx) const; public: struct AdvanceResult { bool stepped {false}; // a step boundary was crossed this frame bool advanced {false}; // ...and there is a real next step bool reset_carry {false}; // next step requests carry/projectile wipe }; explicit Director(const Level::Data& level); void enter_Step(GameContext& ctx); AdvanceResult try_Advance(GameContext& ctx, double dt, CelebrationSystem& celebration, ParticleSystem& particles); void show_Details(GameContext& ctx) const; void record_PickedUp (const std::string& t) { _ledger.picked_up.push_back(t); } void record_Shot () { _ledger.shot = true; } void record_Dropped () { _ledger.dropped = true; } void record_Button (PultAction a) { _ledger.buttons_pressed.push_back(a); } void record_AiDefeated(const std::string& t) { _ledger.ai_defeated.push_back(t); } void record_CompileOk () { _ledger.compile_ok = true; } bool is_LevelComplete() const { return _runner->is_Complete(); } Level::Progression& get_Runner() { return *_runner; } const Level::Progression& get_Runner() const { return *_runner; } const std::string& get_CurrentHint() const { return _runner->get_Current().hint; } int get_MaxAiForStep() const; DynArray& get_StepPlates() { return _step_plates; } }; } // namespace Level } // namespace Nimbin