aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/data/src/entities.rs2
-rw-r--r--server/data/src/lib.rs8
-rw-r--r--server/data/src/registry.rs13
-rw-r--r--server/src/entity/mod.rs3
-rw-r--r--server/src/entity/player_portal_pair.rs62
5 files changed, 63 insertions, 25 deletions
diff --git a/server/data/src/entities.rs b/server/data/src/entities.rs
index 62947b05..cd1ba18d 100644
--- a/server/data/src/entities.rs
+++ b/server/data/src/entities.rs
@@ -44,6 +44,8 @@ pub enum EntityDecl {
#[serde(default = "default_tile")]
in_tile: TileIndex,
#[serde(default = "default_tile")]
+ neutral_tile: TileIndex,
+ #[serde(default = "default_tile")]
out_tile: TileIndex,
},
Customers {
diff --git a/server/data/src/lib.rs b/server/data/src/lib.rs
index d06aadd1..b490fbc2 100644
--- a/server/data/src/lib.rs
+++ b/server/data/src/lib.rs
@@ -225,11 +225,15 @@ fn build_data(
exclusive_tiles.entry(*blocker_tile).or_default();
}
EntityDecl::PlayerPortalPair {
- in_tile, out_tile, ..
+ in_tile,
+ out_tile,
+ neutral_tile,
+ ..
} => {
*in_tile = reg.register_tile("black-hole".to_owned());
+ *neutral_tile = reg.register_tile("grey-hole".to_owned());
*out_tile = reg.register_tile("white-hole".to_owned());
- tile_walkable.extend([*in_tile, *out_tile]);
+ tile_walkable.extend([*in_tile, *neutral_tile, *out_tile]);
}
_ => (),
}
diff --git a/server/data/src/registry.rs b/server/data/src/registry.rs
index 372df653..f405489b 100644
--- a/server/data/src/registry.rs
+++ b/server/data/src/registry.rs
@@ -93,8 +93,11 @@ pub(crate) fn filter_unused_tiles_and_items(data: &mut Gamedata, serverdata: &mu
used_tiles.insert(*blocker_tile);
}
EntityDecl::PlayerPortalPair {
- in_tile, out_tile, ..
- } => used_tiles.extend([*in_tile, *out_tile]),
+ in_tile,
+ out_tile,
+ neutral_tile,
+ ..
+ } => used_tiles.extend([*in_tile, *out_tile, *neutral_tile]),
_ => (),
};
}
@@ -197,9 +200,13 @@ pub(crate) fn filter_unused_tiles_and_items(data: &mut Gamedata, serverdata: &mu
*blocker_tile = tile_map[blocker_tile];
}
EntityDecl::PlayerPortalPair {
- in_tile, out_tile, ..
+ in_tile,
+ out_tile,
+ neutral_tile,
+ ..
} => {
*in_tile = tile_map[in_tile];
+ *neutral_tile = tile_map[neutral_tile];
*out_tile = tile_map[out_tile];
}
_ => (),
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs
index ee8a1a74..c10e1dbd 100644
--- a/server/src/entity/mod.rs
+++ b/server/src/entity/mod.rs
@@ -178,7 +178,8 @@ pub fn construct_entity(decl: &EntityDecl) -> DynEntity {
a,
b,
in_tile,
+ neutral_tile,
out_tile,
- } => Box::new(PlayerPortalPair::new(a, b, in_tile, out_tile)),
+ } => Box::new(PlayerPortalPair::new(a, b, in_tile, neutral_tile, out_tile)),
}
}
diff --git a/server/src/entity/player_portal_pair.rs b/server/src/entity/player_portal_pair.rs
index b73f5891..9691ca05 100644
--- a/server/src/entity/player_portal_pair.rs
+++ b/server/src/entity/player_portal_pair.rs
@@ -30,21 +30,29 @@ pub struct PlayerPortalPair {
a_f: Vec2,
b_f: Vec2,
in_tile: TileIndex,
+ neutral_tile: TileIndex,
out_tile: TileIndex,
- a_out: bool,
- b_out: bool,
+ state: i8,
+ delay: f32,
}
impl PlayerPortalPair {
- pub fn new(a: IVec2, b: IVec2, in_tile: TileIndex, out_tile: TileIndex) -> Self {
+ pub fn new(
+ a: IVec2,
+ b: IVec2,
+ in_tile: TileIndex,
+ neutral_tile: TileIndex,
+ out_tile: TileIndex,
+ ) -> Self {
Self {
a_i: a,
b_i: b,
a_f: a.as_vec2() + vec2(0.5, 0.5),
b_f: b.as_vec2() + vec2(0.5, 0.5),
in_tile,
+ neutral_tile,
out_tile,
- a_out: true,
- b_out: true,
+ state: 1,
+ delay: 0.,
}
}
}
@@ -58,38 +66,54 @@ impl Entity for PlayerPortalPair {
o
};
- if self.a_out && qn(self.a_f, 1.5).is_none() {
+ self.delay -= c.dt;
+
+ let near_a = qn(self.a_f, 1.5);
+ let near_b = qn(self.b_f, 1.5);
+ let in_a = qn(self.a_f, 0.7);
+ let in_b = qn(self.b_f, 0.7);
+
+ if (self.state == 1 && near_b.is_none() && in_a.is_none())
+ || (self.state == -1 && near_a.is_none() && in_b.is_none())
+ {
+ c.game.set_tile(self.b_i, Some(self.neutral_tile));
+ c.game.set_tile(self.a_i, Some(self.neutral_tile));
+ self.state = 0;
+ return Ok(());
+ }
+
+ if self.state == 0 && in_a.is_some() {
c.game.set_tile(self.a_i, Some(self.in_tile));
- self.a_out = false;
+ c.game.set_tile(self.b_i, Some(self.out_tile));
+ self.state = 1;
+ self.delay = 0.2;
return Ok(());
}
- if self.b_out && qn(self.b_f, 1.5).is_none() {
+ if self.state == 0 && in_b.is_some() {
c.game.set_tile(self.b_i, Some(self.in_tile));
- self.b_out = false;
+ c.game.set_tile(self.a_i, Some(self.out_tile));
+ self.state = -1;
+ self.delay = 0.2;
return Ok(());
}
- if !self.a_out
- && let Some(player) = qn(self.a_f, 0.5)
+ if self.state == 1
+ && self.delay < 0.
+ && let Some(player) = in_a
&& let Some(p) = c.game.players.get_mut(&player)
{
p.movement.position = self.b_f;
c.packet_out.push_back(PacketC::MovementSync { player });
- c.game.set_tile(self.b_i, Some(self.out_tile));
- self.b_out = true;
- return Ok(());
}
- if !self.b_out
- && let Some(player) = qn(self.b_f, 0.5)
+ if self.state == -1
+ && self.delay < 0.
+ && let Some(player) = in_b
&& let Some(p) = c.game.players.get_mut(&player)
{
p.movement.position = self.a_f;
c.packet_out.push_back(PacketC::MovementSync { player });
- c.game.set_tile(self.a_i, Some(self.out_tile));
- self.a_out = true;
- return Ok(());
}
Ok(())