added fully custom entity building
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 6 Mar 2022 01:52:36 +0000 (19:52 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 6 Mar 2022 01:52:36 +0000 (19:52 -0600)
run_tree/scenes/level1.scene
src/entity/components/patron.onyx
src/entity/editor.onyx
src/entity/scene.onyx
src/entity/schematics/background.onyx
src/entity/store.onyx
src/gfx/immediate.onyx

index e2282a6bdf153eb6616e31b0608323656b4f7c44..10e5322a0363f42bfbdb7fb5c407eef573dcf75d 100644 (file)
@@ -24,7 +24,7 @@ size.y = 16.0000
 :RenderComponent
 layer = 0
 color.r = 0.2549
-color.g = 0.1721
+color.g = 0.1720
 color.b = 0.0474
 color.a = 1.0000
 
@@ -468,7 +468,7 @@ color.g = 1.0000
 color.b = 1.0000
 color.a = 1.0000
 
-[Tap]
+[Custom]
 id = 14
 flags = 3
 pos.x = 240.0000
@@ -495,6 +495,33 @@ color.a = 1.0000
 item = "beer"
 max_timeout = 2.0000
 
+[Custom]
+id = 157
+flags = 3
+pos.x = 271.0000
+pos.y = 33.0000
+size.x = 32.0000
+size.y = 32.0000
+:SpriteRenderComponent
+sprite.sheet = "./assets/images/spritesheet.png"
+sprite.pos.x = 16.0000
+sprite.pos.y = 0.0000
+sprite.size.x = 16.0000
+sprite.size.y = 16.0000
+sprite.color.r = 1.0000
+sprite.color.g = 1.0000
+sprite.color.b = 1.0000
+sprite.color.a = 1.0000
+:RenderComponent
+layer = 10
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+:DispenserComponent
+item = "burger"
+max_timeout = 4.0000
+
 [Player]
 id = 152
 flags = 2
index ecae8feb210a9a7b989b9a60bcb820fdb89bf170..396a4fc203721353dcecffecc2f4de23d18b3c6a 100644 (file)
@@ -80,6 +80,10 @@ PatronComponent :: struct {
                 holding_object.flags |= .Dead;
                 holding = Entity_Nothing;
 
+                target_entity := scene->get(target);
+                furniture_comp := target_entity->get(FurnitureComponent);
+                furniture_comp.taken = false;
+
                 this->find_exit();
             }
         }
index 25fbc087f43a00a15b4553193eb4c0a5d01ccf59..0ed082a58704a99c84e0ee804e7c2cff123be995 100644 (file)
@@ -64,11 +64,16 @@ editor_update :: (dt: f32) {
     mouse_pos := mouse_raw - scene_render_offset;
 
     if is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) && mouse_raw.x < ~~window_width - sidebar_width && mouse_raw.x >= 0 {
-        schematic := scene.schematics.entries[active_index].value;
-        entity := schematic.create(^scene);
-        entity.schematic = schematic.type;
-        scene->add(entity);
+        entity: ^Entity;
+        if active_index == 0 {
+            entity = scene->make();
+        } else {
+            schematic := scene.schematics.entries[active_index - 1].value;
+            entity = schematic.create(^scene);
+            entity.schematic = schematic.type;
+        }
 
+        scene->add(entity);
         entity.pos = mouse_pos;
         if entity.size.x == 0 do entity.size.x = editor_grid_size;
         if entity.size.y == 0 do entity.size.y = editor_grid_size;
@@ -272,17 +277,21 @@ editor_draw :: () {
     h -= 40;
     y += 40;
 
+    theme := Button_Theme.{};
+
     i := 0;
+    y += 40;
+    theme.active = active_index == i;
+    if draw_button(.{x, y - 18, w, 36}, "Custom", ^theme) do active_index = i;
+
     for^ scene.schematics.entries {
-        defer i += 1;
+        i += 1;
 
         name := it.key;
-        if search_value.count != 0 {
-            if !string.contains(name, search_value) do continue;
-        }
+        if !string.contains(name, search_value) do continue;
 
         y += 40.0f;
-        theme := Button_Theme.{active = active_index == i};
+        theme.active = active_index == i;
         if draw_button(.{x, y - 18, w, 36.0f}, name, ^theme, increment=i) {
             active_index = i;
         }
@@ -328,29 +337,65 @@ editor_draw :: () {
         font_print(editor_big_font, x + 2, y + 24, info.name);
     }
 
-    if draw_button(.{ x + w - 150, y, 150, 24 }, "Delete") {
-        scene->delete(entity);
-        selected_entity_id = Entity_Nothing;
-        return;
-    }
+    if active_index == Component_Selection_Active {
+        if draw_button(.{ x + w - 150, y, 150, 24 }, "Back") {
+            active_index = Nothing_Active;
+            return;
+        }
 
-    if active_index >= 0 do sidebar_width += w;
+        #persist search_buffer: [..] u8;
+        y += 32;
+        draw_textbox(.{x, y, w, 32}, ^search_buffer, placeholder="Search...");
 
-    y += 4;
-    i := 0;
-    y, i = render_struct_fields(ptr_to_any(entity), i, x, y, w, h);
+        y += 32;
+        for^ entry: scene.component_vtables.entries {
+            info = ~~ type_info.get_type_info(entry.key);
+            if !string.contains(info.name, search_buffer) do continue;
+
+            if draw_button(.{ x, y, w, 32 }, info.name, increment=~~y) {
+                new_comp := scene->create_component(entry.key);
+                entity->add(new_comp);
+                active_index = Nothing_Active;
+            }
+            y += 32;
+        }
 
-    y += 32;
-    for^ entry: entity.components.entries {
-        immediate_set_color(.{0, 0, 0});
-        immediate_rectangle(x, y, w, 4);
+    } else {
+        if draw_button(.{ x + w - 150, y, 150, 24 }, "Delete") {
+            scene->delete(entity);
+            selected_entity_id = Entity_Nothing;
+            return;
+        }
+
+        if active_index >= 0 do sidebar_width += w;
 
-        y += 16;
-        info = ~~ type_info.get_type_info(entry.key);
-        font_print(editor_font, x + 2, y + 20, info.name);
+        y += 4;
+        i := 0;
+        y, i = render_struct_fields(ptr_to_any(entity), i, x, y, w, h);
 
-        y, i = render_struct_fields(any.{~~entry.value, entry.key}, i, x, y, w, h);
         y += 32;
+        for^ entry: entity.components.entries {
+            immediate_set_color(.{0, 0, 0});
+            immediate_rectangle(x, y, w, 4);
+
+            y += 16;
+            info = ~~ type_info.get_type_info(entry.key);
+            font_print(editor_font, x + 2, y + 20, info.name);
+
+            if draw_button(.{ x + w - 100, y, 100, 20 }, "Remove", increment=~~y) {
+                entity->remove(entry.value);
+
+                // This has to break, otherwise the loop could be very wrong.
+                break;
+            }
+
+            y, i = render_struct_fields(any.{~~entry.value, entry.key}, i, x, y, w, h);
+            y += 32;
+        }
+
+        if draw_button(.{x, y, w, 40}, "Add component") {
+            active_index = Component_Selection_Active;
+        }
     }
 }
 
@@ -544,10 +589,13 @@ editor_draw :: () {
     active_tab  := Tabs.Edit;
     clicked_tab := Tabs.None;
 
-    active_index := -1;
     field_shown  := -1;
     field_buffer: [..] u8;
 
+    Nothing_Active :: -1;
+    Component_Selection_Active :: -2;
+    active_index := -1;
+
     editor_grid_shown := false;
     editor_grid_size := 16.0f; @TODO // This should be configurable
 
index a0a8414c1baa35b784603b6a0f2a609f03ede7b5..c3aa0027c34aff6948f9d5edb158a7d94407bf92 100644 (file)
@@ -69,6 +69,8 @@ SpriteRenderComponent :: struct {
     sprite: Sprite;
 
     added :: (use comp: ^SpriteRenderComponent, entity: ^Entity) {
+        sprite.color = .{1, 1, 1};
+
         scene->modify_component(entity, RenderComponent) {
             comp.func = SpriteRenderComponent.render;
         }
@@ -123,6 +125,14 @@ Entity :: struct {
             component->added(this);
         }
     }
+
+    remove :: (use this: ^Entity, component: ^Component) => {
+        assert(components[component.type] == component, "Trying to remove a component that the entity doesn't have!");
+    
+        map.delete(^components, component.type);
+        @TODO @LEAK // This should free the component, but it needs access to the entity_allocator
+        // on the scene.
+    }
 }
 
 
index 117d4123801dc5e85c32b110546a2601a24cc6b4..095abf490c239c96b19ee35b765bc3b3483ad5a8 100644 (file)
@@ -17,4 +17,4 @@ Background :: struct {
             return this;
         }
     }
-}
\ No newline at end of file
+}
index c9eb05c61a7d30a83cbe62c1f5dda0091879312e..11f56529d326d1b69e65237626425bf37359b49c 100644 (file)
@@ -19,7 +19,9 @@ scene_save_to_file :: (use this: ^Scene, filename: str) {
 
     for entities {
         info := cast(^Type_Info_Struct) get_type_info(it.schematic);
-        io.write_format(writer, "[{}]\n", info.name);
+        name := info.name;
+        if name.count == 0 do name = "Custom";
+        io.write_format(writer, "[{}]\n", name);
         emit_struct_fields(any.{~~ it, Entity}, writer, "");
 
         for^ it.components.entries {
@@ -117,11 +119,15 @@ scene_load_from_file :: (use this: ^Scene, filename: str) {
                         |> (x => str.{x.data, x.count - 1})(); // In the grossest way possible remove one character from the end.
 
             debug_log(.Debug, "Creating entity from schematic: {}.", entity_kind);
-            current_entity = this->create_from_schematic(entity_kind);
-            if current_entity == null {
-                debug_log(.Error, "Unknown entity kind '{}' on line {}.", entity_kind, line_number);
-                current_entity = null;
-                continue;
+            if entity_kind == "Custom" {
+                current_entity = this->make();
+            } else {
+                current_entity = this->create_from_schematic(entity_kind);
+                if current_entity == null {
+                    debug_log(.Error, "Unknown entity kind '{}' on line {}.", entity_kind, line_number);
+                    current_entity = null;
+                    continue;
+                }
             }
 
             continue;
index be486f4e51073bc4897f4ba6f011aff2ac081463..6756fbe140e97768b62b07bfc1d09b2e86af6c0b 100644 (file)
@@ -131,9 +131,14 @@ immediate_push_scissor :: (x, y, w, h: f32) {
     x += offset.x;
     y += offset.y;
 
-    scissors << .{x, y, w, h};
+    xi := cast(i32) x;
+    yi := cast(i32) y;
+    wi := cast(i32) w;
+    hi := cast(i32) h;
+    scissors << .{xi, yi, wi, hi};
+
     glEnable(GL_SCISSOR_TEST);
-    glScissor(~~x, window_height - ~~(y + h), ~~w, ~~h);
+    glScissor(xi, window_height - yi - hi, wi, hi);
 }
 
 immediate_pop_scissor :: () {
@@ -144,7 +149,7 @@ immediate_pop_scissor :: () {
     if scissors.count > 0 {
         glEnable(GL_SCISSOR_TEST);
         s := scissors[scissors.count - 1];
-        glScissor(~~s.x, window_height - ~~(s.y + s.h), ~~s.w, ~~s.h);
+        glScissor(s.x, window_height - s.y - s.h, s.w, s.h);
     } else {
         glDisable(GL_SCISSOR_TEST);
     }
@@ -188,7 +193,7 @@ Immediate_Vertex :: struct {
     rendering_type := Rendering_Type.Plain;
 
     Scissor :: struct {
-        x, y, w, h: f32;
+        x, y, w, h: i32;
     }
     scissors: [..] Scissor;