#pragma once #include #include #include #include #include #include #include #include #include #include #include "Blueprint.h" #include "BlueprintModeExitedEvent.h" #include "BlueprintPlacementRequestedEvent.h" #include "BuilderModeExitedEvent.h" #include "BuildingType.h" #include "BuildingTypeSelectedEvent.h" #include "BuildingId.h" #include "DemolishModeChangedEvent.h" #include "DemolishModeToggleRequestedEvent.h" #include "EventHandler.h" #include "ExitBlueprintModeRequestedEvent.h" #include "ExitBuilderModeRequestedEvent.h" #include "WeaponFiredEvent.h" #include "SchematicChoiceOption.h" #include "SpeedChangeRequestedEvent.h" #include "entt/entity/entity.hpp" #include "EntitySelectedEvent.h" #include "GameConfig.h" #include "Rotation.h" #include "Tick.h" #include "TickDriver.h" #include "VisualsConfig.h" class Simulation; class QPainter; struct QPointCompare { bool operator()(const QPoint& a, const QPoint& b) const { if (a.x() != b.x()) { return a.x() < b.x(); } return a.y() < b.y(); } }; class GameWorldView : public QOpenGLWidget, public CombinedEventHandler { Q_OBJECT public: GameWorldView(Simulation* sim, const GameConfig* config, const VisualsConfig* visuals, QWidget* parent = nullptr); ~GameWorldView() override; double gameSpeed() const; void resetFrameTimer(); void setGameSpeed(double multiplier); void resetForNewGame(); protected: void initializeGL() override; void paintGL() override; void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; private slots: void onFrame(); private: void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void handleEvent(std::shared_ptr event) override; void drawTiles(QPainter& painter); void drawBuildings(QPainter& painter); void drawStations(QPainter& painter); void drawBeltItems(QPainter& painter); void drawScrap(QPainter& painter); void drawShips(QPainter& painter); void drawDebugSensorRanges(QPainter& painter); void drawDebugOverlay(QPainter& painter); void drawBeams(QPainter& painter); void drawOverlays(QPainter& painter); void drawScreenSpace(QPainter& painter); float tilePx() const; float viewportWidthTiles() const; QPointF worldToWidget(QVector2D worldPos) const; QPointF tileToWidget(QPoint tile) const; QPoint widgetToTile(QPoint widgetPt) const; QRectF tileRect(QPoint tile) const; QRect viewportRect() const; float asteroidLeftEdge() const; float enemyStationRightEdge() const; void clampScroll(); bool isValidPlacement(BuildingType type, QPoint anchor, Rotation rot) const; const BuildingDef* findBuildingDef(BuildingType type) const; BuildingId buildingAtTile(QPoint tile) const; BuildingId siteAtTile(QPoint tile) const; QVector2D widgetToWorld(QPoint widgetPt) const; void drawPortGlyph(QPainter& painter, QPoint bodyTile, Rotation direction, const QColor& color); void placeBlueprintAtTile(QPoint center); std::optional entityPosition(entt::entity entity) const; void stepSpeed(int delta); void placeAtTile(QPoint tile); void enterBuilderMode(BuildingType type); void exitBuilderMode(); void enterBlueprintMode(Blueprint blueprint); void exitBlueprintMode(); void toggleDemolishMode(); struct ActiveBeam { WeaponFiredEvent event; qint64 emittedWallMs; QVector2D targetOffset; }; static constexpr qint64 kBeamLifetimeMs = 300; static constexpr float kScrollSpeedTilesPerSec = 10.0f; Simulation* m_sim; const GameConfig* m_config; const VisualsConfig* m_visuals; TickDriver m_tickDriver; QElapsedTimer m_frameTimer; qint64 m_wallMs; std::mt19937 m_rng; double m_gameSpeedMultiplier; double m_prevNonZeroSpeed; float m_scrollXTiles; QTimer* m_renderTimer; std::vector m_activeBeams; std::optional m_builderType; Rotation m_ghostRotation; QPoint m_ghostTile; bool m_ghostValid; std::set m_beltDragTiles; bool m_dragging; std::optional m_blueprintMode; QPoint m_blueprintGhostTile; bool m_demolishMode; BuildingId m_demolishHoverBuildingId; bool m_debugDraw; std::vector m_selectedBuildingIds; std::optional m_selectedEntity; bool m_boxSelecting; QPoint m_boxStartTile; QPoint m_boxCurrentTile; bool m_scrollLeft; bool m_scrollRight; bool m_gameOverShown; bool m_schematicChoiceShown; Tick m_lastTick = Tick(-1); int m_lastBlocks = -1; int m_lastBossCounter = -1; Tick m_lastBossCountdown = Tick(-1); };