aboutsummaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-02 00:52:42 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-02 00:52:42 +0200
commit8ee3eca5d6de0b950881783821d1be86cd0586d5 (patch)
tree15bfb6fafe9642260fbfcf874f17a2f89afe6b72 /server/src
parenta57c833665172c83eb449f739073ac36238377c9 (diff)
downloadhurrycurry-8ee3eca5d6de0b950881783821d1be86cd0586d5.tar
hurrycurry-8ee3eca5d6de0b950881783821d1be86cd0586d5.tar.bz2
hurrycurry-8ee3eca5d6de0b950881783821d1be86cd0586d5.tar.zst
generalize protocol
Diffstat (limited to 'server/src')
-rw-r--r--server/src/game.rs104
-rw-r--r--server/src/interaction.rs35
-rw-r--r--server/src/protocol.rs29
3 files changed, 84 insertions, 84 deletions
diff --git a/server/src/game.rs b/server/src/game.rs
index 54266351..274a1917 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -19,7 +19,9 @@ use crate::{
customer::DemandState,
data::Gamedata,
interaction::{interact, tick_tile, InteractEffect, TickEffect},
- protocol::{ItemIndex, Message, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex},
+ 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_tile(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),
});
}
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index 69fc9e70..adbd3b43 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_tile(
+ 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),
+}