From: Brendan Hansen Date: Mon, 7 Nov 2022 04:15:36 +0000 (-0600) Subject: maybe working on this again X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=8266ff4dcef26c59bed5bba0cacedd8784260b68;p=bar-game.git maybe working on this again --- diff --git a/src/entity/components/collision_mask.onyx b/src/entity/components/collision_mask.onyx index 707e9c7..b798ca2 100644 --- a/src/entity/components/collision_mask.onyx +++ b/src/entity/components/collision_mask.onyx @@ -120,7 +120,6 @@ CollisionMaskComponent :: struct { ~~(path_pos.x * grid_size), ~~(path_pos.y * grid_size), }; - visited->delete(path_pos); path_pos = visited[path_pos].prev; } diff --git a/src/entity/components/movement.onyx b/src/entity/components/movement.onyx index 81f3816..04b4bc2 100644 --- a/src/entity/components/movement.onyx +++ b/src/entity/components/movement.onyx @@ -52,7 +52,7 @@ MovementComponent :: struct { ent_rect := Entity.get_rect(this); holding: Entity_ID; - if player := this->get(PlayerComponent); player != null { + if player := this->get(PlayerComponent); player { holding = player.holding; } diff --git a/src/entity/components/patron.onyx b/src/entity/components/patron.onyx index bc8ac42..366b0ea 100644 --- a/src/entity/components/patron.onyx +++ b/src/entity/components/patron.onyx @@ -91,7 +91,7 @@ PatronComponent :: struct { consume_timeout -= dt; if consume_timeout < 0 { holding_object := scene->get(holding); - if holding_object != null { + if holding_object { holding_object.flags |= .Dead; holding = Entity_Nothing; diff --git a/src/entity/components/player.onyx b/src/entity/components/player.onyx index bb99537..314a89d 100644 --- a/src/entity/components/player.onyx +++ b/src/entity/components/player.onyx @@ -100,7 +100,7 @@ PlayerComponent :: struct { post_render :: (use this: ^PlayerComponent, entity: ^Entity) { if nearby_interact != Entity_Nothing { it := scene->get(nearby_interact); - if it != null { + if it { r := it->get_rect(); immediate_set_color(.{.2, .2, .8, .7}); immediate_rectangle(r.x, r.y, r.w, r.h); @@ -109,7 +109,7 @@ PlayerComponent :: struct { if nearby_holding != Entity_Nothing && holding == Entity_Nothing { it := scene->get(nearby_holding); - if it != null { + if it { r := it->get_rect(); immediate_set_color(.{.2, .8, .2, .7}); immediate_rectangle(r.x, r.y, r.w, r.h); diff --git a/src/entity/editor.onyx b/src/entity/editor.onyx index dd45a70..8b980db 100644 --- a/src/entity/editor.onyx +++ b/src/entity/editor.onyx @@ -75,7 +75,7 @@ editor_update :: (dt: f32) { } else { schematic := scene.schematics.entries[active_index - 1].value; entity = schematic.create(^scene); - entity.schematic = schematic.type; + entity.schematic = scene.schematics.entries[active_index - 1].key; } scene->add(entity); @@ -361,10 +361,7 @@ editor_draw :: () { } defer scrolling_region_stop(); - info := cast(^type_info.Type_Info_Struct) type_info.get_type_info(entity.schematic); - if info != null { - font_print(editor_big_font, x + 2, y + 24, info.name); - } + font_print(editor_big_font, x + 2, y + 24, entity.schematic); if active_index == Component_Selection_Active { if draw_button(.{ x + w - 150, y, 150, 24 }, "Back") { @@ -378,7 +375,7 @@ editor_draw :: () { y += 32; for^ entry: scene.component_vtables.entries { - info = ~~ type_info.get_type_info(entry.key); + info := cast(^type_info.Type_Info_Struct) 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) { @@ -414,7 +411,7 @@ editor_draw :: () { immediate_rectangle(x, y, w, 4); y += 16; - info = ~~ type_info.get_type_info(entry.key); + info := cast(^type_info.Type_Info_Struct) 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) { diff --git a/src/entity/entities.onyx b/src/entity/entities.onyx index 7891c70..820d84b 100644 --- a/src/entity/entities.onyx +++ b/src/entity/entities.onyx @@ -3,15 +3,8 @@ use core use glfw3 use ogre -@Entity_Schematic.{ - (scene: ^Scene) => wall_create(scene, .{0,0}, .{0,0}) -} -#local Wall :: struct { - render :: (use this: ^Entity) { - r := Entity.get_rect(this); - immediate_rectangle(r.x, r.y, r.w, r.h); - } -} +@Entity_Schematic.{ "Wall" } +(scene: ^Scene) => wall_create(scene, .{0,0}, .{0,0}) wall_create :: (scene: ^Scene, pos, size: Vector2) -> ^Entity { this := scene->make(); @@ -20,16 +13,38 @@ wall_create :: (scene: ^Scene, pos, size: Vector2) -> ^Entity { this.flags |= .Solid; scene->modify_component(this, RenderComponent) { - comp.func = Wall.render; + comp.func = wall_render; } return this; } -@Entity_Schematic.{create} -#local Door :: struct { - create :: (scene: ^Scene) => door_create(scene, .Zero, .Zero); +#local +wall_render :: (use this: ^Entity) { + r := Entity.get_rect(this); + immediate_rectangle(r.x, r.y, r.w, r.h); +} + +@Entity_Schematic.{"Door"} +(scene: ^Scene) => door_create(scene, .Zero, .Zero); + +door_create :: (scene: ^Scene, pos, size: Vector2) -> ^Entity { + this := scene->make(); + this.pos = pos; + this.size = size; + + this.flags |= .Interactable; + this.flags |= .Solid; + + scene->modify_component(this, DoorComponent) {} + scene->modify_component(this, RenderComponent) { comp.func = Door.render; } + scene->modify_component(this, SizeComponent) { comp.func = Door.get_rect; } + scene->modify_component(this, InteractableComponent) { comp.interact = Door.interact; } + + return this; +} +#local Door :: struct { render :: (use this: ^Entity) { immediate_set_color(.{0.7, 0.7, 0.1}); @@ -70,19 +85,3 @@ DoorComponent :: struct { } } -door_create :: (scene: ^Scene, pos, size: Vector2) -> ^Entity { - this := scene->make(); - this.pos = pos; - this.size = size; - - this.flags |= .Interactable; - this.flags |= .Solid; - - scene->modify_component(this, DoorComponent) {} - scene->modify_component(this, RenderComponent) { comp.func = Door.render; } - scene->modify_component(this, SizeComponent) { comp.func = Door.get_rect; } - scene->modify_component(this, InteractableComponent) { comp.interact = Door.interact; } - - return this; -} - diff --git a/src/entity/items.onyx b/src/entity/items.onyx index a9afb9a..dc74117 100644 --- a/src/entity/items.onyx +++ b/src/entity/items.onyx @@ -15,7 +15,9 @@ Item :: struct { Item_Store :: struct { item_allocator: Allocator; items: Map(str, ^Item); +} +#inject Item_Store { load_items_from_file :: item_store_load_items_from_file; get_item :: item_store_get_item; } @@ -89,32 +91,30 @@ item_store_get_item :: (use this: ^Item_Store, id: str) -> ^Item { return items[id]; } -@Entity_Schematic.{create} -#local Item_Entity :: struct { +@Entity_Schematic.{"Item_Entity"} +(scene: ^Scene) => { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{0, 0}; + this.flags |= .Carryable; - create :: (scene) => { - this := scene->make(); - this.pos = .{0, 0}; - this.size = .{0, 0}; - this.flags |= .Carryable; + scene->modify_component(this, RenderComponent) { comp.func = item_entity_render; comp.layer = 10; } + scene->modify_component(this, ItemComponent) {} + return this; +} - scene->modify_component(this, RenderComponent) { comp.func = render; comp.layer = 10; } - scene->modify_component(this, ItemComponent) {} - return this; +#local +item_entity_render :: (use this: ^Entity) { + r := this->get_rect(); + item_comp := this->get(ItemComponent); + item_data := item_store->get_item(item_comp.item); + if item_data == null { + immediate_set_color(.{1,0,0}); + immediate_rectangle(r.x, r.y, r.w, r.h); + return; } - render :: (use this: ^Entity) { - r := this->get_rect(); - item_comp := this->get(ItemComponent); - item_data := item_store->get_item(item_comp.item); - if item_data == null { - immediate_set_color(.{1,0,0}); - immediate_rectangle(r.x, r.y, r.w, r.h); - return; - } - - item_data.sprite->render(r); - } + item_data.sprite->render(r); } ItemComponent :: struct { @@ -122,7 +122,9 @@ ItemComponent :: struct { @Editor_Custom_Field.{render_item_picker} item: str; +} +#inject ItemComponent { get_info :: (use this: ^ItemComponent) -> ^Item { return item_store->get_item(item); } diff --git a/src/entity/scene.onyx b/src/entity/scene.onyx index af11f37..6ee0c23 100644 --- a/src/entity/scene.onyx +++ b/src/entity/scene.onyx @@ -100,7 +100,7 @@ Entity :: struct { flags: Entity_Flags; @Entity_Store.Skip - schematic: type_expr; + schematic: str; nickname: str; @@ -108,17 +108,22 @@ Entity :: struct { // Does every entity need to have a size? size: Vector2; + + @Entity_Store.Skip, Editor_Hidden + components: Map(type_expr, ^Component); +} + +#inject Entity { get_rect :: (use e: ^Entity) => { if e->has(SizeComponent) do return (e->get(SizeComponent)).func(e); return Rect.{ pos.x - size.x / 2, pos.y - size.y / 2, size.x, size.y }; - }; - - @Entity_Store.Skip, Editor_Hidden - components: Map(type_expr, ^Component); + } has :: (use this: ^Entity, component_type: type_expr) => components->has(component_type); + get :: (use this: ^Entity, $component_type: type_expr) => cast(^component_type) components[component_type]; + add :: (use this: ^Entity, component: ^Component) => { if components->has(component.type) do return; components[component.type] = component; @@ -146,8 +151,10 @@ Entity_Flags :: enum #flags { } Entity_Schematic :: struct { + name: str; + + // These will be filled out at runtime. create: (^Scene) -> ^Entity; - type := void; // This will be filled out at runtime. } Scene :: struct { @@ -163,28 +170,30 @@ Scene :: struct { next_entity_id: Entity_ID; width, height: f32; +} - add :: scene_add; - make :: scene_make; - update :: scene_update; - draw :: scene_draw; - get :: scene_get; - delete :: scene_delete; - query :: scene_query; - query_by_flags :: scene_query_by_flags; +#inject Scene { + add :: scene_add + make :: scene_make + update :: scene_update + draw :: scene_draw + get :: scene_get + delete :: scene_delete + query :: scene_query + query_by_flags :: scene_query_by_flags - count_by_component :: scene_count_by_component; + count_by_component :: scene_count_by_component - query_by_component :: scene_query_by_component; - create_component :: scene_create_component; - modify_component :: scene_modify_component; - first_component :: scene_first_component; + query_by_component :: scene_query_by_component + create_component :: scene_create_component + modify_component :: scene_modify_component + first_component :: scene_first_component - create_from_schematic :: scene_create_from_schematic; - duplicate :: scene_duplicate; + create_from_schematic :: scene_create_from_schematic + duplicate :: scene_duplicate - load_from_file :: scene_load_from_file; - save_to_file :: scene_save_to_file; + load_from_file :: scene_load_from_file + save_to_file :: scene_save_to_file } scene_create :: (width, height: f32) -> Scene { @@ -211,22 +220,6 @@ scene_create :: (width, height: f32) -> Scene { if it.kind != .Struct do continue; s_info := cast(^Type_Info_Struct) it; - for^ s_info.tags { - if it.type == Entity_Schematic { - schematic := cast(^Entity_Schematic) it.data; - - // This is (mostly) safe to do as this data is in static memory - // and is not shared with any other type info. - schematic.type = cast(type_expr) index; - - // This is safe to use as the key, as a struct's name exists in static memory. - schematics[s_info.name] = schematic; - - debug_log(.Debug, "Discovered schematic: '{}'", s_info.name); - continue continue; - } - } - if struct_inherits(~~ index, Component) { debug_log(.Debug, "Discovered component: '{}'", s_info.name); @@ -238,6 +231,14 @@ scene_create :: (width, height: f32) -> Scene { } } } + + for get_procedures_with_tag(Entity_Schematic) { + schematic := it.tag; + schematic.create = *cast(^(^Scene) -> ^Entity) ^it.func; + + schematics[schematic.name] = schematic; + debug_log(.Debug, "Discovered schematic: '{}'", schematic.name); + } } scene_add :: (use this: ^Scene, entity: ^Entity) -> Entity_ID { @@ -266,7 +267,7 @@ scene_create_from_schematic :: (use this: ^Scene, schematic_name: str) -> ^Entit if schematic == null do return null; entity := schematic.create(this); - entity.schematic = schematic.type; + entity.schematic = schematic_name; return entity; } @@ -358,15 +359,15 @@ scene_draw :: (use this: ^Scene) { e1_comp := e1->get(RenderComponent); e2_comp := e2->get(RenderComponent); - e1_layer := e1_comp.layer if e1_comp != null else 0; - e2_layer := e2_comp.layer if e2_comp != null else 0; + e1_layer := e1_comp.layer if e1_comp else 0; + e2_layer := e2_comp.layer if e2_comp else 0; return e1_layer - e2_layer; }); for entities { render_comp := it->get(RenderComponent); - if render_comp != null { + if render_comp { immediate_set_color(render_comp.color); render_comp.func(it); @@ -392,7 +393,7 @@ scene_delete :: (use this: ^Scene, ent: ^Entity, delete_from_array := true) { // This assuems that components cannot and will not be shared between entities. for^ ent.components.entries { - if it.value != null { + if it.value { raw_free(entity_allocator, it.value); } } @@ -469,7 +470,9 @@ Sprite :: struct { pos: Vector2; size: Vector2; color: Color; +} +#inject Sprite { render :: (use this: ^Sprite, r: Rect) { texture, valid := texture_lookup(sheet); diff --git a/src/entity/schematics/background.onyx b/src/entity/schematics/background.onyx index 735bb54..47e527f 100644 --- a/src/entity/schematics/background.onyx +++ b/src/entity/schematics/background.onyx @@ -3,17 +3,15 @@ use core // #local background_texture: Texture; -@Entity_Schematic.{ Background.create } -Background :: struct { - create :: (scene) => { - this := scene->make(); - this.pos = .{0, 0}; - this.size = .{0, 0}; +@Entity_Schematic.{ "Background" } +(scene: ^Scene) => { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{0, 0}; - scene->modify_component(this, BackgroundComponent) { - comp.texture_path = "./assets/images/background.png"; - } - - return this; + scene->modify_component(this, BackgroundComponent) { + comp.texture_path = "./assets/images/background.png"; } + + return this; } diff --git a/src/entity/schematics/entryway.onyx b/src/entity/schematics/entryway.onyx index 9b898d1..4422b83 100644 --- a/src/entity/schematics/entryway.onyx +++ b/src/entity/schematics/entryway.onyx @@ -1,24 +1,22 @@ use core -@Entity_Schematic.{ Entryway.create } -Entryway :: struct { - create :: (scene) => { - this := scene->make(); - this.size = .{16, 16}; +@Entity_Schematic.{ "Entryway" } +(scene: ^Scene) => { + this := scene->make(); + this.size = .{16, 16}; - scene->modify_component(this, SpriteRenderComponent) { - comp.sprite.sheet = "./assets/images/spritesheet.png"; - comp.sprite.pos = .{0, 0}; - comp.sprite.size = .{16, 16}; - comp.sprite.color = .{1, 1, 1}; - } - - scene->modify_component(this, EntrywayComponent) { - comp.schematic = "Patron"; - comp.spawned_size = .{16, 32}; - } + scene->modify_component(this, SpriteRenderComponent) { + comp.sprite.sheet = "./assets/images/spritesheet.png"; + comp.sprite.pos = .{0, 0}; + comp.sprite.size = .{16, 16}; + comp.sprite.color = .{1, 1, 1}; + } - return this; + scene->modify_component(this, EntrywayComponent) { + comp.schematic = "Patron"; + comp.spawned_size = .{16, 32}; } + + return this; } diff --git a/src/entity/schematics/furniture.onyx b/src/entity/schematics/furniture.onyx index 7fce57a..b177b31 100644 --- a/src/entity/schematics/furniture.onyx +++ b/src/entity/schematics/furniture.onyx @@ -2,25 +2,21 @@ use core use ogre -@Entity_Schematic.{ - (scene) => Furniture.create(scene, .{0, 0}) -} -Furniture :: struct { - create :: (scene: ^Scene, pos: Vector2) -> ^Entity { - this := scene->make(); - this.pos = pos; - this.size = .{16, 16}; - this.flags |= .Solid; - - scene->modify_component(this, FurnitureComponent) {} +@Entity_Schematic.{ "Furniture" } +(scene: ^Scene) -> ^Entity { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{16, 16}; + this.flags |= .Solid; - scene->modify_component(this, SpriteRenderComponent) { - comp.sprite.sheet = "./assets/images/spritesheet.png"; - comp.sprite.pos = .{0, 32}; - comp.sprite.size = .{32, 32}; - comp.sprite.color = .{1, 1, 1}; - } + scene->modify_component(this, FurnitureComponent) {} - return this; + scene->modify_component(this, SpriteRenderComponent) { + comp.sprite.sheet = "./assets/images/spritesheet.png"; + comp.sprite.pos = .{0, 32}; + comp.sprite.size = .{32, 32}; + comp.sprite.color = .{1, 1, 1}; } + + return this; } diff --git a/src/entity/schematics/patron.onyx b/src/entity/schematics/patron.onyx index b6b1a63..7a4225e 100644 --- a/src/entity/schematics/patron.onyx +++ b/src/entity/schematics/patron.onyx @@ -2,30 +2,27 @@ use core use ogre -@Entity_Schematic.{ - (scene: ^Scene) => Patron.create(scene, .{0,0}) -} -Patron :: struct { - create :: (scene: ^Scene, pos: Vector2) -> ^Entity { - this := scene->make(); - this.pos = pos; - this.size = .{32, 32}; - this.flags |= .Solid; +@Entity_Schematic.{ "Patron" } +(scene: ^Scene) -> ^Entity { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{32, 32}; + this.flags |= .Solid; - scene->modify_component(this, RenderComponent) { - comp.func = render; - comp.layer = 5; - comp.color = .{1, 0, 0}; - } + scene->modify_component(this, RenderComponent) { + comp.func = patron_render; + comp.layer = 5; + comp.color = .{1, 0, 0}; + } - scene->modify_component(this, PatronComponent) {} + scene->modify_component(this, PatronComponent) {} - return this; - } + return this; +} - render :: (use this: ^Entity) { - r := this->get_rect(); - immediate_subimage(^Spritesheet, r.x, r.y, r.w, r.h, 0*16, 4*16, 16, 16); - } +#local +patron_render :: (use this: ^Entity) { + r := this->get_rect(); + immediate_subimage(^Spritesheet, r.x, r.y, r.w, r.h, 0*16, 4*16, 16, 16); } diff --git a/src/entity/schematics/player.onyx b/src/entity/schematics/player.onyx index c71e367..3b06c28 100644 --- a/src/entity/schematics/player.onyx +++ b/src/entity/schematics/player.onyx @@ -31,41 +31,37 @@ player_2_controls :: Player_Controls.{ } -@Entity_Schematic.{ - (scene: ^Scene) => Player.create(scene, .{0,0}) -} -Player :: struct { - create :: (scene: ^Scene, pos: Vector2, controls := player_1_controls) -> ^Entity { - this := scene->make(); - this.pos = pos; - this.size = .{32, 32}; - this.flags |= .Solid; - - scene->modify_component(this, SizeComponent) { - comp.func = (use this: ^Entity) => Rect.{pos.x - size.x / 2, pos.y, size.x, size.y / 2}; - } +@Entity_Schematic.{ "Player" } +(scene: ^Scene) -> ^Entity { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{32, 32}; + this.flags |= .Solid; - scene->modify_component(this, MovementComponent) { - comp.controls = controls; - } - - scene->modify_component(this, PlayerComponent) { - comp.holding = Entity_Nothing; - } + scene->modify_component(this, SizeComponent) { + comp.func = (use this: ^Entity) => Rect.{pos.x - size.x / 2, pos.y, size.x, size.y / 2}; + } - scene->modify_component(this, RenderComponent) { - comp.func = PlayerComponent.render; - comp.color = .{1,1,1}; - } + scene->modify_component(this, MovementComponent) { + comp.controls = player_1_controls; + } - return this; + scene->modify_component(this, PlayerComponent) { + comp.holding = Entity_Nothing; } - #persist assets: struct { - @"assets/images/player.png" - @Texture_Wrap.Clamp - texture: Texture; + scene->modify_component(this, RenderComponent) { + comp.func = PlayerComponent.render; + comp.color = .{1,1,1}; } + + return this; +} + +player_assets: struct { + @"assets/images/player.png" + @Texture_Wrap.Clamp + texture: Texture; } diff --git a/src/entity/schematics/tap.onyx b/src/entity/schematics/tap.onyx index 95e619a..ffcfe23 100644 --- a/src/entity/schematics/tap.onyx +++ b/src/entity/schematics/tap.onyx @@ -1,28 +1,24 @@ use ogre -@Entity_Schematic.{ - (scene) => Tap.create(scene, .{0,0}, .{0,0}) -} -Tap :: struct { - create :: (scene: ^Scene, pos: Vector2, size: Vector2) -> ^Entity { - this := scene->make(); - this.pos = pos; - this.size = size; - this.flags |= .Solid; - this.flags |= .Interactable; - - scene->modify_component(this, SpriteRenderComponent) { - comp.sprite.sheet = "./assets/images/spritesheet.png"; - comp.sprite.pos = .{ 0, 32 }; - comp.sprite.size = .{ 32, 32 }; - comp.sprite.color = .{ 1, 1, 1 }; - } +@Entity_Schematic.{ "Tap" } +(scene: ^Scene) -> ^Entity { + this := scene->make(); + this.pos = .{0, 0}; + this.size = .{0, 0}; + this.flags |= .Solid; + this.flags |= .Interactable; - scene->modify_component(this, DispenserComponent) { - comp.item = "beer"; - } + scene->modify_component(this, SpriteRenderComponent) { + comp.sprite.sheet = "./assets/images/spritesheet.png"; + comp.sprite.pos = .{ 0, 32 }; + comp.sprite.size = .{ 32, 32 }; + comp.sprite.color = .{ 1, 1, 1 }; + } - return this; + scene->modify_component(this, DispenserComponent) { + comp.item = "beer"; } + + return this; } diff --git a/src/entity/store.onyx b/src/entity/store.onyx index de00f7d..3536c9a 100644 --- a/src/entity/store.onyx +++ b/src/entity/store.onyx @@ -18,10 +18,10 @@ scene_save_to_file :: (use this: ^Scene, filename: str) { use runtime.info; for entities { - info := cast(^Type_Info_Struct) get_type_info(it.schematic); - name := info.name; - if name.count == 0 do name = "Custom"; + name := it.schematic; + if !name do name = "Custom"; io.write_format(writer, "[{}]\n", name); + emit_struct_fields(any.{~~ it, Entity}, writer, ""); for^ it.components.entries { @@ -114,7 +114,7 @@ scene_load_from_file :: (use this: ^Scene, filename: str, reset_scene := true) { if line.count <= 1 do continue; if line[0] == #char "[" { - if current_entity != null do this->add(current_entity); + if current_entity do this->add(current_entity); current_component = null; entity_kind := string.advance(line) @@ -183,6 +183,6 @@ scene_load_from_file :: (use this: ^Scene, filename: str, reset_scene := true) { } } - if current_entity != null do this->add(current_entity); + if current_entity do this->add(current_entity); } diff --git a/src/utils/asset_loader.onyx b/src/utils/asset_loader.onyx index ec5f756..761eb61 100644 --- a/src/utils/asset_loader.onyx +++ b/src/utils/asset_loader.onyx @@ -42,10 +42,10 @@ load_assets :: () { out_texture := cast(^Texture) dest; path_tag := array.first(tags, (x) => x.type == str); - if path_tag != null { + if path_tag { path := *cast(^str) path_tag.data; if texture, success := texture_lookup(path); success { - if wrap_tag := array.first(tags, (x) => x.type == Texture_Wrap); wrap_tag != null { + if wrap_tag := array.first(tags, (x) => x.type == Texture_Wrap); wrap_tag { wrap := *cast(^Texture_Wrap) wrap_tag.data; texture_wrap(^texture, wrap); }