aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-07-07 21:17:21 +0200
committermetamuffin <metamuffin@disroot.org>2024-07-07 21:17:21 +0200
commit1406127825e30514dc13909c583895fd682c7107 (patch)
tree483ccbfd98eb7ef47d7684562f0adbbee51a67e6
parentf88a296aac8840f713031b5b716b8d9fa3e18b8c (diff)
downloadhurrycurry-1406127825e30514dc13909c583895fd682c7107.tar
hurrycurry-1406127825e30514dc13909c583895fd682c7107.tar.bz2
hurrycurry-1406127825e30514dc13909c583895fd682c7107.tar.zst
add bus map and tile entities
-rw-r--r--data/index.yaml1
-rw-r--r--data/maps/bus.yaml84
-rw-r--r--data/maps/test.yaml6
-rw-r--r--server/src/data.rs20
-rw-r--r--server/src/entity/conveyor.rs7
-rw-r--r--server/src/entity/mod.rs56
-rw-r--r--server/src/game.rs16
-rw-r--r--server/src/interaction.rs8
-rw-r--r--server/src/lib.rs4
-rw-r--r--test-client/main.ts5
-rw-r--r--test-client/tiles.ts1
11 files changed, 169 insertions, 39 deletions
diff --git a/data/index.yaml b/data/index.yaml
index 05e2de9d..f7abdb3b 100644
--- a/data/index.yaml
+++ b/data/index.yaml
@@ -14,6 +14,7 @@ maps:
- depot
- line
- teeny
+ - bus
recipes:
- none
diff --git a/data/maps/bus.yaml b/data/maps/bus.yaml
new file mode 100644
index 00000000..cfac1380
--- /dev/null
+++ b/data/maps/bus.yaml
@@ -0,0 +1,84 @@
+map:
+ - "''''''''''''''''''''"
+ - "'███████c__c███████'"
+ - "'█#SSSS█t__t█RTFL.█'"
+ - "'█#....█c__c█.....█'"
+ - "'d.....█'__'█.....d'"
+ - "'█...>>>>»»>>>v...█'"
+ - "'█oo.A██▒dd▒██v...█'"
+ - "'████A█.c..c.█v████'"
+ - "'''''A▒ct..tc▒v'''''"
+ - "'''''A<......v<'''''"
+ - "'''''>A......>v'''''"
+ - "'''''A▒ct..tc▒v'''''"
+ - "'████A█.c..c.█v████'"
+ - "'█#..A██▒dd▒██v.pp█'"
+ - "'█#..A<<<««<<<<..p█'"
+ - "'d.....█'__'█.....d'"
+ - "'█.....█'__'█....p█'"
+ - "'█ff#CC█'__'█Xsspp█'"
+ - "'███████'__'███████'"
+ - "'''''''''__'''''''''"
+ - "'''''''''__'''''''''"
+ - "'''''''''!~'''''''''"
+
+tiles:
+ "#": counter
+ "f": counter
+ "p": counter
+ ">": conveyor
+ "<": conveyor
+ "A": conveyor
+ "v": conveyor
+ "t": table
+ "w": counter-window
+ "s": sink
+ "o": oven
+ "S": stove
+ "C": cuttingboard
+ "R": raw-steak-crate
+ "T": tomato-crate
+ "F": flour-crate
+ "L": leek-crate
+ "X": trash
+
+ "c": chair
+ ".": floor
+ "'": grass
+ "*": tree
+ "~": path
+ "!": path
+ "_": path
+ "«": path
+ "»": path
+ "d": door
+ "█": wall
+ "▒": wall-window
+
+tile_entities:
+ ">": !conveyor { dir: [1, 0] }
+ "<": !conveyor { dir: [-1, 0] }
+ "»": !conveyor { dir: [1, 0] }
+ "«": !conveyor { dir: [-1, 0] }
+ "v": !conveyor { dir: [0, 1] }
+ "A": !conveyor { dir: [0, -1] }
+
+items:
+ "S": pot
+ "w": plate
+ "p": plate
+ "f": foodprocessor
+
+chef_spawn: "~"
+customer_spawn: "!"
+
+walkable:
+ - door
+ - floor
+ - chair
+ - grass
+ - path
+
+collider:
+ - wall
+ - tree
diff --git a/data/maps/test.yaml b/data/maps/test.yaml
index 09f0b8a7..bb6137e5 100644
--- a/data/maps/test.yaml
+++ b/data/maps/test.yaml
@@ -34,9 +34,9 @@ map:
tiles:
"⌷": counter
"f": counter
- "<": counter
- "#": counter
- ">": counter
+ "<": conveyor
+ "#": conveyor
+ ">": conveyor
"t": table
"w": counter-window
"s": sink
diff --git a/server/src/data.rs b/server/src/data.rs
index a1c7e894..c667e760 100644
--- a/server/src/data.rs
+++ b/server/src/data.rs
@@ -16,7 +16,7 @@
*/
use crate::{
- entity::EntityDecl,
+ entity::{construct_entity, Entity, EntityDecl},
interaction::Recipe,
protocol::{DemandIndex, ItemIndex, RecipeIndex, TileIndex},
};
@@ -73,6 +73,8 @@ pub struct InitialMap {
customer_spawn: char,
#[serde(default)]
entities: Vec<EntityDecl>,
+ #[serde(default)]
+ tile_entities: HashMap<char, EntityDecl>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -104,7 +106,7 @@ pub struct Gamedata {
#[serde(skip)] pub initial_map: HashMap<IVec2, (TileIndex, Option<ItemIndex>)>,
#[serde(skip)] pub chef_spawn: Vec2,
#[serde(skip)] pub customer_spawn: Vec2,
- #[serde(skip)] pub entities: Vec<EntityDecl>,
+ #[serde(skip)] pub entities: Vec<Entity>,
}
#[derive(Debug, Deserialize, Default)]
@@ -170,6 +172,7 @@ impl Gamedata {
let tile_names = RwLock::new(Vec::new());
let mut recipes = Vec::new();
let mut demands = Vec::new();
+ let mut entities = Vec::new();
for mut r in recipes_in {
let r2 = r.clone();
@@ -238,6 +241,9 @@ impl Gamedata {
.get(&tile)
.ok_or(anyhow!("tile {tile} is undefined"))?
.clone();
+ if let Some(ent) = map_in.tile_entities.get(&tile) {
+ entities.push(construct_entity(Some(pos), ent)?);
+ }
let itemname = map_in.items.get(&tile).cloned();
let tile = TileIndex(register(&tile_names, tilename));
let item = itemname.map(|i| ItemIndex(register(&item_names, i)));
@@ -257,6 +263,14 @@ impl Gamedata {
.map(|i| !map_in.collider.contains(i) && !map_in.walkable.contains(i))
.collect();
+ entities.extend(
+ map_in
+ .entities
+ .iter()
+ .map(|decl| construct_entity(None, decl))
+ .try_collect::<Vec<_>>()?,
+ );
+
Ok(Gamedata {
demands,
tile_collide,
@@ -265,7 +279,7 @@ impl Gamedata {
map_names: HashSet::new(),
initial_map,
item_names,
- entities: map_in.entities,
+ entities,
tile_names,
chef_spawn,
customer_spawn,
diff --git a/server/src/entity/conveyor.rs b/server/src/entity/conveyor.rs
index b74c03ef..48d0d154 100644
--- a/server/src/entity/conveyor.rs
+++ b/server/src/entity/conveyor.rs
@@ -1,4 +1,4 @@
-use super::Entity;
+use super::EntityT;
use crate::{
data::Gamedata,
game::{interact_effect, Tile},
@@ -8,7 +8,7 @@ use anyhow::{anyhow, Result};
use glam::IVec2;
use std::collections::{HashMap, VecDeque};
-#[derive(Debug, Default)]
+#[derive(Debug, Default, Clone)]
pub struct Conveyor {
pub(super) from: IVec2,
pub(super) to: IVec2,
@@ -16,7 +16,7 @@ pub struct Conveyor {
pub(super) max_cooldown: f32,
}
-impl Entity for Conveyor {
+impl EntityT for Conveyor {
fn tick(
&mut self,
data: &Gamedata,
@@ -46,6 +46,7 @@ impl Entity for Conveyor {
Some(to.kind),
packet_out,
points,
+ true,
);
}
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs
index 089c60a5..d286d3bb 100644
--- a/server/src/entity/mod.rs
+++ b/server/src/entity/mod.rs
@@ -1,15 +1,12 @@
pub mod conveyor;
-
use crate::{data::Gamedata, game::Tile, protocol::PacketC};
-use anyhow::Result;
+use anyhow::{anyhow, Result};
use conveyor::Conveyor;
use glam::IVec2;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
-pub type DynEntity = Box<dyn Entity + Send + Sync + 'static>;
-
-pub trait Entity {
+pub trait EntityT: Clone {
fn tick(
&mut self,
data: &Gamedata,
@@ -20,23 +17,54 @@ pub trait Entity {
) -> Result<()>;
}
+#[derive(Debug, Clone)]
+pub enum Entity {
+ Conveyor(Conveyor),
+}
+impl EntityT for Entity {
+ fn tick(
+ &mut self,
+ data: &Gamedata,
+ points: &mut i64,
+ packet_out: &mut VecDeque<PacketC>,
+ tiles: &mut HashMap<IVec2, Tile>,
+ dt: f32,
+ ) -> Result<()> {
+ match self {
+ Entity::Conveyor(x) => x.tick(data, points, packet_out, tiles, dt),
+ }
+ }
+}
+
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum EntityDecl {
Conveyor {
- from: IVec2,
- to: IVec2,
+ from: Option<IVec2>,
+ to: Option<IVec2>,
+ dir: Option<IVec2>,
speed: Option<f32>,
},
}
-pub fn construct_entity(decl: &EntityDecl) -> DynEntity {
- match decl.to_owned() {
- EntityDecl::Conveyor { from, to, speed } => Box::new(Conveyor {
+pub fn construct_entity(pos: Option<IVec2>, decl: &EntityDecl) -> Result<Entity> {
+ Ok(match decl.to_owned() {
+ EntityDecl::Conveyor {
from,
to,
- max_cooldown: 1. / speed.unwrap_or(2.),
- ..Default::default()
- }),
- }
+ speed,
+ dir,
+ } => {
+ let from = from.or(pos).ok_or(anyhow!("conveyor has no start"))?;
+ let to = to
+ .or(dir.map(|s| s + from))
+ .ok_or(anyhow!("conveyor has no destination"))?;
+ Entity::Conveyor(Conveyor {
+ from,
+ to,
+ max_cooldown: 1. / speed.unwrap_or(2.),
+ ..Default::default()
+ })
+ }
+ })
}
diff --git a/server/src/game.rs b/server/src/game.rs
index 7609b965..e8d307db 100644
--- a/server/src/game.rs
+++ b/server/src/game.rs
@@ -18,7 +18,7 @@
use crate::{
customer::DemandState,
data::Gamedata,
- entity::{construct_entity, DynEntity},
+ entity::{Entity, EntityT},
interaction::{interact, tick_slot, InteractEffect, TickEffect},
protocol::{
ItemIndex, ItemLocation, Message, PacketC, PacketS, PlayerID, RecipeIndex, TileIndex,
@@ -69,7 +69,7 @@ pub struct Game {
packet_out: VecDeque<PacketC>,
demand: Option<DemandState>,
pub points: i64,
- entities: Vec<DynEntity>,
+ entities: Vec<Entity>,
end: Option<Instant>,
}
@@ -117,12 +117,7 @@ impl Game {
self.data = gamedata.into();
self.points = 0;
self.end = timer.map(|dur| Instant::now() + dur);
- self.entities = self
- .data
- .entities
- .iter()
- .map(|decl| construct_entity(decl))
- .collect();
+ self.entities = self.data.entities.clone();
for (&p, (tile, item)) in &self.data.initial_map {
self.tiles.insert(
@@ -364,6 +359,7 @@ impl Game {
None,
&mut self.packet_out,
&mut self.points,
+ false,
)
} else {
let player = self
@@ -381,6 +377,7 @@ impl Game {
Some(tile.kind),
&mut self.packet_out,
&mut self.points,
+ false,
)
}
}
@@ -523,11 +520,12 @@ pub fn interact_effect(
this_tile_kind: Option<TileIndex>,
packet_out: &mut VecDeque<PacketC>,
points: &mut i64,
+ automated: bool,
) {
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) {
+ if let Some(effect) = interact(&data, edge, this_tile_kind, this, other, points, automated) {
match effect {
InteractEffect::Put => packet_out.push_back(PacketC::MoveItem {
from: other_loc,
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
index 85df9925..bca480f5 100644
--- a/server/src/interaction.rs
+++ b/server/src/interaction.rs
@@ -122,10 +122,12 @@ pub fn interact(
this: &mut Option<Item>,
other: &mut Option<Item>,
points: &mut i64,
+ automated: bool,
) -> Option<InteractEffect> {
- let interactable = tile
- .map(|tile| data.is_tile_interactable(tile))
- .unwrap_or(true);
+ let interactable = automated
+ || 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 {
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 890e5148..96fb954a 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -15,11 +15,11 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-#![feature(if_let_guard, map_many_mut, let_chains)]
+#![feature(if_let_guard, map_many_mut, let_chains, iterator_try_collect)]
pub mod customer;
pub mod data;
+pub mod entity;
pub mod game;
pub mod interaction;
pub mod protocol;
pub mod state;
-pub mod entity;
diff --git a/test-client/main.ts b/test-client/main.ts
index c4db6935..04d1a5b4 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -98,7 +98,7 @@ export const players = new Map<PlayerID, PlayerData>()
export const tiles = new Map<string, TileData>()
export const items_removed = new Set<ItemData>()
-export let data: Gamedata = { item_names: [], tile_names: [], spawn: [0, 0], tile_collide: [], tile_interact: [] }
+export let data: Gamedata = { item_names: [], tile_names: [], spawn: [0, 0], tile_collide: [], tile_interact: [], map_names: [] }
export let time_remaining: number | null = null
export let global_message: MessageData | undefined = undefined
@@ -245,6 +245,7 @@ function keyboard(ev: KeyboardEvent, down: boolean) {
if (down && ev.code == "Numpad2") send({ type: "communicate", message: { text: "/start small" }, persist: false })
if (down && ev.code == "Numpad3") send({ type: "communicate", message: { text: "/start big" }, persist: false })
if (down && ev.code == "Numpad4") send({ type: "communicate", message: { text: "/start test" }, persist: false })
+ if (down && ev.code == "Numpad5") send({ type: "communicate", message: { text: "/start bus" }, persist: false })
if (down && ev.code == "Numpad0") send({ type: "communicate", message: { text: "/end" }, persist: false })
if (down) keys_down.add(ev.code)
else keys_down.delete(ev.code)
@@ -319,7 +320,7 @@ function frame_update(dt: number) {
if (tile.item !== undefined && tile.item !== null) update_item(tile.item)
}
- const remove = []
+ const remove: ItemData[] = []
for (const item of items_removed) {
update_item(item)
if (item.remove_anim === undefined) item.remove_anim = 0
diff --git a/test-client/tiles.ts b/test-client/tiles.ts
index da5b0761..5ecc1fad 100644
--- a/test-client/tiles.ts
+++ b/test-client/tiles.ts
@@ -170,6 +170,7 @@ export const TILES: { [key: string]: Component[] } = {
"counter-window": [base("rgb(233, 233, 233)")],
"grass": [base("rgb(0, 107, 4)")],
"path": [base("rgb(100, 80, 55)")],
+ "conveyor": [base("rgb(107, 62, 128)")],
"tree": [base("rgb(1, 82, 4)")],
"cuttingboard": [...counter, rect(0.3, "rgb(158, 236, 68)", "rgb(158, 236, 68)", 0.2)],
"trash": [...floor, circle(0.4, "rgb(20, 20, 20)"), cross(0.3, "rgb(90, 36, 36)")],