mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'zesterer/small-fixes' into 'master'
Actually small fixes this time See merge request veloren/veloren!1597
This commit is contained in:
commit
38f9bc15ae
assets
chat-cli/src
client/src
common/src
voxygen/src
world/src
@ -1,10 +1,10 @@
|
||||
[
|
||||
(10, Velorite),
|
||||
(15, VeloriteFrag),
|
||||
(110, Stones),
|
||||
(110, Stones),
|
||||
(150, ShortGrass),
|
||||
(60, Mushroom),
|
||||
(120, CaveMushroom),
|
||||
(2, ShinyGem),
|
||||
(2, Chest),
|
||||
(15, Crate),
|
||||
(15, Crate),
|
||||
]
|
||||
|
@ -44,6 +44,8 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) {
|
||||
float turb_noise = 0.0;
|
||||
float sun_access = 0.0;
|
||||
float moon_access = 0.0;
|
||||
float cloud_sun_access = 0.0;
|
||||
float cloud_moon_access = 0.0;
|
||||
// This is a silly optimisation but it actually nets us a fair few fps by skipping quite a few expensive calcs
|
||||
if (cloud_tendency > 0 || mist > 0.0) {
|
||||
// Turbulence (small variations in clouds/mist)
|
||||
@ -66,9 +68,9 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) {
|
||||
cloud = cloud_flat * pow(cloud_factor, 2) * 20;
|
||||
|
||||
// What proportion of sunlight is *not* being blocked by nearby cloud? (approximation)
|
||||
sun_access = clamp((pos.z - cloud_attr.x + turb_noise * 250.0) * 0.002 + 0.35 + max(mist * 20000, 0), 0, 1);
|
||||
cloud_sun_access = clamp((pos.z - cloud_attr.x + turb_noise * 250.0) * 0.002 + 0.35, 0, 1);
|
||||
// Since we're assuming the sun/moon is always above (not always correct) it's the same for the moon
|
||||
moon_access = sun_access;
|
||||
cloud_moon_access = sun_access;
|
||||
|
||||
#if (CLOUD_MODE >= CLOUD_MODE_HIGH)
|
||||
// Try to calculate a reasonable approximation of the cloud normal
|
||||
@ -79,11 +81,16 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) {
|
||||
(cloud_tendency - cloud_tendency_y) * 4,
|
||||
(pos.z - cloud_attr.x) / 250 + turb_noise + 0.25
|
||||
);
|
||||
sun_access = mix(max(dot(-sun_dir.xyz, cloud_norm) + 0.0, 0.025), sun_access, 0.25);
|
||||
moon_access = mix(max(dot(-moon_dir.xyz, cloud_norm) + 0.35, 0.025), moon_access, 0.25);
|
||||
cloud_sun_access = mix(max(dot(-sun_dir.xyz, cloud_norm) + 0.0, 0.025), cloud_sun_access, 0.25);
|
||||
cloud_moon_access = mix(max(dot(-moon_dir.xyz, cloud_norm) + 0.35, 0.025), cloud_moon_access, 0.25);
|
||||
#endif
|
||||
}
|
||||
|
||||
float mist_sun_access = 0.5 + turb_noise * 0.5;
|
||||
float mist_moon_access = mist_sun_access;
|
||||
sun_access = mix(cloud_sun_access, mist_sun_access, clamp(mist * 20000, 0, 1));
|
||||
moon_access = mix(cloud_moon_access, mist_moon_access, clamp(mist * 20000, 0, 1));
|
||||
|
||||
// Prevent mist (i.e: vapour beneath clouds) being accessible to the sun to avoid visual problems
|
||||
//float suppress_mist = clamp((pos.z - cloud_attr.x + cloud_attr.y) / 300, 0, 1);
|
||||
//sun_access *= suppress_mist;
|
||||
@ -102,6 +109,9 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) {
|
||||
#if (CLOUD_MODE >= CLOUD_MODE_LOW)
|
||||
emission_alt += (noise_3d(vec3(wind_pos.xy * 0.00003 + cloud_tendency * 0.2, time_of_day.x * 0.0001)) - 0.5) * 6000;
|
||||
#endif
|
||||
#if (CLOUD_MODE >= CLOUD_MODE_HIGH)
|
||||
emission_alt += (noise_3d(vec3(wind_pos.xy * 0.0005 + cloud_tendency * 0.2, emission_alt * 0.0001 + time_of_day.x * 0.0005)) - 0.5) * 1000;
|
||||
#endif
|
||||
float tail = (texture(t_noise, wind_pos.xy * 0.00005).x - 0.5) * 10 + (z - emission_alt) * 0.001;
|
||||
vec3 emission_col = vec3(0.6 + tail * 0.6, 1.0, 0.3 + tail * 0.2);
|
||||
float emission_nz = max(texture(t_noise, wind_pos.xy * 0.00003).x - 0.6, 0) / (10.0 + abs(z - emission_alt) / 40);
|
||||
|
@ -519,6 +519,13 @@ Mushroom: Some((
|
||||
offset: (-6.0, -6.0, 0.0),
|
||||
lod_axes: (1.0, 1.0, 1.0),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.1,
|
||||
)),
|
||||
|
||||
// Cave Mushrooms
|
||||
CaveMushroom: Some((
|
||||
variations: [
|
||||
(
|
||||
model: "voxygen.voxel.sprite.mushrooms.mushroom-11",
|
||||
offset: (-8.0, -8.0, 0.0),
|
||||
@ -2028,7 +2035,7 @@ GrassBlue: Some((
|
||||
model: "voxygen.voxel.sprite.underwater_grass.blue-1",
|
||||
offset: (-5.5, -5.5, 0.0),
|
||||
lod_axes: (0.0, 0.0, 0.5),
|
||||
),
|
||||
),
|
||||
],
|
||||
wind_sway: 1.0,
|
||||
)),
|
||||
@ -2044,7 +2051,7 @@ ChestBurried: Some((
|
||||
model: "voxygen.voxel.sprite.underwater_chests.chest_vines",
|
||||
offset: (-10.0, -8.5, 0.0),
|
||||
lod_axes: (0.0, 0.0, 0.5),
|
||||
),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.0,
|
||||
)),
|
||||
@ -2060,7 +2067,7 @@ Mud: Some((
|
||||
model: "voxygen.voxel.sprite.underwater_mud.mud-1",
|
||||
offset: (-8.5, -7.5, 0.0),
|
||||
lod_axes: (0.0, 0.0, 0.5),
|
||||
),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.0,
|
||||
)),
|
||||
|
@ -48,7 +48,7 @@ fn main() {
|
||||
)
|
||||
.expect("Failed to create client instance");
|
||||
|
||||
println!("Server info: {:?}", client.server_info);
|
||||
println!("Server info: {:?}", client.server_info());
|
||||
|
||||
println!("Players online: {:?}", client.get_players());
|
||||
|
||||
|
@ -24,6 +24,7 @@ use common::{
|
||||
InventoryManip, InventoryUpdateEvent,
|
||||
},
|
||||
event::{EventBus, LocalEvent},
|
||||
grid::Grid,
|
||||
msg::{
|
||||
validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
||||
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
||||
@ -70,25 +71,22 @@ pub enum Event {
|
||||
SetViewDistance(u32),
|
||||
Outcome(Outcome),
|
||||
CharacterCreated(CharacterId),
|
||||
CharacterError(String),
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
registered: bool,
|
||||
presence: Option<PresenceKind>,
|
||||
thread_pool: ThreadPool,
|
||||
pub server_info: ServerInfo,
|
||||
pub struct WorldData {
|
||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||
/// else. In the future we'll add more layers, like shadows, rivers, and
|
||||
/// probably foliage, cities, roads, and other structures.
|
||||
pub lod_base: Vec<u32>,
|
||||
pub lod_base: Grid<u32>,
|
||||
/// The "height" layer for LOD; currently includes only land altitudes, but
|
||||
/// in the future should also water depth, and probably other
|
||||
/// information as well.
|
||||
pub lod_alt: Vec<u32>,
|
||||
pub lod_alt: Grid<u32>,
|
||||
/// The "shadow" layer for LOD. Includes east and west horizon angles and
|
||||
/// an approximate max occluder height, which we use to try to
|
||||
/// approximate soft and volumetric shadows.
|
||||
pub lod_horizon: Vec<u32>,
|
||||
pub lod_horizon: Grid<u32>,
|
||||
/// A fully rendered map image for use with the map and minimap; note that
|
||||
/// this can be constructed dynamically by combining the layers of world
|
||||
/// map data (e.g. with shadow map data or river data), but at present
|
||||
@ -98,9 +96,27 @@ pub struct Client {
|
||||
/// in chunks), and the third element holds the minimum height for any land
|
||||
/// chunk (i.e. the sea level) in its x coordinate, and the maximum land
|
||||
/// height above this height (i.e. the max height) in its y coordinate.
|
||||
pub world_map: (Arc<DynamicImage>, Vec2<u16>, Vec2<f32>),
|
||||
pub player_list: HashMap<Uid, PlayerInfo>,
|
||||
pub character_list: CharacterList,
|
||||
map: (Arc<DynamicImage>, Vec2<u16>, Vec2<f32>),
|
||||
}
|
||||
|
||||
impl WorldData {
|
||||
pub fn chunk_size(&self) -> Vec2<u16> { self.map.1 }
|
||||
|
||||
pub fn map_image(&self) -> &Arc<DynamicImage> { &self.map.0 }
|
||||
|
||||
pub fn min_chunk_alt(&self) -> f32 { self.map.2.x }
|
||||
|
||||
pub fn max_chunk_alt(&self) -> f32 { self.map.2.y }
|
||||
}
|
||||
|
||||
pub struct Client {
|
||||
registered: bool,
|
||||
presence: Option<PresenceKind>,
|
||||
thread_pool: ThreadPool,
|
||||
server_info: ServerInfo,
|
||||
world_data: WorldData,
|
||||
player_list: HashMap<Uid, PlayerInfo>,
|
||||
character_list: CharacterList,
|
||||
sites: Vec<SiteInfo>,
|
||||
recipe_book: RecipeBook,
|
||||
available_recipes: HashSet<String>,
|
||||
@ -145,7 +161,6 @@ pub struct Client {
|
||||
pub struct CharacterList {
|
||||
pub characters: Vec<CharacterItem>,
|
||||
pub loading: bool,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
@ -229,11 +244,10 @@ impl Client {
|
||||
let sea_level = world_map.sea_level;
|
||||
let rgba = world_map.rgba;
|
||||
let alt = world_map.alt;
|
||||
let expected_size = (u32::from(map_size.x) * u32::from(map_size.y)) as usize;
|
||||
if rgba.len() != expected_size {
|
||||
if rgba.size() != map_size.map(|e| e as i32) {
|
||||
return Err(Error::Other("Server sent a bad world map image".into()));
|
||||
}
|
||||
if alt.len() != expected_size {
|
||||
if alt.size() != map_size.map(|e| e as i32) {
|
||||
return Err(Error::Other("Server sent a bad altitude map.".into()));
|
||||
}
|
||||
let [west, east] = world_map.horizons;
|
||||
@ -257,7 +271,7 @@ impl Client {
|
||||
let horizons = [unzip_horizons(&west), unzip_horizons(&east)];
|
||||
|
||||
// Redraw map (with shadows this time).
|
||||
let mut world_map_rgba = vec![0u32; rgba.len()];
|
||||
let mut world_map_rgba = vec![0u32; rgba.size().product() as usize];
|
||||
let mut map_config = common::terrain::map::MapConfig::orthographic(
|
||||
map_size_lg,
|
||||
core::ops::RangeInclusive::new(0.0, max_height),
|
||||
@ -274,14 +288,14 @@ impl Client {
|
||||
|pos| {
|
||||
let (rgba, alt, downhill_wpos) = if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
let [r, g, b, a] = rgba[posi].to_le_bytes();
|
||||
let alti = alt[posi];
|
||||
let [r, g, b, a] = rgba[pos].to_le_bytes();
|
||||
let alti = alt[pos];
|
||||
// Compute downhill.
|
||||
let downhill = {
|
||||
let mut best = -1;
|
||||
let mut besth = alti;
|
||||
for nposi in neighbors(map_size_lg, posi) {
|
||||
let nbh = alt[nposi];
|
||||
let nbh = alt.raw()[nposi];
|
||||
if nbh < besth {
|
||||
besth = nbh;
|
||||
best = nposi as isize;
|
||||
@ -317,8 +331,7 @@ impl Client {
|
||||
|wpos| {
|
||||
let pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, f| e / f as i32);
|
||||
rescale_height(if bounds_check(pos) {
|
||||
let posi = pos.y as usize * map_size.x as usize + pos.x as usize;
|
||||
scale_height_big(alt[posi])
|
||||
scale_height_big(alt[pos])
|
||||
} else {
|
||||
0.0
|
||||
})
|
||||
@ -361,7 +374,7 @@ impl Client {
|
||||
entity,
|
||||
lod_base,
|
||||
lod_alt,
|
||||
lod_horizon,
|
||||
Grid::from_raw(map_size.map(|e| e as i32), lod_horizon),
|
||||
(world_map_img, map_size, map_bounds),
|
||||
world_map.sites,
|
||||
recipe_book,
|
||||
@ -386,10 +399,12 @@ impl Client {
|
||||
presence: None,
|
||||
thread_pool,
|
||||
server_info,
|
||||
world_map,
|
||||
lod_base,
|
||||
lod_alt,
|
||||
lod_horizon,
|
||||
world_data: WorldData {
|
||||
lod_base,
|
||||
lod_alt,
|
||||
lod_horizon,
|
||||
map: world_map,
|
||||
},
|
||||
player_list: HashMap::new(),
|
||||
character_list: CharacterList::default(),
|
||||
sites,
|
||||
@ -612,6 +627,14 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn player_list(&self) -> &HashMap<Uid, PlayerInfo> { &self.player_list }
|
||||
|
||||
pub fn character_list(&self) -> &CharacterList { &self.character_list }
|
||||
|
||||
pub fn server_info(&self) -> &ServerInfo { &self.server_info }
|
||||
|
||||
pub fn world_data(&self) -> &WorldData { &self.world_data }
|
||||
|
||||
pub fn recipe_book(&self) -> &RecipeBook { &self.recipe_book }
|
||||
|
||||
pub fn available_recipes(&self) -> &HashSet<String> { &self.available_recipes }
|
||||
@ -1481,13 +1504,13 @@ impl Client {
|
||||
},
|
||||
ServerGeneral::CharacterActionError(error) => {
|
||||
warn!("CharacterActionError: {:?}.", error);
|
||||
self.character_list.error = Some(error);
|
||||
events.push(Event::CharacterError(error));
|
||||
},
|
||||
ServerGeneral::CharacterDataLoadError(error) => {
|
||||
trace!("Handling join error by server");
|
||||
self.presence = None;
|
||||
self.clean_state();
|
||||
self.character_list.error = Some(error);
|
||||
events.push(Event::CharacterError(error));
|
||||
},
|
||||
ServerGeneral::CharacterCreated(character_id) => {
|
||||
events.push(Event::CharacterCreated(character_id));
|
||||
|
@ -1,11 +1,20 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Grid<T> {
|
||||
cells: Vec<T>,
|
||||
size: Vec2<i32>,
|
||||
size: Vec2<i32>, // TODO: use u32
|
||||
}
|
||||
|
||||
impl<T> Grid<T> {
|
||||
pub fn from_raw(size: Vec2<i32>, raw: impl Into<Vec<T>>) -> Self {
|
||||
let cells = raw.into();
|
||||
assert_eq!(size.product() as usize, cells.len());
|
||||
Self { cells, size }
|
||||
}
|
||||
|
||||
pub fn populate_from(size: Vec2<i32>, mut f: impl FnMut(Vec2<i32>) -> T) -> Self {
|
||||
Self {
|
||||
cells: (0..size.y)
|
||||
@ -81,4 +90,32 @@ impl<T> Grid<T> {
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> &[T] { &self.cells }
|
||||
}
|
||||
|
||||
impl<T> Index<Vec2<i32>> for Grid<T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, index: Vec2<i32>) -> &Self::Output {
|
||||
self.get(index).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Attempted to index grid of size {:?} with index {:?}",
|
||||
self.size(),
|
||||
index
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IndexMut<Vec2<i32>> for Grid<T> {
|
||||
fn index_mut(&mut self, index: Vec2<i32>) -> &mut Self::Output {
|
||||
let size = self.size();
|
||||
self.get_mut(index).unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Attempted to index grid of size {:?} with index {:?}",
|
||||
size, index
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ pub mod event;
|
||||
pub mod explosion;
|
||||
pub mod figure;
|
||||
pub mod generation;
|
||||
pub mod grid;
|
||||
pub mod loadout_builder;
|
||||
pub mod lottery;
|
||||
pub mod metrics;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::grid::Grid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vek::*;
|
||||
|
||||
@ -30,12 +31,12 @@ pub struct WorldMapMsg {
|
||||
pub max_height: f32,
|
||||
/// RGB+A; the alpha channel is currently unused, but will be used in the
|
||||
/// future. Entries are in the usual chunk order.
|
||||
pub rgba: Vec<u32>,
|
||||
pub rgba: Grid<u32>,
|
||||
/// Altitudes: bits 2 to 0 are unused, then bits 15 to 3 are used for
|
||||
/// altitude. The remainder are currently unused, but we have plans to
|
||||
/// use 7 bits for water depth (using an integer f7 encoding), and we
|
||||
/// will find other uses for the remaining 12 bits.
|
||||
pub alt: Vec<u32>,
|
||||
pub alt: Grid<u32>,
|
||||
/// Horizon mapping. This is a variant of shadow mapping that is
|
||||
/// specifically designed for height maps; it takes advantage of their
|
||||
/// regular structure (e.g. no holes) to compress all information needed
|
||||
|
@ -173,6 +173,7 @@ impl Block {
|
||||
SpriteKind::WallLamp => Some(16),
|
||||
SpriteKind::FireBowlGround => Some(16),
|
||||
SpriteKind::Velorite | SpriteKind::VeloriteFrag => Some(6),
|
||||
SpriteKind::CaveMushroom => Some(12),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -108,6 +108,7 @@ make_case_elim!(
|
||||
ChestBurried = 0x52,
|
||||
Mud = 0x53,
|
||||
FireBowlGround = 0x54,
|
||||
CaveMushroom = 0x55,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -178,7 +178,7 @@ impl<'a> Widget for Group<'a> {
|
||||
}
|
||||
|
||||
// Helper
|
||||
let uid_to_name_text = |uid, client: &Client| match client.player_list.get(&uid) {
|
||||
let uid_to_name_text = |uid, client: &Client| match client.player_list().get(&uid) {
|
||||
Some(player_info) => player_info
|
||||
.character
|
||||
.as_ref()
|
||||
|
@ -648,10 +648,10 @@ impl Hud {
|
||||
// Load world map
|
||||
let world_map = (
|
||||
ui.add_graphic_with_rotations(Graphic::Image(
|
||||
Arc::clone(&client.world_map.0),
|
||||
Arc::clone(client.world_data().map_image()),
|
||||
Some(water_color),
|
||||
)),
|
||||
client.world_map.1.map(u32::from),
|
||||
client.world_data().chunk_size().map(|e| e as u32),
|
||||
);
|
||||
// Load images.
|
||||
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
|
||||
@ -666,7 +666,7 @@ impl Hud {
|
||||
// Load fonts.
|
||||
let fonts = Fonts::load(&i18n.fonts, &mut ui).expect("Impossible to load fonts!");
|
||||
// Get the server name.
|
||||
let server = &client.server_info.name;
|
||||
let server = &client.server_info().name;
|
||||
// Get the id, unwrap is safe because this CANNOT be None at this
|
||||
// point.
|
||||
|
||||
|
@ -266,7 +266,11 @@ impl<'a> Widget for Social<'a> {
|
||||
}
|
||||
// Online Tab
|
||||
if let SocialTab::Online = self.show.social_tab {
|
||||
let players = self.client.player_list.iter().filter(|(_, p)| p.is_online);
|
||||
let players = self
|
||||
.client
|
||||
.player_list()
|
||||
.iter()
|
||||
.filter(|(_, p)| p.is_online);
|
||||
let count = players.clone().count();
|
||||
let height = if count > 1 {
|
||||
count as f64 - 1.0 + 20.0 * count as f64 - 1.0
|
||||
@ -517,12 +521,12 @@ impl<'a> Widget for Social<'a> {
|
||||
.as_ref()
|
||||
.map(|(s, _)| *s)
|
||||
.filter(|selected| {
|
||||
self.client
|
||||
.player_list
|
||||
.get(selected)
|
||||
.map_or(false, |selected_player| {
|
||||
self.client.player_list().get(selected).map_or(
|
||||
false,
|
||||
|selected_player| {
|
||||
selected_player.is_online && selected_player.character.is_some()
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.selected_entity
|
||||
|
@ -44,7 +44,7 @@ impl CharSelectionState {
|
||||
client: &'a Client,
|
||||
) -> (Option<comp::humanoid::Body>, Option<&'a comp::Loadout>) {
|
||||
char_selection_ui
|
||||
.display_body_loadout(&client.character_list.characters)
|
||||
.display_body_loadout(&client.character_list().characters)
|
||||
.map(|(body, loadout)| {
|
||||
(
|
||||
match body {
|
||||
@ -124,11 +124,11 @@ impl PlayState for CharSelectionState {
|
||||
)));
|
||||
},
|
||||
ui::Event::ClearCharacterListError => {
|
||||
self.client.borrow_mut().character_list.error = None;
|
||||
self.char_selection_ui.error = None;
|
||||
},
|
||||
ui::Event::SelectCharacter(selected) => {
|
||||
let client = self.client.borrow();
|
||||
let server_name = &client.server_info.name;
|
||||
let server_name = &client.server_info().name;
|
||||
// Select newly created character
|
||||
global_state
|
||||
.profile
|
||||
@ -194,6 +194,9 @@ impl PlayState for CharSelectionState {
|
||||
client::Event::CharacterCreated(character_id) => {
|
||||
self.char_selection_ui.select_character(character_id);
|
||||
},
|
||||
client::Event::CharacterError(error) => {
|
||||
self.char_selection_ui.display_error(error);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -287,7 +287,12 @@ impl Controls {
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&mut self, _settings: &Settings, client: &Client) -> Element<Message> {
|
||||
fn view(
|
||||
&mut self,
|
||||
_settings: &Settings,
|
||||
client: &Client,
|
||||
error: &Option<String>,
|
||||
) -> Element<Message> {
|
||||
// TODO: use font scale thing for text size (use on button size for buttons with
|
||||
// text)
|
||||
|
||||
@ -348,7 +353,7 @@ impl Controls {
|
||||
// Note: we don't need to persist this because it is the default
|
||||
if self.selected.is_none() {
|
||||
self.selected = client
|
||||
.character_list
|
||||
.character_list()
|
||||
.characters
|
||||
.get(0)
|
||||
.and_then(|i| i.character.id);
|
||||
@ -356,13 +361,13 @@ impl Controls {
|
||||
// Get the index of the selected character
|
||||
let selected = self.selected.and_then(|id| {
|
||||
client
|
||||
.character_list
|
||||
.character_list()
|
||||
.characters
|
||||
.iter()
|
||||
.position(|i| i.character.id == Some(id))
|
||||
});
|
||||
|
||||
if let Some(error) = &client.character_list.error {
|
||||
if let Some(error) = error {
|
||||
// TODO: use more user friendly errors with suggestions on potential solutions
|
||||
// instead of directly showing error message here
|
||||
*info_content = Some(InfoContent::CharacterError(format!(
|
||||
@ -377,14 +382,14 @@ impl Controls {
|
||||
Some(InfoContent::LoadingCharacters)
|
||||
| Some(InfoContent::CreatingCharacter)
|
||||
| Some(InfoContent::DeletingCharacter)
|
||||
) && !client.character_list.loading
|
||||
) && !client.character_list().loading
|
||||
{
|
||||
*info_content = None;
|
||||
}
|
||||
|
||||
let server = Container::new(
|
||||
Column::with_children(vec![
|
||||
Text::new(&client.server_info.name)
|
||||
Text::new(&client.server_info().name)
|
||||
.size(fonts.cyri.scale(25))
|
||||
.into(),
|
||||
// TODO: show additional server info here
|
||||
@ -399,7 +404,7 @@ impl Controls {
|
||||
.width(Length::Fill);
|
||||
|
||||
let characters = {
|
||||
let characters = &client.character_list.characters;
|
||||
let characters = &client.character_list().characters;
|
||||
let num = characters.len();
|
||||
// Ensure we have enough button states
|
||||
character_buttons.resize_with(num * 2, Default::default);
|
||||
@ -1387,12 +1392,13 @@ pub struct CharSelectionUi {
|
||||
controls: Controls,
|
||||
enter_pressed: bool,
|
||||
select_character: Option<CharacterId>,
|
||||
pub error: Option<String>,
|
||||
}
|
||||
|
||||
impl CharSelectionUi {
|
||||
pub fn new(global_state: &mut GlobalState, client: &Client) -> Self {
|
||||
// Load up the last selected character for this server
|
||||
let server_name = &client.server_info.name;
|
||||
let server_name = &client.server_info().name;
|
||||
let selected_character = global_state.profile.get_selected_character(server_name);
|
||||
|
||||
// Load language
|
||||
@ -1432,6 +1438,7 @@ impl CharSelectionUi {
|
||||
controls,
|
||||
enter_pressed: false,
|
||||
select_character: None,
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1491,12 +1498,15 @@ impl CharSelectionUi {
|
||||
|
||||
pub fn select_character(&mut self, id: CharacterId) { self.select_character = Some(id); }
|
||||
|
||||
pub fn display_error(&mut self, error: String) { self.error = Some(error); }
|
||||
|
||||
// TODO: do we need whole client here or just character list?
|
||||
pub fn maintain(&mut self, global_state: &mut GlobalState, client: &Client) -> Vec<Event> {
|
||||
let mut events = Vec::new();
|
||||
|
||||
let (mut messages, _) = self.ui.maintain(
|
||||
self.controls.view(&global_state.settings, &client),
|
||||
self.controls
|
||||
.view(&global_state.settings, &client, &self.error),
|
||||
global_state.window.renderer_mut(),
|
||||
global_state.clipboard.as_ref(),
|
||||
);
|
||||
@ -1514,7 +1524,7 @@ impl CharSelectionUi {
|
||||
self.controls.update(
|
||||
message,
|
||||
&mut events,
|
||||
&client.character_list.characters,
|
||||
&client.character_list().characters,
|
||||
&*client.state().ability_map(),
|
||||
)
|
||||
});
|
||||
|
@ -28,10 +28,10 @@ impl Lod {
|
||||
locals: renderer.create_consts(&[Locals::default()]).unwrap(),
|
||||
data: LodData::new(
|
||||
renderer,
|
||||
client.world_map.1,
|
||||
&client.lod_base,
|
||||
&client.lod_alt,
|
||||
&client.lod_horizon,
|
||||
client.world_data().chunk_size(),
|
||||
client.world_data().lod_base.raw(),
|
||||
client.world_data().lod_alt.raw(),
|
||||
client.world_data().lod_horizon.raw(),
|
||||
settings.graphics.lod_detail.max(100).min(2500),
|
||||
water_color().into_array().into(),
|
||||
),
|
||||
|
@ -304,7 +304,10 @@ impl Scene {
|
||||
terrain: Terrain::new(renderer),
|
||||
lod: Lod::new(renderer, client, settings),
|
||||
loaded_distance: 0.0,
|
||||
map_bounds: client.world_map.2,
|
||||
map_bounds: Vec2::new(
|
||||
client.world_data().min_chunk_alt(),
|
||||
client.world_data().max_chunk_alt(),
|
||||
),
|
||||
select_pos: None,
|
||||
light_data: Vec::new(),
|
||||
particle_mgr: ParticleMgr::new(renderer),
|
||||
|
@ -106,7 +106,10 @@ impl Scene {
|
||||
let start_angle = 90.0f32.to_radians();
|
||||
let resolution = renderer.get_resolution().map(|e| e as f32);
|
||||
|
||||
let map_bounds = client.world_map.2;
|
||||
let map_bounds = Vec2::new(
|
||||
client.world_data().min_chunk_alt(),
|
||||
client.world_data().max_chunk_alt(),
|
||||
);
|
||||
let map_border = [0.0, 0.0, 0.0, 0.0];
|
||||
let map_image = [0];
|
||||
let alt_image = [0];
|
||||
|
@ -183,6 +183,7 @@ impl SessionState {
|
||||
},
|
||||
client::Event::Outcome(outcome) => outcomes.push(outcome),
|
||||
client::Event::CharacterCreated(_) => {},
|
||||
client::Event::CharacterError(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -931,7 +932,7 @@ impl PlayState for SessionState {
|
||||
HudEvent::ChangeHotbarState(state) => {
|
||||
let client = self.client.borrow();
|
||||
|
||||
let server_name = &client.server_info.name;
|
||||
let server_name = &client.server_info().name;
|
||||
// If we are changing the hotbar state this CANNOT be None.
|
||||
let character_id = match client.presence().unwrap() {
|
||||
PresenceKind::Character(id) => id,
|
||||
|
@ -36,6 +36,7 @@ use crate::{
|
||||
};
|
||||
use common::{
|
||||
assets,
|
||||
grid::Grid,
|
||||
msg::WorldMapMsg,
|
||||
store::Id,
|
||||
terrain::{
|
||||
@ -1498,8 +1499,8 @@ impl WorldSim {
|
||||
dimensions_lg: self.map_size_lg().vec(),
|
||||
sea_level: CONFIG.sea_level,
|
||||
max_height: self.max_height,
|
||||
rgba: v,
|
||||
alt: alts,
|
||||
rgba: Grid::from_raw(self.get_size().map(|e| e as i32), v),
|
||||
alt: Grid::from_raw(self.get_size().map(|e| e as i32), alts),
|
||||
horizons,
|
||||
sites: Vec::new(), // Will be substituted later
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
pub mod fast_noise;
|
||||
pub mod grid;
|
||||
pub mod map_vec;
|
||||
pub mod random;
|
||||
pub mod sampler;
|
||||
@ -11,7 +10,6 @@ pub mod unit_chooser;
|
||||
// Reexports
|
||||
pub use self::{
|
||||
fast_noise::FastNoise,
|
||||
grid::Grid,
|
||||
map_vec::MapVec,
|
||||
random::{RandomField, RandomPerm},
|
||||
sampler::{Sampler, SamplerMut},
|
||||
@ -20,6 +18,8 @@ pub use self::{
|
||||
unit_chooser::UnitChooser,
|
||||
};
|
||||
|
||||
pub use common::grid::Grid;
|
||||
|
||||
use fxhash::FxHasher32;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
Loading…
Reference in New Issue
Block a user