@@ -5,6 +5,7 @@ use super::*;
5
5
pub struct NewtonTask {
6
6
width : f64 ,
7
7
height : f64 ,
8
+ on_ground : bool ,
8
9
}
9
10
10
11
impl NewtonTask {
@@ -22,20 +23,25 @@ impl NewtonTask {
22
23
Some ( NewtonTask {
23
24
width,
24
25
height,
26
+ on_ground : false ,
25
27
} )
26
28
}
27
29
28
- pub async fn tick ( & mut self , h : Handler < Entity > ) {
30
+ pub async fn tick ( & mut self , h : Handler < Entity > , entity_change_set : & EntityChangeSet ) {
31
+ // If it was on ground before and hasn't moved since, skip the turn
32
+ // TODO: detect if the ground is destroyed
33
+ if self . on_ground && !entity_change_set. get ( & h. eid ) . copied ( ) . unwrap_or_default ( ) . position_changed ( ) {
34
+ return ;
35
+ }
36
+
29
37
// Get data from entity
30
38
let Some ( ( mut position, mut velocity) ) = h. observe_any ( |any_entity| {
31
39
let entity = any_entity. as_entity ( ) ;
32
40
( entity. position . clone ( ) , entity. velocity . clone ( ) )
33
41
} ) . await else { return ; } ;
34
42
35
43
// Apply velocity and collisions
36
- let mut changes = EntityChanges :: nothing ( ) ;
37
- let mut new_velocity = velocity. clone ( ) ;
38
- new_velocity. y -= 9.81 /20.0 ;
44
+ velocity. y -= 9.81 /20.0 ;
39
45
let bounding_box = CollisionShape {
40
46
x1 : position. x - self . width /2.0 ,
41
47
y1 : position. y ,
@@ -44,37 +50,21 @@ impl NewtonTask {
44
50
y2 : position. y + self . height ,
45
51
z2 : position. z + self . width /2.0 ,
46
52
} ;
47
- let new_velocity = h. world . try_move ( & bounding_box, & new_velocity) . await ;
48
- if velocity. x != new_velocity. x {
49
- velocity. x = 0.0 ;
50
- changes += EntityChanges :: velocity ( ) ;
51
- }
52
- if velocity. y != new_velocity. y {
53
- velocity. y = 0.0 ;
54
- changes += EntityChanges :: velocity ( ) ;
55
- }
56
- if velocity. z != new_velocity. z {
57
- velocity. z = 0.0 ;
58
- changes += EntityChanges :: velocity ( ) ;
59
- }
60
- if !new_velocity. is_zero ( ) {
61
- changes += EntityChanges :: position ( ) ;
62
- position += new_velocity;
53
+ let new_velocity = h. world . try_move ( & bounding_box, & velocity) . await ;
54
+ self . on_ground = velocity. y < 0.0 && new_velocity. y >= 0.0 ;
55
+ if !velocity. is_zero ( ) {
56
+ position += new_velocity. clone ( ) ;
63
57
}
64
58
65
59
// TODO(feat): Apply air resistance to x and z velocity
66
60
// Keep in mind that velocity shouldn't flicker when constantly kept up by another task but slowed down in this task
67
61
68
62
// Mutate entity
69
63
// TODO(correctness): Before modifying entity values, we should ensure the original values we based the changes on are still the same
70
- if changes. nothing_changed ( ) {
71
- return ;
72
- }
73
64
h. mutate ( |entity| {
74
65
let entity = entity. get_entity_mut ( ) ;
75
- entity. velocity = velocity ;
66
+ entity. velocity = new_velocity ;
76
67
entity. position = position;
77
- ( ( ) , changes)
78
68
} ) . await ;
79
69
}
80
70
}
0 commit comments