mapcreator git · master
SDL3 2.5D game and engine using assets, with map editor
C++ 99.3%git clone https://git.christianimmanuel.de/sdl-graphics/mapcreator.gitwget https://git.christianimmanuel.de/sdl-graphics/mapcreator/archive/mapcreator.tar.gzCleanup a bit input mactive_menu
src/building/building.cpp | 25 +++--- src/building/building.hpp | 5 +- src/building/building_data.cpp | 7 +- src/building/building_data.hpp | 2 - src/character/character.cpp | 193 ++++++++++++++++++++++------------------- src/character/character.hpp | 16 +++- src/game/state_playing.cpp | 49 ++++++----- src/map/tile.cpp | 18 +++- src/map/tile.hpp | 2 + src/objects/object.cpp | 17 +++- 10 files changed, 198 insertions(+), 136 deletions(-) diff --git a/src/building/building.cpp b/src/building/building.cpp index 6ec518d..50a8ba9 100644 --- a/src/building/building.cpp +++ b/src/building/building.cpp @@ -8,10 +8,12 @@ BuildingStatus Building::construction_mode = BuildingStatus::CONSTRUCTING; -bool Building::draw_menu = false; + +BuildingType +Building::selected_building_type = BuildingType::NONE; + int Building::draw_menu_curser_grid = -1; int Building::draw_menu_curser_grid_active = -1; -BuildingType Building::draw_menu_type = BuildingType::NONE; void Building::Draw(SDL_Renderer* renderer, SDL_FPoint position, bool is_transparent, int transparency) { @@ -361,7 +363,7 @@ Building::has_Menu() { } void -Building::open_Menu(const Character* player) { +Building::open_Menu(Character* player) { if (building_status != BuildingStatus::CONSTRUCTED) return; @@ -378,23 +380,17 @@ Building::open_Menu(const Character* player) { if (data.research_station == building_type && data.research_level <= static_cast<size_t>(player->level)) Research::research_items.push_back(data.type); - std::cout << "Open Build menu\n"; + std::cout << "Open Research menu\n"; std::cout << "Build Items: " << Research::research_buildings.size() << std::endl; std::cout << "Item Items: " << Research::research_items.size() << std::endl; - Building::draw_menu = true; - Building::draw_menu_type = building_type; - - BuildingData::draw_menu_building = false; - Inventory::draw_menu = false; + player->active_menu = CharacterMenuType::RESEARCH; + selected_building_type = building_type; return; } if (BuildingData::is_CraftingTable(building_type)) { std::cout << "Open Crafting menu\n"; - Building::draw_menu = true; - Building::draw_menu_type = building_type; - - BuildingData::draw_menu_building = false; - Inventory::draw_menu = false; + player->active_menu = CharacterMenuType::WORKBENCH; + selected_building_type = building_type; return; } } @@ -402,7 +398,6 @@ Building::open_Menu(const Character* player) { void Building::close_Menu() { std::cout << "Close Build menu\n"; - Building::draw_menu = false; Research::research_items.clear(); Research::research_buildings.clear(); } diff --git a/src/building/building.hpp b/src/building/building.hpp index 24d782d..9b4b4fc 100644 --- a/src/building/building.hpp +++ b/src/building/building.hpp @@ -27,8 +27,7 @@ public: std::unordered_map<ResourceType, int> cost_fulfilled; std::unordered_map<ResourceType, float> fractional_buffer; - static bool draw_menu; - static BuildingType draw_menu_type; + static BuildingType selected_building_type; static int draw_menu_curser_grid; static int draw_menu_curser_grid_active; float building_time = 0; @@ -72,7 +71,7 @@ public: bool has_Menu(); void - open_Menu(const Character* player); + open_Menu(Character* player); void close_Menu(); }; diff --git a/src/building/building_data.cpp b/src/building/building_data.cpp index aa778df..71dfd7a 100644 --- a/src/building/building_data.cpp +++ b/src/building/building_data.cpp @@ -19,7 +19,6 @@ const int WORKBENCH_ROW_HEIGHTS[6] = {4, 3, 4, 4, 3, 4}; namespace BuildingData { SDL_Texture* workbench_texture; - bool draw_menu_building = false; ActiveBuild active_build; @@ -603,6 +602,12 @@ namespace BuildingData { for (int x = 0; x < building.position.w; x++) { for (int y = 0; y < building.position.h; y++) { SDL_Point p = {position.x+x, position.y+y}; + if ( Tile::get_FloorType(p) != TileTypeFloors::MEADOW && + Tile::get_FloorType(p) != TileTypeFloors::BRICKS ) + return true; + size_t map_id = static_cast<size_t>(p.y * Map::size.x + x); + if (Map::tile_map[map_id].overlays.size() > 0) + return true; std::vector<TileObject> objects = Map::get_ObjectsFromMapTile(p); std::vector<bool> c_b = Tile::get_CollissionsOfTileFromObject(building, {x, y}); for (TileObject& o : objects) { diff --git a/src/building/building_data.hpp b/src/building/building_data.hpp index 19f7d3a..5bbddac 100644 --- a/src/building/building_data.hpp +++ b/src/building/building_data.hpp @@ -74,8 +74,6 @@ namespace BuildingData { building_data; extern SDL_Texture* workbench_texture; - extern bool - draw_menu_building; extern ActiveBuild active_build; diff --git a/src/character/character.cpp b/src/character/character.cpp index 8daba3b..11e0da1 100644 --- a/src/character/character.cpp +++ b/src/character/character.cpp @@ -22,6 +22,7 @@ Character::Character() researched_buildings(static_cast<size_t>(BuildingType::LAST), false), researched_items (static_cast<size_t>(ItemType::LAST), false) { std::cout << "CREATE CHARACTER\n"; + active_menu = CharacterMenuType::NONE; researched_buildings[static_cast<size_t>(BuildingType::RESEARCH_WOOD_1)] = true; } @@ -224,7 +225,7 @@ Character::Draw(SDL_Renderer* renderer) { SDL_RenderFillRect(renderer, &debug_rect); #endif - if (BuildingData::draw_menu_building) { + if ( is_placing_build ) { BuildingData::draw_SelectedWorkbenchAt(renderer); } // Render Placinf Soil @@ -606,8 +607,9 @@ Character::build_Start() { void Character::interact_WithBuilding(Building* building) { - if (Building::draw_menu) { + if (active_menu == CharacterMenuType::WORKBENCH) { building->close_Menu(); + active_menu = CharacterMenuType::NONE; } else if (building->has_Menu()) { std::cout << "INTERACT OPEN" << std::endl; @@ -740,6 +742,13 @@ Character::block_Stop() { return; } +void +Character::building_Stop() { + BuildingData::active_build.type = BuildingType::NONE; + BuildingData::active_build.data = nullptr; + is_placing_build = false; +} + void Character::drink_Start() { std::cout << "Drinking Start\n"; @@ -1096,17 +1105,14 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { return; } + InventoryItem *sel_item = nullptr; + if (selected_item->object_type == InventoryObjectType::ITEM) { + sel_item = static_cast<InventoryItem*>(selected_item); + } + // BUILD MENU - if (BuildingData::draw_menu_building) { - InventoryItem *it = nullptr; - if (selected_item->object_type == InventoryObjectType::ITEM) { - it = static_cast<InventoryItem*>(selected_item); - } - if (!it || (it && it->type != ItemType::BUILDING_TOOL)) { - messages->Add(MessageKey::BUILDING_TOOL_REQUIRED); - BuildingData::draw_menu_building = false; - Building::draw_menu = false; - } else + //if (BuildingData::draw_menu_building) { + if (active_menu == CharacterMenuType::BUILDING) { if (BuildingData::menu_Hovering(input, win_size, discovered_buildings)) { if (input.click_left_released) { BuildingType t = BuildingData::menu_DetectWorkbenchClick(input, win_size, discovered_buildings); @@ -1124,21 +1130,11 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { } return; } - } else - if ( is_placing_build && - input.click_left_released && - !BuildingData::active_build.is_colliding) { - if (it && it->type == ItemType::BUILDING_TOOL) - Map::place_ConstructionSide(); - return; } - - if (is_placing_build) - BuildingData::update_ActiveBuildData(collider_world.x, collider_world.y - collider.h); - } - + } else // INVENTORY - if (Inventory::draw_menu) { + if (active_menu == CharacterMenuType::INVENTORY) { + //if (Inventory::draw_menu) { if (input.click_left || input.click_left_released) { if (Inventory::cursor_OverBuildMenu(input.mouse_state_raw)) { if (input.click_left_released) { @@ -1173,7 +1169,6 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { Item::craft_Stop(); } return; - } if (keys[SDL_SCANCODE_1] || keys[SDL_SCANCODE_2] || @@ -1182,6 +1177,7 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { keys[SDL_SCANCODE_5] || keys[SDL_SCANCODE_6]) { if (inventory->selected_inventory.is_valid) { + building_Stop(); bool setted_hotbar = false; if (inventory->selected_inventory.vegetable != VegetableData::Type::NONE) { InventoryVegetable& iv = inventory->vegetables.at(inventory->selected_inventory.vegetable); @@ -1190,82 +1186,97 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { } else { setted_hotbar = inventory->set_HotbarItem(Inventory::selected_hotbar, inventory->selected_inventory.item); if (setted_hotbar) { - InventoryItem *it = - static_cast<InventoryItem*>(inventory->selected_inventory.item); - if (it) inventory->Equip(it); + if (sel_item) inventory->Equip(sel_item); } } - if (setted_hotbar) + if (setted_hotbar) { selected_item = inventory->get_SelectedHotbarItem(); + sel_item = nullptr; + if (selected_item->object_type == InventoryObjectType::ITEM) { + sel_item = static_cast<InventoryItem*>(selected_item); + } + } + } + return; + } + } else + // WORKBENCH + if (active_menu == CharacterMenuType::WORKBENCH) { + Building::draw_menu_curser_grid = Research::cursor_ResearchGridTileIndex(input.mouse_state_raw, win_size); + // CRAFT + if (input.click_left_released) { + Craft::craft_Stop(); + + if (Craft::is_CursorOverMenuInfoPanel(input.mouse_state_raw)) { + std::vector<ItemType> rs = Item::get_ResearchedItems(researched_items); + if ( Building::draw_menu_curser_grid_active >= 0 && + Building::draw_menu_curser_grid_active < static_cast<int>(rs.size())) { + if ( Craft::cursor_OverCraftButton(input.mouse_state_raw)) { + Craft::craft_Start(inventory.get(), rs[static_cast<size_t>(Building::draw_menu_curser_grid_active)]); + } + } + + } else { // SELECTING ? + Building::draw_menu_curser_grid_active = Building::draw_menu_curser_grid; + } + } else if (Craft::item.is_crafting) { + if (!Craft::craft_Continue(inventory.get(), messages.get())) { + Craft::craft_Stop(); + std::cout << "Crafting stopped..\n"; + } + } + return; + } else + // RESEARCH + if (active_menu == CharacterMenuType::RESEARCH) { + Building::draw_menu_curser_grid = Research::cursor_ResearchGridTileIndex(input.mouse_state_raw, win_size); + if (input.click_left_released) { + Research::research_Stop(); + + if (Research::is_CursorOverMenuInfoPanel(input.mouse_state_raw)) { + if ( Research::cursor_OverResearchButton(input.mouse_state_raw) && + Building::draw_menu_curser_grid_active >= 0) { + Research::is_researching = true; + Research::research_Start(); + } + + } else { + Building::draw_menu_curser_grid_active = Building::draw_menu_curser_grid; } + } else if (Research::research_item.is_researching) { + if (Research::research_Continue(researched_buildings, researched_items)) + set_BuildingDiscovery(); } } else { + active_menu = CharacterMenuType::NONE; Inventory::selected_build_item = ItemType::NONE; Item::crafting_item.is_crafting = false; + } - if (keys[SDL_SCANCODE_1] || + if (keys[SDL_SCANCODE_1] || keys[SDL_SCANCODE_2] || keys[SDL_SCANCODE_3] || keys[SDL_SCANCODE_4] || keys[SDL_SCANCODE_5] || keys[SDL_SCANCODE_6]) { - selected_item = inventory->get_SelectedHotbarItem(); - std::cout << "SWITCH " << selected_item->id << std::endl; - } + selected_item = inventory->get_SelectedHotbarItem(); + building_Stop(); + if (active_menu == CharacterMenuType::BUILDING) + active_menu = CharacterMenuType::NONE; + std::cout << "SWITCH " << selected_item->id << std::endl; + return; } - // BUILDING - if (Building::draw_menu) { - Building::draw_menu_curser_grid = Research::cursor_ResearchGridTileIndex(input.mouse_state_raw, win_size); - // RESEARCH - if (BuildingData::is_ResearchTable(Building::draw_menu_type)) { - if (input.click_left_released) { - Research::research_Stop(); - - if (Research::is_CursorOverMenuInfoPanel(input.mouse_state_raw)) { - if ( Research::cursor_OverResearchButton(input.mouse_state_raw) && - Building::draw_menu_curser_grid_active >= 0) { - Research::is_researching = true; - Research::research_Start(); - } - - } else { - Building::draw_menu_curser_grid_active = Building::draw_menu_curser_grid; - } - } else if (Research::research_item.is_researching) { - if (Research::research_Continue(researched_buildings, researched_items)) - set_BuildingDiscovery(); - } - return; - } - // CRAFT - if (BuildingData::is_CraftingTable(Building::draw_menu_type)) { - if (input.click_left_released) { - Craft::craft_Stop(); - - if (Craft::is_CursorOverMenuInfoPanel(input.mouse_state_raw)) { - std::vector<ItemType> rs = Item::get_ResearchedItems(researched_items); - if ( Building::draw_menu_curser_grid_active >= 0 && - Building::draw_menu_curser_grid_active < static_cast<int>(rs.size())) { - if ( Craft::cursor_OverCraftButton(input.mouse_state_raw)) { - Craft::craft_Start(inventory.get(), rs[static_cast<size_t>(Building::draw_menu_curser_grid_active)]); - } - } - - } else { // SELECTING ? - Building::draw_menu_curser_grid_active = Building::draw_menu_curser_grid; - } - } else if (Craft::item.is_crafting) { - if (!Craft::craft_Continue(inventory.get(), messages.get())) { - Craft::craft_Stop(); - std::cout << "Crafting stopped..\n"; - } - } - return; - } + if ( Building::construction_mode == BuildingStatus::CONSTRUCTING && + is_placing_build && + input.click_left_released && + !BuildingData::active_build.is_colliding) { + Map::place_ConstructionSide(); + return; } + // INTERACT OBJECT OR ITEM if (input.pressed_c_released && status != CharacterStatus::COLLECT) { SDL_Point tile_point; @@ -1312,13 +1323,12 @@ Character::handle_Input(Input& input, SDL_Rect win_size) { if (!input.pressed_ctrl) { // LEFT CLICK if (input.click_left) { - if (selected_item->object_type == InventoryObjectType::ITEM) { - InventoryItem *it = static_cast<InventoryItem*>(selected_item); - if ( it->type == ItemType::CULTIVATOR && + if (sel_item) { + if ( sel_item->type == ItemType::CULTIVATOR && status != CharacterStatus::CULTIVATING) cultivate_Start(); else - if (it->type == ItemType::BUILDING_TOOL) { + if (sel_item->type == ItemType::BUILDING_TOOL) { build_Start(); return; } else if (using_Weapon() && @@ -1594,6 +1604,15 @@ void Character::handle_Move() { set_TilesInReach(); } + +void Character::Update() { + if ( is_placing_build) + BuildingData::update_ActiveBuildData(collider_world.x, collider_world.y - collider.h); + + handle_Move(); +} + + bool Character::is_RectWithinReach( const SDL_FRect& target) { // Player center float px = x+collider.x+collider.w*0.5; diff --git a/src/character/character.hpp b/src/character/character.hpp index 38dd7f9..f470e82 100644 --- a/src/character/character.hpp +++ b/src/character/character.hpp @@ -22,6 +22,14 @@ // Character stuff +enum class CharacterMenuType { + NONE, + BUILDING, + INVENTORY, + WORKBENCH, + RESEARCH, +}; + enum class CharacterStatus { IDLE, WALK, @@ -142,12 +150,13 @@ class Character { unclocked__buildings; public: + CharacterMenuType active_menu; Inventory_s* selected_item; AnimationData* active_anim = nullptr; CharacterAnimation animation; WalkDirection direction = WalkDirection::UP; - CharacterAttackingLogic attacking_logic; - CharacterConsumingLogic consuming_logic; + CharacterAttackingLogic attacking_logic; + CharacterConsumingLogic consuming_logic; CharacterSprintStartLogic sprintstart_logic; float death_duration; @@ -218,6 +227,8 @@ class Character { void block_Enemy(); void block_Stop(); + void building_Stop(); + void drink_Start(); void drink_River(); void drink_Stop(); @@ -246,6 +257,7 @@ class Character { void handle_Input(Input& input, SDL_Rect win_size); void handle_Animation(); + void Update(); void handle_Move(); void draw_PickupRadius(SDL_Renderer* renderer); diff --git a/src/game/state_playing.cpp b/src/game/state_playing.cpp index eb7a3b2..92de3ed 100644 --- a/src/game/state_playing.cpp +++ b/src/game/state_playing.cpp @@ -100,17 +100,26 @@ void StatePlaying::handle_Events(SDL_Event& event, Game* game) { case SDL_EVENT_KEY_UP: switch (event.key.scancode) { - case SDL_SCANCODE_B: - BuildingData::draw_menu_building = !BuildingData::draw_menu_building; - Inventory::draw_menu = false; - Building::draw_menu = false; + case SDL_SCANCODE_B: { + InventoryItem *sel_item = nullptr; + if (player->selected_item->object_type == InventoryObjectType::ITEM) { + sel_item = static_cast<InventoryItem*>(player->selected_item); + if (sel_item->type == ItemType::BUILDING_TOOL) + player->active_menu = player->active_menu == CharacterMenuType::NONE + ? CharacterMenuType::BUILDING : CharacterMenuType::NONE; + else + player->messages->Add(MessageKey::BUILDING_TOOL_REQUIRED); + } else + player->messages->Add(MessageKey::BUILDING_TOOL_REQUIRED); break; + } case SDL_SCANCODE_R: Inventory::selected_hotbar = !Inventory::selected_hotbar ? Inventory::selected_hotbar_last : 0; break; case SDL_SCANCODE_E: + player->active_menu = player->active_menu == CharacterMenuType::NONE + ? CharacterMenuType::INVENTORY : CharacterMenuType::NONE; Inventory::draw_menu = !Inventory::draw_menu; - BuildingData::draw_menu_building = false; break; case SDL_SCANCODE_K: { Building::construction_mode = Building::construction_mode == BuildingStatus::DECONSTRUCT ? @@ -149,7 +158,7 @@ void StatePlaying::Update(Game* game) { // CHARACTER player->handle_Input(game->input, game->win_size); - player->handle_Move(); + player->Update(); player->handle_Animation(); // MESSAGES @@ -184,20 +193,20 @@ void StatePlaying::Render(Game* game) { player->messages->render_InventoryMessages(game, player->inventory.get()); - if (BuildingData::draw_menu_building) - BuildingData::draw_WorkbenchMenu(game->renderer, game->win_size, player->discovered_buildings); - else - if (Inventory::draw_menu) - player->inventory->draw_Menu( game->renderer, game->win_size, Ui::font_menu, player->researched_items, Inventory::cursor_OverCraftButton(game->input.mouse_state_raw)); - else - if (Building::draw_menu) { - if (BuildingData::is_ResearchTable(Building::draw_menu_type)) { - Research::draw_ReserachMenu(game->renderer, game->win_size, Building::draw_menu_type, player->researched_buildings, player->researched_items, Research::cursor_OverResearchButton(game->input.mouse_state_raw)); - } else - if (BuildingData::is_CraftingTable(Building::draw_menu_type)) { - Craft::draw_CraftMenu(game, Building::draw_menu_type, Craft::cursor_OverCraftButton(game->input.mouse_state_raw)); - } - // std::cout << "CLICKED GRID: " << clicked_grid << std::endl; + switch (player->active_menu) { + case CharacterMenuType::NONE: break; + case CharacterMenuType::BUILDING: + BuildingData::draw_WorkbenchMenu(game->renderer, game->win_size, player->discovered_buildings); + break; + case CharacterMenuType::INVENTORY: + player->inventory->draw_Menu( game->renderer, game->win_size, Ui::font_menu, player->researched_items, Inventory::cursor_OverCraftButton(game->input.mouse_state_raw)); + break; + case CharacterMenuType::RESEARCH: + Research::draw_ReserachMenu(game->renderer, game->win_size, Building::selected_building_type, player->researched_buildings, player->researched_items, Research::cursor_OverResearchButton(game->input.mouse_state_raw)); + break; + case CharacterMenuType::WORKBENCH: + Craft::draw_CraftMenu(game, Building::selected_building_type, Craft::cursor_OverCraftButton(game->input.mouse_state_raw)); + break; } player->inventory->draw_Hotbar(game->renderer, Ui::font_menu); diff --git a/src/map/tile.cpp b/src/map/tile.cpp index f939a3f..a19a7fb 100644 --- a/src/map/tile.cpp +++ b/src/map/tile.cpp @@ -198,14 +198,14 @@ namespace Tile { Tile::active_tileset = &Tile::tilesets[TILE_BACKGROUND][0]; - floor_props.push_back({NONE, true, false}); + floor_props.push_back({NONE, true, false}); floor_props.push_back({MEADOW, true, false}); floor_props.push_back({CLAY, true, false}); floor_props.push_back({SOIL, true, true}); floor_props.push_back({BRICKS, true, false}); floor_props.push_back({ICE, false, false}); floor_props.push_back({DESERT, false, false}); - floor_props.push_back({WATER, false, false}); + floor_props.push_back({WATER, false, false}); return true; } @@ -1127,6 +1127,20 @@ namespace Tile { size_t id = static_cast<size_t>(position.y * tileset.size.x + position.x); return tileset_floor_props[tile_s.set_category][id].tiletype; } + TileTypeFloors + get_FloorType(SDL_Point& world_tile) { + if (Map::tile_map[Map::get_IdFromTilePoint(world_tile)].overlays.size() > 0) { + for (Tile_s t : Map::tile_map[Map::get_IdFromTilePoint(world_tile)].overlays) { + if (t.set_position.x == 0 && t.set_position.y == 0) + return TileTypeFloors::SOIL; + } + } + Tile_s& tile_s = Map::tile_map[Map::get_IdFromTilePoint(world_tile)].background; + SDL_Point& position = tile_s.set_position; + TileSet& tileset = get_TilesetFromMapTile(tile_s); + size_t id = static_cast<size_t>(position.y * tileset.size.x + position.x); + return tileset_floor_props[tile_s.set_category][id].tiletype; + } void transfer_ToMap(Input& input) { diff --git a/src/map/tile.hpp b/src/map/tile.hpp index 5aeb7a4..50fa4cf 100644 --- a/src/map/tile.hpp +++ b/src/map/tile.hpp @@ -213,6 +213,8 @@ namespace Tile { void set_FloorType(Input& input); TileTypeFloors get_FloorType(Tile_s&); + TileTypeFloors + get_FloorType(SDL_Point& world_tile); bool objec_HasCollission(TilesetObject& object); std::vector<bool> get_CollissionsOfTileFromObject(TilesetObject& obj, SDL_Point tile); diff --git a/src/objects/object.cpp b/src/objects/object.cpp index a0cbcb4..7ccf3d8 100644 --- a/src/objects/object.cpp +++ b/src/objects/object.cpp @@ -127,11 +127,20 @@ Object::is_InFrontOf(SDL_FPoint position, SDL_FRect rect) { return false; } - -std::vector<bool> -Object::get_CollisionMap() { - return Tile::get_ObjectCollisionsFromTileset(tileset_id, tileset_object_id, tileset_type); +std::vector<bool> Object::get_CollisionMap() { + std::vector<bool> map = + Tile::get_ObjectCollisionsFromTileset( + tileset_id, + tileset_object_id, + tileset_type); + + if (!map.empty()) + return map; + + const size_t n = Tile::tile_collider_size * Tile::tile_collider_size; + return std::vector<bool>(n, false); } + bool Object::has_Collision() { for (bool collission : get_CollisionMap()) {