Remove ability map from top level functions

This commit is contained in:
Imbris 2020-11-12 00:27:16 -05:00 committed by Sam
parent 9b4fa4e961
commit 37e4ea4669
14 changed files with 84 additions and 53 deletions

View File

@ -96,14 +96,15 @@ impl Tool {
}
pub fn get_abilities(&self, map: &AbilityMap) -> AbilitySet<CharacterAbility> {
let base_abilities = match AbilityMap::load("common.abilities.weapon_ability_manifest") {
Ok(map) => map.0.get(&self.kind).map(|a| a.clone()).unwrap_or_default(),
Err(err) => {
error!(?err, "Error unwrapping");
AbilitySet::default()
},
};
base_abilities
if let Some(set) = map.0.get(&self.kind).cloned() {
set
} else {
error!(
"ToolKind: {:?} has no AbilitySet in the ability map falling back to default",
&self.kind
);
Default::default()
}
}
// TODO: Before merging ron file branch, ensure these are double checked against

View File

@ -181,7 +181,9 @@ impl State {
ecs.insert(BlockChange::default());
ecs.insert(TerrainChanges::default());
ecs.insert(EventBus::<LocalEvent>::default());
ecs.insert(comp::item::tool::AbilityMap::load_expect_cloned("common.abilities.weapon_ability_manifest"));
ecs.insert(comp::item::tool::AbilityMap::load_expect_cloned(
"common.abilities.weapon_ability_manifest",
));
// TODO: only register on the server
ecs.insert(EventBus::<ServerEvent>::default());
ecs.insert(comp::group::GroupManager::default());
@ -255,6 +257,9 @@ impl State {
/// Get the current delta time.
pub fn get_delta_time(&self) -> f32 { self.ecs.read_resource::<DeltaTime>().0 }
/// Get a reference to this state's ability map.
pub fn ability_map(&self) -> Fetch<comp::item::tool::AbilityMap> { self.ecs.read_resource() }
/// Get a reference to this state's terrain.
pub fn terrain(&self) -> Fetch<TerrainGrid> { self.ecs.read_resource() }

View File

@ -9,7 +9,7 @@ use crate::{
use chrono::{NaiveTime, Timelike};
use common::{
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
comp::{self, item::tool::AbilityMap, ChatType, Item, LightEmitter, WaypointArea},
comp::{self, ChatType, Item, LightEmitter, WaypointArea},
effect::Effect,
event::{EventBus, ServerEvent},
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral},
@ -655,8 +655,10 @@ fn handle_spawn(
let body = body();
let map = server.state().ecs().fetch::<AbilityMap>();
let loadout = LoadoutBuilder::build_loadout(body, alignment, None, false, &map).build();
let map = server.state().ability_map();
let loadout =
LoadoutBuilder::build_loadout(body, alignment, None, false, &map)
.build();
drop(map);
let mut entity_base = server

View File

@ -4,7 +4,11 @@ use crate::{
Server,
};
use common::{
comp::{self, item::{self, tool::AbilityMap}, Pos},
comp::{
self,
item::{self, tool::AbilityMap},
Pos,
},
consts::MAX_MOUNT_RANGE,
msg::ServerGeneral,
sync::{Uid, WorldSyncExt},

View File

@ -1,7 +1,7 @@
use crate::{client::Client, Server, StateExt};
use common::{
comp::{
self, item::{self, tool::AbilityMap},
self, item,
slot::{self, Slot},
Pos,
},
@ -203,8 +203,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
if let Some(lantern) = lantern_opt {
swap_lantern(&mut state.ecs().write_storage(), entity, &lantern);
}
let map = state.ecs().fetch::<AbilityMap>();
slot::equip(slot, inventory, loadout, &map);
let ability_map = state.ability_map();
slot::equip(slot, inventory, loadout, &ability_map);
Some(comp::InventoryUpdateEvent::Used)
} else {
None
@ -339,8 +339,8 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
if slot == slot::EquipSlot::Lantern {
snuff_lantern(&mut state.ecs().write_storage(), entity);
}
let map = state.ecs().fetch::<AbilityMap>();
slot::unequip(slot, inventory, loadout, &map);
let ability_map = state.ability_map();
slot::unequip(slot, inventory, loadout, &ability_map);
Some(comp::InventoryUpdateEvent::Used)
} else {
error!(?entity, "Entity doesn't have a loadout, can't unequip...");
@ -366,14 +366,14 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
let mut loadouts = ecs.write_storage();
let inventory = inventories.get_mut(entity);
let loadout = loadouts.get_mut(entity);
let map = state.ecs().fetch::<AbilityMap>();
let ability_map = state.ability_map();
slot::swap(a, b, inventory, loadout, &map);
slot::swap(a, b, inventory, loadout, &ability_map);
// :/
drop(loadouts);
drop(inventories);
drop(map);
drop(ability_map);
state.write_component(
entity,
@ -382,7 +382,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
},
comp::InventoryManip::Drop(slot) => {
let map = state.ecs().fetch::<AbilityMap>();
let ability_map = state.ability_map();
let item = match slot {
Slot::Inventory(slot) => state
.ecs()
@ -393,9 +393,9 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
.ecs()
.write_storage()
.get_mut(entity)
.and_then(|ldt| slot::loadout_remove(slot, ldt, &map)),
.and_then(|ldt| slot::loadout_remove(slot, ldt, &ability_map)),
};
drop(map);
drop(ability_map);
// FIXME: We should really require the drop and write to be atomic!
if let (Some(mut item), Some(pos)) =

View File

@ -46,7 +46,7 @@ use crate::{
};
use common::{
cmd::ChatCommand,
comp::{self, item::tool::AbilityMap, ChatType},
comp::{self, ChatType},
event::{EventBus, ServerEvent},
msg::{
ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg,
@ -159,8 +159,8 @@ impl Server {
state
.ecs_mut()
.insert(CharacterUpdater::new(&persistence_db_dir)?);
let character_loader = CharacterLoader::new(&persistence_db_dir, &*state.ecs().fetch::<AbilityMap>());
let character_loader = CharacterLoader::new(&persistence_db_dir, &*state.ability_map());
state.ecs_mut().insert(character_loader);
state.ecs_mut().insert(Vec::<Outcome>::new());

View File

@ -39,7 +39,7 @@ use crate::{
settings::Settings,
window::{Event, Window},
};
use common::{assets::watch, clock::Clock, comp::item::tool::AbilityMap};
use common::{assets::watch, clock::Clock};
/// A type used to store state that is shared between all play states.
pub struct GlobalState {
@ -110,7 +110,7 @@ pub trait PlayState {
fn enter(&mut self, global_state: &mut GlobalState, direction: Direction);
/// Tick the play state
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>, map: &AbilityMap) -> PlayStateResult;
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>) -> PlayStateResult;
/// Get a descriptive name for this state type.
fn name(&self) -> &'static str;

View File

@ -192,5 +192,5 @@ fn main() {
localization_watcher,
};
run::run(global_state, event_loop, map);
run::run(global_state, event_loop);
}

View File

@ -10,7 +10,12 @@ use crate::{
Direction, GlobalState, PlayState, PlayStateResult,
};
use client::{self, Client};
use common::{assets::Asset, comp::{self, item::tool::AbilityMap}, span, state::DeltaTime};
use common::{
assets::Asset,
comp::{self},
span,
state::DeltaTime,
};
use specs::WorldExt;
use std::{cell::RefCell, rc::Rc};
use tracing::error;
@ -62,7 +67,7 @@ impl PlayState for CharSelectionState {
self.client.borrow_mut().load_character_list();
}
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<WinEvent>, map: &AbilityMap) -> PlayStateResult {
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<WinEvent>) -> PlayStateResult {
span!(_guard, "tick", "<CharSelectionState as PlayState>::tick");
let (client_presence, client_registered) = {
let client = self.client.borrow();
@ -88,7 +93,7 @@ impl PlayState for CharSelectionState {
// Maintain the UI.
let events = self
.char_selection_ui
.maintain(global_state, &mut self.client.borrow_mut(), map);
.maintain(global_state, &mut self.client.borrow_mut());
for event in events {
match event {

View File

@ -184,7 +184,9 @@ impl Mode {
let loadout = LoadoutBuilder::new()
.defaults()
.active_item(Some(LoadoutBuilder::default_item_config_from_str(tool, map)))
.active_item(Some(LoadoutBuilder::default_item_config_from_str(
tool, map,
)))
.build();
let loadout = Box::new(loadout);
@ -1172,7 +1174,13 @@ impl Controls {
.into()
}
fn update(&mut self, message: Message, events: &mut Vec<Event>, characters: &[CharacterItem], map: &AbilityMap) {
fn update(
&mut self,
message: Message,
events: &mut Vec<Event>,
characters: &[CharacterItem],
map: &AbilityMap,
) {
match message {
Message::Back => {
if matches!(&self.mode, Mode::Create { .. }) {
@ -1242,7 +1250,8 @@ impl Controls {
Message::Tool(value) => {
if let Mode::Create { tool, loadout, .. } = &mut self.mode {
*tool = value;
loadout.active_item = Some(LoadoutBuilder::default_item_config_from_str(*tool, map));
loadout.active_item =
Some(LoadoutBuilder::default_item_config_from_str(*tool, map));
}
},
Message::RandomizeCharacter => {
@ -1411,7 +1420,7 @@ impl CharSelectionUi {
}
// TODO: do we need whole client here or just character list?
pub fn maintain(&mut self, global_state: &mut GlobalState, client: &mut Client, map: &AbilityMap) -> Vec<Event> {
pub fn maintain(&mut self, global_state: &mut GlobalState, client: &mut Client) -> Vec<Event> {
let mut events = Vec::new();
let (mut messages, _) = self.ui.maintain(
@ -1425,8 +1434,12 @@ impl CharSelectionUi {
}
messages.into_iter().for_each(|message| {
self.controls
.update(message, &mut events, &client.character_list.characters, map)
self.controls.update(
message,
&mut events,
&client.character_list.characters,
&*client.state().ability_map(),
)
});
events

View File

@ -12,7 +12,11 @@ use crate::{
Direction, GlobalState, PlayState, PlayStateResult,
};
use client_init::{ClientInit, Error as InitError, Msg as InitMsg};
use common::{assets::Asset, comp::{self, item::tool::AbilityMap}, span};
use common::{
assets::Asset,
comp::{self},
span,
};
use tracing::error;
use ui::{Event as MainMenuEvent, MainMenuUi};
@ -48,7 +52,7 @@ impl PlayState for MainMenuState {
}
}
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>, map: &AbilityMap) -> PlayStateResult {
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>) -> PlayStateResult {
span!(_guard, "tick", "<MainMenuState as PlayState>::tick");
let mut localized_strings = crate::i18n::Localization::load_expect(
&crate::i18n::i18n_asset_key(&global_state.settings.language.selected_language),
@ -263,7 +267,7 @@ impl PlayState for MainMenuState {
},
#[cfg(feature = "singleplayer")]
MainMenuEvent::StartSingleplayer => {
let singleplayer = Singleplayer::new(None, map); // TODO: Make client and server use the same thread pool
let singleplayer = Singleplayer::new(None); // TODO: Make client and server use the same thread pool
global_state.singleplayer = Some(singleplayer);
},

View File

@ -4,11 +4,11 @@ use crate::{
window::{Event, EventLoop},
Direction, GlobalState, PlayState, PlayStateResult,
};
use common::{comp::item::tool::AbilityMap, no_guard_span, span, util::GuardlessSpan};
use common::{no_guard_span, span, util::GuardlessSpan};
use std::{mem, time::Duration};
use tracing::debug;
pub fn run(mut global_state: GlobalState, event_loop: EventLoop, map: &AbilityMap) {
pub fn run(mut global_state: GlobalState, event_loop: EventLoop) {
// Set up the initial play state.
let mut states: Vec<Box<dyn PlayState>> = vec![Box::new(MainMenuState::new(&mut global_state))];
states.last_mut().map(|current_state| {
@ -26,8 +26,6 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop, map: &AbilityMa
let mut poll_span = None;
let mut event_span = None;
let map = map.clone();
event_loop.run(move |event, _, control_flow| {
// Continuously run loop since we handle sleeping
*control_flow = winit::event_loop::ControlFlow::Poll;
@ -55,7 +53,7 @@ pub fn run(mut global_state: GlobalState, event_loop: EventLoop, map: &AbilityMa
event_span.take();
poll_span.take();
if polled_twice {
handle_main_events_cleared(&mut states, control_flow, &mut global_state, &map);
handle_main_events_cleared(&mut states, control_flow, &mut global_state);
}
poll_span = Some(no_guard_span!("Poll Winit"));
polled_twice = !polled_twice;
@ -84,7 +82,6 @@ fn handle_main_events_cleared(
states: &mut Vec<Box<dyn PlayState>>,
control_flow: &mut winit::event_loop::ControlFlow,
global_state: &mut GlobalState,
map: &AbilityMap,
) {
span!(guard, "Handle MainEventsCleared");
// Screenshot / Fullscreen toggle
@ -105,7 +102,7 @@ fn handle_main_events_cleared(
let mut exit = true;
while let Some(state_result) = states.last_mut().map(|last| {
let events = global_state.window.fetch_events();
last.tick(global_state, events, map)
last.tick(global_state, events)
}) {
// Implement state transfer logic.
match state_result {

View File

@ -15,7 +15,7 @@ use client::{self, Client};
use common::{
assets::Asset,
comp,
comp::{item::tool::AbilityMap, ChatMsg, ChatType, InventoryUpdateEvent, Pos, Vel},
comp::{ChatMsg, ChatType, InventoryUpdateEvent, Pos, Vel},
consts::{MAX_MOUNT_RANGE, MAX_PICKUP_RANGE},
event::EventBus,
msg::PresenceKind,
@ -203,7 +203,7 @@ impl PlayState for SessionState {
}
}
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>, map: &AbilityMap) -> PlayStateResult {
fn tick(&mut self, global_state: &mut GlobalState, events: Vec<Event>) -> PlayStateResult {
span!(_guard, "tick", "<Session as PlayState>::tick");
// TODO: let mut client = self.client.borrow_mut();
// NOTE: Not strictly necessary, but useful for hotloading translation changes.

View File

@ -1,5 +1,5 @@
use client::Client;
use common::{clock::Clock, comp::item::tool::AbilityMap};
use common::clock::Clock;
use crossbeam::channel::{bounded, unbounded, Receiver, Sender, TryRecvError};
use server::{Error as ServerError, Event, Input, Server};
use std::{
@ -31,7 +31,7 @@ pub struct Singleplayer {
}
impl Singleplayer {
pub fn new(client: Option<&Client>,map: &AbilityMap) -> Self {
pub fn new(client: Option<&Client>) -> Self {
let (sender, receiver) = unbounded();
// Determine folder to save server data in