Nimbin[12]?SDL & Graphics / mapcreator / src/farm/farm.cpp

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
src/farm/farm.cpp 6.6 KB · 194 lines raw
#include "farm.hpp"

#include "map/map.hpp"


namespace Farm {
    void soil_Place(SDL_Point position) {
        static const SDL_Point offsets[] = {
            { 0,  0 },
            { -1, 0 },
            {  1, 0 },
            {  0,-1 },
            {  0, 1 }
        };

        for (const SDL_Point& off : offsets) {
            SDL_Point p{ position.x + off.x, position.y + off.y };
            const size_t id = Map::get_IdFromTilePoint(p);
            if (id == SIZE_MAX)
                continue;

            auto& overlays = Map::tile_map[id].overlays;

            // --- RULE 1 ---
            // If any existing overlay on this tile already has offset {0,0},
            // skip placing anything on this tile.
            if (!overlays.empty()) {
                for (const auto& o : overlays) {
                    if (o.set_category == TileCategory::TILE_OVERLAY_FARM && o.set_position.x == 0 && o.set_position.y == 0)
                        goto skip_this_offset;
                }
            }

            // --- RULE 2 ---
            // If we are placing at offset {0,0} on a tile that
            // has overlays with offsets != {0,0}, remove them first.
            if (off.x == 0 && off.y == 0) {
                bool requires_cleanup = false;

                // Detect whether removal is needed
                for (const auto& o : overlays) {
                    if (o.set_category == TileCategory::TILE_OVERLAY_FARM &&
                            (o.set_position.x != 0 || o.set_position.y != 0)) {
                        requires_cleanup = true;
                        break;
                    }
                }

                // Remove only TILE_OVERLAY_FARM overlays (non-zero offsets)
                if (requires_cleanup) {
                    overlays.erase(
                            std::remove_if(
                                overlays.begin(),
                                overlays.end(),
                                [](const Tile_s& o) {
                                return o.set_category == TileCategory::TILE_OVERLAY_FARM &&
                                (o.set_position.x != 0 || o.set_position.y != 0);
                                }
                                ),
                            overlays.end()
                            );
                }
            }

            // --- PLACE ---
            overlays.emplace_back(Tile_s{
                    0,                      // set_id
                    0,                      // object_id
                    TileCategory::TILE_OVERLAY_FARM,
                    off                     // set_position
                    });

skip_this_offset:
            continue;
        }
    }
    void OLDsoil_Remove(SDL_Point position) {
        static const SDL_Point offsets[] = {
            { 0,  0 },
            { -1, 0 },
            {  1, 0 },
            {  0,-1 },
            {  0, 1 }
        };

        for (const SDL_Point& off : offsets) {
            SDL_Point p{ position.x + off.x, position.y + off.y };
            const size_t id = Map::get_IdFromTilePoint(p);
            if (id == SIZE_MAX)
                continue;

            auto& overlays = Map::tile_map[id].overlays;

            overlays.erase(
                    std::remove_if(
                        overlays.begin(),
                        overlays.end(),
                        [&](const Tile_s& o) {
                            return o.set_category == TileCategory::TILE_OVERLAY_FARM &&
                                o.set_position.x == off.x &&
                                o.set_position.y == off.y;
                        }),
                    overlays.end()
            );
        }
    }

    void soil_Remove(SDL_Point position) {
        static const SDL_Point offsets[] = {
            { 0,  0 },
            { -1, 0 },
            {  1, 0 },
            {  0,-1 },
            {  0, 1 }
        };

        struct ToPlace { SDL_Point target; };
        std::vector<SDL_Point> to_place;

        for (const SDL_Point& off : offsets) {
            SDL_Point p{ position.x + off.x, position.y + off.y };
            const size_t id = Map::get_IdFromTilePoint(p);
            if (id == SIZE_MAX)
                continue;

            auto& overlays = Map::tile_map[id].overlays;

            // Remove and mark overlays to recreate
            overlays.erase(
                    std::remove_if(overlays.begin(), overlays.end(),
                        [&](const Tile_s& o) {
                            if (o.set_category != TileCategory::TILE_OVERLAY_FARM)
                                return false;

                            // Remove overlay matching offset
                            if (o.set_position.x == off.x && o.set_position.y == off.y)
                                return true;
                            else if (!(off.x == 0 && off.y == 0) &&
                                    o.set_position.x == 0 && o.set_position.y == 0) {
                                // Remove overlay at {0,0} and mark to recreate
                                to_place.push_back(p);
                                return true;
                            }
                            return false;
                        }),
                        overlays.end()
                    );
        }

        for (const SDL_Point& p : to_place) {
            soil_Place(p);
        }
    }

    bool soil_IsMaptile(SDL_Point& tile_world) {
        for (Tile_s o : Map::tile_map[Map::get_IdFromTilePoint(tile_world)].overlays) {
            if ( o.set_category == TileCategory::TILE_OVERLAY_FARM &&
                 o.set_position.x == 0 && o.set_position.y == 0) {
                return true;
            }
        }
        return false;
    }

    void soil_Render(SDL_Renderer* renderer,
            SDL_FPoint position,
            SDL_Point position_offset,
            Uint8 alpha) {
        SDL_FRect src = {16.0f + position_offset.x * 16.0f,
            16.0f + position_offset.y * 16.0f,
            16.0f, 16.0f};

        SDL_FRect dst = {Scale(position.x),
            Scale(position.y),
            Scale(16),
            Scale(16)};

        SDL_Texture* tex = Tile::tilesets[TILE_OVERLAY][0].texture;

        SDL_SetTextureAlphaMod(tex, alpha);
        SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

        SDL_RenderTexture(renderer, tex, &src, &dst);

        SDL_SetTextureAlphaMod(tex, 255);
    }

    void soil_RenderRemove(SDL_Renderer* renderer, SDL_FPoint position) {
        SDL_FRect dst = {Scale(position.x), Scale(position.y), Scale(16), Scale(16)};

        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 100);
        SDL_RenderFillRect(renderer, &dst);
    }
}