diff --git a/assets/common/recipe_book.ron b/assets/common/recipe_book.ron index 04b662e43d..bda7282cbb 100644 --- a/assets/common/recipe_book.ron +++ b/assets/common/recipe_book.ron @@ -2198,7 +2198,7 @@ is_recycling: false, ), "lockpick": ( - output: ("common.items.utility.lockpick_0", 10), + output: ("common.items.utility.lockpick_0", 2), inputs: [ (Item("common.items.mineral.ingot.copper"), 3, false), (Item("common.items.tool.craftsman_hammer"), 0, false), diff --git a/assets/common/trading/sellable_materials.ron b/assets/common/trading/sellable_materials.ron index 46b240cc12..3007c4905a 100644 --- a/assets/common/trading/sellable_materials.ron +++ b/assets/common/trading/sellable_materials.ron @@ -50,8 +50,8 @@ // Gatherables (0.1, Item("common.items.crafting_ing.seashells")), - (0.2, Item("common.items.crafting_ing.honey")), - (0.2, Item("common.items.flowers.moonbell")), + (9.0, Item("common.items.crafting_ing.honey")), + (5.0, Item("common.items.flowers.moonbell")), (1.0, Item("common.items.crafting_ing.cotton_boll")), (1.0, Item("common.items.flowers.pyrebloom")), (3.0, Item("common.items.crafting_ing.twigs")), diff --git a/assets/voxygen/element/ui/quests/quest_bg.png b/assets/voxygen/element/ui/quests/quest_bg.png new file mode 100644 index 0000000000..4ab5ba0a98 --- /dev/null +++ b/assets/voxygen/element/ui/quests/quest_bg.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12cd5a384f2f44d0933ee3026ba94683e11c3389cc9f9d9d4328e0f2f0cedc92 +size 29463 diff --git a/assets/voxygen/element/ui/quests/quest_frame.png b/assets/voxygen/element/ui/quests/quest_frame.png new file mode 100644 index 0000000000..879a114137 --- /dev/null +++ b/assets/voxygen/element/ui/quests/quest_frame.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:458e3cecf915bc3af7d9340722952a24b5a6b71d66aeb92ad9cf9715579331cf +size 3713 diff --git a/assets/voxygen/element/ui/quests/quest_icon.png b/assets/voxygen/element/ui/quests/quest_icon.png new file mode 100644 index 0000000000..cfb6fcb2f5 --- /dev/null +++ b/assets/voxygen/element/ui/quests/quest_icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca040299e7fb06c4ea5b0b22f84abf8bdb588d8f8052427f39f615d8d99fb4ed +size 394 diff --git a/assets/voxygen/i18n/en/hud/quest.ftl b/assets/voxygen/i18n/en/hud/quest.ftl new file mode 100644 index 0000000000..526e45c092 --- /dev/null +++ b/assets/voxygen/i18n/en/hud/quest.ftl @@ -0,0 +1,7 @@ +hud-quest = Quest +hud-quest-intro = Greetings, { $playername }! +hud-quest-desc-fetch = Please help me find: +hud-quest-desc-kill = Could you help me kill +hud-quest-reward = I will reward you with: +hud-quest-accept = Accept +hud-quest-decline = Decline \ No newline at end of file diff --git a/assets/voxygen/voxel/armor/misc/head/exclamation.vox b/assets/voxygen/voxel/armor/misc/head/exclamation.vox index 5304297467..69f6671630 100644 --- a/assets/voxygen/voxel/armor/misc/head/exclamation.vox +++ b/assets/voxygen/voxel/armor/misc/head/exclamation.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6a3369c5a2fc3e75d6ecb07d8e282b877b50f999afb629ac2c6b69359658b8a -size 1208 +oid sha256:d1d474655c8c46d7005fa5ceb1d35f64dd2d243b3daed621f1d9a70cedd0704f +size 22827 diff --git a/assets/world/manifests/spots_savannah/wolf_burrow.ron b/assets/world/manifests/spots_savannah/wolf_burrow.ron index 116c4b6e80..fe2f159124 100644 --- a/assets/world/manifests/spots_savannah/wolf_burrow.ron +++ b/assets/world/manifests/spots_savannah/wolf_burrow.ron @@ -5,10 +5,12 @@ specifier: "world.structure.natural.wolf_burrow", center: (10, 10, 6), custom_indices: { + 8: Filled(Air, (r: 255, g: 255, b: 255)), 20: Sprite(ShortGrass), 19: Sprite(Mushroom), - 18: Sprite(Chest), - 17: Sprite(Bones), + 18: Sprite(CommonLockedChest), + 17: Sprite(Bones), + 242: EntitySpawner("common.entity.wild.aggressive.wolf", 0.5), }, ), ] diff --git a/assets/world/structure/natural/wolf_burrow.vox b/assets/world/structure/natural/wolf_burrow.vox index 7baec93c7f..a37b8e9e87 100644 --- a/assets/world/structure/natural/wolf_burrow.vox +++ b/assets/world/structure/natural/wolf_burrow.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a251945a41ed9e46688ad1e5ab7705535264957ef807e305a823b715bbc6d264 -size 16044 +oid sha256:a8b3ab9d287bee5f64d81ecff9fd0ac6b13fbe93cb755e2fead75f9523dfc709 +size 16008 diff --git a/common/src/terrain/sprite.rs b/common/src/terrain/sprite.rs index f7e92b7e49..fac1e38f45 100644 --- a/common/src/terrain/sprite.rs +++ b/common/src/terrain/sprite.rs @@ -517,7 +517,7 @@ impl SpriteKind { .and_then(|cfg| cfg.unlock) .unwrap_or_else(|| match self { // Example, do not let this merge with twigs requiring cheese to pick up - SpriteKind::CommonLockedChest => UnlockKind::Requires(ItemDefinitionId::Simple("common.items.utility.lockpick_0").to_owned()), + SpriteKind::CommonLockedChest => UnlockKind::Consumes(ItemDefinitionId::Simple("common.items.utility.lockpick_0").to_owned()), _ => UnlockKind::Free, }) } diff --git a/voxygen/src/hud/img_ids.rs b/voxygen/src/hud/img_ids.rs index cac95e08c1..8dfd03b43d 100644 --- a/voxygen/src/hud/img_ids.rs +++ b/voxygen/src/hud/img_ids.rs @@ -103,6 +103,12 @@ image_ids! { wpn_icon_border_press: "voxygen.element.ui.generic.buttons.border_press", wpn_icon_border_pressed: "voxygen.element.ui.generic.buttons.border_pressed", + // Quest Window + quest_bg: "voxygen.element.ui.quests.quest_bg", + quest_frame: "voxygen.element.ui.quests.quest_frame", + quest_ico: "voxygen.element.ui.quests.quest_icon", + + // Social Window social_frame_on: "voxygen.element.ui.social.social_frame", social_bg_on: "voxygen.element.ui.social.social_bg", @@ -155,7 +161,7 @@ image_ids! { chat_tab_settings_bg: "voxygen.element.ui.settings.chat_tab_settings_bg", chat_tab_settings_frame: "voxygen.element.ui.settings.chat_tab_settings_frame", - quest_bg: "voxygen.element.ui.quests.temp_quest_bg", + quest_bg0: "voxygen.element.ui.quests.temp_quest_bg", // Slider slider: "voxygen.element.ui.generic.slider.track", @@ -616,9 +622,7 @@ image_ids! { health_bar_group_bg: "voxygen.element.ui.generic.frames.enemybar_bg_1", // Enemy Bar Content: enemy_bar: "voxygen.element.ui.skillbar.enemy_bar_content", - map_icon: "voxygen.element.ui.generic.buttons.map", - grid_button: "voxygen.element.ui.generic.buttons.border", grid_button_hover: "voxygen.element.ui.generic.buttons.border_mo", grid_button_press: "voxygen.element.ui.generic.buttons.border_press", diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index adaefa381f..159fb4867c 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -18,6 +18,7 @@ mod overhead; mod overitem; mod popup; mod prompt_dialog; +mod quest; mod settings_window; mod skillbar; mod slots; @@ -48,6 +49,7 @@ use map::Map; use minimap::{MiniMap, VoxelMinimap}; use popup::Popup; use prompt_dialog::PromptDialog; +use quest::Quest; use serde::{Deserialize, Serialize}; use settings_window::{SettingsTab, SettingsWindow}; use skillbar::Skillbar; @@ -318,6 +320,7 @@ widget_ids! { esc_menu, small_window, social_window, + quest_window, crafting_window, settings_window, group_window, @@ -891,6 +894,7 @@ pub struct Show { social: bool, diary: bool, group: bool, + quest: bool, group_menu: bool, esc_menu: bool, open_windows: Windows, @@ -941,6 +945,7 @@ impl Show { self.crafting = false; self.crafting_fields.salvage = false; self.social = false; + self.quest = false; self.diary = false; self.want_grab = !self.any_window_requires_cursor(); } @@ -958,6 +963,15 @@ impl Show { } } + fn quest(&mut self, open: bool) { + if !self.esc_menu { + self.quest = open; + self.diary = false; + self.map = false; + self.want_grab = !self.any_window_requires_cursor(); + } + } + fn crafting(&mut self, open: bool) { if !self.esc_menu { if !self.crafting && open { @@ -990,6 +1004,7 @@ impl Show { fn diary(&mut self, open: bool) { if !self.esc_menu { self.social = false; + self.quest = false; self.crafting = false; self.crafting_fields.salvage = false; self.bag = false; @@ -1009,6 +1024,7 @@ impl Show { }; self.bag = false; self.social = false; + self.quest = false; self.crafting = false; self.crafting_fields.salvage = false; self.diary = false; @@ -1060,6 +1076,7 @@ impl Show { || self.diary || self.help || self.intro + || self.quest || !matches!(self.open_windows, Windows::None) } @@ -1072,6 +1089,7 @@ impl Show { self.intro = false; self.map = false; self.social = false; + self.quest = false; self.diary = false; self.crafting = false; self.open_windows = Windows::None; @@ -1125,6 +1143,7 @@ impl Show { && !self.esc_menu && !self.map && !self.social + && !self.quest && !self.crafting && !self.diary && !self.help @@ -1373,6 +1392,8 @@ impl Hud { social: false, diary: false, group: false, + // Change this before implementation! + quest: false, group_menu: false, chat_tab_settings_index: None, settings_tab: SettingsTab::Interface, @@ -3313,6 +3334,37 @@ impl Hud { } } } + // Quest Window + let stats = client.state().ecs().read_storage::(); + if self.show.quest { + if let Some(stats) = stats.get(entity) { + match Quest::new( + &self.show, + client, + &self.imgs, + &self.fonts, + i18n, + &self.rot_imgs, + tooltip_manager, + stats, + &self.item_imgs, + self.pulse, + ) + .set(self.ids.quest_window, ui_widgets) + { + Some(quest::Event::Close) => { + self.show.quest(false); + if !self.show.bag { + self.show.want_grab = true; + self.force_ungrab = false; + } else { + self.force_ungrab = true + }; + }, + None => {}, + } + } + } // Social Window if self.show.social { @@ -4063,7 +4115,7 @@ impl Hud { self.show.want_grab = false; let quest_headline = i18n.get_msg("hud-temp_quest_headline"); let quest_text = i18n.get_msg("hud-temp_quest_text"); - Image::new(self.imgs.quest_bg) + Image::new(self.imgs.quest_bg0) .w_h(404.0, 858.0) .middle_of(ui_widgets.window) .set(self.ids.quest_bg, ui_widgets); diff --git a/voxygen/src/hud/quest.rs b/voxygen/src/hud/quest.rs new file mode 100644 index 0000000000..332224df9f --- /dev/null +++ b/voxygen/src/hud/quest.rs @@ -0,0 +1,337 @@ +use client::Client; +use common::comp::{inventory::item::item_key::ItemKey, Stats}; +use conrod_core::{ + color, + widget::{self, Button, Image, Rectangle, Scrollbar, Text}, + widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, +}; +use i18n::Localization; + +use crate::ui::{fonts::Fonts, TooltipManager}; +use inline_tweak::*; + +use super::{ + img_ids::{Imgs, ImgsRot}, + item_imgs::{animate_by_pulse, ItemImgs}, + Show, HP_COLOR, TEXT_COLOR, TEXT_DULL_RED_COLOR, TEXT_VELORITE, UI_HIGHLIGHT_0, UI_MAIN, +}; + +pub struct State { + ids: Ids, +} + +widget_ids! { + pub struct Ids { + quest_close, + bg, + frame, + icon, + close, + title_align, + title, + content_align, + scrollbar, + intro_txt, + desc_txt_0, + quest_objectives[], + quest_reward_txt, + objective_text, + quest_rewards_frames[], + quest_rewards_icons[], + quest_rewards_txts[], + accept_btn, + decline_btn, + } +} + +#[derive(WidgetCommon)] +pub struct Quest<'a> { + _show: &'a Show, + _client: &'a Client, + imgs: &'a Imgs, + fonts: &'a Fonts, + localized_strings: &'a Localization, + _rot_imgs: &'a ImgsRot, + _tooltip_manager: &'a mut TooltipManager, + stats: &'a Stats, + item_imgs: &'a ItemImgs, + pulse: f32, + + #[conrod(common_builder)] + common: widget::CommonBuilder, +} + +impl<'a> Quest<'a> { + pub fn new( + _show: &'a Show, + _client: &'a Client, + imgs: &'a Imgs, + fonts: &'a Fonts, + localized_strings: &'a Localization, + _rot_imgs: &'a ImgsRot, + _tooltip_manager: &'a mut TooltipManager, + stats: &'a Stats, + item_imgs: &'a ItemImgs, + pulse: f32, + ) -> Self { + Self { + _show, + _client, + imgs, + _rot_imgs, + fonts, + localized_strings, + _tooltip_manager, + stats, + item_imgs, + pulse, + common: widget::CommonBuilder::default(), + } + } +} + +pub enum Event { + Close, +} + +impl<'a> Widget for Quest<'a> { + type Event = Option; + type State = State; + type Style = (); + + fn init_state(&self, id_gen: widget::id::Generator) -> Self::State { + Self::State { + ids: Ids::new(id_gen), + } + } + + fn style(&self) -> Self::Style {} + + fn update(self, args: widget::UpdateArgs) -> Self::Event { + let widget::UpdateArgs { state, ui, .. } = args; + let mut event = None; + + // Window BG + Image::new(self.imgs.quest_bg) + .bottom_left_with_margins_on(ui.window, tweak!(308.0), tweak!(500.0)) + .color(Some(UI_MAIN)) + .w_h(280.0, 460.0) + .set(state.ids.bg, ui); + // Window frame + Image::new(self.imgs.quest_frame) + .middle_of(state.ids.bg) + .color(Some(UI_HIGHLIGHT_0)) + .w_h(280.0, 460.0) + .set(state.ids.frame, ui); + + // Icon + Image::new(self.imgs.quest_ico) + .w_h(30.0, 30.0) + .top_left_with_margins_on(state.ids.frame, 6.0, 6.0) + .set(state.ids.icon, ui); + // X-Button + if Button::image(self.imgs.close_button) + .w_h(24.0, 25.0) + .hover_image(self.imgs.close_button_hover) + .press_image(self.imgs.close_button_press) + .top_right_with_margins_on(state.ids.frame, 0.0, 0.0) + .set(state.ids.close, ui) + .was_clicked() + { + event = Some(Event::Close); + } + + // Title + Rectangle::fill_with([212.0, 42.0], color::TRANSPARENT) + .top_left_with_margins_on(state.ids.frame, 2.0, 44.0) + .set(state.ids.title_align, ui); + Text::new(&self.localized_strings.get_msg("hud-quest")) + .middle_of(state.ids.title_align) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .color(TEXT_COLOR) + .set(state.ids.title, ui); + + // Content Alignment + Rectangle::fill_with([tweak!(270.0), tweak!(395.0)], color::TRANSPARENT) + .mid_top_with_margin_on(state.ids.frame, tweak!(55.0)) + .scroll_kids_vertically() + .set(state.ids.content_align, ui); + Scrollbar::y_axis(state.ids.content_align) + .thickness(4.0) + .color(Color::Rgba(0.79, 1.09, 1.09, 0.0)) + .set(state.ids.scrollbar, ui); + + // Quest Text + + // Introduction + + Text::new( + &self + .localized_strings + .get_msg_ctx("hud-quest-intro", &i18n::fluent_args! { + "playername" => self.stats.name.to_string(), + }), + ) + .top_left_with_margins_on(state.ids.content_align, tweak!(0.0), tweak!(2.0)) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(tweak!(20))) + .color(TEXT_COLOR) + .set(state.ids.intro_txt, ui); + + enum QuestType { + FetchQuest, + // KillQuest, + } + + // Define type of quest to change introduction text + + let quest_type = QuestType::FetchQuest; + + let q_desc0 = match quest_type { + QuestType::FetchQuest => "hud-quest-desc-fetch", + // QuestType::KillQuest => "hud-quest-desc-kill", + }; + + Text::new(&self.localized_strings.get_msg(q_desc0)) + .top_left_with_margins_on(state.ids.intro_txt, tweak!(40.0), tweak!(0.0)) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(tweak!(20))) + .color(TEXT_COLOR) + .set(state.ids.desc_txt_0, ui); + + // Objective(s) + let objective_amount = 20.0; + let objective_name = "Flower"; + let objective_txt = format!("{}x {}", objective_amount, objective_name); + + Text::new(&objective_txt) + .down_from(state.ids.desc_txt_0, tweak!(10.0)) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(tweak!(20))) + .color(TEXT_VELORITE) + .set(state.ids.objective_text, ui); + + Text::new(&self.localized_strings.get_msg("hud-quest-reward")) + .down_from(state.ids.objective_text, tweak!(30.0)) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(tweak!(20))) + .color(TEXT_COLOR) + .set(state.ids.quest_reward_txt, ui); + + // insert reward item data here + // [amount, item_desc] + + //("common.items.weapons.sword.caladbolg"); + let rewards = vec![ + (1, "common.items.weapons.dagger.starter_dagger", "Dagger"), + (4, "common.items.crafting_ing.seashells", "Seashell"), + ( + 8, + "common.items.crafting_ing.animal_misc.raptor_feather", + "Raptor Feather", + ), + ]; + let rewards_amount = rewards.len(); + + if state.ids.quest_rewards_frames.len() < rewards_amount { + state.update(|s| { + s.ids + .quest_rewards_frames + .resize(rewards.len(), &mut ui.widget_id_generator()) + }) + }; + if state.ids.quest_rewards_icons.len() < rewards_amount { + state.update(|s| { + s.ids + .quest_rewards_icons + .resize(rewards.len(), &mut ui.widget_id_generator()) + }) + }; + if state.ids.quest_rewards_txts.len() < rewards_amount { + state.update(|s| { + s.ids + .quest_rewards_txts + .resize(rewards.len(), &mut ui.widget_id_generator()) + }) + }; + + for (i, item) in rewards.iter().enumerate() { + // Slot BG + let mut frame_img = Image::new(self.imgs.skillbar_slot) + .w_h(40.0, 40.0) + .color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))); + + if i == 0 { + frame_img = frame_img.down_from(state.ids.quest_reward_txt, tweak!(10.0)) + } else { + frame_img = frame_img.down_from(state.ids.quest_rewards_frames[i - 1], tweak!(5.0)) + } + frame_img.set(state.ids.quest_rewards_frames[i], ui); + + // Item amount and text + let item_txt = if item.0 == 1 { + item.2.to_string() + } else { + format!("{}x {}", item.0, item.2) + }; + //INPUT QUALITY HERE TO CHANGE COLOR + let item_quality = TEXT_VELORITE; + Text::new(&item_txt) + .right_from(state.ids.quest_rewards_frames[i], tweak!(10.0)) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(tweak!(18))) + .color(item_quality) + .set(state.ids.quest_rewards_txts[i], ui); + // Item image + Image::new(animate_by_pulse( + &self + .item_imgs + .img_ids_or_not_found_img(ItemKey::Simple(item.1.to_string())), + self.pulse, + )) + .w_h(38.0, 38.0) + .middle_of(state.ids.quest_rewards_frames[i]) + .color(Some(Color::Rgba(1.0, 1.0, 1.0, 1.0))) + .set(state.ids.quest_rewards_icons[i], ui); + } + + // Accept/Decline Buttons + + if Button::image(self.imgs.button) + .bottom_left_with_margins_on(state.ids.content_align, tweak!(5.0), tweak!(5.0)) + .w_h(tweak!(120.0), tweak!(50.0)) + .hover_image(self.imgs.button_hover) + .press_image(self.imgs.button_press) + .label(&self.localized_strings.get_msg("hud-quest-accept")) + .label_y(conrod_core::position::Relative::Scalar(3.0)) + .label_color(TEXT_COLOR) + .label_font_size(self.fonts.cyri.scale(20)) + .label_font_id(self.fonts.cyri.conrod_id) + .image_color(HP_COLOR) + .set(state.ids.accept_btn, ui) + .was_clicked() + { + event = Some(Event::Close); + }; + + if Button::image(self.imgs.button) + .bottom_right_with_margins_on(state.ids.content_align, tweak!(5.0), tweak!(5.0)) + .w_h(tweak!(120.0), tweak!(50.0)) + .hover_image(self.imgs.button_hover) + .press_image(self.imgs.button_press) + .label(&self.localized_strings.get_msg("hud-quest-decline")) + .label_y(conrod_core::position::Relative::Scalar(3.0)) + .label_color(TEXT_COLOR) + .label_font_size(self.fonts.cyri.scale(20)) + .label_font_id(self.fonts.cyri.conrod_id) + .image_color(TEXT_DULL_RED_COLOR) + .set(state.ids.decline_btn, ui) + .was_clicked() + { + event = Some(Event::Close); + }; + + event + } +} diff --git a/world/src/layer/spot.rs b/world/src/layer/spot.rs index 7c625b4aa2..b326e4b520 100644 --- a/world/src/layer/spot.rs +++ b/world/src/layer/spot.rs @@ -436,7 +436,7 @@ impl Spot { Self::generate_spots( Spot::ForestCamp, world, - 8.0, + 4.0, |g, c| { g < 0.25 && !c.near_cliffs() @@ -450,7 +450,7 @@ impl Spot { Self::generate_spots( Spot::SnowCamp, world, - 6.0, + 1.0, |g, c| { g < 0.25 && !c.near_cliffs() @@ -480,7 +480,7 @@ impl Spot { Self::generate_spots( Spot::GraveSmall, world, - 50.0, + 2.0, |g, c| { g < 0.25 && !c.near_cliffs()