Implement sending world map across the network.

This commit is contained in:
Joshua Yanovski 2020-01-11 20:25:48 +01:00
parent bacc5271d4
commit 9520ef4f6d
8 changed files with 35 additions and 31 deletions

View File

@ -11,6 +11,7 @@ pub use specs::{
Builder, DispatcherBuilder, Entity as EcsEntity, ReadStorage, WorldExt,
};
use byteorder::{ByteOrder, LittleEndian};
use common::{
comp::{self, ControlEvent, Controller, ControllerInputs, InventoryManip},
msg::{
@ -55,7 +56,7 @@ pub struct Client {
client_state: ClientState,
thread_pool: ThreadPool,
pub server_info: ServerInfo,
pub world_map: Arc<DynamicImage>,
pub world_map: (Arc<DynamicImage>, Vec2<u32>),
pub player_list: HashMap<u64, String>,
postbox: PostBox<ClientMsg, ServerMsg>,
@ -87,7 +88,7 @@ impl Client {
entity_package,
server_info,
time_of_day,
// world_map: /*(map_size, world_map)*/map_size,
world_map: (map_size, world_map),
}) => {
// TODO: Display that versions don't match in Voxygen
if server_info.git_hash != common::util::GIT_HASH.to_string() {
@ -105,23 +106,23 @@ impl Client {
let entity = state.ecs_mut().apply_entity_package(entity_package);
*state.ecs_mut().write_resource() = time_of_day;
// assert_eq!(world_map.len(), map_size.x * map_size.y);
let map_size = Vec2::new(1024, 1024);
let world_map_raw = vec![0u8; 4 * /*world_map.len()*/map_size.x * map_size.y];
// LittleEndian::write_u32_into(&world_map, &mut world_map_raw);
assert_eq!(world_map.len(), (map_size.x * map_size.y) as usize);
// let map_size = Vec2::new(1024, 1024);
let mut world_map_raw = vec![0u8; 4 * world_map.len()/*map_size.x * map_size.y*/];
LittleEndian::write_u32_into(&world_map, &mut world_map_raw);
log::debug!("Preparing image...");
let world_map = Arc::new(image::DynamicImage::ImageRgba8({
// Should not fail if the dimensions are correct.
let world_map = image::ImageBuffer::from_raw(
map_size.x as u32,
map_size.y as u32,
map_size.x,
map_size.y,
world_map_raw,
);
world_map.ok_or(Error::Other("Server sent a bad world map image".into()))?
}));
log::debug!("Done preparing image...");
(state, entity, server_info, world_map)
(state, entity, server_info, (world_map, map_size))
}
Some(ServerMsg::Error(ServerError::TooManyPlayers)) => {
return Err(Error::TooManyPlayers)

View File

@ -37,7 +37,7 @@ pub enum ServerMsg {
entity_package: sync::EntityPackage<EcsCompPacket>,
server_info: ServerInfo,
time_of_day: state::TimeOfDay,
// world_map: Vec2<usize>, /*, Vec<u32>)*/
world_map: (Vec2<u32>, Vec<u32>)
},
PlayerListUpdate(PlayerListUpdate),
StateAnswer(Result<ClientState, (RequestStateError, ClientState)>),

View File

@ -67,7 +67,7 @@ const SEND_TOK: Token = Token(3);
const RECV_TOK: Token = Token(4);
const MIDDLEMAN_TOK: Token = Token(5);
const MAX_MSG_BYTES: usize = 1 << 20;
const MAX_MSG_BYTES: usize = 1 << 24;
enum CtrlMsg {
Shutdown,

View File

@ -43,7 +43,7 @@ impl From<channel::TryRecvError> for Error {
pub trait PostMsg = Serialize + DeserializeOwned + 'static + Send;
const MAX_MSG_SIZE: usize = 1 << 20;
const MAX_MSG_SIZE: usize = 1 << 24;
pub struct PostOffice<S: PostMsg, R: PostMsg> {
listener: TcpListener,

View File

@ -1078,7 +1078,7 @@ impl Server {
.create_entity_package(entity),
server_info: self.server_info.clone(),
time_of_day: *self.state.ecs().read_resource(),
// world_map: (WORLD_SIZE/*, self.world.sim().get_map()*/),
world_map: (WORLD_SIZE.map(|e| e as u32), self.world.sim().get_map()),
});
log::debug!("Done initial sync with client.");

View File

@ -1,6 +1,6 @@
use super::{img_ids::Imgs, Fonts, Show, TEXT_COLOR};
use client::{self, Client};
use common::comp;
use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize};
use conrod_core::{
color,
image::Id,
@ -30,7 +30,7 @@ widget_ids! {
pub struct Map<'a> {
_show: &'a Show,
client: &'a Client,
_world_map: Id,
world_map: (Id, Vec2<u32>),
imgs: &'a Imgs,
fonts: &'a Fonts,
#[conrod(common_builder)]
@ -43,7 +43,7 @@ impl<'a> Map<'a> {
show: &'a Show,
client: &'a Client,
imgs: &'a Imgs,
world_map: Id,
world_map: (Id, Vec2<u32>),
fonts: &'a Fonts,
pulse: f32,
velocity: f32,
@ -51,7 +51,7 @@ impl<'a> Map<'a> {
Self {
_show: show,
imgs,
_world_map: world_map,
world_map,
client,
fonts: fonts,
common: widget::CommonBuilder::default(),
@ -159,7 +159,10 @@ impl<'a> Widget for Map<'a> {
}
// Map Image
Image::new(/*self.world_map*/ self.imgs.map_placeholder)
let (world_map, worldsize) = self.world_map;
let worldsize = worldsize.map2(TerrainChunkSize::RECT_SIZE, |e, f| e as f64 * f as f64);
Image::new(world_map/*self.imgs.map_placeholder*/)
.middle_of(state.ids.map_bg)
.color(Some(Color::Rgba(1.0, 1.0, 1.0, fade - 0.1)))
.w_h(700.0, 700.0)
@ -174,9 +177,8 @@ impl<'a> Widget for Map<'a> {
.get(self.client.entity())
.map_or(Vec3::zero(), |pos| pos.0);
let worldsize = 32768.0; // TODO This has to get the actual world size and not be hardcoded
let x = player_pos.x as f64 / worldsize * 700.0/*= x-Size of the map image*/;
let y = (/*1.0 -*/player_pos.y as f64 / worldsize) * 700.0;
let x = player_pos.x as f64 / worldsize.x * 700.0;
let y = (1.0 - player_pos.y as f64 / worldsize.y) * 700.0;
let indic_ani = (self.pulse * 6.0/*animation speed*/).cos()/*starts at 1.0*/ * 0.5 + 0.50; // changes the animation frame
let indic_scale = 1.2;
// Indicator

View File

@ -1,6 +1,6 @@
use super::{img_ids::Imgs, Fonts, Show, HP_COLOR, TEXT_COLOR};
use client::{self, Client};
use common::comp;
use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize};
use conrod_core::{
color,
image::Id,
@ -33,7 +33,7 @@ pub struct MiniMap<'a> {
client: &'a Client,
imgs: &'a Imgs,
_world_map: Id,
world_map: (Id, Vec2<u32>),
fonts: &'a Fonts,
#[conrod(common_builder)]
common: widget::CommonBuilder,
@ -46,7 +46,7 @@ impl<'a> MiniMap<'a> {
show: &'a Show,
client: &'a Client,
imgs: &'a Imgs,
world_map: Id,
world_map: (Id, Vec2<u32>),
fonts: &'a Fonts,
pulse: f32,
zoom: f32,
@ -55,7 +55,7 @@ impl<'a> MiniMap<'a> {
show,
client,
imgs,
_world_map: world_map,
world_map,
fonts: fonts,
common: widget::CommonBuilder::default(),
pulse,
@ -135,7 +135,9 @@ impl<'a> Widget for MiniMap<'a> {
}
}*/
// Map Image
Image::new(/*self.world_map*/ self.imgs.map_placeholder)
let (world_map, worldsize) = self.world_map;
let worldsize = worldsize.map2(TerrainChunkSize::RECT_SIZE, |e, f| e as f64 * f as f64);
Image::new(world_map/*self.imgs.map_placeholder*/)
.middle_of(state.ids.mmap_frame_bg)
.w_h(92.0 * 4.0 * zoom, 82.0 * 4.0 * zoom)
.parent(state.ids.mmap_frame_bg)
@ -149,9 +151,8 @@ impl<'a> Widget for MiniMap<'a> {
.get(self.client.entity())
.map_or(Vec3::zero(), |pos| pos.0);
let worldsize = 32768.0; // TODO This has to get the actual world size and not be hardcoded
let x = player_pos.x as f64 / worldsize * 92.0 * 4.0;
let y = (/*1.0X-*/player_pos.y as f64 / worldsize) * 82.0 * 4.0;
let x = player_pos.x as f64 / worldsize.x * 92.0 * 4.0;
let y = (1.0 - player_pos.y as f64 / worldsize.y) * 82.0 * 4.0;
let indic_ani = (self.pulse * 6.0).cos() * 0.5 + 0.5; //Animation timer
let indic_scale = 0.8;
// Indicator

View File

@ -425,7 +425,7 @@ impl Show {
pub struct Hud {
ui: Ui,
ids: Ids,
world_map: Id,
world_map: (Id, Vec2<u32>),
imgs: Imgs,
item_imgs: ItemImgs,
fonts: Fonts,
@ -454,7 +454,7 @@ impl Hud {
// Generate ids.
let ids = Ids::new(ui.id_generator());
// Load world map
let world_map = ui.add_graphic(Graphic::Image(client.world_map.clone()));
let world_map = (ui.add_graphic(Graphic::Image(client.world_map.0.clone())), client.world_map.1);
// Load images.
let imgs = Imgs::load(&mut ui).expect("Failed to load images!");
// Load rotation images.