prototyping a patreon component
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 28 Feb 2022 20:24:19 +0000 (14:24 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 28 Feb 2022 20:24:19 +0000 (14:24 -0600)
run_tree/scenes/quick_save_new.scene
src/entity/components/patreon.onyx [new file with mode: 0644]
src/entity/editor.onyx
src/entity/manager.onyx
src/entity/schematics/patreon.onyx [new file with mode: 0644]
src/game.onyx

index fda31956bdc7efeb34c06db8861646c9559ac084..6f015f27c71746b042cb4a2e8eddf42cfbcbb456 100644 (file)
@@ -29,8 +29,8 @@ color.a = 1.0000
 [Player]
 id = 12
 flags = 2
-pos.x = 390.5043
-pos.y = 187.4996
+pos.x = 170.8592
+pos.y = 40.2234
 size.x = 32.0000
 size.y = 32.0000
 :MovementComponent
@@ -40,7 +40,7 @@ controls.left = 65
 controls.right = 68
 controls.interact = 70
 controls.pick_up = 71
-facing = 2
+facing = 3
 :PlayerComponent
 holding = 0
 :RenderComponent
@@ -68,6 +68,24 @@ color.g = 1.0000
 color.b = 1.0000
 color.a = 1.0000
 
+[Patreon]
+id = 15
+flags = 1
+pos.x = 397.0000
+pos.y = 59.0000
+size.x = 32.0000
+size.y = 32.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 0.0000
+color.b = 0.0000
+color.a = 1.0000
+:PatreonComponent
+state = 1
+order_item = "beer"
+holding = 0
+
 [Tap]
 id = 14
 flags = 3
diff --git a/src/entity/components/patreon.onyx b/src/entity/components/patreon.onyx
new file mode 100644 (file)
index 0000000..bf20088
--- /dev/null
@@ -0,0 +1,110 @@
+
+use package core
+
+#local Patreon_State :: enum {
+    Waiting_To_Place_Order;
+    Waiting_For_Order;
+    Consuming_Order;
+    Leaving;
+}
+
+PatreonComponent :: struct {
+    use component: Component;
+
+    state := Patreon_State.Waiting_To_Place_Order;
+    order_item: str;
+    holding: Entity_ID;
+    consume_timeout: f32;
+
+    init :: (use this: ^PatreonComponent) {
+        order_item = "beer";
+    }
+
+    added :: (use this: ^PatreonComponent, entity: ^Entity) {
+        entity.flags |= .Interactable;
+
+        scene->create_and_add(entity, InteractableComponent) {
+            comp.interact = interact;
+        }
+    }
+
+    update :: (use this: ^PatreonComponent, entity: ^Entity, dt: f32) {
+        if consume_timeout > 0 && state == .Consuming_Order {
+            consume_timeout -= dt;
+            if consume_timeout < 0 {
+                state = .Leaving;
+                holding_object := scene->get(holding);
+                holding_object.flags |= .Dead;
+                holding = Entity_Nothing;
+            }
+        }
+
+        if holding != Entity_Nothing {
+            holding_object := scene->get(holding);
+            r := Entity.get_rect(holding_object);
+            holding_object.pos = entity.pos + .{-10, 0};
+        }
+    }
+
+    interact :: (entity: ^Entity, interactor: ^Entity) {
+        patreon := entity->get(PatreonComponent);
+
+        switch patreon.state {
+            case .Waiting_To_Place_Order {
+                if interactor->has(PlayerComponent) {
+                    patreon.state = .Waiting_For_Order;
+                }
+            }
+
+            case .Waiting_For_Order {
+                player_comp := interactor->get(PlayerComponent);
+                if player_comp == null do return;
+                if player_comp.holding == Entity_Nothing do return;
+                if item := scene->get(player_comp.holding); item->has(ItemComponent) {
+                    item_comp := item->get(ItemComponent);
+                    if item_comp.item == patreon.order_item {
+                        patreon.state = .Consuming_Order;
+                        patreon.consume_timeout = 10;
+                        patreon.holding = player_comp.holding;
+                        player_comp.holding = Entity_Nothing;
+                    }
+                }
+            }
+        }
+    }
+
+    post_render :: (use this: ^PatreonComponent, entity: ^Entity) {
+        if state == .Waiting_For_Order {
+            r := entity->get_rect();
+
+            r = Rect.{ r.x + (r.w - 24) / 2, r.y - r.h / 2 - 16, 24, 24 };
+            immediate_set_color(.{0, 0, 0});
+            immediate_rectangle(r.x, r.y, r.w, r.h);
+
+            r.x += 2;
+            r.y += 2;
+            r.w -= 4;
+            r.h -= 4;
+            immediate_set_color(.{1, 1, 1});
+            immediate_rectangle(r.x, r.y, r.w, r.h);
+
+            r.x += 2;
+            r.y += 2;
+            r.w -= 4;
+            r.h -= 4;
+
+            item_data := item_store->get_item(order_item);
+            texture, loaded := texture_lookup(item_data.texture_path);
+
+            immediate_set_color(item_data.color);
+            if !loaded {
+                immediate_rectangle(r.x, r.y, 16, 16);
+            } else {
+                tp := item_data.texture_pos;
+                ts := item_data.texture_size;
+                immediate_subimage(^texture, r.x, r.y, r.w, r.h,
+                                             tp.x, tp.y, ts.x, ts.y);
+            }
+        }
+    }
+}
\ No newline at end of file
index bd276db27f35c22311fa3ba98828f46a339514cd..ffe68cbb3a2581adbc82dd3dcc7fc98fb37327dc 100644 (file)
@@ -63,7 +63,8 @@ editor_update :: (dt: f32) {
         scene->add(entity);
 
         entity.pos = mouse_pos;
-        entity.size = .{editor_grid_size, editor_grid_size};
+        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,6 +273,9 @@ editor_draw :: () {
 
     y += 4;
     i := 0;
+    y, i = render_struct_fields(ptr_to_any(entity), i, x, y, w, h);
+
+    y += 32;
     for^ entry: entity.components.entries {
         y += 16;
         info = ~~ type_info.get_type_info(entry.key);
index 9919b21a999a35bba6891fe1f64722030d2ab7d7..8ecd845bd039d6bf1264330d90b8977f09549399 100644 (file)
@@ -95,7 +95,7 @@ Entity :: struct {
         return Rect.{ pos.x - size.x / 2, pos.y - size.y / 2, size.x, size.y };
     };
 
-    #tag Entity_Store.Skip
+    #tag Entity_Store.Skip, Editor_Hidden
     components: Map(type_expr, ^Component);
 
     has :: (use this: ^Entity,  component_type: type_expr) => components->has(component_type);
@@ -114,6 +114,7 @@ Entity_Flags :: enum #flags {
     Interactable :: 0x01;
     Solid        :: 0x02;
     Carryable    :: 0x04;
+    Dead         :: 0x80000000;
 }
 
 Entity_Schematic :: struct {
@@ -275,6 +276,15 @@ entity_manager_update :: (use this: ^Entity_Manager, dt: f32) {
             }
         }
     }
+
+    while i := 0; i < entities.count {
+        defer i += 1;
+
+        if entities[i].flags & .Dead {
+            this->delete(entities[i]);
+            i -= 1;
+        }
+    }
 }
 
 entity_manager_draw :: (use this: ^Entity_Manager) {
diff --git a/src/entity/schematics/patreon.onyx b/src/entity/schematics/patreon.onyx
new file mode 100644 (file)
index 0000000..6e10261
--- /dev/null
@@ -0,0 +1,29 @@
+
+use package core
+
+Patreon :: struct {
+    #struct_tag Entity_Schematic.{
+        (scene) => Patreon.create(scene, .{0,0})
+    }
+
+    create :: (scene: ^Entity_Manager, pos: Vector2) -> ^Entity {
+        this := scene->make();
+        this.pos = pos;
+        this.size = .{32, 32};
+
+        scene->create_and_add(this, RenderComponent) {
+            comp.func = render;
+            comp.color = .{1, 0, 0};
+        }
+
+        scene->create_and_add(this, PatreonComponent) {}
+
+        return this;
+    }
+
+    render :: (use this: ^Entity) {
+        r := this->get_rect();
+        immediate_image(^Player.assets.texture, r.x, r.y, r.w, r.h);
+    }
+}
+
index db904b4c91ea051162763ae04ea5bfde3c7855fe..05d080b47541e54afc50171e430de6bd274783fe 100644 (file)
@@ -57,7 +57,7 @@ game_draw :: () {
     immediate_flush();
     canvas_use(null);
     
-    immediate_clear(.{1, 1, 1});
+    immediate_clear(.{0.04, 0.04, 0.06});
     immediate_set_color(.{1, 1, 1});
 
     texture := canvas_to_texture(^scene_canvas);
@@ -66,7 +66,9 @@ game_draw :: () {
     view_rect.y = ~~ ((window_height - scene_canvas.height) / 2);
     view_rect.w = ~~ scene_canvas.width;
     view_rect.h = ~~ scene_canvas.height;
-    // view_rect := Rect.{0, 0, ~~window_width, ~~window_height};
+    if !editor_shown() {
+        view_rect = Rect.{0, 0, ~~window_width, ~~window_height};
+    }
     scene_render_offset = Rect.top_left(view_rect);
 
     glDisable(GL_CULL_FACE);