diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-10 17:16:03 +0100 |
|---|---|---|
| committer | tpart <tpart120@proton.me> | 2026-02-26 20:48:35 +0100 |
| commit | b634bad931f530ee0a207e1461ffc5e52ebb83e3 (patch) | |
| tree | 90a45e8c67e6a7c66e49c7409f0c37881eade96e /server/game-core | |
| parent | 0ed9e8387a66b3af78412feea62fdc8b9804f793 (diff) | |
| download | hurrycurry-b634bad931f530ee0a207e1461ffc5e52ebb83e3.tar hurrycurry-b634bad931f530ee0a207e1461ffc5e52ebb83e3.tar.bz2 hurrycurry-b634bad931f530ee0a207e1461ffc5e52ebb83e3.tar.zst | |
compiles with tile stacks
Diffstat (limited to 'server/game-core')
| -rw-r--r-- | server/game-core/src/gamedata_index.rs | 2 | ||||
| -rw-r--r-- | server/game-core/src/interaction.rs | 30 | ||||
| -rw-r--r-- | server/game-core/src/lib.rs | 85 |
3 files changed, 72 insertions, 45 deletions
diff --git a/server/game-core/src/gamedata_index.rs b/server/game-core/src/gamedata_index.rs index 8aa5e4af..d4bbcce1 100644 --- a/server/game-core/src/gamedata_index.rs +++ b/server/game-core/src/gamedata_index.rs @@ -30,7 +30,7 @@ impl GamedataIndex { self.tile_collide.clear(); for tile in (0..data.tile_names.len()).map(TileIndex) { - self.tile_collide.push(!data.tile_walkable.contains(&tile)); + self.tile_collide.push(!data.tile_collide.contains(&tile)); } for (ri, r) in data.recipes() { diff --git a/server/game-core/src/interaction.rs b/server/game-core/src/interaction.rs index 275e87d1..28efc43e 100644 --- a/server/game-core/src/interaction.rs +++ b/server/game-core/src/interaction.rs @@ -33,9 +33,13 @@ impl Game { ItemLocation::Player(pid, _) => Some(pid), _ => None, }; - let this_tile_kind = match this_loc { - ItemLocation::Tile(t) => self.tiles.get(&t).map(|t| t.kind), - _ => None, + let this_tile_parts = match this_loc { + ItemLocation::Tile(t) => self + .tiles + .get(&t) + .map(|t| t.parts.clone()) + .unwrap_or_default(), + _ => Vec::new(), }; let (this_slot, other_slot) = match (this_loc, other_loc) { @@ -94,7 +98,7 @@ impl Game { && let Some(inv) = &mut item.active { let recipe = &self.data.recipe(inv.recipe); - if recipe.supports_tile(this_tile_kind) + if this_tile_parts.iter().any(|p| recipe.supports_tile(*p)) && let Recipe::Active { outputs, speed, .. } = recipe { if edge { @@ -142,7 +146,7 @@ impl Game { return Ok(()); } for (ri, recipe) in self.data.recipes() { - if !recipe.supports_tile(this_tile_kind) { + if !this_tile_parts.iter().any(|p| recipe.supports_tile(*p)) { continue; } match recipe { @@ -238,7 +242,7 @@ impl Game { } let can_place = automated - || this_tile_kind.is_none_or(|tile| { + || this_tile_parts.iter().any(|tile| { other_slot.as_ref().is_some_and(|other| { self.data .tile_placeable_items @@ -276,9 +280,13 @@ impl Game { } pub fn tick_slot(&mut self, loc: ItemLocation, dt: f32) -> Result<(), TrError> { - let tile = match loc { - ItemLocation::Tile(t) => self.tiles.get(&t).map(|t| t.kind), - _ => None, + let parts = match loc { + ItemLocation::Tile(t) => self + .tiles + .get(&t) + .map(|t| t.parts.clone()) + .unwrap_or_default(), + _ => Vec::new(), }; let slot = match loc { ItemLocation::Tile(p) => { @@ -303,7 +311,7 @@ impl Game { let r = &self.data.recipe(a.recipe); let prev_speed = a.speed; - if r.supports_tile(tile) { + if parts.iter().any(|p| r.supports_tile(*p)) { if a.speed <= 0. && let Recipe::Passive { speed, .. } = &self.data.recipe(a.recipe) { @@ -355,7 +363,7 @@ impl Game { } else if let Some(recipes) = self.data_index.recipe_passive_by_input.get(&item.kind) { for &ri in recipes { let recipe = self.data.recipe(ri); - if recipe.supports_tile(tile) + if parts.iter().any(|p| recipe.supports_tile(*p)) && let Recipe::Passive { input, warn, speed, .. } = recipe diff --git a/server/game-core/src/lib.rs b/server/game-core/src/lib.rs index a0d4d05d..bee97652 100644 --- a/server/game-core/src/lib.rs +++ b/server/game-core/src/lib.rs @@ -47,7 +47,7 @@ pub struct Item { } pub struct Tile { - pub kind: TileIndex, + pub parts: Vec<TileIndex>, pub item: Option<Item>, } @@ -82,6 +82,7 @@ pub struct Game { pub item_locations_index: HashSet<ItemLocation>, pub events: VecDeque<PacketC>, + pub map_changes: HashSet<IVec2>, } impl Game { @@ -165,12 +166,10 @@ impl Game { }); } } - PacketC::UpdateMap { - tile, - kind, - neighbors: _, - } => { - self.set_tile(tile, kind); + PacketC::UpdateMap { changes } => { + for (pos, tiles) in changes { + self.set_tile(pos, tiles); + } } PacketC::Communicate { player, @@ -196,32 +195,58 @@ impl Game { } } - pub fn set_tile(&mut self, pos: IVec2, kind: Option<TileIndex>) { + pub fn set_tile(&mut self, pos: IVec2, parts: Vec<TileIndex>) { self.tiles.remove(&pos); self.walkable.remove(&pos); - if let Some(prev) = self.tiles.get(&pos) - && let Some(set) = self.tile_index.get_mut(&prev.kind) - { - set.remove(&pos); - } - if let Some(kind) = kind { - self.tiles.insert(pos, Tile { kind, item: None }); - if !self.data_index.tile_collide[kind.0] { - self.walkable.insert(pos); + if let Some(prev) = self.tiles.get(&pos) { + for &part in &prev.parts { + self.tile_index.entry(part).or_default().remove(&pos); } - self.tile_index.entry(kind).or_default().insert(pos); } - self.events.push_back(PacketC::UpdateMap { - tile: pos, - kind, - neighbors: [ - self.tiles.get(&(pos + IVec2::NEG_Y)).map(|e| e.kind), - self.tiles.get(&(pos + IVec2::NEG_X)).map(|e| e.kind), - self.tiles.get(&(pos + IVec2::Y)).map(|e| e.kind), - self.tiles.get(&(pos + IVec2::X)).map(|e| e.kind), - ], + if self.data.walkable(&parts) { + self.walkable.insert(pos); + } + for &part in &parts { + self.tile_index.entry(part).or_default().insert(pos); + } + if !parts.is_empty() { + self.tiles.insert(pos, Tile { parts, item: None }); + } + self.map_changes.insert(pos); + } + pub fn add_tile_part(&mut self, pos: IVec2, part: TileIndex) { + self.map_changes.insert(pos); + let tile = self.tiles.entry(pos).or_insert(Tile { + item: None, + parts: vec![], }); + if tile.parts.contains(&part) { + return; + } + tile.parts.push(part); + self.tile_index.entry(part).or_default().insert(pos); + self.walkable.remove(&pos); + if self.data.walkable(&tile.parts) { + self.walkable.insert(pos); + } } + pub fn remove_tile_part(&mut self, pos: IVec2, part: TileIndex) { + let Some(tile) = self.tiles.get_mut(&pos) else { + return; + }; + let lb = tile.parts.len(); + tile.parts.retain(|&p| p != part); + if tile.parts.len() == lb { + return; + } + self.map_changes.insert(pos); + self.tile_index.entry(part).or_default().remove(&pos); + self.walkable.remove(&pos); + if self.data.walkable(&tile.parts) { + self.walkable.insert(pos); + } + } + pub fn set_item(&mut self, pos: IVec2, kind: Option<ItemIndex>) { let Some(tile) = self.tiles.get_mut(&pos) else { return; @@ -292,9 +317,3 @@ impl Game { PlayerID(self.player_id_counter) } } - -impl From<TileIndex> for Tile { - fn from(kind: TileIndex) -> Self { - Self { kind, item: None } - } -} |