Nimbin[12]?SDL & Graphics / mapcreator / commits / 74a9387

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

Bug fixes i think

Christian Immanuel · 2025-12-19 07:24 · 74a938759c99684b67dd34ac332f8e9f4420a661

 src/bird/bird.cpp           |  38 +++---
 src/character/animation.hpp |   1 +
 src/character/character.cpp |  69 +++++++---
 src/character/character.hpp |   2 +
 src/character/enemy.cpp     |   2 +
 src/defaults/defaults.cpp   |   2 +-
 src/defaults/input.cpp      | 301 --------------------------------------------
 src/defaults/ui.cpp         |   8 +-
 src/game/state_modify.cpp   |   6 +-
 src/game/state_playing.cpp  |  16 ++-
 src/map/map.cpp             |  12 +-
 src/map/tile.cpp            |   6 +-
 src/objects/object.cpp      |  32 ++++-
 src/objects/object.hpp      |  11 +-
 14 files changed, 145 insertions(+), 361 deletions(-)

diff --git a/src/bird/bird.cpp b/src/bird/bird.cpp
index 5ffb3e8..fd1c70c 100644
--- a/src/bird/bird.cpp
+++ b/src/bird/bird.cpp
@@ -405,31 +405,36 @@ void Bird::pick_FlyTarget(const SDL_FPoint& player_pos) {
     float angle, radius, dx, dy, dist_sq;
     constexpr int max_attempts = 100;
 
+    SDL_FPoint new_pos = target_pos;
     for (int i = 0; i < max_attempts; ++i) {
         angle = (rand() % 628) / 100.0f;  // 0 to ~2*PI
         radius = MIN_RADIUS + (rand() % static_cast<int>(MAX_RADIUS - MIN_RADIUS));
 
-        target_pos.x = player_pos.x + cosf(angle) * radius;
-        target_pos.y = player_pos.y - FLIGHT_HEIGHT + sinf(angle) * (radius * 0.3f);
+        new_pos.x = player_pos.x + cosf(angle) * radius;
+        new_pos.y = player_pos.y - FLIGHT_HEIGHT + sinf(angle) * (radius * 0.3f);
 
         // Clamp within map bounds
-        target_pos.x = std::clamp(target_pos.x, 0.0f, static_cast<float>(Map::size.x * Tile::tile_size));
-        target_pos.y = std::clamp(target_pos.y, 0.0f, static_cast<float>(Map::size.y * Tile::tile_size));
+        new_pos.x = std::clamp(new_pos.x, 0.0f, static_cast<float>(Map::size.x * Tile::tile_size));
+        new_pos.y = std::clamp(new_pos.y, 0.0f, static_cast<float>(Map::size.y * Tile::tile_size));
 
-        dx = target_pos.x - pos_x;
-        dy = target_pos.y - pos_y;
+        dx = new_pos.x - pos_x;
+        dy = new_pos.y - pos_y;
         dist_sq = dx * dx + dy * dy;
 
         if (!Map::is_FreePosition({
-                    target_pos.x - tile_size / 2,
-                    target_pos.y - tile_size / 2,
+                    new_pos.x - tile_size / 2,
+                    new_pos.y - tile_size / 2,
                     tile_size,
                     tile_size
                     }))
-            dist_sq = MIN_DIST*MIN_DIST+1;
+            continue;
 
-        if (dist_sq >= MIN_DIST * MIN_DIST)
+        //dist_sq = MIN_DIST*MIN_DIST+1;
+
+        if (dist_sq >= MIN_DIST * MIN_DIST) {
+            target_pos = new_pos;
             return;
+        }
     };
     set_State(BirdState::IDLE, 0.8);
 }
@@ -437,18 +442,21 @@ void Bird::pick_FlyTarget(const SDL_FPoint& player_pos) {
 void Bird::pick_GroundTarget(const SDL_FPoint& player_pos) {
     constexpr int max_attempts = 100;
 
+    SDL_FPoint new_pos = target_pos;
     for (int i = 0; i < max_attempts; ++i) {
         float offset_x= static_cast<float>((rand() % 64) - 32);  // -32 to +32
         float offset_y= static_cast<float>((rand() % 64) - 32);  // -32 to +32
-        target_pos.x = player_pos.x + offset_x;
-        target_pos.y = player_pos.y + offset_y;
+        new_pos.x = player_pos.x + offset_x;
+        new_pos.y = player_pos.y + offset_y;
         if (Map::is_FreePosition({
-                    target_pos.x - tile_size / 2,
-                    target_pos.y - tile_size / 2,
+                    new_pos.x - tile_size / 2,
+                    new_pos.y - tile_size / 2,
                     tile_size,
                     tile_size
-                    }))
+                    })) {
+            target_pos = new_pos;
             return;
+        }
     };
     set_State(BirdState::IDLE, 0.8);
 }
diff --git a/src/character/animation.hpp b/src/character/animation.hpp
index 4fbf771..1d12396 100644
--- a/src/character/animation.hpp
+++ b/src/character/animation.hpp
@@ -31,6 +31,7 @@ struct CharacterAnimation {
     std::unordered_map<WalkDirection, AnimationData> build;
     std::unordered_map<WalkDirection, AnimationData> hit;
     std::unordered_map<WalkDirection, AnimationData> attack_sword;
+    std::unordered_map<WalkDirection, AnimationData> hit_woodaxe_stone;
     std::unordered_map<WalkDirection, AnimationData> death;
     std::unordered_map<WalkDirection, AnimationData> craft;
     std::unordered_map<WalkDirection, AnimationData> block;
diff --git a/src/character/character.cpp b/src/character/character.cpp
index 9537a0e..35c4eb5 100644
--- a/src/character/character.cpp
+++ b/src/character/character.cpp
@@ -45,6 +45,8 @@ Character::Init(SDL_Renderer* renderer) {
     moving = false;
     flip = false;
     tile_size = 64;
+    height    = 48; 
+    width     = 16;
     collider.w = 7;
     collider.h = 7;
     collider.x = (tile_size/2 - collider.w/2);
@@ -114,6 +116,10 @@ Character::Init(SDL_Renderer* renderer) {
     animation.attack_sword[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Pierce_Base/Pierce_Wood_Side.png", tile_size, tile_size);
     animation.attack_sword[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Pierce_Base/Pierce_Wood_Top.png",   tile_size, tile_size);
 
+    animation.hit_woodaxe_stone[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Slice_Base/Slice_Down.png", tile_size, tile_size);
+    animation.hit_woodaxe_stone[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Slice_Base/Slice_Side.png", tile_size, tile_size);
+    animation.hit_woodaxe_stone[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Slice_Base/Slice_Up.png",   tile_size, tile_size);
+
     animation.death[WalkDirection::DOWN] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Down-Sheet.png", tile_size, tile_size);
     animation.death[WalkDirection::SIDE] = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Side-Sheet.png", tile_size, tile_size);
     animation.death[WalkDirection::UP]   = Animation::load(renderer, "Pixel_Crawler/Entities/Characters/Body_A/Animations/Death_Base/Death_Up-Sheet.png",   tile_size, tile_size);
@@ -410,18 +416,8 @@ Character::find_ClosestObject(SDL_Point* tile_found, ObjectCategory category) {
             if (selected_item->object_type == InventoryObjectType::ITEM) {
                 it = static_cast<InventoryItem*>(selected_item);
             }
-            if ( category == o->category  ) {
-                if ( o->category == ObjectCategory::BUILDING ) {
-                    *tile_found = tile_point;
-                    return &object;
-                }
-                if ( o->category == ObjectCategory::RESOURCE && it &&
-                     static_cast<Resource*>(o)->is_Collectable(it->type)) {
-                    *tile_found = tile_point;
-                    return &object;
-                }
-            }
             if ( (category == ObjectCategory::NONE && o->category != ObjectCategory::STATIC)) {
+                // THATS MIXING SHT
                 if ( (o->category == ObjectCategory::RESOURCE && it &&
                      (static_cast<Resource*>(o)->is_Collectable(it->type)))
                       || o->category == ObjectCategory::BUILDING) {
@@ -432,6 +428,18 @@ Character::find_ClosestObject(SDL_Point* tile_found, ObjectCategory category) {
                     Vegetable* veg = static_cast<Vegetable*>(o);
                     if (veg->is_Collectable())
                         return &object;
+                } else {
+                }
+            } else
+            if ( category == o->category  ) {
+                if ( o->category == ObjectCategory::BUILDING ) {
+                    *tile_found = tile_point;
+                    return &object;
+                }
+                if ( o->category == ObjectCategory::RESOURCE && it &&
+                     static_cast<Resource*>(o)->is_Collectable(it->type)) {
+                    *tile_found = tile_point;
+                    return &object;
                 }
             }
         }
@@ -1005,6 +1013,32 @@ Character::death() {
 }
 
 
+void
+set_AttackAnimation(AnimationData* &ad, WalkDirection& dir, Character* ch) {
+    switch (static_cast<InventoryItem*>(ch->selected_item)->type) {
+        case ItemType::SWORD_WOOD:
+            ad = &ch->animation.attack_sword[dir];
+            break;
+
+        case ItemType::WOODAXE_STONE:
+            ad = &ch->animation.hit_woodaxe_stone[dir];
+            break;
+
+        default:
+            ad = nullptr;
+            return;
+    }
+
+    if (!ad || ad->frames.empty()) {
+        fprintf(stderr,
+                "ERROR: Empty ATTACK animation\n"
+                "  item=%d dir=%d\n",
+                (int)static_cast<InventoryItem*>(ch->selected_item)->type,
+                (int)dir
+               );
+    }
+}
+
 void
 Character::handle_Animation() {
     AnimationData* active_anim_ref = nullptr;
@@ -1035,7 +1069,7 @@ Character::handle_Animation() {
             break;
 
         case CharacterStatus::ATTACK:
-            active_anim_ref = &animation.attack_sword[dir];
+            set_AttackAnimation(active_anim_ref, dir, this);
             break;
 
         case CharacterStatus::HIT:
@@ -1069,6 +1103,10 @@ Character::handle_Animation() {
 
     if (status == CharacterStatus::DEAD) {
         if (active_anim_ref) {
+            /* THIS SHOULD NOT BE REQUIRED
+            if ( active_anim_ref->frames.size() == 0)
+                active_anim_ref = &animation.idle[dir];
+                */
             AnimationData& ad = *active_anim_ref;
 
             // lock last frame
@@ -1088,6 +1126,11 @@ Character::handle_Animation() {
         Animation::update(*active_anim_ref, static_cast<float>(Default::delta_time));
         active_anim = active_anim_ref;
     }
+
+    if (active_anim->frames.size() == 0) {
+        std::cout << "STATUS: " << (int)status << " " << std::endl;
+        exit(1);
+    }
 }
 
 
@@ -1115,7 +1158,6 @@ Character::handle_Input(Input& input, SDL_Rect win_size) {
     }
 
     // BUILD MENU
-    //if (BuildingData::draw_menu_building) {
     if (active_menu == CharacterMenuType::BUILDING) {
         if (BuildingData::menu_Hovering(input, win_size, discovered_buildings)) {
             if (input.click_left_released) {
@@ -1138,7 +1180,6 @@ Character::handle_Input(Input& input, SDL_Rect win_size) {
     } else
     // INVENTORY
     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) {
diff --git a/src/character/character.hpp b/src/character/character.hpp
index 1e9d33d..1a91f2a 100644
--- a/src/character/character.hpp
+++ b/src/character/character.hpp
@@ -164,6 +164,8 @@ class Character {
     float death_duration;
     float death_duration_max;
 
+    int height;
+    int width;
     SDL_FRect     collider;
     SDL_FPoint    collider_world;
     SDL_Point tile_world;
diff --git a/src/character/enemy.cpp b/src/character/enemy.cpp
index 4a76807..dceac29 100644
--- a/src/character/enemy.cpp
+++ b/src/character/enemy.cpp
@@ -225,6 +225,8 @@ Enemy::Draw(SDL_Renderer* renderer) {
     */
 
     // HEALTH BAR
+    if (stats.health <= 0) return;
+
     float bar_width  = Scale(40.0f);
     float bar_height = Scale(4.0f);
 
diff --git a/src/defaults/defaults.cpp b/src/defaults/defaults.cpp
index db1b227..ef9f18f 100644
--- a/src/defaults/defaults.cpp
+++ b/src/defaults/defaults.cpp
@@ -21,7 +21,7 @@ namespace Default {
     int   fps = 0;
     int   fps_counter = 0;
 
-    float game_scale = 2;
+    float game_scale;
 
     SDL_Color menu_hovering_color = {255, 255, 100, 160};
 
diff --git a/src/defaults/input.cpp b/src/defaults/input.cpp
index c9b910f..7c8ef68 100644
--- a/src/defaults/input.cpp
+++ b/src/defaults/input.cpp
@@ -18,304 +18,3 @@ Input::update_Mousetileposition() {
         static_cast<int>((Input::mouse_state.y - mouse_game_offset.y) / selection_size)
     };
 }
-
-
-/*
-void
-Input::event_InputModify(SDL_Event& event) {
-    if (cursor_over_tileset) {
-        mouse_game_offset = {(int)Tile::tileset_offset.x,
-                            (int)Tile::tileset_offset.y };
-    }
-    switch (event.type) {
-        case SDL_EVENT_KEY_DOWN:
-            switch (event.key.scancode) {
-                case SDL_SCANCODE_H:
-                    Tile::draw_tile_set = !Tile::draw_tile_set;
-                    break;
-                case SDL_SCANCODE_O: {
-                    Tile::tile_selected   = false;
-                    Tile::object_selected = false;
-                    Tile::draw_tile_set   = true;
-
-                    ModifyState_s state;
-                    if (Tile::active_tileset_type == TILE_BACKGROUND) {
-                        state = MODIFY_FLOOR_TYPE;
-                    } else {
-                        if (Input::pressed_ctrl)
-                            state = MODIFY_OBJECTS_PROPS;
-                        else if (Input::pressed_shift)
-                            state = MODIFY_OBJECTS_PROPS_RESOURCE;
-                        else
-                            state = MODIFY_OBJECTS;
-                    }
-
-                    Default::modify_state = (Default::modify_state != state)
-                        ? state
-                        : MODIFY_TILES;
-                    break; }
-                default:
-                    break;
-                case SDL_SCANCODE_M:
-                    // if (Default::game_state != GAME_MODIFY || !Tile::draw_tile_set) break;
-                    if (!Tile::draw_tile_set) {
-                        Tile::draw_tile_set   = true;
-                        break;
-                    }
-
-                    Tile::tile_selected   = false;
-                    Tile::object_selected = false;
-                    Tile::draw_tile_set   = true;
-                    if (Input::pressed_ctrl) {
-                        Default::modify_state = MODIFY_TILES;
-                            Tile::active_tileset_type =
-                            static_cast<TileType>(
-                                (Tile::active_tileset_type + 1) == TILE_TYPE_LAST
-                                ? TILE_TYPE_FIRST+1
-                                : Tile::active_tileset_type+1
-                            );
-                        Tile::active_tileset_id = 0;
-                    } else if (Input::pressed_shift)
-                        Tile::active_tileset_id =
-                            Tile::active_tileset_id == 0
-                            ? Tile::tilesets[Tile::active_tileset_type].size() - 1
-                            : Tile::active_tileset_id -1;
-                    else {
-                        Tile::active_tileset_id =
-                            (Tile::active_tileset_id + 1) % Tile::tilesets[Tile::active_tileset_type].size();
-                    }
-
-                    Tile::active_tileset = &Tile::tilesets[Tile::active_tileset_type][Tile::active_tileset_id];
-                    //Tile::fix_TilesetObjectInfo();
-                    break;
-                case SDL_SCANCODE_RIGHTBRACKET:
-                    if (Input::pressed_ctrl) {
-                        Tile::selection_tile_dimension.x++;
-                        Tile::selection_tile_dimension.y++;
-                    } else if (Input::pressed_shift)
-                        Tile::selection_tile_dimension.y++;
-                    else
-                        Tile::selection_tile_dimension.x++;
-                    break;
-                case SDL_SCANCODE_SLASH: // thats - MINUS
-                    if (Input::pressed_ctrl) {
-                        Tile::selection_tile_dimension.x = Tile::selection_tile_dimension.x > 0
-                            ? Tile::selection_tile_dimension.x -1 : 0;
-                        Tile::selection_tile_dimension.y = Tile::selection_tile_dimension.y > 1
-                            ? Tile::selection_tile_dimension.y -1 : 1;
-                    } else if (Input::pressed_shift)
-                        Tile::selection_tile_dimension.y = Tile::selection_tile_dimension.y > 1
-                            ? Tile::selection_tile_dimension.y -1 : 1;
-                    else
-                        Tile::selection_tile_dimension.x = Tile::selection_tile_dimension.x > 1
-                            ? Tile::selection_tile_dimension.x -1 : 1;
-                    break;
-                case SDL_SCANCODE_S:
-                    if (Input::pressed_ctrl) {
-                        Map::save_MapTiles(Map::tile_map, Map::save_path);
-                        Map::save_TileCollision( Map::save_collission_path);
-                        Tile::save_Collissions();
-                        Tile::save_Objects();
-                    } else {
-                        Default::game_scale = (Default::game_scale == 1) ? 2 : 1;
-                    }
-                    break;
-                case SDL_SCANCODE_R:
-                    if (Input::pressed_ctrl) {
-                        Map::Reset();
-                    }
-                    break;
-                case SDL_SCANCODE_K:
-                    if (Input::pressed_shift) {
-                        Map::init_Collider();
-                    } else if (Input::pressed_ctrl
-                               && Default::modify_state == MODIFY_COLLISSION) {
-                        Map::set_CollissionFromTileset();
-                    } else
-                    Default::modify_state = (Default::modify_state != MODIFY_COLLISSION)
-                        ? MODIFY_COLLISSION
-                        : MODIFY_TILES;
-                    break;
-        }
-    }
-}
-*/
-
-/*
-void
-Input::event_InputPlay(SDL_Event& event, Character& player) {
-    if (cursor_over_tileset) {
-        mouse_game_offset = {(int)Tile::tileset_offset.x,
-                            (int)Tile::tileset_offset.y };
-    }
-
-    clicked_on_map = false;
-    switch (event.type) {
-        case SDL_EVENT_KEY_DOWN: {
-                 if (event.key.scancode >= SDL_SCANCODE_1 && event.key.scancode <= SDL_SCANCODE_6) {
-                     Inventory::selected_hotbar_last = Inventory::selected_hotbar;
-                     Inventory::selected_hotbar = (int)(event.key.scancode - SDL_SCANCODE_1) + 1;
-                 }
-                 break;
-             }
-
-        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;
-                    Research::draw_menu  = false;
-                    break;
-                case SDL_SCANCODE_R:
-                    Inventory::selected_hotbar = !Inventory::selected_hotbar ? Inventory::selected_hotbar_last : 0;
-                    break;
-                case SDL_SCANCODE_E:
-                    Inventory::draw_menu = !Inventory::draw_menu;
-                    BuildingData::draw_menu_building = false;
-                    break;
-                case SDL_SCANCODE_K:
-                    //player.build_SetDeconstruct();
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case SDL_EVENT_MOUSE_BUTTON_UP:
-            if (!pressed_ctrl && !pressed_shift)
-                clicked_on_map = true;
-            break;
-        default:
-            break;
-    }
-}
-*/
-
-/*
-void
-Input::event_Input(SDL_Window* window, SDL_Rect& win_size) {
-
-    SDL_Event event;
-
-    Uint32 mouse_buttons = SDL_GetMouseState(&Input::mouse_state_raw.x, &Input::mouse_state_raw.y);
-
-    Input::mouse_state.x = Input::mouse_state_raw.x/Default::game_scale;
-    Input::mouse_state.y = Input::mouse_state_raw.y/Default::game_scale;
-
-    Input::click_left = (mouse_buttons & SDL_BUTTON_MASK(SDL_BUTTON_LEFT)) != 0;
-
-    // START set Input::mouse_tile_position
-    Tile::set_HoveringTileset(Input::mouse_state);
-    cursor_over_tileset = Tile::hovering_set;
-
-    mouse_game_offset = {Map::offset.x,
-                         Map::offset.y };
-    // END set Input::mouse_tile_position
-    Input::click_left_released = false;
-    Input::pressed_return_released = false;
-    pressed_arrowdown_released = false;
-    pressed_arrowup_released = false;
-    pressed_c_released = false;
-
-    while (SDL_PollEvent(&event)) {
-        switch (event.type) {
-            case SDL_EVENT_QUIT:
-                game_running = false;
-                break;
-            case SDL_EVENT_WINDOW_RESIZED:
-            case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: {
-                int w, h;
-                SDL_GetWindowSize(window, &w, &h);
-                win_size.w = w;
-                win_size.h = h;
-                break;
-            }
-            case SDL_EVENT_MOUSE_BUTTON_UP:
-                Input::click_left_released = true;
-                Input::click_left = false;
-                break;
-            case SDL_EVENT_MOUSE_WHEEL:
-                if (event.wheel.y > 0)
-                    Default::game_scale += 0.1f;
-                else if (event.wheel.y < 0)
-                    Default::game_scale -= 0.1f;
-
-                if (Default::game_scale < 0.5)
-                    Default::game_scale = 0.5;
-                if (Default::game_scale > 4.2f)
-                    Default::game_scale = 4.2f;
-                break;
-
-            case SDL_EVENT_KEY_DOWN:
-                switch (event.key.scancode) {
-                    case SDL_SCANCODE_LSHIFT:
-                        Input::pressed_shift = true;
-                        break;
-                    case SDL_SCANCODE_LCTRL:
-                        Input::pressed_ctrl = true;
-                        break;
-                    case SDL_SCANCODE_RETURN:
-                        Input::pressed_return = true;
-                        break;
-                    case SDL_SCANCODE_I:
-                        Ui::draw_key_info = !Ui::draw_key_info;
-                        break;
-                    case SDL_SCANCODE_C:
-                        Input::pressed_c = true;
-                        break;
-                    case SDL_SCANCODE_9:
-                            Default::game_state = GAME_PLAY;
-                            break;
-                    case SDL_SCANCODE_0:
-                        Default::game_state = GAME_MODIFY;
-                        Tile::draw_tile_set = true;
-                        break;
-                    case SDL_SCANCODE_Q:
-                        if (Input::pressed_ctrl)
-                            game_running = false;
-                        break;
-                    default:
-                        break;
-                }
-                break;
-
-            case SDL_EVENT_KEY_UP:
-                switch (event.key.scancode) {
-                    case SDL_SCANCODE_LCTRL:
-                        Input::pressed_ctrl = false;
-                        break;
-                    case SDL_SCANCODE_LSHIFT:
-                        Input::pressed_shift = false;
-                        break;
-                    case SDL_SCANCODE_C:
-                        Input::pressed_c = false;
-                        Input::pressed_c_released = true;
-                        break;
-                    case SDL_SCANCODE_RETURN:
-                        Input::pressed_return = false;
-                        Input::pressed_return_released = true;
-                        break;
-                    case SDL_SCANCODE_DOWN:
-                        Input::pressed_arrowdown_released = true;
-                        break;
-                    case SDL_SCANCODE_UP:
-                        Input::pressed_arrowup_released = true;
-                        break;
-                    default:
-                        break;
-                }
-            default:
-                break;
-        }
-
-
-        // Handle Game Moddes
-        if (Default::game_state == GAME_MODIFY)
-            event_InputModify(event);
-        else
-            event_InputPlay(event, player);
-        update_Mousetileposition();
-    }
-
-
-}
-*/
diff --git a/src/defaults/ui.cpp b/src/defaults/ui.cpp
index 054502f..71d8654 100644
--- a/src/defaults/ui.cpp
+++ b/src/defaults/ui.cpp
@@ -34,14 +34,16 @@ keyboard_layout = {
 
 std::vector<std::pair<std::string, std::string>>
 keyboard_layout_playing = {
-    {               "0", "Game mode: modify"},
+    {             "f10", "Game mode: modify"},
     {          "Scroll", "Zoom in or out"},
+    {               "0", "Zoom reset"},
     {       "[w,a,s,d]", "Move in direction"},
-    {               "c", "Collect item"},
+    {               "c", "Collect item | interact | plant"},
+    {               "i", "Info toggle"},
     {               "e", "Inventory toggle"},
     {               "b", "Build menu toggle"},
     {               "k", "Building set deconstruct"},
-    {     "Right-Click", "Attack | Build | Deconstruct"},
+    {      "Left-Click", "Attack | Build | Deconstruct"},
     {          "ctrl+q", "Exit game"}
 };
 
diff --git a/src/game/state_modify.cpp b/src/game/state_modify.cpp
index b1b3166..80ae20b 100644
--- a/src/game/state_modify.cpp
+++ b/src/game/state_modify.cpp
@@ -12,6 +12,9 @@ bool StateModify::Init(Game* game) {
         std::cerr << "Something went wrong in StateModify::Init\n";
     }
 
+    //Tile::tileset_offset.x = Map::offset.x;
+    //Tile::tileset_offset.y = Map::offset.y;
+
     return true;
 }
 
@@ -170,8 +173,9 @@ void StateModify::StateModify::Update(Game* game) {
 }
 
 void StateModify::StateModify::Render(Game* game) {
-    if (Tile::draw_tile_set)
+    if (Tile::draw_tile_set) {
         Tile::draw_Tileset(game->renderer, game->input);
+    }
 
     if (Tile::object_selected)
         Tile::draw_SelectedObject(game->renderer, game->input);
diff --git a/src/game/state_playing.cpp b/src/game/state_playing.cpp
index 02c8c57..6df48c1 100644
--- a/src/game/state_playing.cpp
+++ b/src/game/state_playing.cpp
@@ -43,24 +43,26 @@ bool StatePlaying::Init(Game* game) {
     if (Map::tile_collission_map.size() == 0) Map::init_Collider();
 
     Map::offset = {0, 0};
-    Default::game_scale = 2;
+    Default::game_scale = 2.8;
 
 
     // START CHEAT
     if (game->is_cheating) {
-        player->inventory->add_Resource(ResourceType::WOOD, 120, player->messages.get());
+        player->inventory->add_Resource(ResourceType::WOOD,  120, player->messages.get());
         player->inventory->add_Resource(ResourceType::STONE, 120, player->messages.get());
-        player->inventory->add_Resource(ResourceType::CLAY, 120, player->messages.get());
-        player->inventory->add_Resource(ResourceType::IRON, 120, player->messages.get());
+        player->inventory->add_Resource(ResourceType::CLAY,  120, player->messages.get());
+        player->inventory->add_Resource(ResourceType::IRON,  120, player->messages.get());
         player->set_ResourceDiscovery(ResourceType::WOOD);
         player->set_ResourceDiscovery(ResourceType::STONE);
         player->set_ResourceDiscovery(ResourceType::CLAY);
         player->set_ResourceDiscovery(ResourceType::IRON);
-        player->researched_items[static_cast<size_t>(ItemType::SWORD_WOOD)] = true;
-        player->researched_items[static_cast<size_t>(ItemType::CULTIVATOR)] = true;
+        player->researched_items[static_cast<size_t>(ItemType::SWORD_WOOD)]    = true;
+        player->researched_items[static_cast<size_t>(ItemType::WOODAXE_STONE)] = true;
+        player->researched_items[static_cast<size_t>(ItemType::CULTIVATOR)]    = true;
         player->researched_buildings[static_cast<size_t>(BuildingType::CRAFTING_WOOD_1)] = true;
         player->set_BuildingDiscovery();
         player->inventory->add_Item(ItemType::SWORD_WOOD, player->messages.get());
+        player->inventory->add_Item(ItemType::WOODAXE_STONE, player->messages.get());
         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());
@@ -99,6 +101,8 @@ void StatePlaying::handle_Events(SDL_Event& event, Game* game) {
                  if (event.key.scancode >= SDL_SCANCODE_1 && event.key.scancode <= SDL_SCANCODE_6) {
                      player->inventory->selected_hotbar_last = player->inventory->selected_hotbar;
                      player->inventory->selected_hotbar = (int)(event.key.scancode - SDL_SCANCODE_1) + 1;
+                 } if (event.key.scancode == SDL_SCANCODE_0) {
+                     Default::game_scale = 2.8;
                  }
                  break;
              }
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 08e8881..717c11b 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -168,7 +168,6 @@ namespace Map {
 
     void
     set_TileCollissionForObjects(SDL_Point map_tile) {
-        std::cout << "SET " << map_tile.x << " " << map_tile.y << std::endl;
         const size_t tile_index = static_cast<size_t>(map_tile.y * Map::size.x + map_tile.x);
 
         const size_t scale = Tile::tile_size / Tile::tile_collider_size;
@@ -903,12 +902,17 @@ namespace Map {
 
 
                     player_behind = false;
-                    if ( object->is_InFrontOf({m_xf, m_yf},
+                    int am_i_behind_an_object = object->is_InFrontOf({m_xf, m_yf},
                                            {character_collider_x,
                                             character_collider_y,
                                             player.collider.w,
-                                            player.collider.h})) {
-                        player_behind = true;
+                                            player.collider.h});
+                    if (am_i_behind_an_object) {
+                        if ( am_i_behind_an_object == 1 &&
+                             character_collider_y-player.height/3 > m_yf &&
+                             ( player.collider_world.x > m_xf ||
+                               player.collider_world.x < m_xf+object->dimension.x ) )
+                            player_behind = true;
                         if (!character_drawn) {
                             //std::cout << "DRAW BEHIND\n";
                             player.Draw(renderer);
diff --git a/src/map/tile.cpp b/src/map/tile.cpp
index 90080f5..67e0255 100644
--- a/src/map/tile.cpp
+++ b/src/map/tile.cpp
@@ -28,7 +28,7 @@ namespace Tile {
 
     std::unordered_map<TileType, std::vector<TileSet>> tilesets;
     std::vector<SDL_Point> selected_tiles;
-    SDL_FPoint tileset_offset = {0, Ui::top_bar_height/Default::game_scale};
+    SDL_FPoint tileset_offset = {0, Ui::top_bar_height};
     SDL_FPoint tileset_offset_to_set = {0, 0};
     bool setting_tileset_offset = false;
 
@@ -1217,7 +1217,7 @@ namespace Tile {
 
                 for (int y = 0; y < object.position.h && !tile_exists; y++) {
                     for (int x = 0; x < object.position.w && !tile_exists; x++) {
-                        bool shall_set_on_tile = true;
+                        //bool shall_set_on_tile = true;
                         o.draw_from_this_tile = false;
 
                         o.position.x = x; o.position.y = y;
@@ -1247,7 +1247,7 @@ namespace Tile {
                                 }
                                 std::cout << '\n';
                             }
-                            shall_set_on_tile = check;
+                            //shall_set_on_tile = check;
 
                             std::cout << "---- tile (" << x << "," << y << ") ----\n";
                         } else {
diff --git a/src/objects/object.cpp b/src/objects/object.cpp
index 8ae6e2f..a0781e7 100644
--- a/src/objects/object.cpp
+++ b/src/objects/object.cpp
@@ -11,6 +11,29 @@
 std::vector<Object*> Object::objects;
 
 
+Object::~Object() {
+    for (int y = 0; y < dimension.y; y++) {
+        for (int x = 0; x < dimension.x; x++) {
+            size_t m_id = static_cast<size_t>((y+world_tile_position.y)*Map::size.x+(x+world_tile_position.x));
+            if (m_id >= static_cast<size_t>(Map::size.x*Map::size.y))
+                continue;
+            std::vector<TileObject>& objects = Map::tile_map[m_id].objects;
+
+            for (auto it = objects.begin(); it != objects.end(); ) {
+                if (it->object_id == id)
+                    it = objects.erase(it);
+                else ++it;
+            }
+        }
+    }
+    for (auto it = objects.begin(); it != objects.end(); ++it) {
+        if (*it == this) {
+            objects.erase(it);
+            break;
+        }
+    }
+};
+
 const char* Object::to_String(ObjectType type) {
         switch (type) {
             case ObjectType::NONE:   return "NONE";
@@ -62,7 +85,7 @@ Object::get_SetPosition() {
         return Tile::tilesets[tileset_type][tileset_id].objects[tileset_object_id].tileset_info.set_position;
 }
 
-bool
+int
 Object::is_InFrontOf(SDL_FPoint world_position, SDL_FRect rect) {
     const int scale = Tile::tile_size / Tile::tile_collider_size;
 
@@ -92,7 +115,8 @@ Object::is_InFrontOf(SDL_FPoint world_position, SDL_FRect rect) {
 
     // is above object
     if (rect_y+rect_h < obj_y)
-        return true;
+        return 2;
+
     // is below object
     if (obj_y + obj_h <= rect_y)
         return false;
@@ -100,7 +124,7 @@ Object::is_InFrontOf(SDL_FPoint world_position, SDL_FRect rect) {
     //
     int rect_row = rect_y - obj_y;
     if (rect_row >= obj_h)
-        return true;
+        return 2;
 
     bool collission_below  = false;
     bool anywhere_above  = false;
@@ -116,7 +140,7 @@ Object::is_InFrontOf(SDL_FPoint world_position, SDL_FRect rect) {
                     //std::cout << "ABOVE \n";
                     anywhere_above = true;
                     if (x > start_x && x < end_x) {
-                        std::cout << "SUPABOVE \n";
+                        //std::cout << "SUPABOVE \n";
                         //collission_above = true;
                         return false;
                     }
diff --git a/src/objects/object.hpp b/src/objects/object.hpp
index 0d7b4c9..3586bb1 100644
--- a/src/objects/object.hpp
+++ b/src/objects/object.hpp
@@ -86,19 +86,12 @@ class Object {
     }
 
     virtual
-    ~Object() {
-        for (auto it = objects.begin(); it != objects.end(); ++it) {
-            if (*it == this) {
-                objects.erase(it);
-                break;
-            }
-        }
-    };
+    ~Object();
 
     virtual SDL_Point
     get_SetPosition();
 
-    bool
+    int
     is_InFrontOf(SDL_FPoint ob_position, SDL_FRect rect);
 
     bool