mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Removed ability set as field on items.
This commit is contained in:
parent
a37174d6f2
commit
a35b8b4aad
@ -1,244 +1,244 @@
|
||||
// Maps a tool kind to a set of abilities
|
||||
// A set of abilities is a primary, a secondary, and a vec of all extra abilities
|
||||
({
|
||||
Sword: (
|
||||
Tool(Sword): (
|
||||
primary: "common.abilities.sword.triplestrike",
|
||||
secondary: "common.abilities.sword.dash",
|
||||
abilities: [
|
||||
(Some(Sword(UnlockSpin)), "common.abilities.sword.spin"),
|
||||
],
|
||||
),
|
||||
Axe: (
|
||||
Tool(Axe): (
|
||||
primary: "common.abilities.axe.doublestrike",
|
||||
secondary: "common.abilities.axe.spin",
|
||||
abilities: [
|
||||
(Some(Axe(UnlockLeap)), "common.abilities.axe.leap"),
|
||||
],
|
||||
),
|
||||
Hammer: (
|
||||
Tool(Hammer): (
|
||||
primary: "common.abilities.hammer.singlestrike",
|
||||
secondary: "common.abilities.hammer.charged",
|
||||
abilities: [
|
||||
(Some(Hammer(UnlockLeap)), "common.abilities.hammer.leap"),
|
||||
],
|
||||
),
|
||||
Bow: (
|
||||
Tool(Bow): (
|
||||
primary: "common.abilities.bow.basic",
|
||||
secondary: "common.abilities.bow.charged",
|
||||
abilities: [
|
||||
(Some(Bow(UnlockRepeater)), "common.abilities.bow.repeater"),
|
||||
],
|
||||
),
|
||||
Unique(Husk): (
|
||||
Tool(Unique(Husk)): (
|
||||
primary: "common.abilities.unique.husk.singlestrike",
|
||||
secondary: "common.abilities.unique.husk.triplestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Spear: (
|
||||
Tool(Spear): (
|
||||
primary: "common.abilities.spear.doublestrike",
|
||||
secondary: "common.abilities.spear.dash",
|
||||
abilities: [],
|
||||
|
||||
),
|
||||
HammerSimple: (
|
||||
Tool(HammerSimple): (
|
||||
primary: "common.abilities.hammersimple.doublestrike",
|
||||
secondary: "common.abilities.hammersimple.doublestrike",
|
||||
abilities: [],
|
||||
),
|
||||
AxeSimple: (
|
||||
Tool(AxeSimple): (
|
||||
primary: "common.abilities.axesimple.doublestrike",
|
||||
secondary: "common.abilities.axesimple.dash",
|
||||
abilities: [],
|
||||
),
|
||||
SwordSimple: (
|
||||
Tool(SwordSimple): (
|
||||
primary: "common.abilities.swordsimple.doublestrike",
|
||||
secondary: "common.abilities.swordsimple.dash",
|
||||
abilities: [
|
||||
],
|
||||
),
|
||||
StaffSimple: (
|
||||
Tool(StaffSimple): (
|
||||
primary: "common.abilities.staffsimple.firebomb",
|
||||
secondary: "common.abilities.staffsimple.flamethrower",
|
||||
abilities: [],
|
||||
),
|
||||
BowSimple: (
|
||||
Tool(BowSimple): (
|
||||
primary: "common.abilities.bowsimple.basic",
|
||||
secondary: "common.abilities.bowsimple.basic",
|
||||
abilities: [
|
||||
],
|
||||
),
|
||||
Staff: (
|
||||
Tool(Staff): (
|
||||
primary: "common.abilities.staff.firebomb",
|
||||
secondary: "common.abilities.staff.flamethrower",
|
||||
abilities: [
|
||||
(Some(Staff(UnlockShockwave)), "common.abilities.staff.fireshockwave"),
|
||||
],
|
||||
),
|
||||
Sceptre: (
|
||||
Tool(Sceptre): (
|
||||
primary: "common.abilities.sceptre.lifestealbeam",
|
||||
secondary: "common.abilities.sceptre.healingbeam",
|
||||
abilities: [
|
||||
(Some(Sceptre(UnlockAura)), "common.abilities.sceptre.wardingaura"),
|
||||
],
|
||||
),
|
||||
Dagger: (
|
||||
Tool(Dagger): (
|
||||
primary: "common.abilities.dagger.tempbasic",
|
||||
secondary: "common.abilities.dagger.tempbasic",
|
||||
abilities: [],
|
||||
),
|
||||
Shield: (
|
||||
Tool(Shield): (
|
||||
primary: "common.abilities.shield.tempbasic",
|
||||
secondary: "common.abilities.shield.block",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(StoneGolemFist): (
|
||||
Tool(Unique(StoneGolemFist)): (
|
||||
primary: "common.abilities.unique.stonegolemfist.singlestrike",
|
||||
secondary: "common.abilities.unique.stonegolemfist.shockwave",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.stonegolemfist.spin"),
|
||||
],
|
||||
),
|
||||
Unique(BeastClaws): (
|
||||
Tool(Unique(BeastClaws)): (
|
||||
primary: "common.abilities.unique.beastclaws.basic",
|
||||
secondary: "common.abilities.unique.beastclaws.basic",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(WendigoMagic): (
|
||||
Tool(Unique(WendigoMagic)): (
|
||||
primary: "common.abilities.unique.wendigomagic.frostbomb",
|
||||
secondary: "common.abilities.unique.wendigomagic.singlestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(TidalClaws): (
|
||||
Tool(Unique(TidalClaws)): (
|
||||
primary: "common.abilities.staff.flamethrower",
|
||||
secondary: "common.abilities.unique.wendigomagic.singlestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadMedQuick): (
|
||||
Tool(Unique(QuadMedQuick)): (
|
||||
primary: "common.abilities.unique.quadmedquick.triplestrike",
|
||||
secondary: "common.abilities.unique.quadmedquick.dash",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadMedJump): (
|
||||
Tool(Unique(QuadMedJump)): (
|
||||
primary: "common.abilities.unique.quadmedjump.leap",
|
||||
secondary: "common.abilities.unique.quadmedjump.doublestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.quadmedjump.quickleap"),
|
||||
],
|
||||
),
|
||||
Unique(QuadMedCharge): (
|
||||
Tool(Unique(QuadMedCharge)): (
|
||||
primary: "common.abilities.unique.quadmedcharge.doublestrike",
|
||||
secondary: "common.abilities.unique.quadmedcharge.dash",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadMedHoof): (
|
||||
Tool(Unique(QuadMedHoof)): (
|
||||
primary: "common.abilities.unique.quadmedhoof.basic",
|
||||
secondary: "common.abilities.unique.quadmedhoof.basic",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadMedBasic): (
|
||||
Tool(Unique(QuadMedBasic)): (
|
||||
primary: "common.abilities.unique.quadmedbasic.singlestrike",
|
||||
secondary: "common.abilities.unique.quadmedbasic.triplestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadLowRanged): (
|
||||
Tool(Unique(QuadLowRanged)): (
|
||||
primary: "common.abilities.unique.quadlowranged.singlestrike",
|
||||
secondary: "common.abilities.unique.quadlowranged.firebomb",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadLowBreathe): (
|
||||
Tool(Unique(QuadLowBreathe)): (
|
||||
primary: "common.abilities.unique.quadlowbreathe.flamethrower",
|
||||
secondary: "common.abilities.unique.quadlowbreathe.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.quadlowbreathe.dash"),
|
||||
],
|
||||
),
|
||||
Unique(QuadLowTail): (
|
||||
Tool(Unique(QuadLowTail)): (
|
||||
primary: "common.abilities.unique.quadlowtail.charged",
|
||||
secondary: "common.abilities.unique.quadlowtail.triplestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadLowQuick): (
|
||||
Tool(Unique(QuadLowQuick)): (
|
||||
primary: "common.abilities.unique.quadlowquick.dash",
|
||||
secondary: "common.abilities.unique.quadlowquick.quadstrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadLowBasic): (
|
||||
Tool(Unique(QuadLowBasic)): (
|
||||
primary: "common.abilities.unique.quadlowbasic.triplestrike",
|
||||
secondary: "common.abilities.unique.quadlowbasic.singlestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(QuadLowBeam): (
|
||||
Tool(Unique(QuadLowBeam)): (
|
||||
primary: "common.abilities.unique.quadlowbeam.healingbeam",
|
||||
secondary: "common.abilities.unique.quadlowbreathe.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.quadlowbreathe.dash"),
|
||||
],
|
||||
),
|
||||
Unique(QuadSmallBasic): (
|
||||
Tool(Unique(QuadSmallBasic)): (
|
||||
primary: "common.abilities.unique.quadsmallbasic.singlestrike",
|
||||
secondary: "common.abilities.unique.quadsmallbasic.singlestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(TheropodBasic): (
|
||||
Tool(Unique(TheropodBasic)): (
|
||||
primary: "common.abilities.unique.theropodbasic.triplestrike",
|
||||
secondary: "common.abilities.unique.theropodbasic.triplestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(TheropodBird): (
|
||||
Tool(Unique(TheropodBird)): (
|
||||
primary: "common.abilities.unique.theropodbird.triplestrike",
|
||||
secondary: "common.abilities.unique.theropodbird.triplestrike",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(TheropodCharge): (
|
||||
Tool(Unique(TheropodCharge)): (
|
||||
primary: "common.abilities.unique.theropodbird.triplestrike",
|
||||
secondary: "common.abilities.unique.theropodbasic.dash",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(ObjectTurret): (
|
||||
Tool(Unique(ObjectTurret)): (
|
||||
primary: "common.abilities.unique.turret.arrows",
|
||||
secondary: "common.abilities.unique.turret.arrows",
|
||||
abilities: [],
|
||||
),
|
||||
Unique(MindflayerStaff): (
|
||||
primary: "common.abilities.unique.mindflayer.cursedflames",
|
||||
secondary: "common.abilities.unique.mindflayer.necroticvortex",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.mindflayer.dimensionaldoor"),
|
||||
(None, "common.abilities.unique.mindflayer.summonminions"),
|
||||
],
|
||||
),
|
||||
Unique(BirdLargeBreathe): (
|
||||
// Tool(Unique(MindflayerStaff)): (
|
||||
// primary: "common.abilities.unique.mindflayer.cursedflames",
|
||||
// secondary: "common.abilities.unique.mindflayer.necroticvortex",
|
||||
// abilities: [
|
||||
// (None, "common.abilities.unique.mindflayer.dimensionaldoor"),
|
||||
// (None, "common.abilities.unique.mindflayer.summonminions"),
|
||||
// ],
|
||||
// ),
|
||||
Tool(Unique(BirdLargeBreathe)): (
|
||||
primary: "common.abilities.unique.birdlargebreathe.firebomb",
|
||||
secondary: "common.abilities.unique.birdlargebreathe.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.birdlargebreathe.flamethrower"),
|
||||
],
|
||||
),
|
||||
Unique(BirdLargeFire): (
|
||||
Tool(Unique(BirdLargeFire)): (
|
||||
primary: "common.abilities.unique.birdlargefire.firebomb",
|
||||
secondary: "common.abilities.unique.birdlargefire.triplestrike",
|
||||
abilities: [
|
||||
(None, "common.abilities.unique.birdlargefire.fireshockwave"),
|
||||
],
|
||||
),
|
||||
Debug: (
|
||||
Tool(Debug): (
|
||||
primary: "common.abilities.debug.forwardboost",
|
||||
secondary: "common.abilities.debug.upboost",
|
||||
abilities: [
|
||||
(None, "common.abilities.debug.possess"),
|
||||
],
|
||||
),
|
||||
Farming: (
|
||||
Tool(Farming): (
|
||||
primary: "common.abilities.farming.basic",
|
||||
secondary: "common.abilities.farming.basic",
|
||||
abilities: [],
|
||||
),
|
||||
Pick: (
|
||||
Tool(Pick): (
|
||||
primary: "common.abilities.pick.swing",
|
||||
secondary: "common.abilities.pick.swing",
|
||||
abilities: [],
|
||||
),
|
||||
Empty: (
|
||||
Tool(Empty): (
|
||||
primary: "common.abilities.empty.basic",
|
||||
secondary: "common.abilities.empty.basic",
|
||||
abilities: [],
|
@ -2,7 +2,7 @@ ItemDef(
|
||||
name: "Mindflayer Staff",
|
||||
description: "Placeholder",
|
||||
kind: Tool((
|
||||
kind: Unique(MindflayerStaff),
|
||||
kind: Staff,
|
||||
hands: Two,
|
||||
stats: Direct((
|
||||
equip_time_secs: 0.01,
|
||||
|
@ -4,7 +4,7 @@ pub mod tool;
|
||||
|
||||
// Reexports
|
||||
pub use modular::{ModularComponent, ModularComponentKind, ModularComponentTag};
|
||||
pub use tool::{AbilitySet, Hands, MaterialStatManifest, Tool, ToolKind, UniqueKind};
|
||||
pub use tool::{AbilitySet, AbilitySpec, Hands, MaterialStatManifest, Tool, ToolKind, UniqueKind};
|
||||
|
||||
use crate::{
|
||||
assets::{self, AssetExt, Error},
|
||||
@ -28,6 +28,7 @@ use serde::{de, Deserialize, Serialize, Serializer};
|
||||
use specs::{Component, DerefFlaggedStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::{fmt, sync::Arc};
|
||||
use tracing::error;
|
||||
use vek::Rgb;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
@ -275,17 +276,19 @@ pub struct ItemDef {
|
||||
pub tags: Vec<ItemTag>,
|
||||
#[serde(default)]
|
||||
pub slots: u16,
|
||||
ability_map: AbilityMap,
|
||||
/// Used to specify a custom ability set for a weapon. Leave None (or don't
|
||||
/// include field in ItemDef) to use default ability set for weapon kind.
|
||||
pub ability_set: Option<String>,
|
||||
}
|
||||
|
||||
impl PartialEq for ItemDef {
|
||||
fn eq(&self, other: &Self) -> bool { self.item_definition_id == other.item_definition_id }
|
||||
}
|
||||
|
||||
// TODO: Look into removing ItemConfig and just using AbilitySet
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct ItemConfig {
|
||||
pub abilities: AbilitySet<CharacterAbility>,
|
||||
pub block_ability: Option<CharacterAbility>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -293,19 +296,34 @@ pub enum ItemConfigError {
|
||||
BadItemKind,
|
||||
}
|
||||
|
||||
impl TryFrom<(&ItemKind, &[Item], &AbilityMap, &MaterialStatManifest)> for ItemConfig {
|
||||
impl TryFrom<(&Item, &AbilityMap, &MaterialStatManifest)> for ItemConfig {
|
||||
type Error = ItemConfigError;
|
||||
|
||||
fn try_from(
|
||||
(item_kind, components, map, msm): (&ItemKind, &[Item], &AbilityMap, &MaterialStatManifest),
|
||||
(item, ability_map, msm): (&Item, &AbilityMap, &MaterialStatManifest),
|
||||
) -> Result<Self, Self::Error> {
|
||||
if let ItemKind::Tool(tool) = item_kind {
|
||||
let abilities = tool.get_abilities(msm, components, map);
|
||||
if let ItemKind::Tool(tool) = &item.kind {
|
||||
// If no custom ability set is specified, fall back to abilityset of tool kind.
|
||||
let ability_set_key = item
|
||||
.item_def
|
||||
.ability_set
|
||||
.as_ref()
|
||||
.map_or(AbilitySpec::Tool(tool.kind), |set| {
|
||||
AbilitySpec::Custom(set.to_string())
|
||||
});
|
||||
|
||||
Ok(ItemConfig {
|
||||
abilities,
|
||||
block_ability: None,
|
||||
})
|
||||
let abilities = if let Some(set) = ability_map.get_ability_set(&ability_set_key) {
|
||||
set.clone().modified_by_tool(&tool, msm, &item.components)
|
||||
} else {
|
||||
error!(
|
||||
"No AbilitySet in the ability map for specification: {:?} falling back to \
|
||||
default",
|
||||
ability_set_key
|
||||
);
|
||||
Default::default()
|
||||
};
|
||||
|
||||
Ok(ItemConfig { abilities })
|
||||
} else {
|
||||
Err(ItemConfigError::BadItemKind)
|
||||
}
|
||||
@ -395,10 +413,6 @@ impl assets::Compound for ItemDef {
|
||||
.load_owned::<RawItemDef>(specifier)
|
||||
.or_else(|e| modular::synthesize_modular_asset(specifier).ok_or(e))?;
|
||||
|
||||
let ability_map_handle =
|
||||
cache.load::<AbilityMap>("common.abilities.weapon_ability_manifest")?;
|
||||
let ability_map = ability_map_handle.read().clone();
|
||||
|
||||
let RawItemDef {
|
||||
name,
|
||||
description,
|
||||
@ -406,6 +420,7 @@ impl assets::Compound for ItemDef {
|
||||
quality,
|
||||
tags,
|
||||
slots,
|
||||
ability_set,
|
||||
} = raw;
|
||||
|
||||
// Some commands like /give_item provide the asset specifier separated with \
|
||||
@ -422,7 +437,7 @@ impl assets::Compound for ItemDef {
|
||||
quality,
|
||||
tags,
|
||||
slots,
|
||||
ability_map,
|
||||
ability_set,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -437,6 +452,7 @@ struct RawItemDef {
|
||||
tags: Vec<ItemTag>,
|
||||
#[serde(default)]
|
||||
slots: u16,
|
||||
ability_set: Option<String>,
|
||||
}
|
||||
|
||||
impl assets::Asset for RawItemDef {
|
||||
@ -474,13 +490,18 @@ impl Item {
|
||||
pub fn new_from_item_def(
|
||||
inner_item: Arc<ItemDef>,
|
||||
input_components: &[Item],
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> Self {
|
||||
let mut components = Vec::new();
|
||||
if inner_item.is_modular() {
|
||||
// recipe ensures that types match (i.e. no axe heads on a sword hilt, or double
|
||||
// sword blades)
|
||||
components.extend(input_components.iter().map(|comp| comp.duplicate(msm)));
|
||||
components.extend(
|
||||
input_components
|
||||
.iter()
|
||||
.map(|comp| comp.duplicate(ability_map, msm)),
|
||||
);
|
||||
}
|
||||
|
||||
let mut item = Item {
|
||||
@ -491,7 +512,7 @@ impl Item {
|
||||
item_def: inner_item,
|
||||
item_config: None,
|
||||
};
|
||||
item.update_item_config(msm);
|
||||
item.update_item_config(ability_map, msm);
|
||||
item
|
||||
}
|
||||
|
||||
@ -499,8 +520,10 @@ impl Item {
|
||||
/// Panics if the asset does not exist.
|
||||
pub fn new_from_asset_expect(asset_specifier: &str) -> Self {
|
||||
let inner_item = Arc::<ItemDef>::load_expect_cloned(asset_specifier);
|
||||
// TODO: Figure out better way to get msm and ability_map
|
||||
let msm = MaterialStatManifest::default();
|
||||
Item::new_from_item_def(inner_item, &[], &msm)
|
||||
let ability_map = AbilityMap::default();
|
||||
Item::new_from_item_def(inner_item, &[], &ability_map, &msm)
|
||||
}
|
||||
|
||||
/// Creates a Vec containing one of each item that matches the provided
|
||||
@ -513,14 +536,20 @@ impl Item {
|
||||
/// it exists
|
||||
pub fn new_from_asset(asset: &str) -> Result<Self, Error> {
|
||||
let inner_item = Arc::<ItemDef>::load_cloned(asset)?;
|
||||
// TODO: Get msm and ability_map less hackily
|
||||
let msm = MaterialStatManifest::default();
|
||||
Ok(Item::new_from_item_def(inner_item, &[], &msm))
|
||||
let ability_map = AbilityMap::default();
|
||||
Ok(Item::new_from_item_def(inner_item, &[], &ability_map, &msm))
|
||||
}
|
||||
|
||||
/// Duplicates an item, creating an exact copy but with a new item ID
|
||||
pub fn duplicate(&self, msm: &MaterialStatManifest) -> Self {
|
||||
let mut new_item =
|
||||
Item::new_from_item_def(Arc::clone(&self.item_def), &self.components, msm);
|
||||
pub fn duplicate(&self, ability_map: &AbilityMap, msm: &MaterialStatManifest) -> Self {
|
||||
let mut new_item = Item::new_from_item_def(
|
||||
Arc::clone(&self.item_def),
|
||||
&self.components,
|
||||
ability_map,
|
||||
msm,
|
||||
);
|
||||
new_item.set_amount(self.amount()).expect(
|
||||
"`new_item` has the same `item_def` and as an invariant, \
|
||||
self.set_amount(self.amount()) should always succeed.",
|
||||
@ -529,7 +558,7 @@ impl Item {
|
||||
|(new_item_slot, old_item_slot)| {
|
||||
*new_item_slot = old_item_slot
|
||||
.as_ref()
|
||||
.map(|old_item| old_item.duplicate(msm));
|
||||
.map(|old_item| old_item.duplicate(ability_map, msm));
|
||||
},
|
||||
);
|
||||
new_item
|
||||
@ -596,22 +625,22 @@ impl Item {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_component(&mut self, component: Item, msm: &MaterialStatManifest) {
|
||||
pub fn add_component(
|
||||
&mut self,
|
||||
component: Item,
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) {
|
||||
// TODO: hook for typechecking (not needed atm if this is only used by DB
|
||||
// persistence, but will definitely be needed once enhancement slots are
|
||||
// added to prevent putting a sword into another sword)
|
||||
self.components.push(component);
|
||||
// adding a component changes the stats, so recalculate the ItemConfig
|
||||
self.update_item_config(msm);
|
||||
self.update_item_config(ability_map, msm);
|
||||
}
|
||||
|
||||
fn update_item_config(&mut self, msm: &MaterialStatManifest) {
|
||||
if let Ok(item_config) = ItemConfig::try_from((
|
||||
self.kind(),
|
||||
self.components(),
|
||||
&self.item_def.ability_map,
|
||||
msm,
|
||||
)) {
|
||||
fn update_item_config(&mut self, ability_map: &AbilityMap, msm: &MaterialStatManifest) {
|
||||
if let Ok(item_config) = ItemConfig::try_from((&*self, ability_map, msm)) {
|
||||
self.item_config = Some(Box::new(item_config));
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ fn make_component_def(
|
||||
quality,
|
||||
tags: vec![ItemTag::ModularComponent(tag)],
|
||||
slots: 0,
|
||||
ability_set: None,
|
||||
};
|
||||
(identifier, item)
|
||||
}
|
||||
@ -230,6 +231,7 @@ fn make_weapon_def(toolkind: ToolKind) -> (String, RawItemDef) {
|
||||
quality,
|
||||
tags: Vec::new(),
|
||||
slots: 0,
|
||||
ability_set: None,
|
||||
};
|
||||
(identifier, item)
|
||||
}
|
||||
@ -282,6 +284,7 @@ fn make_tagexample_def(
|
||||
quality,
|
||||
tags: vec![ItemTag::ModularComponent(tag)],
|
||||
slots: 0,
|
||||
ability_set: None,
|
||||
};
|
||||
(identifier, item)
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ use std::{
|
||||
ops::{AddAssign, DivAssign, MulAssign, Sub},
|
||||
time::Duration,
|
||||
};
|
||||
use tracing::error;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum ToolKind {
|
||||
@ -167,6 +166,7 @@ impl Asset for MaterialStatManifest {
|
||||
|
||||
impl Default for MaterialStatManifest {
|
||||
fn default() -> MaterialStatManifest {
|
||||
// TODO: Don't do this, loading a default should have no ability to panic
|
||||
MaterialStatManifest::load_expect_cloned("common.material_stats_manifest")
|
||||
}
|
||||
}
|
||||
@ -310,23 +310,6 @@ impl Tool {
|
||||
Duration::from_secs_f32(self.stats.resolve_stats(msm, components).equip_time_secs)
|
||||
}
|
||||
|
||||
pub fn get_abilities(
|
||||
&self,
|
||||
msm: &MaterialStatManifest,
|
||||
components: &[Item],
|
||||
map: &AbilityMap,
|
||||
) -> AbilitySet<CharacterAbility> {
|
||||
if let Some(set) = map.0.get(&self.kind).cloned() {
|
||||
set.modified_by_tool(&self, msm, components)
|
||||
} else {
|
||||
error!(
|
||||
"ToolKind: {:?} has no AbilitySet in the ability map falling back to default",
|
||||
&self.kind
|
||||
);
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_block(&self) -> bool {
|
||||
matches!(
|
||||
self.kind,
|
||||
@ -386,17 +369,32 @@ impl Default for AbilitySet<CharacterAbility> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
pub enum AbilitySpec {
|
||||
Tool(ToolKind),
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AbilityMap<T = CharacterAbility>(HashMap<ToolKind, AbilitySet<T>>);
|
||||
pub struct AbilityMap<T = CharacterAbility>(HashMap<AbilitySpec, AbilitySet<T>>);
|
||||
|
||||
impl Default for AbilityMap {
|
||||
fn default() -> Self {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(ToolKind::Empty, AbilitySet::default());
|
||||
AbilityMap(map)
|
||||
// TODO: Revert to old default
|
||||
if let Ok(map) = Self::load_cloned("common.abilities.ability_set_manifest") {
|
||||
map
|
||||
} else {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(AbilitySpec::Tool(ToolKind::Empty), AbilitySet::default());
|
||||
AbilityMap(map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> AbilityMap<T> {
|
||||
pub fn get_ability_set(&self, key: &AbilitySpec) -> Option<&AbilitySet<T>> { self.0.get(key) }
|
||||
}
|
||||
|
||||
impl Asset for AbilityMap<String> {
|
||||
type Loader = assets::RonLoader;
|
||||
|
||||
@ -416,7 +414,7 @@ impl assets::Compound for AbilityMap {
|
||||
.iter()
|
||||
.map(|(kind, set)| {
|
||||
(
|
||||
*kind,
|
||||
kind.clone(),
|
||||
// expect cannot fail because CharacterAbility always
|
||||
// provides a default value in case of failure
|
||||
set.map_ref(|s| cache.load_expect(&s).cloned()),
|
||||
@ -451,7 +449,6 @@ pub enum UniqueKind {
|
||||
TheropodCharge,
|
||||
ObjectTurret,
|
||||
WoodenSpear,
|
||||
MindflayerStaff,
|
||||
BirdLargeBreathe,
|
||||
BirdLargeFire,
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use tracing::{debug, trace, warn};
|
||||
use crate::{
|
||||
comp::{
|
||||
inventory::{
|
||||
item::{ItemDef, ItemKind, MaterialStatManifest, TagExampleInfo},
|
||||
item::{tool::AbilityMap, ItemDef, ItemKind, MaterialStatManifest, TagExampleInfo},
|
||||
loadout::Loadout,
|
||||
slot::{EquipSlot, Slot, SlotError},
|
||||
},
|
||||
@ -377,9 +377,14 @@ impl Inventory {
|
||||
}
|
||||
|
||||
/// Remove just one item from the slot
|
||||
pub fn take(&mut self, inv_slot_id: InvSlotId, msm: &MaterialStatManifest) -> Option<Item> {
|
||||
pub fn take(
|
||||
&mut self,
|
||||
inv_slot_id: InvSlotId,
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> Option<Item> {
|
||||
if let Some(Some(item)) = self.slot_mut(inv_slot_id) {
|
||||
let mut return_item = item.duplicate(msm);
|
||||
let mut return_item = item.duplicate(ability_map, msm);
|
||||
|
||||
if item.is_stackable() && item.amount() > 1 {
|
||||
item.decrease_amount(1).ok()?;
|
||||
@ -399,11 +404,12 @@ impl Inventory {
|
||||
pub fn take_half(
|
||||
&mut self,
|
||||
inv_slot_id: InvSlotId,
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> Option<Item> {
|
||||
if let Some(Some(item)) = self.slot_mut(inv_slot_id) {
|
||||
if item.is_stackable() && item.amount() > 1 {
|
||||
let mut return_item = item.duplicate(msm);
|
||||
let mut return_item = item.duplicate(ability_map, msm);
|
||||
let returning_amount = item.amount() / 2;
|
||||
item.decrease_amount(returning_amount).ok()?;
|
||||
return_item.set_amount(returning_amount).expect(
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
assets::{self, AssetExt, AssetHandle},
|
||||
comp::{
|
||||
item::{modular, ItemDef, ItemTag, MaterialStatManifest},
|
||||
item::{modular, tool::AbilityMap, ItemDef, ItemTag, MaterialStatManifest},
|
||||
Inventory, Item,
|
||||
},
|
||||
terrain::SpriteKind,
|
||||
@ -29,6 +29,7 @@ impl Recipe {
|
||||
pub fn perform(
|
||||
&self,
|
||||
inv: &mut Inventory,
|
||||
ability_map: &AbilityMap,
|
||||
msm: &MaterialStatManifest,
|
||||
) -> Result<Option<(Item, u32)>, Vec<(&RecipeInput, u32)>> {
|
||||
// Get ingredient cells from inventory,
|
||||
@ -39,7 +40,7 @@ impl Recipe {
|
||||
.for_each(|(pos, n)| {
|
||||
(0..n).for_each(|_| {
|
||||
let component = inv
|
||||
.take(pos, msm)
|
||||
.take(pos, ability_map, msm)
|
||||
.expect("Expected item to exist in inventory");
|
||||
components.push(component);
|
||||
})
|
||||
@ -47,7 +48,7 @@ impl Recipe {
|
||||
|
||||
for i in 0..self.output.1 {
|
||||
let crafted_item =
|
||||
Item::new_from_item_def(Arc::clone(&self.output.0), &components, msm);
|
||||
Item::new_from_item_def(Arc::clone(&self.output.0), &components, ability_map, msm);
|
||||
if let Err(item) = inv.push(crafted_item) {
|
||||
return Ok(Some((item, self.output.1 - i)));
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use common::{
|
||||
self,
|
||||
aura::{Aura, AuraKind, AuraTarget},
|
||||
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
||||
inventory::item::MaterialStatManifest,
|
||||
inventory::item::{tool::AbilityMap, MaterialStatManifest},
|
||||
invite::InviteKind,
|
||||
ChatType, Inventory, Item, LightEmitter, WaypointArea,
|
||||
},
|
||||
@ -332,6 +332,7 @@ fn handle_give_item(
|
||||
}
|
||||
});
|
||||
} else {
|
||||
let ability_map = server.state.ecs().read_resource::<AbilityMap>();
|
||||
let msm = server.state.ecs().read_resource::<MaterialStatManifest>();
|
||||
// This item can't stack. Give each item in a loop.
|
||||
server
|
||||
@ -342,7 +343,7 @@ fn handle_give_item(
|
||||
.map(|mut inv| {
|
||||
for i in 0..give_amount {
|
||||
// NOTE: Deliberately ignores items that couldn't be pushed.
|
||||
if inv.push(item.duplicate(&msm)).is_err() {
|
||||
if inv.push(item.duplicate(&ability_map, &msm)).is_err() {
|
||||
res = Err(format!(
|
||||
"Player inventory full. Gave {} of {} items.",
|
||||
i, give_amount
|
||||
|
@ -6,7 +6,7 @@ use vek::{Rgb, Vec3};
|
||||
use common::{
|
||||
comp::{
|
||||
self,
|
||||
item::{self, MaterialStatManifest},
|
||||
item::{self, tool::AbilityMap, MaterialStatManifest},
|
||||
slot::{self, Slot},
|
||||
},
|
||||
consts::MAX_PICKUP_RANGE,
|
||||
@ -138,7 +138,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
};
|
||||
|
||||
// NOTE: We dup the item for message purposes.
|
||||
let item_msg = item.duplicate(&state.ecs().read_resource::<MaterialStatManifest>());
|
||||
let item_msg = item.duplicate(
|
||||
&state.ecs().read_resource::<AbilityMap>(),
|
||||
&state.ecs().read_resource::<MaterialStatManifest>(),
|
||||
);
|
||||
|
||||
// Next, we try to equip the picked up item
|
||||
let event = match inventory.try_equip(item).or_else(|returned_item| {
|
||||
@ -198,8 +201,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
|
||||
if let Some(item) = comp::Item::try_reclaim_from_block(block) {
|
||||
// NOTE: We dup the item for message purposes.
|
||||
let item_msg =
|
||||
item.duplicate(&state.ecs().read_resource::<MaterialStatManifest>());
|
||||
let item_msg = item.duplicate(
|
||||
&state.ecs().read_resource::<AbilityMap>(),
|
||||
&state.ecs().read_resource::<MaterialStatManifest>(),
|
||||
);
|
||||
let (event, item_was_added) = match inventory.push(item) {
|
||||
Ok(_) => (
|
||||
Some(comp::InventoryUpdate::new(
|
||||
@ -276,6 +281,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
Some(comp::InventoryUpdateEvent::Used)
|
||||
} else if let Some(item) = inventory.take(
|
||||
slot,
|
||||
&state.ecs().read_resource::<AbilityMap>(),
|
||||
&state.ecs().read_resource::<item::MaterialStatManifest>(),
|
||||
) {
|
||||
match item.kind() {
|
||||
@ -476,6 +482,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
.expect("We know entity exists since we got its inventory.");
|
||||
},
|
||||
comp::InventoryManip::SplitSwap(slot, target) => {
|
||||
let ability_map = state.ecs().read_resource::<AbilityMap>();
|
||||
let msm = state.ecs().read_resource::<MaterialStatManifest>();
|
||||
|
||||
// If both slots have items and we're attemping to split from one stack
|
||||
@ -495,7 +502,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
}
|
||||
|
||||
let item = match slot {
|
||||
Slot::Inventory(slot) => inventory.take_half(slot, &msm),
|
||||
Slot::Inventory(slot) => inventory.take_half(slot, &ability_map, &msm),
|
||||
Slot::Equip(_) => None,
|
||||
};
|
||||
|
||||
@ -546,9 +553,10 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
drop(inventories);
|
||||
},
|
||||
comp::InventoryManip::SplitDrop(slot) => {
|
||||
let ability_map = &state.ecs().read_resource::<AbilityMap>();
|
||||
let msm = state.ecs().read_resource::<MaterialStatManifest>();
|
||||
let item = match slot {
|
||||
Slot::Inventory(slot) => inventory.take_half(slot, &msm),
|
||||
Slot::Inventory(slot) => inventory.take_half(slot, &ability_map, &msm),
|
||||
Slot::Equip(_) => None,
|
||||
};
|
||||
|
||||
@ -615,6 +623,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
.and_then(|r| {
|
||||
r.perform(
|
||||
&mut inventory,
|
||||
&state.ecs().read_resource::<AbilityMap>(),
|
||||
&state.ecs().read_resource::<item::MaterialStatManifest>(),
|
||||
)
|
||||
.ok()
|
||||
@ -631,6 +640,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
|
||||
// Drop the item if there wasn't enough space
|
||||
if let Some(Some((item, amount))) = craft_result {
|
||||
let ability_map = &state.ecs().read_resource::<AbilityMap>();
|
||||
let msm = state.ecs().read_resource::<MaterialStatManifest>();
|
||||
for _ in 0..amount {
|
||||
dropped_items.push((
|
||||
@ -640,7 +650,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
||||
state
|
||||
.read_component_copied::<comp::Ori>(entity)
|
||||
.unwrap_or_default(),
|
||||
item.duplicate(&msm),
|
||||
item.duplicate(ability_map, &msm),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,10 @@ use crate::Server;
|
||||
use common::{
|
||||
comp::{
|
||||
agent::{Agent, AgentEvent},
|
||||
inventory::{item::MaterialStatManifest, Inventory},
|
||||
inventory::{
|
||||
item::{tool::AbilityMap, MaterialStatManifest},
|
||||
Inventory,
|
||||
},
|
||||
},
|
||||
trade::{PendingTrade, ReducedInventory, TradeAction, TradeId, TradeResult, Trades},
|
||||
};
|
||||
@ -251,6 +254,7 @@ fn commit_trade(ecs: &specs::World, trade: &PendingTrade) -> TradeResult {
|
||||
}
|
||||
}
|
||||
let mut items = [Vec::new(), Vec::new()];
|
||||
let ability_map = ecs.read_resource::<AbilityMap>();
|
||||
let msm = ecs.read_resource::<MaterialStatManifest>();
|
||||
for who in [0, 1].iter().cloned() {
|
||||
for (slot, quantity) in trade.offers[who].iter() {
|
||||
@ -259,7 +263,7 @@ fn commit_trade(ecs: &specs::World, trade: &PendingTrade) -> TradeResult {
|
||||
inventories
|
||||
.get_mut(entities[who])
|
||||
.expect(invmsg)
|
||||
.take(*slot, &msm)
|
||||
.take(*slot, &ability_map, &msm)
|
||||
.map(|item| items[who].push(item));
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ impl Server {
|
||||
)?);
|
||||
|
||||
let ability_map = comp::item::tool::AbilityMap::<CharacterAbility>::load_expect_cloned(
|
||||
"common.abilities.weapon_ability_manifest",
|
||||
"common.abilities.ability_set_manifest",
|
||||
);
|
||||
state.ecs_mut().insert(ability_map);
|
||||
|
||||
|
@ -11,7 +11,7 @@ use common::{
|
||||
character::CharacterId,
|
||||
comp::{
|
||||
inventory::{
|
||||
item::MaterialStatManifest,
|
||||
item::{tool::AbilityMap, MaterialStatManifest},
|
||||
loadout::{Loadout, LoadoutError},
|
||||
loadout_builder::LoadoutBuilder,
|
||||
slot::InvSlotId,
|
||||
@ -37,6 +37,7 @@ pub struct ItemModelPair {
|
||||
// server
|
||||
lazy_static! {
|
||||
pub static ref MATERIAL_STATS_MANIFEST: MaterialStatManifest = MaterialStatManifest::default();
|
||||
pub static ref ABILITY_MAP: AbilityMap = AbilityMap::default();
|
||||
}
|
||||
|
||||
/// Returns a vector that contains all item rows to upsert; parent is
|
||||
@ -317,7 +318,7 @@ pub fn convert_inventory_from_database_items(
|
||||
}
|
||||
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
||||
if let Some(Some(parent)) = inventory.slot_mut(slot(&inventory_items[j].position)?) {
|
||||
parent.add_component(item, &MATERIAL_STATS_MANIFEST);
|
||||
parent.add_component(item, &ABILITY_MAP, &MATERIAL_STATS_MANIFEST);
|
||||
} else {
|
||||
return Err(PersistenceError::ConversionError(format!(
|
||||
"Parent slot {} for component {} was empty even though it occurred earlier in \
|
||||
@ -373,7 +374,7 @@ pub fn convert_loadout_from_database_items(
|
||||
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
||||
loadout
|
||||
.update_item_at_slot_using_persistence_key(&database_items[j].position, |parent| {
|
||||
parent.add_component(item, &MATERIAL_STATS_MANIFEST);
|
||||
parent.add_component(item, &ABILITY_MAP, &MATERIAL_STATS_MANIFEST);
|
||||
})
|
||||
.map_err(convert_error)?;
|
||||
} else {
|
||||
|
@ -1536,7 +1536,8 @@ impl<'a> AgentData<'a> {
|
||||
Some(ToolKind::Unique(UniqueKind::TheropodBasic)) => Tactic::Theropod,
|
||||
Some(ToolKind::Unique(UniqueKind::TheropodBird)) => Tactic::Theropod,
|
||||
Some(ToolKind::Unique(UniqueKind::ObjectTurret)) => Tactic::Turret,
|
||||
Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => Tactic::Mindflayer,
|
||||
// TODO: Figure this out
|
||||
// Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => Tactic::Mindflayer,
|
||||
Some(ToolKind::Unique(UniqueKind::BirdLargeBreathe)) => Tactic::BirdLargeBreathe,
|
||||
Some(ToolKind::Unique(UniqueKind::BirdLargeFire)) => Tactic::BirdLargeFire,
|
||||
_ => Tactic::Melee,
|
||||
|
@ -1,9 +1,9 @@
|
||||
use common::{
|
||||
comp::{
|
||||
item::MaterialStatManifest, Auras, BeamSegment, Body, Buffs, CanBuild, CharacterState,
|
||||
Collider, Combo, Density, Energy, Group, Health, Inventory, Item, LightEmitter, Mass,
|
||||
MountState, Mounting, Ori, Player, Poise, Pos, Scale, Shockwave, SkillSet, Stats, Sticky,
|
||||
Vel,
|
||||
item::{tool::AbilityMap, MaterialStatManifest},
|
||||
Auras, BeamSegment, Body, Buffs, CanBuild, CharacterState, Collider, Combo, Density,
|
||||
Energy, Group, Health, Inventory, Item, LightEmitter, Mass, MountState, Mounting, Ori,
|
||||
Player, Poise, Pos, Scale, Shockwave, SkillSet, Stats, Sticky, Vel,
|
||||
},
|
||||
uid::Uid,
|
||||
};
|
||||
@ -65,6 +65,7 @@ pub struct TrackedComps<'a> {
|
||||
pub character_state: ReadStorage<'a, CharacterState>,
|
||||
pub shockwave: ReadStorage<'a, Shockwave>,
|
||||
pub beam_segment: ReadStorage<'a, BeamSegment>,
|
||||
pub ability_map: ReadExpect<'a, AbilityMap>,
|
||||
pub msm: ReadExpect<'a, MaterialStatManifest>,
|
||||
}
|
||||
impl<'a> TrackedComps<'a> {
|
||||
@ -124,7 +125,7 @@ impl<'a> TrackedComps<'a> {
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.item
|
||||
.get(entity)
|
||||
.map(|item| item.duplicate(&self.msm))
|
||||
.map(|item| item.duplicate(&self.ability_map, &self.msm))
|
||||
.map(|c| comps.push(c.into()));
|
||||
self.scale
|
||||
.get(entity)
|
||||
|
@ -2,10 +2,7 @@ use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{ToolKind, UniqueKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use common::{comp::item::ToolKind, states::utils::StageSection};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct BeamAnimation;
|
||||
@ -62,9 +59,7 @@ impl Animation for BeamAnimation {
|
||||
next.hand_l.orientation = Quaternion::rotation_x(0.0);
|
||||
next.hand_r.orientation = Quaternion::rotation_x(0.0);
|
||||
match active_tool_kind {
|
||||
Some(ToolKind::StaffSimple)
|
||||
| Some(ToolKind::Sceptre)
|
||||
| Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Sceptre) | Some(ToolKind::Staff) => {
|
||||
let (move1base, move2shake, _move2base, move3) = match stage_section {
|
||||
Some(StageSection::Buildup) => (
|
||||
(anim_time.powf(0.25)).min(1.0),
|
||||
|
@ -2,10 +2,7 @@ use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{ToolKind, UniqueKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use common::{comp::item::ToolKind, states::utils::StageSection};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct BlinkAnimation;
|
||||
@ -81,7 +78,7 @@ impl Animation for BlinkAnimation {
|
||||
next.hand_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
match active_tool_kind {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Staff) => {
|
||||
next.head.orientation =
|
||||
Quaternion::rotation_x(move1 * -0.3) * Quaternion::rotation_y(move1 * -0.1);
|
||||
next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
|
||||
|
@ -2,10 +2,7 @@ use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{ToolKind, UniqueKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use common::{comp::item::ToolKind, states::utils::StageSection};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct SpinMeleeAnimation;
|
||||
@ -84,7 +81,7 @@ impl Animation for SpinMeleeAnimation {
|
||||
next.hand_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
match active_tool_kind {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Staff) => {
|
||||
next.head.orientation = Quaternion::rotation_x(move1 * -0.3 + move2 * 0.5);
|
||||
next.control_l.position = Vec3::new(
|
||||
-1.0 + move1 * -10.0 + move2 * -10.0,
|
||||
|
@ -171,8 +171,7 @@ impl Animation for StunnedAnimation {
|
||||
next.control.orientation =
|
||||
Quaternion::rotation_x(-1.0 + short * 0.2) * Quaternion::rotation_y(-1.8);
|
||||
},
|
||||
Some(ToolKind::StaffSimple)
|
||||
| Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Staff) => {
|
||||
next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
|
||||
next.control_r.position = Vec3::new(1.0, 2.0, 2.0);
|
||||
|
||||
|
@ -2,10 +2,7 @@ use super::{
|
||||
super::{vek::*, Animation},
|
||||
BipedLargeSkeleton, SkeletonAttr,
|
||||
};
|
||||
use common::{
|
||||
comp::item::{ToolKind, UniqueKind},
|
||||
states::utils::StageSection,
|
||||
};
|
||||
use common::{comp::item::ToolKind, states::utils::StageSection};
|
||||
use std::f32::consts::PI;
|
||||
|
||||
pub struct SummonAnimation;
|
||||
@ -85,7 +82,7 @@ impl Animation for SummonAnimation {
|
||||
next.hand_r.orientation = Quaternion::rotation_x(0.0);
|
||||
|
||||
match active_tool_kind {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Staff) => {
|
||||
next.head.orientation = Quaternion::rotation_x(0.0);
|
||||
next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
|
||||
next.control_r.position = Vec3::new(
|
||||
|
@ -210,8 +210,7 @@ impl Animation for WieldAnimation {
|
||||
next.control.orientation =
|
||||
Quaternion::rotation_x(-1.0 + short * 0.2) * Quaternion::rotation_y(-1.8);
|
||||
},
|
||||
Some(ToolKind::StaffSimple)
|
||||
| Some(ToolKind::Unique(UniqueKind::MindflayerStaff)) => {
|
||||
Some(ToolKind::StaffSimple) | Some(ToolKind::Staff) => {
|
||||
next.control_l.position = Vec3::new(-1.0, 3.0, 12.0);
|
||||
next.control_r.position = Vec3::new(1.0, 2.0, 2.0);
|
||||
|
||||
|
@ -2345,7 +2345,6 @@ impl Hud {
|
||||
let skillsets = ecs.read_storage::<comp::SkillSet>();
|
||||
let character_states = ecs.read_storage::<comp::CharacterState>();
|
||||
let controllers = ecs.read_storage::<comp::Controller>();
|
||||
let ability_map = ecs.fetch::<comp::item::tool::AbilityMap>();
|
||||
let bodies = ecs.read_storage::<comp::Body>();
|
||||
// Combo floater stuffs
|
||||
self.floaters
|
||||
@ -2397,7 +2396,6 @@ impl Hud {
|
||||
item_tooltip_manager,
|
||||
&mut self.slot_manager,
|
||||
i18n,
|
||||
&ability_map,
|
||||
&msm,
|
||||
combo,
|
||||
)
|
||||
|
@ -23,7 +23,7 @@ use common::comp::{
|
||||
self,
|
||||
inventory::slot::EquipSlot,
|
||||
item::{
|
||||
tool::{AbilityMap, Tool, ToolKind},
|
||||
tool::{Tool, ToolKind},
|
||||
Hands, Item, ItemKind, MaterialStatManifest,
|
||||
},
|
||||
Energy, Health, Inventory, SkillSet,
|
||||
@ -153,7 +153,6 @@ pub struct Skillbar<'a> {
|
||||
pulse: f32,
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
ability_map: &'a AbilityMap,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo: Option<ComboFloater>,
|
||||
}
|
||||
@ -179,7 +178,6 @@ impl<'a> Skillbar<'a> {
|
||||
item_tooltip_manager: &'a mut ItemTooltipManager,
|
||||
slot_manager: &'a mut slots::SlotManager,
|
||||
localized_strings: &'a Localization,
|
||||
ability_map: &'a AbilityMap,
|
||||
msm: &'a MaterialStatManifest,
|
||||
combo: Option<ComboFloater>,
|
||||
) -> Self {
|
||||
@ -203,7 +201,6 @@ impl<'a> Skillbar<'a> {
|
||||
item_tooltip_manager,
|
||||
slot_manager,
|
||||
localized_strings,
|
||||
ability_map,
|
||||
msm,
|
||||
combo,
|
||||
}
|
||||
@ -448,14 +445,7 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.stamina_txt, ui);
|
||||
}
|
||||
// Slots
|
||||
let content_source = (
|
||||
self.hotbar,
|
||||
self.inventory,
|
||||
self.energy,
|
||||
self.skillset,
|
||||
self.ability_map,
|
||||
self.msm,
|
||||
); // TODO: avoid this
|
||||
let content_source = (self.hotbar, self.inventory, self.energy, self.skillset); // TODO: avoid this
|
||||
let image_source = (self.item_imgs, self.imgs);
|
||||
let mut slot_maker = SlotMaker {
|
||||
// TODO: is a separate image needed for the frame?
|
||||
@ -740,9 +730,11 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.middle_of(state.ids.m2_slot_bg)
|
||||
.image_color(if let Some((item, tool)) = tool {
|
||||
if self.energy.current()
|
||||
>= tool
|
||||
.get_abilities(&self.msm, item.components(), self.ability_map)
|
||||
>= item
|
||||
.item_config_expect()
|
||||
.abilities
|
||||
.secondary
|
||||
.clone()
|
||||
.adjusted_by_skills(self.skillset, Some(tool.kind))
|
||||
.get_energy_cost()
|
||||
{
|
||||
|
@ -6,8 +6,8 @@ use super::{
|
||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||
use common::comp::{
|
||||
item::{
|
||||
tool::{AbilityMap, Hands, ToolKind},
|
||||
ItemKind, MaterialStatManifest,
|
||||
tool::{Hands, ToolKind},
|
||||
ItemKind,
|
||||
},
|
||||
slot::InvSlotId,
|
||||
Energy, Inventory, SkillSet,
|
||||
@ -122,14 +122,7 @@ pub enum HotbarImage {
|
||||
SceptreAura,
|
||||
}
|
||||
|
||||
type HotbarSource<'a> = (
|
||||
&'a hotbar::State,
|
||||
&'a Inventory,
|
||||
&'a Energy,
|
||||
&'a SkillSet,
|
||||
&'a AbilityMap,
|
||||
&'a MaterialStatManifest,
|
||||
);
|
||||
type HotbarSource<'a> = (&'a hotbar::State, &'a Inventory, &'a Energy, &'a SkillSet);
|
||||
type HotbarImageSource<'a> = (&'a ItemImgs, &'a img_ids::Imgs);
|
||||
|
||||
impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
@ -137,7 +130,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
|
||||
fn image_key(
|
||||
&self,
|
||||
(hotbar, inventory, energy, skillset, ability_map, msm): &HotbarSource<'a>,
|
||||
(hotbar, inventory, energy, skillset): &HotbarSource<'a>,
|
||||
) -> Option<(Self::ImageKey, Option<Color>)> {
|
||||
hotbar.get(*self).and_then(|contents| match contents {
|
||||
hotbar::SlotContents::Inventory(idx) => inventory
|
||||
@ -169,10 +162,8 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
hotbar_image(tool.kind).map(|i| {
|
||||
(
|
||||
i,
|
||||
if let Some(skill) = tool
|
||||
.get_abilities(&msm, item.components(), ability_map)
|
||||
.abilities
|
||||
.get(0)
|
||||
if let Some(skill) =
|
||||
item.item_config_expect().abilities.abilities.get(0)
|
||||
{
|
||||
if energy.current()
|
||||
>= skill
|
||||
@ -219,8 +210,9 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
hotbar_image(tool.kind).map(|i| {
|
||||
(
|
||||
i,
|
||||
if let Some(skill) = tool
|
||||
.get_abilities(&msm, item.components(), ability_map)
|
||||
if let Some(skill) = item
|
||||
.item_config_expect()
|
||||
.abilities
|
||||
.abilities
|
||||
.get(skill_index)
|
||||
{
|
||||
@ -245,7 +237,7 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
})
|
||||
}
|
||||
|
||||
fn amount(&self, (hotbar, inventory, _, _, _, _): &HotbarSource<'a>) -> Option<u32> {
|
||||
fn amount(&self, (hotbar, inventory, _, _): &HotbarSource<'a>) -> Option<u32> {
|
||||
hotbar
|
||||
.get(*self)
|
||||
.and_then(|content| match content {
|
||||
|
Loading…
Reference in New Issue
Block a user