Select Git revision
Lorenz Martin Diel authored
Level.hpp 8.16 KiB
/**
* Level.hpp
*
* @authors Max Körschen
* @author Frederik Keens
* @author Lorenz Diel
*/
#pragma once
#include "../combat/CombatEngine.hpp"
#include "../core/Engine.hpp"
#include "../core/Scene.hpp"
#include "../core/Tile.hpp"
#include "../effect/Effect.hpp"
#include "../entities/Building.hpp"
#include "../entities/Bullet.hpp"
#include "../entities/Unit.hpp"
#include "../physics/PhysicsEngine.hpp"
#include "../player/Player.hpp"
#include "../ui/TileMarker.hpp"
#include "../ui/context/ContextMenu.hpp"
#include "../ui/context/RecruitingMenu.hpp"
#include "../ui/modals/HelpMenu.hpp"
#include "../ui/modals/UnitInfoMenu.hpp"
#include <SDL.h>
#include <array>
#include <memory>
#include <queue>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace advanced_wars
{
const int NUM_TILE_IDS = 30; // Aktualisieren, falls weitere IDs hinzugefügt werden
const int NUM_MOVEMENT_TYPES = 6;
const std::array<std::array<int, NUM_MOVEMENT_TYPES>, NUM_TILE_IDS> MOVE_COST_TABLE = {
{
// FOOT, WHEELED, TREAD, AIR, SEA, LANDER
{1, 2, 1, 1, 999, 999}, // PLAIN
{999, 999, 999, 1, 1, 1}, // WATER
{1, 3, 2, 1, 999, 999}, // FOREST
{2, 999, 999, 1, 999, 999}, // MOUNTAIN
{1, 1, 1, 1, 999, 999}, // BRIDGE_HORIZONTAL
{1, 1, 1, 1, 999, 999}, // BRIDE_VERTICAL
{1, 1, 1, 1, 999, 999}, // STREET_HORIZONTAL
{1, 1, 1, 1, 999, 999}, // STREET_VERTICAL
{1, 1, 1, 1, 999, 999}, // STREET_CROSSING
{1, 1, 1, 1, 999, 999}, // STREET_JUNCTION_RIGHT
{1, 1, 1, 1, 999, 999}, // STREET_JUNCTION_LEFT
{1, 1, 1, 1, 999, 999}, // STREET_JUNCTION_DOWN
{1, 1, 1, 1, 999, 999}, // STREET_JUNCTION_UP
{1, 1, 1, 1, 999, 999}, // STREET_CORNER_TOP_LEFT
{1, 1, 1, 1, 999, 999}, // STREET_CORNER_TOP_RIGHT
{1, 1, 1, 1, 999, 999}, // STREET_CORNER_BOTTOM_LEFT
{1, 1, 1, 1, 999, 999}, // STREET_CORNER_BOTTOM_RIGHT
{999, 999, 999, 1, 2, 2}, // RIFF
{999, 999, 999, 1, 1, 1}, // CLIFF_TOP
{999, 999, 999, 1, 1, 1}, // CLIFF_BOTTOM
{999, 999, 999, 1, 1, 1}, // CLIFF_LEFT
{999, 999, 999, 1, 1, 1}, // CLIFF_RIGHT
{999, 999, 999, 1, 1, 1}, // CLIFF_CORNER_TOP_LEFT
{999, 999, 999, 1, 1, 1}, // CLIFF_CORNER_TOP_RIGHT
{999, 999, 999, 1, 1, 1}, // CLIFF_CORNER_BOTTOM_LEFT
{999, 999, 999, 1, 1, 1}, // CLIFF_CORNER_BOTTOM_RIGHT
{999, 999, 999, 1, 1, 1}, // CLIFF_INVERSE_CORNER_TOP_LEFT
{999, 999, 999, 1, 1, 1}, // CLIFF_INVERSE_CORNER_TOP_RIGHT
{999, 999, 999, 1, 1, 1}, // CLIFF_INVERSE_CORNER_BOTTOM_LEFT
{999, 999, 999, 1, 1, 1}, // CLIFF_INVERSE_CORNER_BOTTOM_RIGHT
}
};
enum class LevelState
{
SELECTING_STATE,
MOVEMENT_STATE,
ANIMATING_STATE,
MENUACTIVE_STATE,
ATTACKING_STATE,
RECRUITING_STATE,
};
/**
* @brief The main window of the game
*/
class Level : public Scene
{
public:
Level(const std::string& path, Engine& engine);
// std::shared_ptr<Level> loadLevel(
// std::string name, int width, int height, std::vector<Tile> tiles,
// std::vector<Building> buildings, std::vector<Effect> effects, std::queue<Player>
// turnQ);
void render(Engine& engine) override;
/*
on event
key down
escape -> deselect/ open pause menu
key left -> move one tile left
key right -> move one tile right
key up -> move one tile up / change context menu selection up
key down -> move one tile down / change context menu selection down
key enter -> confirm selection in context menu /
confirm selected position(moving)/
select entity on tile
mousebutton down
button left -> select field/building/unit/
move to position
*/
void handleEvent(Engine& engine, SDL_Event& event) override;
int addBuilding(Building building);
Building removeBuilding(int id);
void addUnit(
int tileX, int tileY, Faction factionId, UnitTypeId unitTypeId, UnitState unitState,
Config& config);
void removeUnit(int id);
int addEffect(Effect effect);
Effect removeEffect(int id);
std::vector<std::pair<int, int>> calculateMovementRange(Unit& unit);
int getMoveCost(TileId type, MovementType movementType);
std::pair<int, int> calcTilePos(int mouseX, int mouseY);
void selectEntity(int x, int y);
int selectUnit(int tileX, int tileY);
int selectBuilding(int tileX, int tileY);
void handleSelectingEvents(Engine& engine, SDL_Event& event);
void handleMenuActiveEvents(Engine& engine, SDL_Event& event);
void handleMovementEvents(Engine& engine, SDL_Event& event);
void handleAttackingEvents(Engine& engine, SDL_Event& event);
void handleRecruitingEvent(Engine& engine, SDL_Event& event);
bool clickCheckLeft(int mouseX, int mouseY);
bool clickCheckRight(int mouseX, int mouseY);
void changeTurn();
void handleAttack(std::pair<int, int> tilePos);
void handleMovement(std::pair<int, int> tilePos);
void handlePositionMarker(Engine& engine, SDL_Event& event);
std::unordered_map<int, std::unique_ptr<Unit>>& getUnits() { return m_units; }
int getSelectedUnit() const { return m_selectedUnit; }
void setSelectedUnit(int id) { m_selectedUnit = id; }
void setShowAttackableTiles(bool show) { m_showAttackableTiles = show; }
void setShowReachableTiles(bool show) { m_showReachableTiles = show; }
void setState(LevelState state) { m_state = state; }
std::unordered_set<int>& getAttackableUnitIds() { return m_attackableUnitIds; }
LevelState getState() { return m_state; }
TileMarker getTilemarker() { return m_currentPos; }
void spawnBullet(Unit& attacker, Unit& target);
private:
bool m_gameOver = false;
std::string m_name;
int m_width = 0;
int m_height = 0;
std::vector<Tile> m_tiles;
std::unordered_map<int, Building> m_buildings;
std::unordered_map<int, std::unique_ptr<Unit>> m_units;
int m_unitIdIterator = 5;
std::vector<std::pair<int, int>> m_reachableTiles;
std::vector<std::pair<int, int>> m_attackableTiles;
std::unordered_map<int, Effect> m_effects;
std::unique_ptr<Bullet> m_bullet;
std::queue<Player> m_turnQ;
int m_selectedUnit;
int m_selectedBuilding;
int m_captureBuilding;
ContextMenu m_contextMenu;
RecruitingMenu m_recruitingMenu;
bool m_toggleHelpmenu = false;
HelpMenu m_helpMenu;
int m_id;
LevelState m_state;
TileMarker m_currentPos;
bool m_showReachableTiles = false;
bool m_showAttackableTiles = false;
std::unordered_set<int> m_attackableUnitIds;
UnitInfoMenu m_unitInfoMenu;
bool m_showUnitInfoMenu = false;
std::pair<int, int> m_unitFallbackPosition;
std::unique_ptr<PhysicsEngine> m_physicsEngine;
std::unique_ptr<CombatEngine> m_combatEngine;
Uint32 m_lastFrameTime = 0;
};
} // namespace advanced_wars