From e74bbbbbd2b0c938d21b4ceb2ca46c8444d52d44 Mon Sep 17 00:00:00 2001 From: Edgaru089 Date: Thu, 11 Apr 2024 17:00:40 +0800 Subject: [PATCH] WIP Map editor --- bundle.cpp | 4 +- ig001.hpp | 56 +++++++++++++++++++ map.cpp | 4 ++ map_types.hpp | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++ types.hpp | 41 ++++++++++++++ 5 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 ig001.hpp create mode 100644 map_types.hpp diff --git a/bundle.cpp b/bundle.cpp index b2a1075..403e39b 100644 --- a/bundle.cpp +++ b/bundle.cpp @@ -20,6 +20,9 @@ std::map primitive_name_upper = { {render_Polygon, "POLY"}, }; + +char buf[1024]; + std::string toString(render_Bundle &b) { #define APPEND_FMT(...) \ do { \ @@ -30,7 +33,6 @@ std::string toString(render_Bundle &b) { #define EXPAND_RGBA(packed) ((packed >> IM_COL32_R_SHIFT) & 0xff), ((packed >> IM_COL32_G_SHIFT) & 0xff), ((packed >> IM_COL32_B_SHIFT) & 0xff) std::string str; - static char buf[1024]; APPEND_FMT("BUNDLE %s\n", b.name.c_str()); for (auto &p: b.prims) { diff --git a/ig001.hpp b/ig001.hpp new file mode 100644 index 0000000..1e035fb --- /dev/null +++ b/ig001.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "gui/gui.hpp" +#include "gui/imgui/imgui.h" +#include "types.hpp" +#include + +static inline Vec2 DragButton(const char *pushid) { + if (strlen(pushid) > 0) + ig::PushID(pushid); + + Vec2 d; // = 0 + ig::Button("Drag"); + if (ig::IsItemActive()) + d = ig::GetIO().MouseDelta; + + if (strlen(pushid) > 0) + ig::PopID(); + return d; +} + +static inline bool DragVec2(const char *label, Vec2 *vec2, float speed = 1.0f) { + float f[2] = {(float)vec2->x, (float)vec2->y}; + bool ok = ig::DragFloat2(label, f, speed); + vec2->x = f[0]; + vec2->y = f[1]; + + ig::SameLine(); + Vec2 delta = DragButton(label); + if (delta != Vec2()) { + ok = true; + *vec2 = *vec2 + delta; + } + + return ok; +} + +static inline bool DragBox2(const char *pushid, Box2 *box2, float speed = 1.0f) { + if (strlen(pushid) > 0) + ig::PushID(pushid); + + bool ok1 = DragVec2("Lefttop", &box2->lefttop, speed); + bool ok2 = DragVec2("Size", &box2->size, speed); + + if (strlen(pushid) > 0) + ig::PopID(); + + return ok1 || ok2; +} + +static inline bool DragDouble(const char *label, double *d, float speed = 1.0f) { + float f = (float)*d; + bool ok = ig::DragFloat(label, &f, speed); + *d = f; + return ok; +} diff --git a/map.cpp b/map.cpp index 3233e25..470630c 100644 --- a/map.cpp +++ b/map.cpp @@ -2,7 +2,11 @@ #include "gui/gui.hpp" #include "gui/imgui/imgui.h" #include "gui/imgui/imgui_stdlib.h" +#include "map_types.hpp" +#include +static std::set entities, to_delete; + void ui_map() { } diff --git a/map_types.hpp b/map_types.hpp new file mode 100644 index 0000000..69bfd55 --- /dev/null +++ b/map_types.hpp @@ -0,0 +1,146 @@ + +#include "gui/imgui/imgui.h" +#include "types.hpp" +#include "ig001.hpp" +#include "gui/imgui/imgui_stdlib.h" +#include + + +class EntityBase { +public: + virtual std::string type() = 0; + + virtual std::string to_file() = 0; + + // Pointer to the entity base is pushed outside + virtual void imgui() {} + virtual void draw(Vec2 offset, bool selected) {} +}; + +inline static void draw_box2(Box2 box, bool selected, ImU32 color) { + ImDrawList *list = ig::GetBackgroundDrawList(); + list->AddRect(box.lefttop.im(), (box.lefttop + box.size).im(), color); + if (selected) { + list->AddLine(box.lefttop.im(), (box.lefttop + box.size).im(), color); + list->AddLine((box.lefttop + Vec2(box.size.x, 0)).im(), (box.lefttop + Vec2(0, box.size.y)).im(), color); + } +} + +inline static void draw_vec2(Vec2 vec, bool selected, ImU32 color) { + ImDrawList *list = ig::GetBackgroundDrawList(); + list->AddLine((vec + Vec2(-10, -10)).im(), (vec + Vec2(10, 10)).im(), color); + list->AddLine((vec + Vec2(-10, 10)).im(), (vec + Vec2(10, -10)).im(), color); + if (selected) + list->AddCircle(vec.im(), 7.0f, color); +} + + +// Defined in bundle.cpp +extern char buf[1024]; + +class Hitbox: public EntityBase { +public: + std::string type() override { return "hitbox"; } + std::string to_file() override { + snprintf(buf, sizeof(buf), "HITBOX %lf %lf %lf %lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); + return buf; + } + + void imgui() override { DragBox2("", &box); } + void draw(Vec2 offset, bool selected) override { draw_box2(box.offset(offset), selected, IM_COL32(0, 255, 0, 255)); } + + Box2 box; +}; + +class Player: public EntityBase { +public: + std::string type() override { return "player"; } + std::string to_file() override { + snprintf(buf, sizeof(buf), "PLAYER %lf %lf\n", pos.x, pos.y); + return buf; + } + + void imgui() override { DragVec2("Player Spawn", &pos); } + void draw(Vec2 offset, bool selected) override { draw_vec2(pos, selected, IM_COL32_WHITE); } + + Vec2 pos; +}; + +class HazardRespawn: public EntityBase { +public: + std::string type() override { return "hazard_respawn"; } + std::string to_file() override { + snprintf(buf, sizeof(buf), "HAZARD_RESPAWN %lf %lf %lf %lf %lf %lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y, pos.x, pos.y); + return buf; + } + + void imgui() override { + DragBox2("", &box); + DragVec2("Respawn", &pos); + } + void draw(Vec2 offset, bool selected) override { + draw_box2(box, selected, IM_COL32(255, 0, 255, 255)); + draw_vec2(pos, selected, IM_COL32(255, 0, 255, 255)); + } + + Box2 box; + Vec2 pos; +}; + +class Hazard: public EntityBase { +public: + std::string type() override { return "hazard"; } + std::string to_file() override { + snprintf(buf, sizeof(buf), "HAZARD %lf %lf %lf %lf\n", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); + return buf; + } + + void imgui() override { DragBox2("", &box); } + void draw(Vec2 offset, bool selected) override { draw_box2(box, selected, IM_COL32(255, 0, 0, 255)); } + + Box2 box; +}; + +class Textbox: public EntityBase { +public: + std::string type() override { return "textbox"; } + std::string to_file() override { + std::string str; + snprintf(buf, sizeof(buf), "TEXTBOX %lf %lf %lf %lf ", box.lefttop.x, box.lefttop.y, box.size.x, box.size.y); + str += buf; + + // Escape all the whitespaces + for (char c: text) { + switch (c) { + case '\t': + str += "\\t"; + break; + case ' ': + str += "\\s"; + break; + case '\n': + str += "\\n"; + break; + default: + str.push_back(c); + } + } + + str += "\n"; + return str; + } + + void imgui() override { + DragBox2("", &box); + ig::InputTextMultiline("##Text", &text, ImVec2(-1, 0)); + } + void draw(Vec2 offset, bool selected) override { + draw_box2(box, selected, IM_COL32(0, 0, 255, 255)); + // Draw text + ImDrawList *list = ig::GetBackgroundDrawList(); + list->AddText(box.lefttop.im(), IM_COL32_WHITE, text.c_str()); + } + + std::string text; + Box2 box; +}; diff --git a/types.hpp b/types.hpp index 57e793d..ef93c23 100644 --- a/types.hpp +++ b/types.hpp @@ -28,3 +28,44 @@ typedef struct { std::string name; std::vector prims; } render_Bundle; + + +class Vec2 { +public: + Vec2(): x(0.0), y(0.0) {} + Vec2(double x, double y): x(x), y(y) {} + + Vec2(ImVec2 iv): x(iv.x), y(iv.y) {} + + ImVec2 im() { return ImVec2(x, y); } + +public: + Vec2 operator+(Vec2 other) const { + return Vec2(x + other.x, y + other.y); + } + Vec2 operator*(double other) const { + return Vec2(x * other, y * other); + } + + bool operator==(Vec2 other) const { + return x == other.x && y == other.y; + } + bool operator!=(Vec2 other) const { return !(*this == other); } + + double x, y; +}; + +class Box2 { +public: + Box2(): lefttop(), size() {} + Box2(Vec2 lefttop, Vec2 size): lefttop(lefttop), size(size) {} + Box2(double ltx, double lty, double sx, double sy): lefttop(ltx, lty), size(sx, sy) {} + +public: + Box2 offset(Vec2 off) { + return Box2(lefttop + off, size); + } + + Vec2 lefttop; + Vec2 size; +};