game_engine.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #pragma once
  2. #include <QMatrix4x4>
  3. #include <QObject>
  4. #include <QPointF>
  5. #include <QStringList>
  6. #include <QVariant>
  7. #include <QVector3D>
  8. #include <algorithm>
  9. #include <cstdint>
  10. #include <memory>
  11. #include <vector>
  12. namespace Engine {
  13. namespace Core {
  14. class World;
  15. using EntityID = unsigned int;
  16. struct MovementComponent;
  17. struct TransformComponent;
  18. struct RenderableComponent;
  19. } // namespace Core
  20. } // namespace Engine
  21. namespace Render {
  22. namespace GL {
  23. class Renderer;
  24. class Camera;
  25. class ResourceManager;
  26. class GroundRenderer;
  27. class TerrainRenderer;
  28. class FogRenderer;
  29. } // namespace GL
  30. } // namespace Render
  31. namespace Game {
  32. namespace Systems {
  33. class SelectionSystem;
  34. class ArrowSystem;
  35. class PickingService;
  36. } // namespace Systems
  37. } // namespace Game
  38. class QQuickWindow;
  39. class GameEngine : public QObject {
  40. Q_OBJECT
  41. public:
  42. GameEngine();
  43. ~GameEngine();
  44. Q_PROPERTY(QObject *selectedUnitsModel READ selectedUnitsModel NOTIFY
  45. selectedUnitsChanged)
  46. Q_PROPERTY(bool paused READ paused WRITE setPaused)
  47. Q_PROPERTY(float timeScale READ timeScale WRITE setGameSpeed)
  48. Q_PROPERTY(QString victoryState READ victoryState NOTIFY victoryStateChanged)
  49. Q_PROPERTY(QString cursorMode READ cursorMode WRITE setCursorMode NOTIFY
  50. cursorModeChanged)
  51. Q_PROPERTY(qreal globalCursorX READ globalCursorX NOTIFY globalCursorChanged)
  52. Q_PROPERTY(qreal globalCursorY READ globalCursorY NOTIFY globalCursorChanged)
  53. Q_PROPERTY(
  54. bool hasUnitsSelected READ hasUnitsSelected NOTIFY selectedUnitsChanged)
  55. Q_PROPERTY(
  56. int playerTroopCount READ playerTroopCount NOTIFY troopCountChanged)
  57. Q_PROPERTY(
  58. int maxTroopsPerPlayer READ maxTroopsPerPlayer NOTIFY troopCountChanged)
  59. Q_PROPERTY(
  60. QVariantList availableMaps READ availableMaps NOTIFY availableMapsChanged)
  61. Q_PROPERTY(int enemyTroopsDefeated READ enemyTroopsDefeated NOTIFY enemyTroopsDefeatedChanged)
  62. Q_INVOKABLE void onMapClicked(qreal sx, qreal sy);
  63. Q_INVOKABLE void onRightClick(qreal sx, qreal sy);
  64. Q_INVOKABLE void onClickSelect(qreal sx, qreal sy, bool additive = false);
  65. Q_INVOKABLE void onAreaSelected(qreal x1, qreal y1, qreal x2, qreal y2,
  66. bool additive = false);
  67. Q_INVOKABLE void setHoverAtScreen(qreal sx, qreal sy);
  68. Q_INVOKABLE void onAttackClick(qreal sx, qreal sy);
  69. Q_INVOKABLE void onStopCommand();
  70. Q_INVOKABLE void onPatrolClick(qreal sx, qreal sy);
  71. Q_INVOKABLE void cameraMove(float dx, float dz);
  72. Q_INVOKABLE void cameraElevate(float dy);
  73. Q_INVOKABLE void resetCamera();
  74. Q_INVOKABLE void cameraZoom(float delta);
  75. Q_INVOKABLE float cameraDistance() const;
  76. Q_INVOKABLE void cameraYaw(float degrees);
  77. Q_INVOKABLE void cameraOrbit(float yawDeg, float pitchDeg);
  78. Q_INVOKABLE void cameraOrbitDirection(int direction, bool shift);
  79. Q_INVOKABLE void cameraFollowSelection(bool enable);
  80. Q_INVOKABLE void cameraSetFollowLerp(float alpha);
  81. Q_INVOKABLE void setPaused(bool paused) { m_runtime.paused = paused; }
  82. Q_INVOKABLE void setGameSpeed(float speed) {
  83. m_runtime.timeScale = std::max(0.0f, speed);
  84. }
  85. bool paused() const { return m_runtime.paused; }
  86. float timeScale() const { return m_runtime.timeScale; }
  87. QString victoryState() const { return m_runtime.victoryState; }
  88. QString cursorMode() const { return m_runtime.cursorMode; }
  89. void setCursorMode(const QString &mode);
  90. qreal globalCursorX() const;
  91. qreal globalCursorY() const;
  92. bool hasUnitsSelected() const;
  93. int playerTroopCount() const;
  94. int maxTroopsPerPlayer() const { return m_level.maxTroopsPerPlayer; }
  95. int enemyTroopsDefeated() const;
  96. Q_INVOKABLE bool hasSelectedType(const QString &type) const;
  97. Q_INVOKABLE void recruitNearSelected(const QString &unitType);
  98. Q_INVOKABLE QVariantMap getSelectedProductionState() const;
  99. Q_INVOKABLE QString getSelectedUnitsCommandMode() const;
  100. Q_INVOKABLE void setRallyAtScreen(qreal sx, qreal sy);
  101. Q_INVOKABLE QVariantList availableMaps() const;
  102. Q_INVOKABLE void startSkirmish(const QString &mapPath);
  103. Q_INVOKABLE void openSettings();
  104. Q_INVOKABLE void loadSave();
  105. Q_INVOKABLE void exitGame();
  106. void setWindow(QQuickWindow *w) { m_window = w; }
  107. void ensureInitialized();
  108. void update(float dt);
  109. void render(int pixelWidth, int pixelHeight);
  110. void getSelectedUnitIds(std::vector<Engine::Core::EntityID> &out) const;
  111. bool getUnitInfo(Engine::Core::EntityID id, QString &name, int &health,
  112. int &maxHealth, bool &isBuilding, bool &alive) const;
  113. bool hasPatrolPreviewWaypoint() const { return m_patrol.hasFirstWaypoint; }
  114. QVector3D getPatrolPreviewWaypoint() const { return m_patrol.firstWaypoint; }
  115. private:
  116. struct RuntimeState {
  117. bool initialized = false;
  118. bool paused = false;
  119. bool loading = false;
  120. float timeScale = 1.0f;
  121. int localOwnerId = 1;
  122. QString victoryState = "";
  123. QString cursorMode = "normal";
  124. int lastTroopCount = 0;
  125. std::uint64_t visibilityVersion = 0;
  126. };
  127. struct ViewportState {
  128. int width = 0;
  129. int height = 0;
  130. };
  131. struct LevelState {
  132. QString mapName;
  133. Engine::Core::EntityID playerUnitId = 0;
  134. float camFov = 45.0f;
  135. float camNear = 0.1f;
  136. float camFar = 1000.0f;
  137. int maxTroopsPerPlayer = 50;
  138. };
  139. struct HoverState {
  140. Engine::Core::EntityID entityId = 0;
  141. };
  142. struct PatrolState {
  143. QVector3D firstWaypoint;
  144. bool hasFirstWaypoint = false;
  145. };
  146. Game::Systems::ArrowSystem *m_arrowSystem = nullptr;
  147. void initialize();
  148. void checkVictoryCondition();
  149. bool screenToGround(const QPointF &screenPt, QVector3D &outWorld);
  150. bool worldToScreen(const QVector3D &world, QPointF &outScreen) const;
  151. void syncSelectionFlags();
  152. QObject *selectedUnitsModel();
  153. std::unique_ptr<Engine::Core::World> m_world;
  154. std::unique_ptr<Render::GL::Renderer> m_renderer;
  155. std::unique_ptr<Render::GL::Camera> m_camera;
  156. std::shared_ptr<Render::GL::ResourceManager> m_resources;
  157. std::unique_ptr<Render::GL::GroundRenderer> m_ground;
  158. std::unique_ptr<Render::GL::TerrainRenderer> m_terrain;
  159. std::unique_ptr<Render::GL::FogRenderer> m_fog;
  160. Game::Systems::SelectionSystem *m_selectionSystem = nullptr;
  161. std::unique_ptr<Game::Systems::PickingService> m_pickingService;
  162. QQuickWindow *m_window = nullptr;
  163. RuntimeState m_runtime;
  164. ViewportState m_viewport;
  165. bool m_followSelectionEnabled = false;
  166. LevelState m_level;
  167. QObject *m_selectedUnitsModel = nullptr;
  168. HoverState m_hover;
  169. PatrolState m_patrol;
  170. int m_enemyTroopsDefeated = 0;
  171. signals:
  172. void selectedUnitsChanged();
  173. void enemyTroopsDefeatedChanged();
  174. void victoryStateChanged();
  175. void cursorModeChanged();
  176. void globalCursorChanged();
  177. void troopCountChanged();
  178. void availableMapsChanged();
  179. };