diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/customer/mod.rs | 2 | ||||
| -rw-r--r-- | server/src/game.rs | 130 | ||||
| -rw-r--r-- | server/src/interaction.rs | 35 | ||||
| -rw-r--r-- | server/src/protocol.rs | 29 | 
4 files changed, 110 insertions, 86 deletions
diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index 9e0dd797..c29b4852 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -118,7 +118,7 @@ impl DemandState {                  id,                  PacketS::Join {                      name: faker::name::fr_fr::Name().fake(), -                    character: -1 - (random::<i16>() as i32), +                    character: -1 - (random::<u16>() as i32),                  },              ));              let chair = self.select_chair().ok_or(anyhow!("no free chair found"))?; diff --git a/server/src/game.rs b/server/src/game.rs index 54266351..711b66b5 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -18,8 +18,10 @@  use crate::{      customer::DemandState,      data::Gamedata, -    interaction::{interact, tick_tile, InteractEffect, TickEffect}, -    protocol::{ItemIndex, Message, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex}, +    interaction::{interact, tick_slot, InteractEffect, TickEffect}, +    protocol::{ +        ItemIndex, ItemLocation, Message, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex, +    },  };  use anyhow::{anyhow, bail, Result};  use glam::{IVec2, Vec2}; @@ -65,6 +67,7 @@ pub struct Game {      pub players: HashMap<PlayerID, Player>,      packet_out: VecDeque<PacketC>,      demand: Option<DemandState>, +    score_changed: bool,      pub points: i64,      end: Option<Instant>,  } @@ -78,6 +81,7 @@ impl Game {              tiles: Default::default(),              demand: None,              end: None, +            score_changed: false,              points: 0,          }      } @@ -166,8 +170,8 @@ impl Game {                  name: player.name.clone(),              });              if let Some(item) = &player.item { -                out.push(PacketC::SetPlayerItem { -                    player: id, +                out.push(PacketC::SetItem { +                    location: ItemLocation::Player(id),                      item: Some(item.kind),                  })              } @@ -191,8 +195,8 @@ impl Game {                  kind: Some(tdata.kind.clone()),              });              if let Some(item) = &tdata.item { -                out.push(PacketC::SetTileItem { -                    tile, +                out.push(PacketC::SetItem { +                    location: ItemLocation::Tile(tile),                      item: Some(item.kind),                  })              } @@ -250,8 +254,8 @@ impl Game {                      let pos = p.position.floor().as_ivec2();                      if let Some(tile) = self.tiles.get_mut(&pos) {                          if tile.item.is_none() { -                            self.packet_out.push_back(PacketC::SetTileItem { -                                tile: pos, +                            self.packet_out.push_back(PacketC::SetItem { +                                location: ItemLocation::Tile(pos),                                  item: Some(item.kind),                              });                              tile.item = Some(item); @@ -325,76 +329,59 @@ impl Game {                  if let Some(effect) = interact(                      &self.data,                      edge, -                    tile.kind, +                    Some(tile.kind),                      &mut tile.item,                      &mut player.item,                      &mut self.points,                  ) {                      match effect { -                        InteractEffect::Put => self.packet_out.push_back(PacketC::PutItem { -                            player: pid, -                            tile: pos, +                        InteractEffect::Put => self.packet_out.push_back(PacketC::MoveItem { +                            from: ItemLocation::Player(pid), +                            to: ItemLocation::Tile(pos),                          }), -                        InteractEffect::Take => self.packet_out.push_back(PacketC::TakeItem { -                            player: pid, -                            tile: pos, +                        InteractEffect::Take => self.packet_out.push_back(PacketC::MoveItem { +                            from: ItemLocation::Tile(pos), +                            to: ItemLocation::Player(pid),                          }),                          InteractEffect::Produce => {                              if tile_had_item { -                                self.packet_out.push_back(PacketC::SetActive { -                                    tile: pos, +                                self.packet_out.push_back(PacketC::SetProgress { +                                    item: ItemLocation::Tile(pos),                                      progress: None,                                      warn: false,                                  }); -                                self.packet_out.push_back(PacketC::SetTileItem { -                                    tile: pos, +                                self.packet_out.push_back(PacketC::SetItem { +                                    location: ItemLocation::Tile(pos),                                      item: None,                                  });                              }                              if player_had_item { -                                self.packet_out.push_back(PacketC::PutItem { -                                    player: pid, -                                    tile: pos, +                                self.packet_out.push_back(PacketC::MoveItem { +                                    from: ItemLocation::Player(pid), +                                    to: ItemLocation::Tile(pos),                                  }); -                                self.packet_out.push_back(PacketC::SetTileItem { -                                    tile: pos, +                                self.packet_out.push_back(PacketC::SetItem { +                                    location: ItemLocation::Tile(pos),                                      item: None,                                  });                              }                              if let Some(i) = &player.item { -                                self.packet_out.push_back(PacketC::SetTileItem { -                                    tile: pos, +                                self.packet_out.push_back(PacketC::SetItem { +                                    location: ItemLocation::Tile(pos),                                      item: Some(i.kind),                                  }); -                                self.packet_out.push_back(PacketC::TakeItem { -                                    player: pid, -                                    tile: pos, +                                self.packet_out.push_back(PacketC::MoveItem { +                                    from: ItemLocation::Tile(pos), +                                    to: ItemLocation::Player(pid),                                  })                              }                              if let Some(i) = &tile.item { -                                self.packet_out.push_back(PacketC::SetTileItem { -                                    tile: pos, +                                self.packet_out.push_back(PacketC::SetItem { +                                    location: ItemLocation::Tile(pos),                                      item: Some(i.kind),                                  });                              } -                            self.packet_out.push_back({ -                                PacketC::Score { -                                    time_remaining: self -                                        .end -                                        .map(|t| (t - Instant::now()).as_secs_f32()), -                                    points: self.points, -                                    demands_failed: self -                                        .demand -                                        .as_ref() -                                        .map(|d| d.failed) -                                        .unwrap_or_default(), -                                    demands_completed: self -                                        .demand -                                        .as_ref() -                                        .map(|d| d.completed) -                                        .unwrap_or_default(), -                                } -                            }) +                            self.score_changed = true                          }                      }                  } @@ -423,10 +410,17 @@ impl Game {                      kind: i,                      active: None,                  }); -                self.packet_out -                    .push_back(PacketC::SetPlayerItem { player, item }) +                self.packet_out.push_back(PacketC::SetItem { +                    location: ItemLocation::Player(player), +                    item, +                })              }          } + +        if self.score_changed { +            self.score_changed = false; +            self.packet_out.push_back(self.score()) +        }          Ok(())      } @@ -455,11 +449,11 @@ impl Game {          }          for (&pos, tile) in &mut self.tiles { -            if let Some(effect) = tick_tile(dt, &self.data, tile) { +            if let Some(effect) = tick_slot(dt, &self.data, Some(tile.kind), &mut tile.item) {                  match effect { -                    TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetActive { +                    TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress {                          warn, -                        tile: pos, +                        item: ItemLocation::Tile(pos),                          progress: tile                              .item                              .as_ref() @@ -469,8 +463,8 @@ impl Game {                              .map(|i| i.progress),                      }),                      TickEffect::Produce => { -                        self.packet_out.push_back(PacketC::SetTileItem { -                            tile: pos, +                        self.packet_out.push_back(PacketC::SetItem { +                            location: ItemLocation::Tile(pos),                              item: tile.item.as_ref().map(|i| i.kind),                          });                      } @@ -478,6 +472,30 @@ impl Game {              }          } +        for (&pid, player) in &mut self.players { +            if let Some(effect) = tick_slot(dt, &self.data, None, &mut player.item) { +                match effect { +                    TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress { +                        warn, +                        item: ItemLocation::Player(pid), +                        progress: player +                            .item +                            .as_ref() +                            .unwrap() +                            .active +                            .as_ref() +                            .map(|i| i.progress), +                    }), +                    TickEffect::Produce => { +                        self.packet_out.push_back(PacketC::SetItem { +                            location: ItemLocation::Player(pid), +                            item: player.item.as_ref().map(|i| i.kind), +                        }); +                    } +                } +            } +        } +          return self.end.map(|t| t < Instant::now()).unwrap_or_default();      }  } diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 69fc9e70..85df9925 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -17,7 +17,7 @@  */  use crate::{      data::Gamedata, -    game::{Involvement, Item, Tile}, +    game::{Involvement, Item},      protocol::{ItemIndex, TileIndex},  };  use log::info; @@ -96,12 +96,12 @@ impl Recipe {              }          }      } -    pub fn supports_tile(&self, tile: TileIndex) -> bool { +    pub fn supports_tile(&self, tile: Option<TileIndex>) -> bool {          if let Some(tile_constraint) = self.tile() { -            if tile != tile_constraint { -                false +            if let Some(tile) = tile { +                tile == tile_constraint              } else { -                true +                false              }          } else {              true @@ -118,17 +118,19 @@ pub enum InteractEffect {  pub fn interact(      data: &Gamedata,      edge: bool, -    tile_kind: TileIndex, +    tile: Option<TileIndex>,      this: &mut Option<Item>,      other: &mut Option<Item>,      points: &mut i64,  ) -> Option<InteractEffect> { -    let interactable = data.is_tile_interactable(tile_kind); +    let interactable = tile +        .map(|tile| data.is_tile_interactable(tile)) +        .unwrap_or(true);      if interactable && other.is_none() {          if let Some(item) = this {              if let Some(active) = &mut item.active {                  let recipe = &data.recipe(active.recipe); -                if recipe.supports_tile(tile_kind) { +                if recipe.supports_tile(tile) {                      if let Recipe::Active { outputs, .. } = recipe {                          if edge {                              active.working += 1; @@ -150,7 +152,7 @@ pub fn interact(      }      if interactable {          for (ri, recipe) in data.recipes() { -            if !recipe.supports_tile(tile_kind) { +            if !recipe.supports_tile(tile) {                  continue;              }              match recipe { @@ -233,18 +235,23 @@ pub enum TickEffect {      Progress(bool),      Produce,  } -pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect> { -    if let Some(item) = &mut tile.item { +pub fn tick_slot( +    dt: f32, +    data: &Gamedata, +    tile: Option<TileIndex>, +    slot: &mut Option<Item>, +) -> Option<TickEffect> { +    if let Some(item) = slot {          if let Some(a) = &mut item.active {              let r = &data.recipe(a.recipe); -            if r.supports_tile(tile.kind) { +            if r.supports_tile(tile) {                  a.progress += a.working as f32 * dt / r.duration().unwrap();              } else if let Some(revert_duration) = r.revert_duration() {                  a.progress -= dt / revert_duration;              }              if a.progress >= 1. {                  if let Recipe::Passive { output, .. } = &data.recipe(a.recipe) { -                    tile.item = output.map(|kind| Item { kind, active: None }); +                    *slot = output.map(|kind| Item { kind, active: None });                      return Some(TickEffect::Produce);                  };                  a.progress = 1.; @@ -255,7 +262,7 @@ pub fn tick_tile(dt: f32, data: &Gamedata, tile: &mut Tile) -> Option<TickEffect              return Some(TickEffect::Progress(r.warn()));          } else {              for (ri, recipe) in data.recipes() { -                if recipe.supports_tile(tile.kind) { +                if recipe.supports_tile(tile) {                      if let Recipe::Passive { input, .. } = recipe {                          if *input == item.kind {                              item.active = Some(Involvement { diff --git a/server/src/protocol.rs b/server/src/protocol.rs index 176eb31b..54992feb 100644 --- a/server/src/protocol.rs +++ b/server/src/protocol.rs @@ -99,24 +99,16 @@ pub enum PacketC {          pos: Vec2,          rot: f32,      }, -    TakeItem { -        tile: IVec2, -        player: PlayerID, -    }, -    PutItem { -        player: PlayerID, -        tile: IVec2, -    }, -    SetTileItem { -        tile: IVec2, -        item: Option<ItemIndex>, +    MoveItem { +        from: ItemLocation, +        to: ItemLocation,      }, -    SetPlayerItem { -        player: PlayerID, +    SetItem { +        location: ItemLocation,          item: Option<ItemIndex>,      }, -    SetActive { -        tile: IVec2, +    SetProgress { +        item: ItemLocation,          progress: Option<f32>,          warn: bool,      }, @@ -150,3 +142,10 @@ pub enum PacketC {          message: String,      },  } + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "snake_case")] +pub enum ItemLocation { +    Tile(IVec2), +    Player(PlayerID), +}  |