diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-02 14:57:22 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-02 14:57:22 +0200 |
commit | f15d6305a7f70e34ba1e5484d4f185d844cc3aaa (patch) | |
tree | dff0fd75749312084ab6210435af35132687bce6 /server/src/game.rs | |
parent | 9cffa5019b017045b7dbdf6577c89b70b8a11a50 (diff) | |
download | hurrycurry-f15d6305a7f70e34ba1e5484d4f185d844cc3aaa.tar hurrycurry-f15d6305a7f70e34ba1e5484d4f185d844cc3aaa.tar.bz2 hurrycurry-f15d6305a7f70e34ba1e5484d4f185d844cc3aaa.tar.zst |
interaction between players
Diffstat (limited to 'server/src/game.rs')
-rw-r--r-- | server/src/game.rs | 183 |
1 files changed, 115 insertions, 68 deletions
diff --git a/server/src/game.rs b/server/src/game.rs index 711b66b5..838a71e4 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -67,7 +67,6 @@ pub struct Game { pub players: HashMap<PlayerID, Player>, packet_out: VecDeque<PacketC>, demand: Option<DemandState>, - score_changed: bool, pub points: i64, end: Option<Instant>, } @@ -81,7 +80,6 @@ impl Game { tiles: Default::default(), demand: None, end: None, - score_changed: false, points: 0, } } @@ -219,6 +217,8 @@ impl Game { } } pub fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> { + let points_before = self.points; + match packet { PacketS::Join { name, character } => { let position = if player.0 < 0 { @@ -306,7 +306,7 @@ impl Game { let pid = player; let player = self .players - .get_mut(&player) + .get_mut(&pid) .ok_or(anyhow!("player does not exist"))?; let tile = self .tiles @@ -319,74 +319,55 @@ impl Game { if !edge && player.interacting != Some(pos) { bail!("already not interacting here") } - if edge && (pos.as_vec2() + Vec2::splat(0.5)).distance(player.position) > 2. { + let entpos = pos.as_vec2() + Vec2::splat(0.5); + if edge && entpos.distance(player.position) > 2. { bail!("interacting too far from player"); } + player.interacting = if edge { Some(pos) } else { None }; - let tile_had_item = tile.item.is_some(); - let player_had_item = player.item.is_some(); + let other_pid = if !self.data.is_tile_interactable(tile.kind) { + self.players + .iter() + .find(|(id, p)| **id != pid && p.position.distance(entpos) < 0.7) + .map(|(&id, _)| id) + } else { + None + }; - if let Some(effect) = interact( - &self.data, - edge, - Some(tile.kind), - &mut tile.item, - &mut player.item, - &mut self.points, - ) { - match effect { - 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::MoveItem { - from: ItemLocation::Tile(pos), - to: ItemLocation::Player(pid), - }), - InteractEffect::Produce => { - if tile_had_item { - self.packet_out.push_back(PacketC::SetProgress { - item: ItemLocation::Tile(pos), - progress: None, - warn: false, - }); - self.packet_out.push_back(PacketC::SetItem { - location: ItemLocation::Tile(pos), - item: None, - }); - } - if player_had_item { - self.packet_out.push_back(PacketC::MoveItem { - from: ItemLocation::Player(pid), - to: ItemLocation::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::SetItem { - location: ItemLocation::Tile(pos), - item: Some(i.kind), - }); - 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::SetItem { - location: ItemLocation::Tile(pos), - item: Some(i.kind), - }); - } - self.score_changed = true - } - } - } + if let Some(base_pid) = other_pid { + let [other, this] = self + .players + .get_many_mut([&pid, &base_pid]) + .ok_or(anyhow!("interacting with yourself. this is impossible"))?; + interact_effect( + &self.data, + edge, + &mut this.item, + ItemLocation::Player(base_pid), + &mut other.item, + ItemLocation::Player(pid), + None, + &mut self.packet_out, + &mut self.points, + ) + } else { + let player = self + .players + .get_mut(&pid) + .ok_or(anyhow!("player does not exist"))?; - player.interacting = if edge { Some(pos) } else { None }; + interact_effect( + &self.data, + edge, + &mut tile.item, + ItemLocation::Tile(pos), + &mut player.item, + ItemLocation::Player(pid), + Some(tile.kind), + &mut self.packet_out, + &mut self.points, + ) + } } PacketS::Communicate { message, persist } => { info!("{player:?} message {message:?}"); @@ -417,8 +398,7 @@ impl Game { } } - if self.score_changed { - self.score_changed = false; + if self.points != points_before { self.packet_out.push_back(self.score()) } Ok(()) @@ -505,3 +485,70 @@ impl From<TileIndex> for Tile { Self { kind, item: None } } } + +fn interact_effect( + data: &Gamedata, + edge: bool, + this: &mut Option<Item>, + this_loc: ItemLocation, + other: &mut Option<Item>, + other_loc: ItemLocation, + this_tile_kind: Option<TileIndex>, + packet_out: &mut VecDeque<PacketC>, + points: &mut i64, +) { + let this_had_item = this.is_some(); + let other_had_item = other.is_some(); + + if let Some(effect) = interact(&data, edge, this_tile_kind, this, other, points) { + match effect { + InteractEffect::Put => packet_out.push_back(PacketC::MoveItem { + from: other_loc, + to: this_loc, + }), + InteractEffect::Take => packet_out.push_back(PacketC::MoveItem { + from: this_loc, + to: other_loc, + }), + InteractEffect::Produce => { + if this_had_item { + packet_out.push_back(PacketC::SetProgress { + item: this_loc, + progress: None, + warn: false, + }); + packet_out.push_back(PacketC::SetItem { + location: this_loc, + item: None, + }); + } + if other_had_item { + packet_out.push_back(PacketC::MoveItem { + from: other_loc, + to: this_loc, + }); + packet_out.push_back(PacketC::SetItem { + location: this_loc, + item: None, + }); + } + if let Some(i) = &other { + packet_out.push_back(PacketC::SetItem { + location: this_loc, + item: Some(i.kind), + }); + packet_out.push_back(PacketC::MoveItem { + from: this_loc, + to: other_loc, + }) + } + if let Some(i) = &this { + packet_out.push_back(PacketC::SetItem { + location: this_loc, + item: Some(i.kind), + }); + } + } + } + } +} |