diff options
-rw-r--r-- | data/map.yaml | 33 | ||||
-rw-r--r-- | server/src/customer/mod.rs | 2 | ||||
-rw-r--r-- | server/src/data.rs | 28 | ||||
-rw-r--r-- | server/src/interaction.rs | 100 |
4 files changed, 99 insertions, 64 deletions
diff --git a/data/map.yaml b/data/map.yaml index de121cc4..cef040cc 100644 --- a/data/map.yaml +++ b/data/map.yaml @@ -3,26 +3,18 @@ map: - "|ctc.ctc.ctc.ctc.ctc.|" - "|.....c..............|" - "|c...c...+--www---dd-+" - - "|tc.ctc..|SS...CC#..X|" + - "|tc.ctc..|ss...CC#..X|" - "|c...c...w........~.R|" - "|c.......w..######..T|" - "|tc......w..........F|" - - "|c.....ct|##ss#oo####|" + - "|c.....ct|##SS#oo####|" - "+---dd---+-----------+" - "......................" - ".........!............" - "......................" tiles: - "~": floor - "!": floor - ".": floor - "+": wall - "-": wall - "|": wall - "d": door "t": table - "c": chair "#": counter "w": window "s": sink @@ -34,10 +26,27 @@ tiles: "F": flour-crate "D": dirty-plate-crate "X": trash + + "c": chair + "~": floor + "!": floor + ".": floor + "d": door -chef_spawn: "~" -customer_spawn: "!" + "+": wall + "-": wall + "|": wall items: "S": pot "w": plate + +chef_spawn: "~" +customer_spawn: "!" + +walkable: + - door + - floor + - chair +collider: + - wall diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index fa67de57..4b715c78 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -78,7 +78,7 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack } PacketC::UpdateMap { pos, tile, .. } => { let tilename = state.demand.data.tile_name(tile); - if tilename == "floor" || tilename == "door" || tilename == "chair" { + if !state.demand.data.is_tile_colliding(tile) { state.walkable.insert(pos); } if tilename == "chair" { diff --git a/server/src/data.rs b/server/src/data.rs index 9c200e5b..fd6f266d 100644 --- a/server/src/data.rs +++ b/server/src/data.rs @@ -33,6 +33,8 @@ pub struct InitialMap { map: Vec<String>, tiles: HashMap<char, String>, items: HashMap<char, String>, + collider: Vec<String>, + walkable: Vec<String>, chef_spawn: char, customer_spawn: char, } @@ -57,6 +59,8 @@ pub struct Gamedata { pub demands: Vec<Demand>, pub item_names: Vec<String>, pub tile_names: Vec<String>, + pub tile_collide: Vec<bool>, + pub tile_interact: Vec<bool>, #[serde(skip)] pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>, pub chef_spawn: Vec2, @@ -138,12 +142,26 @@ pub fn build_gamedata( } } + let item_names = item_names.into_inner().unwrap(); + let tile_names = tile_names.into_inner().unwrap(); + + let tile_collide = tile_names + .iter() + .map(|i| !map_in.walkable.contains(i)) + .collect(); + let tile_interact = tile_names + .iter() + .map(|i| !map_in.collider.contains(i) && !map_in.walkable.contains(i)) + .collect(); + Gamedata { demands, + tile_collide, + tile_interact, recipes, initial_map, - item_names: item_names.into_inner().unwrap(), - tile_names: tile_names.into_inner().unwrap(), + item_names, + tile_names, chef_spawn, customer_spawn, } @@ -164,6 +182,12 @@ impl Gamedata { pub fn tile_name(&self, index: TileIndex) -> &String { &self.tile_names[index.0] } + pub fn is_tile_colliding(&self, index: TileIndex) -> bool { + self.tile_collide[index.0] + } + pub fn is_tile_interactable(&self, index: TileIndex) -> bool { + self.tile_interact[index.0] + } pub fn item_name(&self, index: ItemIndex) -> &String { &self.item_names[index.0] } diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 93f54b2d..7f694ad8 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -87,7 +87,8 @@ pub fn interact( tile: &mut Tile, player: &mut Player, ) -> Option<InteractEffect> { - if player.item.is_none() { + let interactable = data.is_tile_interactable(tile.kind); + if interactable && player.item.is_none() { if let Some(item) = &mut tile.item { if let Some(active) = &mut item.active { let recipe = &data.recipe(active.recipe); @@ -111,66 +112,67 @@ pub fn interact( if !edge { return None; } - - for (ri, recipe) in data.recipes() { - if !recipe.supports_tile(tile.kind) { - continue; - } - match recipe { - Recipe::Active { input, .. } => { - if player.item.is_none() { - if let Some(item) = &mut tile.item { - if item.kind == *input { - if item.active.is_none() { - info!("start active recipe {ri:?}"); - item.active = Some(Involvement { - recipe: ri, - working: 1, - progress: 0., - }); + if interactable { + for (ri, recipe) in data.recipes() { + if !recipe.supports_tile(tile.kind) { + continue; + } + match recipe { + Recipe::Active { input, .. } => { + if player.item.is_none() { + if let Some(item) = &mut tile.item { + if item.kind == *input { + if item.active.is_none() { + info!("start active recipe {ri:?}"); + item.active = Some(Involvement { + recipe: ri, + working: 1, + progress: 0., + }); + } } } } - } - if tile.item.is_none() { - if let Some(item) = &player.item { - if item.kind == *input { - let mut item = player.item.take().unwrap(); - if let Some(active) = &mut item.active { - active.working += 1; - } else { - info!("start active recipe {ri:?}"); - item.active = Some(Involvement { - recipe: ri, - working: 1, - progress: 0., - }); + if tile.item.is_none() { + if let Some(item) = &player.item { + if item.kind == *input { + let mut item = player.item.take().unwrap(); + if let Some(active) = &mut item.active { + active.working += 1; + } else { + info!("start active recipe {ri:?}"); + item.active = Some(Involvement { + recipe: ri, + working: 1, + progress: 0., + }); + } + tile.item = Some(item); + return Some(InteractEffect::Put); } - tile.item = Some(item); - return Some(InteractEffect::Put); } } } - } - Recipe::Instant { - inputs, outputs, .. - } => { - let on_tile = tile.item.as_ref().map(|i| i.kind); - let in_hand = player.item.as_ref().map(|i| i.kind); - let ok = (inputs[0] == on_tile && inputs[1] == in_hand) - || (inputs[1] == on_tile && inputs[0] == in_hand); - if ok { - info!("instant recipe {ri:?}"); - player.item = outputs[0].map(|kind| Item { kind, active: None }); - tile.item = outputs[1].map(|kind| Item { kind, active: None }); - return Some(InteractEffect::Produce); + Recipe::Instant { + inputs, outputs, .. + } => { + let on_tile = tile.item.as_ref().map(|i| i.kind); + let in_hand = player.item.as_ref().map(|i| i.kind); + let ok = (inputs[0] == on_tile && inputs[1] == in_hand) + || (inputs[1] == on_tile && inputs[0] == in_hand); + if ok { + info!("instant recipe {ri:?}"); + player.item = outputs[0].map(|kind| Item { kind, active: None }); + tile.item = outputs[1].map(|kind| Item { kind, active: None }); + return Some(InteractEffect::Produce); + } } + _ => (), } - _ => (), } } - if tile.item.is_none() { + if interactable && tile.item.is_none() { if let Some(item) = player.item.take() { tile.item = Some(item); return Some(InteractEffect::Put); |