@@ -31,7 +31,10 @@ impl Plugin for MapPlugin {
31
31
. register_rollback_type :: < Handle < MapElementMeta > > ( )
32
32
} )
33
33
. extend_rollback_schedule ( |schedule| {
34
- schedule. add_system_to_stage ( RollbackStage :: Last , despawn_out_of_bounds) ;
34
+ schedule. add_system_to_stage (
35
+ RollbackStage :: Last ,
36
+ handle_out_of_bounds_players_and_items,
37
+ ) ;
35
38
} )
36
39
. add_plugin ( elements:: MapElementsPlugin ) ;
37
40
}
@@ -43,6 +46,12 @@ impl Plugin for MapPlugin {
43
46
#[ reflect( Component , Default ) ]
44
47
pub struct MapElementHydrated ;
45
48
49
+ /// If this component and a [`Transform`] component is added to any entity, it will be moved back to
50
+ /// given position if the entity ever ends up outside the map bounds.
51
+ #[ derive( Deref , DerefMut , Component , Reflect , Default , Debug ) ]
52
+ #[ reflect( Default , Component ) ]
53
+ pub struct MapRespawnPoint ( pub Vec3 ) ;
54
+
46
55
// /// Contains the scripts that have been added for the currently loaded map
47
56
// #[derive(Deref, DerefMut, Default)]
48
57
// pub struct MapScripts(pub HashSet<Handle<JsScript>>);
@@ -260,10 +269,11 @@ pub fn hydrate_map(
260
269
session_manager. start_session ( ) ;
261
270
}
262
271
263
- fn despawn_out_of_bounds (
272
+ fn handle_out_of_bounds_players_and_items (
264
273
mut commands : Commands ,
265
274
map : Query < & MapMeta > ,
266
275
players : Query < ( Entity , & Transform ) , With < PlayerIdx > > ,
276
+ mut items : Query < ( & mut Transform , & MapRespawnPoint ) , Without < PlayerIdx > > ,
267
277
) {
268
278
const KILL_ZONE_BORDER : f32 = 500.0 ;
269
279
let Ok ( map) = map. get_single ( ) else {
@@ -275,11 +285,21 @@ fn despawn_out_of_bounds(
275
285
let right_kill_zone = map_width + KILL_ZONE_BORDER ;
276
286
let bottom_kill_zone = -KILL_ZONE_BORDER ;
277
287
288
+ // Kill out of bounds players
278
289
for ( player_ent, transform) in & players {
279
290
let pos = transform. translation ;
280
291
281
292
if pos. x < left_kill_zone || pos. x > right_kill_zone || pos. y < bottom_kill_zone {
282
293
commands. add ( PlayerKillCommand :: new ( player_ent) ) ;
283
294
}
284
295
}
296
+
297
+ // Reset out of bound item positions
298
+ for ( mut transform, respawn_point) in & mut items {
299
+ let pos = transform. translation ;
300
+
301
+ if pos. x < left_kill_zone || pos. x > right_kill_zone || pos. y < bottom_kill_zone {
302
+ transform. translation = respawn_point. 0 ;
303
+ }
304
+ }
285
305
}
0 commit comments