Nimbin[12]?SDL & Graphics / mapcreator / commits / c60d6fb

mapcreator git · master

SDL3 2.5D game and engine using assets, with map editor

sdl3 c++ game engine map-editor cmake · first commit 2025-10-31 · last commit 2026-09-07 (1 month ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/sdl-spieleentwicklung/map_creator

C++ 99.3%
git clone https://git.christianimmanuel.de/sdl-graphics/mapcreator.gitwget https://git.christianimmanuel.de/sdl-graphics/mapcreator/archive/mapcreator.tar.gz

Fix use after free vegetable AND other vegetable stuff AND maybe more

Christian Immanuel · 2026-02-19 16:33 · c60d6fbae28bd37af4357471c7099f13d607937a

 src/character/character.cpp   | 22 +++++++++++---
 src/character/enemy.cpp       |  2 +-
 src/defaults/ui.cpp           | 68 +++++++++++++++++++++++++++++++++++++++++++
 src/game/state_playing.cpp    |  2 ++
 src/inventory/inventory.cpp   |  9 +++---
 src/inventory/inventory.hpp   |  2 +-
 src/vegetables/vegetables.cpp |  4 +--
 7 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/src/character/character.cpp b/src/character/character.cpp
index 2a4899d..93b59e1 100644
--- a/src/character/character.cpp
+++ b/src/character/character.cpp
@@ -456,9 +456,7 @@ Character::is_Colliding(const SDL_FRect& rect) {
 
 TileObject*
 Character::find_ClosestObject(SDL_Point* tile_found, ObjectCategory category) {
-                std::cout << "JUU 1" << (int)category << std::endl;
     for (const SDL_Point& tile_point : tiles_in_reach) {
-                std::cout << "JUU 2 ";
         auto& objects = Map::get_ObjectsFromMapTile(tile_point);
         for (auto& object : objects) {
             Object* o = Object::get_ObjectById(object.object_id);
@@ -470,7 +468,6 @@ Character::find_ClosestObject(SDL_Point* tile_found, ObjectCategory category) {
             it = static_cast<InventoryItem*>(selected_item);
             // }
             if ( (category == ObjectCategory::NONE && o->category != ObjectCategory::STATIC)) {
-                std::cout << "JUU " << (int)o->category << std::endl;;
                 // THATS MIXING SHT
                 if ( (o->category == ObjectCategory::RESOURCE && it &&
                      (static_cast<Resource*>(o)->is_Collectable(it->type)))
@@ -735,6 +732,10 @@ Character::add_ToStatsBonus(InventoryObjectType object_type,
             entry.type == type)
         {
             entry.stats = sb;
+            entry.duration = sb.duration;
+            health_Increase(sb.health);
+            stamina_Increase(sb.stamina);
+            std::cout << "ADD STATS " << (int)type << std::endl;
             return;
         }
     }
@@ -959,8 +960,13 @@ Character::eat_Something() {
     //InventoryVegetable
     if (selected_item->object_type == InventoryObjectType::VEGETABLE) {
         InventoryVegetable* it = static_cast<InventoryVegetable*>(selected_item);
-        inventory->remove_Vegetable(it->type, 1);
         add_ToStatsBonus(InventoryObjectType::VEGETABLE, static_cast<uint32_t>(it->type), it->stats_bonus);
+        if (inventory->remove_Vegetable(it->type, 1) == 0) {
+            bool setted_hotbar = inventory->set_HotbarItem(Inventory::selected_hotbar, Inventory::hotbar_hands);
+            if (setted_hotbar)
+                inventory->Equip(Inventory::hotbar_hands);
+            selected_item = inventory->get_SelectedHotbarItem();
+        }
     }
 
     consume_Stop();
@@ -1704,9 +1710,17 @@ Character::handle_Input(Input& input, SDL_Rect win_size) {
                 Building::draw_menu_curser_grid_active = Building::draw_menu_curser_grid;
             }
         } else if (Craft::item.is_crafting) {
+            bool enable_attackable = Craft::item.type == ItemType::SWORD_WOOD;
             if (!Craft::craft_Continue(inventory.get(), messages.get())) {
                 Craft::craft_Stop();
                 std::cout << "Crafting stopped..\n";
+            } else {
+                if (enable_attackable) {
+                    if (!is_attackable) {
+                        std::cout << "IM ATTACKABLE NOW!\n";
+                        is_attackable = true;
+                    }
+                }
             }
         }
         return;
diff --git a/src/character/enemy.cpp b/src/character/enemy.cpp
index 30f5da0..91e8709 100644
--- a/src/character/enemy.cpp
+++ b/src/character/enemy.cpp
@@ -57,7 +57,7 @@ Enemy::Enemy(WeaponType weapon_type, WeaponMaterial weapon_material, SDL_FPoint
 
         max_death_time = 10.0;
 
-        stats = { 4,  4, 1, false, false, 0, 1.2 };
+        stats = status;
 
         death_duration = 0;
         death_duration_max = 0.8;
diff --git a/src/defaults/ui.cpp b/src/defaults/ui.cpp
index 16a1a36..078cbea 100644
--- a/src/defaults/ui.cpp
+++ b/src/defaults/ui.cpp
@@ -454,5 +454,73 @@ namespace Ui {
         SDL_RenderRect(renderer, &thirst_bg);
         SDL_RenderRect(renderer, &energy_bg);
         SDL_RenderRect(renderer, &health_bg);
+
+
+
+
+
+
+
+
+
+
+
+
+        const float icon_size = 32.0f;
+        const float icon_spacing = 6.0f;
+        const float icons_y = start_y - icon_size - 8.0f;
+
+        const float max_duration = 300.0f;
+
+        for (size_t n = 0; n < player.stats_bonus.size(); ++n) {
+
+            const CharacterStatsBonus& bonus = player.stats_bonus[n];
+
+            const VegetableData::CropDefinition* data =
+                VegetableData::get_DataByType(
+                        static_cast<VegetableData::Type>(bonus.type)
+                        );
+
+            if (!data)
+                continue;
+
+            SDL_FRect dst = {
+                thirst_bg.x + n * (icon_size + icon_spacing),
+                icons_y,
+                icon_size,
+                icon_size
+            };
+
+            SDL_FRect src = {
+                static_cast<float>(data->icon_tile_x * 16),
+                static_cast<float>(data->icon_tile_y * 16),
+                16.0f,
+                16.0f
+            };
+
+            SDL_RenderTexture(renderer, Icon::icons_texture, &src, &dst);
+
+            // -------- duration overlay --------
+
+            float ratio = bonus.duration / max_duration;
+            if (ratio < 0.0f) ratio = 0.0f;
+            if (ratio > 1.0f) ratio = 1.0f;
+
+            float overlay_h = dst.h * ratio;
+
+            SDL_FRect overlay = {
+                dst.x,
+                dst.y + (dst.h - overlay_h),
+                dst.w,
+                overlay_h
+            };
+
+            SDL_SetRenderDrawColor(renderer, 0, 0, 0, 140);
+            SDL_RenderFillRect(renderer, &overlay);
+
+            // border
+            SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+            SDL_RenderRect(renderer, &dst);
+        }
     }
 }
diff --git a/src/game/state_playing.cpp b/src/game/state_playing.cpp
index b5a4646..185b770 100644
--- a/src/game/state_playing.cpp
+++ b/src/game/state_playing.cpp
@@ -76,6 +76,8 @@ bool StatePlaying::Init(Game* game) {
         player->inventory->add_Item(ItemType::BUILDING_TOOL, player->messages.get());
         player->inventory->add_Item(ItemType::CULTIVATOR, player->messages.get());
         player->inventory->add_Vegetable(VegetableData::Type::CARROT, 4, player->messages.get());
+        player->inventory->add_Vegetable(VegetableData::Type::CABBAGE, 4, player->messages.get());
+        player->is_attackable = true;
     }
     // END CHEAT
 
diff --git a/src/inventory/inventory.cpp b/src/inventory/inventory.cpp
index 1e7438c..e05e77b 100644
--- a/src/inventory/inventory.cpp
+++ b/src/inventory/inventory.cpp
@@ -97,21 +97,22 @@ Inventory::add_Vegetable(VegetableData::Type type, size_t amount, Messages* mess
         messages->Add(MessageKey::ADD_VEGETABLE, static_cast<void*>(t));
 }
 
-bool
+int
 Inventory::remove_Vegetable(VegetableData::Type type, size_t amount) {
     auto it = vegetables.find(type);
+    int ret = -1;
     if (it == vegetables.end() || it->second.count < amount)
-        return false;
+        return ret;
 
-    std::cout << "TSCHÖÖ VEG\n";
     it->second.count -= amount;
+    ret = it->second.count;
     if (it->second.count == 0) {
         vegetables.erase(it);
         bool setted_hotbar = set_HotbarItem(Inventory::selected_hotbar, Inventory::hotbar_hands);
         if (setted_hotbar)
             Equip(Inventory::hotbar_hands);
     }
-    return true;
+    return ret;
 }
 
 int
diff --git a/src/inventory/inventory.hpp b/src/inventory/inventory.hpp
index d84c22f..707f771 100644
--- a/src/inventory/inventory.hpp
+++ b/src/inventory/inventory.hpp
@@ -114,7 +114,7 @@ public:
     Inventory(Inventory&& other);
 
     void add_Vegetable(VegetableData::Type, size_t amount, Messages*);
-    bool remove_Vegetable(VegetableData::Type type, size_t amount);
+    int  remove_Vegetable(VegetableData::Type type, size_t amount);
     int  get_Vegetable(VegetableData::Type type) const;
 
     void add_Seed(VegetableData::Type, size_t amount, Messages*);
diff --git a/src/vegetables/vegetables.cpp b/src/vegetables/vegetables.cpp
index 42b0530..46b1c91 100644
--- a/src/vegetables/vegetables.cpp
+++ b/src/vegetables/vegetables.cpp
@@ -9,9 +9,9 @@ namespace VegetableData {
     const CropDefinition crop_defs[(int)Type::COUNT] = {
         //        STAGE: 0    1    2    3    4
         { "",0,0,0,0,0,0,0,0,0,0,0,false , { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
-        { "carrot",   2,1, 5,1, 6,1, 7,1, 23,0, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
+        { "carrot",   2,1, 5,1, 6,1, 7,1, 23,0, (5-2+1)+1, false, { 0.0f, 10.0f, 0.0f, 0.0f, 300.0f } },
         { "raddish",  2,3, 5,3, 6,3, 7,3, 23,1, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
-        { "cabbage",  2,5, 5,5, 6,5, 7,5, 23,2, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
+        { "cabbage",  2,5, 5,5, 6,5, 7,5, 23,2, (5-2+1)+1, false, { 10.0f, 0.0f, 0.0f, 0.0f, 300.0f } },
         { "salad",    2,7, 5,7, 6,7, 7,7, 23,3, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
         { "broccoli", 2,9, 5,9, 6,9, 7,9, 23,4, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } },
         { "onion",    2,11,5,11,6,11,7,11,23,5, (5-2+1)+1, false, { 5.0f, 5.0f, 0.0f, 0.0f, 300.0f } }