Skip to content

Commit

Permalink
Add weapon swap icons
Browse files Browse the repository at this point in the history
  • Loading branch information
Zerthox committed Dec 25, 2024
1 parent 2031bca commit add26fa
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 83 deletions.
Binary file added reffect/src/assets/bundle_drop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions reffect/src/assets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
pub static MONSTER_ICON: &[u8] = include_bytes!("monster_skill.png");

pub static TEMP_ICON: &[u8] = include_bytes!("temp_skill.png");

pub static WEAPON_SWAP: &[u8] = include_bytes!("weapon_swap.png");

pub static BUNDLE_DROP: &[u8] = include_bytes!("bundle_drop.png");
Binary file added reffect/src/assets/weapon_swap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions reffect/src/elements/icon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
},
render_util::{debug_optional, draw_spinner_bg, draw_text_bg, Rect},
settings::icon::{DurationBarSettings, DurationTextSettings, StackTextSettings},
trigger::{ProgressActive, ProgressValue},
trigger::{ProgressActive, ProgressValue, Skill},
};
use nexus::imgui::Ui;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -65,9 +65,11 @@ impl Icon {
if let Some(active) = active {
let [width, height] = size;
let small_size = width.min(height);
let texture = self
.source
.get_texture(active.id().filter(|_| ctx.settings.use_game_icons));
let texture = self.source.get_texture(if ctx.settings.use_game_icons {
active.skill()
} else {
Skill::Unknown
});

let (start, end) = Self::bounds(size);
let start = state.pos.add(start);
Expand Down Expand Up @@ -206,7 +208,7 @@ impl RenderDebug for Icon {
ui,
"Texture",
self.source
.get_texture(None)
.get_texture(Skill::Unknown)
.map(|texture| texture.id() as *mut ()),
);
}
Expand Down
13 changes: 11 additions & 2 deletions reffect/src/elements/icon/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
lockbox::Lockbox,
render_util::{enum_combo, impl_static_variants, input_text_simple_menu, Validation},
texture_manager::TextureManager,
trigger::Skill,
};
use nexus::imgui::{ComboBoxFlags, TextureId, Ui};
use reffect_internal::{Interface, Internal};
Expand Down Expand Up @@ -59,10 +60,18 @@ impl IconSource {
TextureManager::add_source(self)
}

pub fn get_texture(&self, skill_id: Option<u32>) -> Option<TextureId> {
pub fn get_texture(&self, skill: Skill) -> Option<TextureId> {
match self {
Self::Empty => None,
Self::Dynamic => Internal::get_skill_icon(skill_id?).map(|srv| srv.as_raw().into()),
Self::Dynamic => match skill {
Skill::Unknown => TextureManager::get_texture(&IconSource::Unknown),
Skill::WeaponSwap => TextureManager::get_weapon_swap(),
Skill::BundleDrop => TextureManager::get_bundle_drop(),
Skill::Id(id) => match Internal::get_skill_icon(id) {
Some(tex) => Some(tex.as_raw().into()),
None => TextureManager::get_texture(&IconSource::Unknown),
},
},
_ => TextureManager::get_texture(self),
}
}
Expand Down
88 changes: 58 additions & 30 deletions reffect/src/texture_manager.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use crate::{
addon::Addon,
assets::{MONSTER_ICON, TEMP_ICON},
elements::icon::IconSource,
};
use crate::{addon::Addon, assets, elements::icon::IconSource};
use nexus::{
imgui::TextureId,
texture::{
Expand All @@ -24,21 +20,36 @@ static TEXTURE_MANAGER: OnceLock<Mutex<TextureManager>> = OnceLock::new();
#[derive(Debug)]
pub struct TextureManager {
loader: Option<TextureLoader>,
error: Option<TextureId>,
pending: HashMap<String, IconSource>,
loaded: HashMap<IconSource, TextureId>,
error: Option<TextureId>,
weapon: Option<TextureId>,
bundle: Option<TextureId>,
}

impl TextureManager {
const ERROR_ID: &'static str = "REFFECT_ICON_ERROR";
const WEAPON_ID: &'static str = "REFFECT_ICON_WEAPON";
const BUNDLE_ID: &'static str = "REFFECT_ICON_BUNDLE";

fn new() -> Self {
Self {
loader: TextureLoader::spawn(Self::loader_thread),
error: None,
pending: HashMap::new(),
loaded: HashMap::new(),
error: None,
weapon: None,
bundle: None,
}
.with_defaults()
}

fn with_defaults(mut self) -> Self {
self.try_load_from_mem(Self::ERROR_ID, assets::TEMP_ICON);
self.try_load_from_mem(Self::WEAPON_ID, assets::WEAPON_SWAP);
self.try_load_from_mem(Self::BUNDLE_ID, assets::BUNDLE_DROP);
self.try_load_from_mem(IconSource::UNKNOWN_ID, assets::MONSTER_ICON);
self
}

fn loader_thread(source: IconSource) -> bool {
Expand Down Expand Up @@ -72,12 +83,6 @@ impl TextureManager {
self.loaded.contains_key(source) || self.pending.contains_key(&source.generate_id())
}

fn with_defaults(mut self) -> Self {
self.try_load_from_mem(Self::ERROR_ID, TEMP_ICON);
self.try_load_from_mem(IconSource::UNKNOWN_ID, MONSTER_ICON);
self
}

fn try_load_from_mem(&mut self, id: impl AsRef<str>, data: impl AsRef<[u8]>) {
// check for the texture ourself to avoid recursive locking
let id = id.as_ref();
Expand All @@ -90,7 +95,7 @@ impl TextureManager {
}

pub fn load() -> &'static Mutex<TextureManager> {
TEXTURE_MANAGER.get_or_init(|| Mutex::new(Self::new().with_defaults()))
TEXTURE_MANAGER.get_or_init(|| Mutex::new(Self::new()))
}

fn lock() -> MutexGuard<'static, TextureManager> {
Expand All @@ -105,10 +110,16 @@ impl TextureManager {
}
}

pub fn get_weapon_swap() -> Option<TextureId> {
Self::lock().weapon
}

pub fn get_bundle_drop() -> Option<TextureId> {
Self::lock().bundle
}

pub fn get_texture(source: &IconSource) -> Option<TextureId> {
// TODO: error state?
let textures = Self::lock();
textures.loaded.get(source).copied()
Self::lock().loaded.get(source).copied()
}

pub fn add_source(source: &IconSource) {
Expand Down Expand Up @@ -165,22 +176,39 @@ impl TextureManager {
}

fn add_loaded(&mut self, pending_id: &str, texture_id: Option<TextureId>) {
if pending_id == Self::ERROR_ID {
self.error = texture_id;
if self.error.is_none() {
log::error!("Failed to error icon source");
match pending_id {
Self::ERROR_ID => {
if texture_id.is_none() {
log::error!("Failed to error icon source");
}
self.error = texture_id;
}
} else if let Some(source) = self.pending.remove(pending_id) {
if let Some(texture_id) = texture_id {
self.loaded.insert(source, texture_id);
} else {
log::warn!("Failed to load icon source {}", source.pretty_print());
if let Some(texture_id) = self.error {
self.loaded.insert(source, texture_id);
Self::WEAPON_ID => {
if texture_id.is_none() {
log::error!("Failed to weapon swap icon source");
}
self.weapon = texture_id;
}
Self::BUNDLE_ID => {
if texture_id.is_none() {
log::error!("Failed to bundle drop icon source");
}
self.bundle = texture_id;
}
_ => {
if let Some(source) = self.pending.remove(pending_id) {
if let Some(texture_id) = texture_id {
self.loaded.insert(source, texture_id);
} else {
log::warn!("Failed to load icon source {}", source.pretty_print());
if let Some(texture_id) = self.error {
self.loaded.insert(source, texture_id);
}
}
} else {
log::warn!("Received load for non-pending texture \"{pending_id}\"");
}
}
} else {
log::warn!("Received load for non-pending texture \"{pending_id}\"");
}
}
}
Expand Down
73 changes: 42 additions & 31 deletions reffect/src/trigger/progress/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ pub enum ProgressActive {
end: u32,
},
Ability {
id: u32,
skill: Skill,
ammo: u32,
rate: f32,
duration: u32,
recharge: u32,
end: u32,
ammo_duration: u32,
ammo_recharge: u32,
ammo_end: u32,
},
}
Expand Down Expand Up @@ -57,14 +57,14 @@ impl ProgressActive {
}

/// Creates new timed active progress from a recharge.
pub fn from_recharge(recharge: &Recharge) -> Self {
pub fn from_recharge(skill: Skill, recharge: &Recharge) -> Self {
let duration = recharge.recharge;
Self::Ability {
id: 0,
ammo: if duration > 0 { 1 } else { 0 },
duration,
skill,
ammo: if duration == 0 { 1 } else { 0 },
recharge: duration,
end: recharge.end(),
ammo_duration: 0,
ammo_recharge: 0,
ammo_end: 0,
rate: 1.0,
}
Expand All @@ -81,15 +81,15 @@ impl ProgressActive {
ammo_recharge_remaining,
} = *ability;
Self::Ability {
id,
skill: id.into(),
ammo,
duration: recharge,
recharge,
end: if recharge > 0 {
skillbar.last_update + Self::unscale(recharge_remaining, skillbar.recharge_rate)
} else {
0
},
ammo_duration: ammo_recharge,
ammo_recharge,
ammo_end: if ammo_recharge > 0 {
skillbar.last_update
+ Self::unscale(ammo_recharge_remaining, skillbar.recharge_rate)
Expand Down Expand Up @@ -119,28 +119,24 @@ impl ProgressActive {
}

/// Creates an ability progress for edit mode.
pub const fn edit_ability(id: u32, progress: f32, now: u32) -> Self {
// half speed
let slow = if progress < 0.5 {
2.0 * progress
} else {
2.0 * progress - 1.0
};
pub const fn edit_ability(skill: Skill, progress: f32, now: u32) -> Self {
Self::Ability {
id,
skill,
ammo: (5.0 * progress) as u32,
duration: 5000,
recharge: 5000,
end: now + (5000.0 * progress) as u32,
rate: 1.0,
ammo_duration: 10_000,
ammo_end: now + (10000.0 * slow) as u32,
ammo_recharge: 5000,
ammo_end: now + (5000.0 * progress) as u32,
}
}

pub const fn id(&self) -> Option<u32> {
/// Returns the assoicated skill.
pub const fn skill(&self) -> Skill {
match *self {
Self::Fixed { .. } => None,
Self::Buff { id, .. } | Self::Ability { id, .. } => Some(id),
Self::Fixed { .. } => Skill::Unknown,
Self::Buff { id, .. } => Skill::Id(id),
Self::Ability { skill, .. } => skill,
}
}

Expand Down Expand Up @@ -242,10 +238,10 @@ impl ProgressActive {
Self::Fixed { max, .. } => max,
Self::Buff { duration, .. } => duration,
Self::Ability {
duration,
ammo_duration,
recharge,
ammo_recharge,
..
} => value.pick(duration, ammo_duration),
} => value.pick(recharge, ammo_recharge),
}
}

Expand All @@ -261,10 +257,10 @@ impl ProgressActive {
}
}
Self::Ability {
duration,
ammo_duration,
recharge,
ammo_recharge,
..
} => Self::format_seconds(value.pick(duration, ammo_duration)),
} => Self::format_seconds(value.pick(recharge, ammo_recharge)),
}
}

Expand Down Expand Up @@ -336,3 +332,18 @@ impl ProgressValue {
}
}
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Skill {
#[default]
Unknown,
WeaponSwap,
BundleDrop,
Id(u32),
}

impl From<u32> for Skill {
fn from(id: u32) -> Self {
Self::Id(id)
}
}
Loading

0 comments on commit add26fa

Please sign in to comment.