mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed review feedback.
This commit is contained in:
parent
b678f7f46e
commit
dfcb8c8519
@ -755,8 +755,7 @@ impl Client {
|
||||
| ClientGeneral::RequestSiteInfo(_)
|
||||
| ClientGeneral::UnlockSkillGroup(_)
|
||||
| ClientGeneral::RequestPlayerPhysics { .. }
|
||||
| ClientGeneral::RequestLossyTerrainCompression { .. }
|
||||
| ClientGeneral::ChangeAbility { .. } => {
|
||||
| ClientGeneral::RequestLossyTerrainCompression { .. } => {
|
||||
#[cfg(feature = "tracy")]
|
||||
{
|
||||
ingame = 1.0;
|
||||
@ -1397,8 +1396,11 @@ impl Client {
|
||||
)));
|
||||
}
|
||||
|
||||
pub fn change_ability(&mut self, slot: usize, new_ability: comp::Ability) {
|
||||
self.send_msg(ClientGeneral::ChangeAbility { slot, new_ability })
|
||||
pub fn change_ability(&mut self, slot: usize, new_ability: comp::ability::AuxiliaryAbility) {
|
||||
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::ChangeAbility {
|
||||
slot,
|
||||
new_ability,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Execute a single client tick, handle input and update the game state by
|
||||
|
@ -75,10 +75,6 @@ pub enum ClientGeneral {
|
||||
RefundSkill(Skill),
|
||||
UnlockSkillGroup(SkillGroupKind),
|
||||
RequestSiteInfo(SiteId),
|
||||
ChangeAbility {
|
||||
slot: usize,
|
||||
new_ability: comp::Ability,
|
||||
},
|
||||
//Only in Game, via terrain stream
|
||||
TerrainChunkRequest {
|
||||
key: Vec2<i32>,
|
||||
@ -131,8 +127,7 @@ impl ClientMsg {
|
||||
| ClientGeneral::RequestSiteInfo(_)
|
||||
| ClientGeneral::UnlockSkillGroup(_)
|
||||
| ClientGeneral::RequestPlayerPhysics { .. }
|
||||
| ClientGeneral::RequestLossyTerrainCompression { .. }
|
||||
| ClientGeneral::ChangeAbility { .. } => {
|
||||
| ClientGeneral::RequestLossyTerrainCompression { .. } => {
|
||||
c_type == ClientType::Game && presence.is_some()
|
||||
},
|
||||
//Always possible
|
||||
|
@ -3,7 +3,6 @@ use crate::{
|
||||
combat::{self, CombatEffect, DamageKind, Knockback},
|
||||
comp::{
|
||||
self, aura, beam, buff,
|
||||
controller::InputKind,
|
||||
inventory::{
|
||||
item::{
|
||||
tool::{Stats, ToolKind},
|
||||
@ -36,10 +35,10 @@ pub const MAX_ABILITIES: usize = 5;
|
||||
// considerations.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct AbilityPool {
|
||||
pub primary: Ability,
|
||||
pub secondary: Ability,
|
||||
pub movement: Ability,
|
||||
pub abilities: [Ability; MAX_ABILITIES],
|
||||
pub primary: PrimaryAbility,
|
||||
pub secondary: SecondaryAbility,
|
||||
pub movement: MovementAbility,
|
||||
pub abilities: [AuxiliaryAbility; MAX_ABILITIES],
|
||||
}
|
||||
|
||||
impl Component for AbilityPool {
|
||||
@ -49,10 +48,10 @@ impl Component for AbilityPool {
|
||||
impl Default for AbilityPool {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
primary: Ability::ToolPrimary,
|
||||
secondary: Ability::ToolSecondary,
|
||||
movement: Ability::SpeciesMovement,
|
||||
abilities: [Ability::Empty; MAX_ABILITIES],
|
||||
primary: PrimaryAbility::Tool,
|
||||
secondary: SecondaryAbility::Tool,
|
||||
movement: MovementAbility::Species,
|
||||
abilities: [AuxiliaryAbility::Empty; MAX_ABILITIES],
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -64,28 +63,31 @@ impl AbilityPool {
|
||||
pool
|
||||
}
|
||||
|
||||
pub fn change_ability(&mut self, slot: usize, new_ability: Ability) {
|
||||
if new_ability.is_valid_abilities_ability() {
|
||||
if let Some(ability) = self.abilities.get_mut(slot) {
|
||||
*ability = new_ability;
|
||||
}
|
||||
pub fn change_ability(&mut self, slot: usize, new_ability: AuxiliaryAbility) {
|
||||
if let Some(ability) = self.abilities.get_mut(slot) {
|
||||
*ability = new_ability;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ability(&self, input: InputKind) -> Ability {
|
||||
pub fn get_ability(&self, input: AbilityInput) -> Ability {
|
||||
match input {
|
||||
InputKind::Primary => Some(self.primary),
|
||||
InputKind::Secondary => Some(self.secondary),
|
||||
InputKind::Roll => Some(self.movement),
|
||||
InputKind::Ability(index) => self.abilities.get(index).copied(),
|
||||
_ => None,
|
||||
AbilityInput::Primary => self.primary.into(),
|
||||
AbilityInput::Secondary => self.secondary.into(),
|
||||
AbilityInput::Movement => self.movement.into(),
|
||||
AbilityInput::Auxiliary(index) => self
|
||||
.abilities
|
||||
.get(index)
|
||||
.copied()
|
||||
.map(|a| a.into())
|
||||
.unwrap_or(Ability::Empty),
|
||||
}
|
||||
.unwrap_or(Ability::Empty)
|
||||
}
|
||||
|
||||
/// Returns the CharacterAbility from an ability input, and also whether the
|
||||
/// ability was from a weapon wielded in the offhand
|
||||
pub fn activate_ability(
|
||||
&self,
|
||||
input: InputKind,
|
||||
input: AbilityInput,
|
||||
inv: Option<&Inventory>,
|
||||
skill_set: &SkillSet,
|
||||
body: &Body,
|
||||
@ -121,19 +123,19 @@ impl AbilityPool {
|
||||
Ability::ToolSecondary => ability_set(EquipSlot::ActiveOffhand)
|
||||
.map(|abilities| abilities.secondary.clone())
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), true))
|
||||
.or({
|
||||
.or_else(|| {
|
||||
ability_set(EquipSlot::ActiveMainhand)
|
||||
.map(|abilities| abilities.secondary.clone())
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false))
|
||||
}),
|
||||
Ability::SpeciesMovement => matches!(body, Body::Humanoid(_))
|
||||
.then_some(CharacterAbility::default_roll())
|
||||
.map(|ability| (ability.adjusted_by_skills(skill_set, None), false)),
|
||||
Ability::MainWeaponAbility(index) => ability_set(EquipSlot::ActiveMainhand)
|
||||
.then(|| CharacterAbility::default_roll)
|
||||
.map(|ability| (ability().adjusted_by_skills(skill_set, None), false)),
|
||||
Ability::MainWeaponAux(index) => ability_set(EquipSlot::ActiveMainhand)
|
||||
.and_then(|abilities| abilities.abilities.get(index).cloned())
|
||||
.and_then(unlocked)
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveMainhand), false)),
|
||||
Ability::OffWeaponAbility(index) => ability_set(EquipSlot::ActiveOffhand)
|
||||
Ability::OffWeaponAux(index) => ability_set(EquipSlot::ActiveOffhand)
|
||||
.and_then(|abilities| abilities.abilities.get(index).cloned())
|
||||
.and_then(unlocked)
|
||||
.map(|ability| (scale_ability(ability, EquipSlot::ActiveOffhand), true)),
|
||||
@ -147,11 +149,11 @@ impl AbilityPool {
|
||||
inv: Option<&Inventory>,
|
||||
skill_set: Option<&SkillSet>,
|
||||
equip_slot: EquipSlot,
|
||||
) -> Vec<Ability> {
|
||||
) -> Vec<AuxiliaryAbility> {
|
||||
let ability_from_slot = move |i| match equip_slot {
|
||||
EquipSlot::ActiveMainhand => Ability::MainWeaponAbility(i),
|
||||
EquipSlot::ActiveOffhand => Ability::OffWeaponAbility(i),
|
||||
_ => Ability::Empty,
|
||||
EquipSlot::ActiveMainhand => AuxiliaryAbility::MainWeapon(i),
|
||||
EquipSlot::ActiveOffhand => AuxiliaryAbility::OffWeapon(i),
|
||||
_ => AuxiliaryAbility::Empty,
|
||||
};
|
||||
|
||||
inv
|
||||
@ -166,28 +168,36 @@ impl AbilityPool {
|
||||
|
||||
let main_abilities = iter_unlocked_abilities(inv, skill_set, EquipSlot::ActiveMainhand);
|
||||
let off_abilities = iter_unlocked_abilities(inv, skill_set, EquipSlot::ActiveOffhand);
|
||||
for (i, ability) in
|
||||
(0..MAX_ABILITIES).zip(main_abilities.iter().chain(off_abilities.iter()))
|
||||
{
|
||||
self.change_ability(i, *ability);
|
||||
}
|
||||
|
||||
(0..MAX_ABILITIES)
|
||||
.zip(main_abilities.iter().chain(off_abilities.iter()))
|
||||
.for_each(|(i, ability)| {
|
||||
self.change_ability(i, *ability);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub enum AbilityInput {
|
||||
Primary,
|
||||
Secondary,
|
||||
Movement,
|
||||
Auxiliary(usize),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum Ability {
|
||||
ToolPrimary,
|
||||
ToolSecondary,
|
||||
SpeciesMovement,
|
||||
MainWeaponAbility(usize),
|
||||
OffWeaponAbility(usize),
|
||||
MainWeaponAux(usize),
|
||||
OffWeaponAux(usize),
|
||||
Empty,
|
||||
/* For future use
|
||||
* ArmorAbility(usize), */
|
||||
}
|
||||
|
||||
impl Ability {
|
||||
pub fn ability_id(self, inv: Option<&Inventory>) -> Option<&String> {
|
||||
pub fn ability_id(self, inv: Option<&Inventory>) -> Option<&str> {
|
||||
let ability_id_set = |equip_slot| {
|
||||
inv.and_then(|inv| inv.equipped(equip_slot))
|
||||
.map(|i| &i.item_config_expect().ability_ids)
|
||||
@ -195,30 +205,81 @@ impl Ability {
|
||||
|
||||
match self {
|
||||
Ability::ToolPrimary => {
|
||||
ability_id_set(EquipSlot::ActiveMainhand).map(|ids| &ids.primary)
|
||||
ability_id_set(EquipSlot::ActiveMainhand).map(|ids| ids.primary.as_str())
|
||||
},
|
||||
Ability::ToolSecondary => ability_id_set(EquipSlot::ActiveOffhand)
|
||||
.map(|ids| &ids.secondary)
|
||||
.or_else(|| ability_id_set(EquipSlot::ActiveMainhand).map(|ids| &ids.secondary)),
|
||||
.map(|ids| ids.secondary.as_str())
|
||||
.or_else(|| {
|
||||
ability_id_set(EquipSlot::ActiveMainhand).map(|ids| ids.secondary.as_str())
|
||||
}),
|
||||
Ability::SpeciesMovement => None, // TODO: Make not None
|
||||
Ability::MainWeaponAbility(index) => ability_id_set(EquipSlot::ActiveMainhand)
|
||||
.and_then(|ids| ids.abilities.get(index).map(|(_, id)| id)),
|
||||
Ability::OffWeaponAbility(index) => ability_id_set(EquipSlot::ActiveOffhand)
|
||||
.and_then(|ids| ids.abilities.get(index).map(|(_, id)| id)),
|
||||
Ability::MainWeaponAux(index) => ability_id_set(EquipSlot::ActiveMainhand)
|
||||
.and_then(|ids| ids.abilities.get(index).map(|(_, id)| id.as_str())),
|
||||
Ability::OffWeaponAux(index) => ability_id_set(EquipSlot::ActiveOffhand)
|
||||
.and_then(|ids| ids.abilities.get(index).map(|(_, id)| id.as_str())),
|
||||
Ability::Empty => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines whether an ability is a valid entry for the abilities array
|
||||
/// on the ability pool
|
||||
pub fn is_valid_abilities_ability(self) -> bool {
|
||||
match self {
|
||||
Ability::ToolPrimary => false,
|
||||
Ability::ToolSecondary => false,
|
||||
Ability::SpeciesMovement => false,
|
||||
Ability::MainWeaponAbility(_) => true,
|
||||
Ability::OffWeaponAbility(_) => true,
|
||||
Ability::Empty => true,
|
||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum PrimaryAbility {
|
||||
Tool,
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl From<PrimaryAbility> for Ability {
|
||||
fn from(primary: PrimaryAbility) -> Self {
|
||||
match primary {
|
||||
PrimaryAbility::Tool => Ability::ToolPrimary,
|
||||
PrimaryAbility::Empty => Ability::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum SecondaryAbility {
|
||||
Tool,
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl From<SecondaryAbility> for Ability {
|
||||
fn from(primary: SecondaryAbility) -> Self {
|
||||
match primary {
|
||||
SecondaryAbility::Tool => Ability::ToolSecondary,
|
||||
SecondaryAbility::Empty => Ability::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
|
||||
pub enum MovementAbility {
|
||||
Species,
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl From<MovementAbility> for Ability {
|
||||
fn from(primary: MovementAbility) -> Self {
|
||||
match primary {
|
||||
MovementAbility::Species => Ability::SpeciesMovement,
|
||||
MovementAbility::Empty => Ability::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub enum AuxiliaryAbility {
|
||||
MainWeapon(usize),
|
||||
OffWeapon(usize),
|
||||
Empty,
|
||||
}
|
||||
|
||||
impl From<AuxiliaryAbility> for Ability {
|
||||
fn from(primary: AuxiliaryAbility) -> Self {
|
||||
match primary {
|
||||
AuxiliaryAbility::MainWeapon(i) => Ability::MainWeaponAux(i),
|
||||
AuxiliaryAbility::OffWeapon(i) => Ability::OffWeaponAux(i),
|
||||
AuxiliaryAbility::Empty => Ability::Empty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
ability,
|
||||
inventory::slot::{EquipSlot, InvSlotId, Slot},
|
||||
invite::{InviteKind, InviteResponse},
|
||||
BuffKind,
|
||||
@ -135,6 +136,10 @@ pub enum ControlEvent {
|
||||
RemoveBuff(BuffKind),
|
||||
Respawn,
|
||||
Utterance(UtteranceKind),
|
||||
ChangeAbility {
|
||||
slot: usize,
|
||||
new_ability: ability::AuxiliaryAbility,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@ -189,6 +194,19 @@ impl InputKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InputKind> for Option<ability::AbilityInput> {
|
||||
fn from(input: InputKind) -> Option<ability::AbilityInput> {
|
||||
use ability::AbilityInput;
|
||||
match input {
|
||||
InputKind::Primary => Some(AbilityInput::Primary),
|
||||
InputKind::Secondary => Some(AbilityInput::Secondary),
|
||||
InputKind::Roll => Some(AbilityInput::Movement),
|
||||
InputKind::Ability(index) => Some(AbilityInput::Auxiliary(index)),
|
||||
InputKind::Jump | InputKind::Fly | InputKind::Block => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct InputAttr {
|
||||
pub select_pos: Option<Vec3<f32>>,
|
||||
|
@ -451,14 +451,14 @@ impl TryFrom<(&Item, &AbilityMap, &MaterialStatManifest)> for ItemConfig {
|
||||
if let ItemKind::Tool(tool) = &item.kind {
|
||||
// TODO: Maybe try to make an ecs resource?
|
||||
let ability_ids_map =
|
||||
AbilityMap::<String>::load_expect_cloned("common.abilities.ability_set_manifest");
|
||||
AbilityMap::<String>::load_expect("common.abilities.ability_set_manifest").read();
|
||||
|
||||
// If no custom ability set is specified, fall back to abilityset of tool kind.
|
||||
let (tool_default, tool_default_ids) = {
|
||||
let key = &AbilitySpec::Tool(tool.kind);
|
||||
let tool_default = |tool_kind| {
|
||||
let key = &AbilitySpec::Tool(tool_kind);
|
||||
(
|
||||
ability_map.get_ability_set(key).cloned(),
|
||||
ability_ids_map.get_ability_set(key).cloned(),
|
||||
ability_map.get_ability_set(key),
|
||||
ability_ids_map.get_ability_set(key),
|
||||
)
|
||||
};
|
||||
let (abilities, ability_ids) = if let Some(set_key) = item.ability_spec() {
|
||||
@ -476,13 +476,17 @@ impl TryFrom<(&Item, &AbilityMap, &MaterialStatManifest)> for ItemConfig {
|
||||
default ability set.",
|
||||
set_key
|
||||
);
|
||||
let (abilities, ids) = tool_default(tool.kind);
|
||||
(
|
||||
tool_default.unwrap_or_default(),
|
||||
tool_default_ids.unwrap_or_default(),
|
||||
abilities.cloned().unwrap_or_default(),
|
||||
ids.cloned().unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
} else if let (Some(set), Some(ids)) = (tool_default, tool_default_ids) {
|
||||
(set.modified_by_tool(tool, msm, &item.components), ids)
|
||||
} else if let (Some(set), Some(ids)) = tool_default(tool.kind) {
|
||||
(
|
||||
set.clone().modified_by_tool(tool, msm, &item.components),
|
||||
ids.clone(),
|
||||
)
|
||||
} else {
|
||||
error!(
|
||||
"No ability set defined for tool: {:?}, falling back to default ability set.",
|
||||
|
@ -381,17 +381,18 @@ impl Default for AbilitySet<CharacterAbility> {
|
||||
AbilitySet {
|
||||
primary: CharacterAbility::default(),
|
||||
secondary: CharacterAbility::default(),
|
||||
abilities: vec![],
|
||||
abilities: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for AbilitySet<String> {
|
||||
fn default() -> Self {
|
||||
AbilitySet {
|
||||
primary: "".to_string(),
|
||||
secondary: "".to_string(),
|
||||
abilities: vec![],
|
||||
primary: String::new(),
|
||||
secondary: String::new(),
|
||||
abilities: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#[cfg(not(target_arch = "wasm32"))] mod ability;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub mod ability;
|
||||
#[cfg(not(target_arch = "wasm32"))] mod admin;
|
||||
#[cfg(not(target_arch = "wasm32"))] pub mod agent;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -821,16 +821,18 @@ pub fn handle_jump(
|
||||
}
|
||||
|
||||
fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKind) {
|
||||
if let Some((ability, from_offhand)) = data
|
||||
.ability_pool
|
||||
.activate_ability(input, data.inventory, data.skill_set, data.body)
|
||||
.filter(|(ability, _)| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = CharacterState::from((
|
||||
&ability,
|
||||
AbilityInfo::from_input(data, from_offhand, input),
|
||||
data,
|
||||
));
|
||||
if let Some(ability_input) = input.into() {
|
||||
if let Some((ability, from_offhand)) = data
|
||||
.ability_pool
|
||||
.activate_ability(ability_input, data.inventory, data.skill_set, data.body)
|
||||
.filter(|(ability, _)| ability.requirements_paid(data, update))
|
||||
{
|
||||
update.character = CharacterState::from((
|
||||
&ability,
|
||||
AbilityInfo::from_input(data, from_offhand, input),
|
||||
data,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use common::{
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
Body, BuffChange, ControlEvent, Controller, Pos,
|
||||
AbilityPool, Body, BuffChange, ControlEvent, Controller, Pos,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
uid::UidAllocator,
|
||||
@ -27,16 +27,25 @@ pub struct ReadData<'a> {
|
||||
pub struct Sys;
|
||||
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (ReadData<'a>, WriteStorage<'a, Controller>);
|
||||
type SystemData = (
|
||||
ReadData<'a>,
|
||||
WriteStorage<'a, Controller>,
|
||||
WriteStorage<'a, AbilityPool>,
|
||||
);
|
||||
|
||||
const NAME: &'static str = "controller";
|
||||
const ORIGIN: Origin = Origin::Common;
|
||||
const PHASE: Phase = Phase::Create;
|
||||
|
||||
fn run(_job: &mut Job<Self>, (read_data, mut controllers): Self::SystemData) {
|
||||
fn run(
|
||||
_job: &mut Job<Self>,
|
||||
(read_data, mut controllers, mut ability_pools): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = read_data.server_bus.emitter();
|
||||
|
||||
for (entity, controller) in (&read_data.entities, &mut controllers).join() {
|
||||
for (entity, controller, mut ability_pool) in
|
||||
(&read_data.entities, &mut controllers, &mut ability_pools).join()
|
||||
{
|
||||
// Sanitize inputs to avoid clients sending bad data
|
||||
controller.inputs.sanitize();
|
||||
|
||||
@ -103,6 +112,9 @@ impl<'a> System<'a> for Sys {
|
||||
server_emitter.emit(ServerEvent::Sound { sound });
|
||||
}
|
||||
},
|
||||
ControlEvent::ChangeAbility { slot, new_ability } => {
|
||||
ability_pool.change_ability(slot, new_ability)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,8 @@ use crate::TerrainPersistence;
|
||||
use crate::{client::Client, presence::Presence, Settings};
|
||||
use common::{
|
||||
comp::{
|
||||
AbilityPool, Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Health, Ori, Player,
|
||||
Pos, SkillSet, Vel,
|
||||
Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Health, Ori, Player, Pos, SkillSet,
|
||||
Vel,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
resources::PlayerPhysicsSettings,
|
||||
@ -40,7 +40,6 @@ impl Sys {
|
||||
velocities: &mut WriteStorage<'_, Vel>,
|
||||
orientations: &mut WriteStorage<'_, Ori>,
|
||||
controllers: &mut WriteStorage<'_, Controller>,
|
||||
ability_pools: &mut WriteStorage<'_, AbilityPool>,
|
||||
settings: &Read<'_, Settings>,
|
||||
build_areas: &Read<'_, BuildAreas>,
|
||||
player_physics_settings: &mut Write<'_, PlayerPhysicsSettings>,
|
||||
@ -282,11 +281,6 @@ impl Sys {
|
||||
} => {
|
||||
presence.lossy_terrain_compression = lossy_terrain_compression;
|
||||
},
|
||||
ClientGeneral::ChangeAbility { slot, new_ability } => {
|
||||
if let Some(mut ability_pool) = ability_pools.get_mut(entity) {
|
||||
ability_pool.change_ability(slot, new_ability);
|
||||
}
|
||||
},
|
||||
ClientGeneral::RequestCharacterList
|
||||
| ClientGeneral::CreateCharacter { .. }
|
||||
| ClientGeneral::DeleteCharacter(_)
|
||||
@ -321,7 +315,6 @@ impl<'a> System<'a> for Sys {
|
||||
WriteStorage<'a, Presence>,
|
||||
WriteStorage<'a, Client>,
|
||||
WriteStorage<'a, Controller>,
|
||||
WriteStorage<'a, AbilityPool>,
|
||||
Read<'a, Settings>,
|
||||
Read<'a, BuildAreas>,
|
||||
Write<'a, PlayerPhysicsSettings>,
|
||||
@ -351,7 +344,6 @@ impl<'a> System<'a> for Sys {
|
||||
mut presences,
|
||||
mut clients,
|
||||
mut controllers,
|
||||
mut ability_pools,
|
||||
settings,
|
||||
build_areas,
|
||||
mut player_physics_settings,
|
||||
@ -387,7 +379,6 @@ impl<'a> System<'a> for Sys {
|
||||
&mut velocities,
|
||||
&mut orientations,
|
||||
&mut controllers,
|
||||
&mut ability_pools,
|
||||
&settings,
|
||||
&build_areas,
|
||||
&mut player_physics_settings,
|
||||
|
@ -64,21 +64,25 @@ impl State {
|
||||
.read_storage::<common::comp::AbilityPool>()
|
||||
.get(client.entity())
|
||||
{
|
||||
use common::comp::Ability;
|
||||
for (i, ability) in ability_pool.abilities.iter().enumerate() {
|
||||
if matches!(ability, Ability::Empty) {
|
||||
self.slots
|
||||
.iter_mut()
|
||||
.filter(|s| matches!(s, Some(SlotContents::Ability(index)) if *index == i))
|
||||
.for_each(|s| *s = None)
|
||||
} else if let Some(slot) = self
|
||||
.slots
|
||||
.iter_mut()
|
||||
.find(|s| !matches!(s, Some(SlotContents::Ability(index)) if *index != i))
|
||||
{
|
||||
*slot = Some(SlotContents::Ability(i));
|
||||
use common::comp::ability::AuxiliaryAbility;
|
||||
for ((i, ability), hotbar_slot) in ability_pool
|
||||
.abilities
|
||||
.iter()
|
||||
.enumerate()
|
||||
.zip(self.slots.iter_mut())
|
||||
{
|
||||
if matches!(ability, AuxiliaryAbility::Empty) {
|
||||
if matches!(hotbar_slot, Some(SlotContents::Ability(_))) {
|
||||
// If ability is empty but hotbar shows an ability, clear it
|
||||
*hotbar_slot = None;
|
||||
}
|
||||
} else {
|
||||
// If an ability is not empty show it on the hotbar
|
||||
*hotbar_slot = Some(SlotContents::Ability(i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.slots.iter_mut().for_each(|slot| *slot = None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ pub enum Event {
|
||||
UnlockSkill(Skill),
|
||||
RequestSiteInfo(SiteId),
|
||||
// TODO: This variant currently unused. UI is needed for it to be properly used.
|
||||
ChangeAbility(usize, comp::Ability),
|
||||
ChangeAbility(usize, comp::ability::AuxiliaryAbility),
|
||||
|
||||
SettingsChange(SettingsChange),
|
||||
}
|
||||
|
@ -21,9 +21,9 @@ use i18n::Localization;
|
||||
use client::{self, Client};
|
||||
use common::comp::{
|
||||
self,
|
||||
controller::InputKind,
|
||||
ability::AbilityInput,
|
||||
item::{ItemDesc, MaterialStatManifest},
|
||||
AbilityPool, Body, Energy, Health, Inventory, SkillSet,
|
||||
Ability, AbilityPool, Body, Energy, Health, Inventory, SkillSet,
|
||||
};
|
||||
use conrod_core::{
|
||||
color,
|
||||
@ -609,7 +609,7 @@ impl<'a> Skillbar<'a> {
|
||||
hotbar::SlotContents::Ability(i) => ability_pool
|
||||
.abilities
|
||||
.get(i)
|
||||
.and_then(|a| a.ability_id(Some(inventory)))
|
||||
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)))
|
||||
.and_then(|id| util::ability_description(id)),
|
||||
})
|
||||
};
|
||||
@ -679,7 +679,8 @@ impl<'a> Skillbar<'a> {
|
||||
.right_from(state.ids.slot5, slot_offset)
|
||||
.set(state.ids.m1_slot_bg, ui);
|
||||
|
||||
let primary_ability_id = self.ability_pool.primary.ability_id(Some(self.inventory));
|
||||
let primary_ability_id =
|
||||
Ability::from(self.ability_pool.primary).ability_id(Some(self.inventory));
|
||||
|
||||
Button::image(
|
||||
primary_ability_id.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id)),
|
||||
@ -693,7 +694,8 @@ impl<'a> Skillbar<'a> {
|
||||
.right_from(state.ids.m1_slot_bg, slot_offset)
|
||||
.set(state.ids.m2_slot_bg, ui);
|
||||
|
||||
let secondary_ability_id = self.ability_pool.secondary.ability_id(Some(self.inventory));
|
||||
let secondary_ability_id =
|
||||
Ability::from(self.ability_pool.secondary).ability_id(Some(self.inventory));
|
||||
|
||||
Button::image(
|
||||
secondary_ability_id.map_or(self.imgs.nothing, |id| util::ability_image(self.imgs, id)),
|
||||
@ -705,7 +707,7 @@ impl<'a> Skillbar<'a> {
|
||||
>= self
|
||||
.ability_pool
|
||||
.activate_ability(
|
||||
InputKind::Secondary,
|
||||
AbilityInput::Secondary,
|
||||
Some(self.inventory),
|
||||
self.skillset,
|
||||
self.body,
|
||||
|
@ -6,7 +6,7 @@ use super::{
|
||||
};
|
||||
use crate::ui::slot::{self, SlotKey, SumSlot};
|
||||
use common::comp::{
|
||||
controller::InputKind, slot::InvSlotId, AbilityPool, Body, Energy, Inventory, SkillSet,
|
||||
ability::AbilityInput, slot::InvSlotId, Ability, AbilityPool, Body, Energy, Inventory, SkillSet,
|
||||
};
|
||||
use conrod_core::{image, Color};
|
||||
use specs::Entity as EcsEntity;
|
||||
@ -138,14 +138,14 @@ impl<'a> SlotKey<HotbarSource<'a>, HotbarImageSource<'a>> for HotbarSlot {
|
||||
let ability_id = ability_pool
|
||||
.abilities
|
||||
.get(i)
|
||||
.and_then(|a| a.ability_id(Some(inventory)));
|
||||
.and_then(|a| Ability::from(*a).ability_id(Some(inventory)));
|
||||
|
||||
ability_id
|
||||
.map(|id| HotbarImage::Ability(id.to_string()))
|
||||
.and_then(|image| {
|
||||
ability_pool
|
||||
.activate_ability(
|
||||
InputKind::Ability(i),
|
||||
AbilityInput::Auxiliary(i),
|
||||
Some(inventory),
|
||||
skillset,
|
||||
body,
|
||||
|
Loading…
Reference in New Issue
Block a user