From: Brendan Hansen Date: Mon, 7 Mar 2022 14:22:40 +0000 (-0600) Subject: bug fixing and entity duplicating X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=2c5e693200ce5152010f645a5c786624a91332b2;p=bar-game.git bug fixing and entity duplicating --- diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 1b4ee0b..a000fc2 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -35,6 +35,7 @@ "command": "./run.sh", "args": ["run"], "dependsOn": "Build game", + "dependsOrder": "sequence" } ] } \ No newline at end of file diff --git a/run_tree/assets/sounds/interact-1.wav b/run_tree/assets/sounds/interact-1.wav new file mode 100644 index 0000000..55acb5a Binary files /dev/null and b/run_tree/assets/sounds/interact-1.wav differ diff --git a/run_tree/scenes/level1.scene b/run_tree/scenes/level1.scene index 8405292..0808b4a 100644 --- a/run_tree/scenes/level1.scene +++ b/run_tree/scenes/level1.scene @@ -1,7 +1,7 @@ [Background] id = 100 flags = 0 -pos.x = 406.5000 +pos.x = 422.5000 pos.y = 311.5000 size.x = 941.0000 size.y = 751.0000 @@ -495,6 +495,330 @@ color.a = 1.0000 item = "beer" max_timeout = 2.0000 +[Furniture] +id = 164 +flags = 2 +pos.x = 536.0000 +pos.y = 176.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 32.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 165 +flags = 2 +pos.x = 536.0000 +pos.y = 96.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 32.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 167 +flags = 2 +pos.x = 136.0000 +pos.y = 416.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 32.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 168 +flags = 2 +pos.x = 536.0000 +pos.y = 416.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 32.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 169 +flags = 2 +pos.x = 560.0000 +pos.y = 96.0000 +size.x = 32.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 1 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 32.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 170 +flags = 2 +pos.x = 560.0000 +pos.y = 176.0000 +size.x = 32.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 1 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 32.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 171 +flags = 2 +pos.x = 560.0000 +pos.y = 416.0000 +size.x = 32.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 1 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 32.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 172 +flags = 2 +pos.x = 160.0000 +pos.y = 416.0000 +size.x = 32.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 1 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = 32.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 173 +flags = 2 +pos.x = 584.0000 +pos.y = 416.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = -16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 174 +flags = 2 +pos.x = 584.0000 +pos.y = 176.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = -16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 175 +flags = 2 +pos.x = 584.0000 +pos.y = 96.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = -16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + +[Furniture] +id = 176 +flags = 2 +pos.x = 184.0000 +pos.y = 416.0000 +size.x = 16.0000 +size.y = 32.0000 +:FurnitureComponent +furniture_type = 0 +taken = false +:SpriteRenderComponent +sprite.sheet = "./assets/images/spritesheet.png" +sprite.pos.x = 48.0000 +sprite.pos.y = 32.0000 +sprite.size.x = -16.0000 +sprite.size.y = 32.0000 +sprite.color.r = 1.0000 +sprite.color.g = 1.0000 +sprite.color.b = 1.0000 +sprite.color.a = 1.0000 +:RenderComponent +layer = 0 +color.r = 1.0000 +color.g = 1.0000 +color.b = 1.0000 +color.a = 1.0000 + [Custom] id = 157 flags = 3 diff --git a/src/build.onyx b/src/build.onyx index 8906ca4..429f03f 100644 --- a/src/build.onyx +++ b/src/build.onyx @@ -4,7 +4,7 @@ package runtime.vars MAJOR_VERSION :: 0 MINOR_VERSION :: 1 -DEBUG :: true +// DEBUG :: true #load_path ONYX_PATH diff --git a/src/entity/components/patron.onyx b/src/entity/components/patron.onyx index 2bc4255..45655af 100644 --- a/src/entity/components/patron.onyx +++ b/src/entity/components/patron.onyx @@ -18,6 +18,7 @@ PatronComponent :: struct { order_show_animation: f32; holding: Entity_ID; consume_timeout: f32; + annoy_timeout: f32; init :: (use this: ^PatronComponent) { order_item = random.choice(item_store.items.entries).key; @@ -61,6 +62,12 @@ PatronComponent :: struct { target = random.choice(exits).id; } + release_seat :: (use this: ^PatronComponent) { + target_entity := scene->get(target); + furniture_comp := target_entity->get(FurnitureComponent); + furniture_comp.taken = false; + } + update :: (use this: ^PatronComponent, entity: ^Entity, dt: f32) { if state == .Walking_To_Seat { if target == Entity_Nothing { @@ -77,18 +84,18 @@ PatronComponent :: struct { consume_timeout -= dt; if consume_timeout < 0 { holding_object := scene->get(holding); - holding_object.flags |= .Dead; - holding = Entity_Nothing; + if holding_object != null { + holding_object.flags |= .Dead; + holding = Entity_Nothing; - item_comp := holding_object->get(ItemComponent); - item_info := item_comp->get_info(); + item_comp := holding_object->get(ItemComponent); + item_info := item_comp->get_info(); - money_comp := scene->first_component(MoneyComponent); - money_comp->deposit(item_info.sell_value); + money_comp := scene->first_component(MoneyComponent); + money_comp->deposit(item_info.sell_value); + } - target_entity := scene->get(target); - furniture_comp := target_entity->get(FurnitureComponent); - furniture_comp.taken = false; + this->release_seat(); state = .Leaving; this->find_exit(); @@ -99,6 +106,17 @@ PatronComponent :: struct { if order_show_animation > 0 { order_show_animation *= 0.75; } + + if annoy_timeout > 0 { + annoy_timeout -= dt; + + if annoy_timeout < 0 { + // Angry walkout + this->release_seat(); + state = .Leaving; + this->find_exit(); + } + } } if target != Entity_Nothing { @@ -131,6 +149,7 @@ PatronComponent :: struct { if interactor->has(PlayerComponent) { patron.state = .Waiting_For_Order; patron.order_show_animation = 1.0f; + patron.annoy_timeout = random.float(15, 20); @Hardcoded Audio_Manager.play_sound("./assets/sounds/prompt-1.wav"); } @@ -175,6 +194,14 @@ PatronComponent :: struct { immediate_set_color(.{0.9, 0.9, 0.9}); immediate_rectangle(r.x, r.y, r.w, r.h); + if annoy_timeout < 10 { @Hardcoded + immediate_set_color(.{1, 0, 0}); + ar := r; + ar.h *= 1 - annoy_timeout / 10; + ar.y = r.y + r.h - ar.h; + immediate_rectangle(ar.x, ar.y, ar.w, ar.h); + } + r.x += 2; r.y += 2; r.w -= 4; diff --git a/src/entity/components/player.onyx b/src/entity/components/player.onyx index 0501ba1..dbf2a80 100644 --- a/src/entity/components/player.onyx +++ b/src/entity/components/player.onyx @@ -54,6 +54,7 @@ PlayerComponent :: struct { it := scene->get(player.nearby_interact); interact_comp := it->get(InteractableComponent); interact_comp.interact(it, this); + Audio_Manager.play_sound("./assets/sounds/interact-1.wav"); } // diff --git a/src/entity/editor.onyx b/src/entity/editor.onyx index 0ed082a..7d123b3 100644 --- a/src/entity/editor.onyx +++ b/src/entity/editor.onyx @@ -85,7 +85,8 @@ editor_update :: (dt: f32) { mouse_pos := mouse_raw - scene_render_offset; if mouse_raw.x < ~~window_width - sidebar_width && mouse_pos.x >= 0 { - if is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) { + if !dragging && !resizing && + (is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) || is_button_just_up(GLFW_MOUSE_BUTTON_RIGHT)) { if active_tab == .Edit do active_index = -1; selected_entity_id = Entity_Nothing; @@ -96,8 +97,8 @@ editor_update :: (dt: f32) { } } - dragging = is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && selected_entity_id != Entity_Nothing; - resizing = is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) && selected_entity_id != Entity_Nothing; + dragging = false; + resizing = false; } } @@ -112,6 +113,13 @@ editor_update :: (dt: f32) { if selected_entity_id != Entity_Nothing && active_tab == .Edit { selected_entity := scene->get(selected_entity_id); + { + mouse_pos := mouse_get_position_vector() - scene_render_offset; + contains := Rect.contains(selected_entity->get_rect(), mouse_pos); + dragging = dragging || (is_button_just_down(GLFW_MOUSE_BUTTON_LEFT) && contains); + resizing = resizing || (is_button_just_down(GLFW_MOUSE_BUTTON_RIGHT) && contains); + } + if dragging { if editor_grid_shown { new_top_left := mouse_get_position_vector() - scene_render_offset; @@ -361,11 +369,17 @@ editor_draw :: () { } } else { - if draw_button(.{ x + w - 150, y, 150, 24 }, "Delete") { + if draw_button(.{ x + w - 100, y, 100, 24 }, "Delete") { scene->delete(entity); selected_entity_id = Entity_Nothing; return; } + if draw_button(.{ x + w - 204, y, 100, 24 }, "Duplicate") { + new_entity := scene->duplicate(entity); + new_entity.pos = entity.pos + .{16, 16}; + selected_entity_id = new_entity.id; + return; + } if active_index >= 0 do sidebar_width += w; @@ -501,16 +515,16 @@ editor_draw :: () { switch info.kind { case .Enum { enum_info := cast(^type_info.Type_Info_Enum) info; - value: u64; - switch enum_info.backing_type { - case i8, u8 do value = cast(u64) *(cast(^u8) v.data); - case i16, u16 do value = cast(u64) *(cast(^u16) v.data); - case i32, u32 do value = cast(u64) *(cast(^u32) v.data); - case i64, u64 do value = cast(u64) *(cast(^u64) v.data); - case #default do assert(false, "Bad enum backing type"); - } - if enum_info.is_flags { + value: u64; + switch enum_info.backing_type { + case i8, u8 do value = cast(u64) *(cast(^u8) v.data); + case i16, u16 do value = cast(u64) *(cast(^u16) v.data); + case i32, u32 do value = cast(u64) *(cast(^u32) v.data); + case i64, u64 do value = cast(u64) *(cast(^u64) v.data); + case #default do assert(false, "Bad enum backing type"); + } + for^ enum_info.members { y += 20; checkbox_value := (value & it.value) != 0; @@ -529,7 +543,10 @@ editor_draw :: () { } } } else { - @TODO // Add radio buttons for enum type. + for^ enum_info.members { + y += 20; + draw_radio(.{x, y, w, 20}, cast(^i32) v.data, ~~it.value, it.name, increment=~~y); + } } } diff --git a/src/entity/scene.onyx b/src/entity/scene.onyx index 8105363..b8f87ae 100644 --- a/src/entity/scene.onyx +++ b/src/entity/scene.onyx @@ -180,6 +180,7 @@ Scene :: struct { first_component :: scene_first_component; create_from_schematic :: scene_create_from_schematic; + duplicate :: scene_duplicate; load_from_file :: scene_load_from_file; save_to_file :: scene_save_to_file; @@ -268,6 +269,23 @@ scene_create_from_schematic :: (use this: ^Scene, schematic_name: str) -> ^Entit return entity; } +scene_duplicate :: (use this: ^Scene, entity: ^Entity) -> ^Entity { + new_entity := this->make(); + new_entity.flags = entity.flags; + new_entity.schematic = entity.schematic; + new_entity.pos = entity.pos; + new_entity.size = entity.size; + + for^ entity.components.entries { + comp := this->create_component(it.key); + memory.copy(comp, it.value, type_info.size_of(it.key)); + new_entity->add(comp); + } + + this->add(new_entity); + return new_entity; +} + scene_create_component :: (use this: ^Scene, component_type: type_expr) -> ^Component { comp := cast(^Component) new(component_type, allocator=entity_allocator); comp.type = component_type; diff --git a/src/gfx/ui.onyx b/src/gfx/ui.onyx index 8765ac4..d9e81b4 100644 --- a/src/gfx/ui.onyx +++ b/src/gfx/ui.onyx @@ -503,6 +503,98 @@ draw_checkbox :: (use r: Rect, value: ^bool, text: str, theme := ^default_checkb } +// +// Radio buttons +// +Radio_Theme :: struct { + use text_theme := Text_Theme.{}; + use animation_theme := Animation_Theme.{}; + + box_color := Color.{ 0.2, 0.2, 0.2 }; + box_border_width := 4.0f; @InPixels + box_size := 20.0f; @InPixels + + checked_color := Color.{ 0, 0, 1 }; + checked_hover_color := Color.{ 0.6, 0.6, 1 }; + + background_color := Color.{ 0.05, 0.05, 0.05 }; // Background of the checkbox button. + hover_color := Color.{ 0.3, 0.3, 0.3 }; + click_color := Color.{ 0.5, 0.5, 0.7 }; +} + +#local default_radio_theme := Radio_Theme.{}; + +draw_radio :: (use r: Rect, value: ^$T, set_to: T, text: str, theme := ^default_radio_theme, site := #callsite, increment := 0) -> bool { + result := false; + + hash := get_site_hash(site, increment); + animation_state := get_animation(hash); + mx, my := mouse_get_position(); + + contains := Rect.contains(r, .{~~mx, ~~my}); + + if is_active_item(hash) { + renew_active_item(hash); + if is_button_just_up(GLFW_MOUSE_BUTTON_LEFT) { + if is_hot_item(hash) && contains { + result = true; + *value = set_to; + animation_state.click_time = 1.0f; + } + + set_active_item(0); + } + } elseif is_hot_item(hash) { + if is_button_down(GLFW_MOUSE_BUTTON_LEFT) { + set_active_item(hash); + } + } + + if contains { + set_hot_item(hash); + } + + if is_hot_item(hash) { + move_towards(^animation_state.hover_time, 1.0f, theme.hover_speed); + } else { + move_towards(^animation_state.hover_time, 0.0f, theme.hover_speed); + } + + box_border_width := theme.box_border_width; + box_size := theme.box_size; + + immediate_set_color(theme.box_color); + immediate_rectangle(x + 4, y + (h - box_size) / 2, box_size, box_size); + + surface_color : Color; + if *value == set_to { + surface_color = theme.checked_color; + surface_color = color_lerp(animation_state.hover_time, surface_color, theme.checked_hover_color); + + } else { + surface_color = theme.background_color; + surface_color = color_lerp(animation_state.hover_time, surface_color, theme.hover_color); + } + + surface_color = color_lerp(animation_state.click_time, surface_color, theme.click_color); + + immediate_set_color(surface_color); + immediate_rectangle(x + 4 + box_border_width, y + (h - box_size) / 2 + box_border_width, box_size - box_border_width * 2, box_size - box_border_width * 2); + + font := font_lookup(.{theme.font_name, theme.font_size}); + text_width := font_get_width(font, text); + text_height := font_get_height(font, text); + + font_set_color(theme.text_color); + font_draw(font, x + box_size + 4 * 2, y + font.em + (h - text_height) / 2, text); + + move_towards(^animation_state.click_time, 0.0f, theme.click_decay_speed); + + return result; +} + + + scrolling_region_start :: (r: Rect, max_y_scroll := 10000.0f, site := #callsite, increment := 0) { hash := get_site_hash(site, increment); diff --git a/src/sfx/audio_manager.onyx b/src/sfx/audio_manager.onyx index 7e7bdd0..99708d2 100644 --- a/src/sfx/audio_manager.onyx +++ b/src/sfx/audio_manager.onyx @@ -53,7 +53,7 @@ Audio_Manager :: struct { alBufferData(buffer, al_format, wav_file.data.data, wav_file.data.count, wav_file.sample_rate); memory.free_slice(^wav_file.loaded_file_data); - map.put(^loaded_sounds, path, .{ buffer }); + loaded_sounds[path] = .{ buffer }; return .{ buffer }; }