mittens_engine/engine/ecs/component/
kinetic_response.rs1use crate::engine::ecs::ComponentId;
2use crate::engine::ecs::component::Component;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum KineticResponseMode {
6 Slide,
8
9 Push,
12}
13
14#[derive(Debug, Clone)]
20pub struct KineticResponseComponent {
21 pub enabled: bool,
22 pub mode: KineticResponseMode,
23
24 pub max_iterations: u32,
26
27 pub push_out_epsilon: f32,
29
30 pub push_strength: f32,
32
33 pub friction: f32,
37
38 pub friction_y: f32,
43
44 pub max_speed: f32,
46
47 pub velocity: [f32; 3],
49
50 pub gravity_coefficient: f32,
55
56 component: Option<ComponentId>,
57}
58
59impl KineticResponseComponent {
60 pub fn new(mode: KineticResponseMode) -> Self {
61 Self {
62 enabled: true,
63 mode,
64 max_iterations: 6,
65 push_out_epsilon: 0.001,
66 push_strength: 4.0,
67 friction: 0.0,
68 friction_y: 0.0,
69 max_speed: 6.0,
70 velocity: [0.0, 0.0, 0.0],
71 gravity_coefficient: 0.0,
72 component: None,
73 }
74 }
75
76 pub fn slide() -> Self {
77 let mut c = Self::new(KineticResponseMode::Slide);
78 c.push_strength = 0.0;
79 c.friction = 0.0;
80 c.max_speed = 0.0;
81 c
82 }
83
84 pub fn push() -> Self {
85 Self::new(KineticResponseMode::Push)
86 }
87
88 pub fn with_push_strength(mut self, push_strength: f32) -> Self {
89 self.push_strength = push_strength;
90 self
91 }
92
93 pub fn with_friction(mut self, friction: f32) -> Self {
94 self.friction = friction.max(0.0);
95 self
96 }
97
98 pub fn with_friction_y(mut self, friction_y: f32) -> Self {
99 self.friction_y = friction_y.max(0.0);
100 self
101 }
102}
103
104impl Default for KineticResponseComponent {
105 fn default() -> Self {
106 Self::slide()
107 }
108}
109
110impl Component for KineticResponseComponent {
111 fn name(&self) -> &'static str {
112 "kinetic_response"
113 }
114
115 fn set_id(&mut self, component: ComponentId) {
116 self.component = Some(component);
117 }
118
119 fn as_any(&self) -> &dyn std::any::Any {
120 self
121 }
122
123 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
124 self
125 }
126
127 fn init(&mut self, emit: &mut dyn crate::engine::ecs::SignalEmitter, component: ComponentId) {
128 emit.push_intent_now(
129 component,
130 crate::engine::ecs::IntentValue::RegisterKineticResponse {
131 component_ids: vec![component],
132 },
133 );
134 }
135
136 fn cleanup(
137 &mut self,
138 emit: &mut dyn crate::engine::ecs::SignalEmitter,
139 component: ComponentId,
140 ) {
141 emit.push_intent_now(
142 component,
143 crate::engine::ecs::IntentValue::RemoveKineticResponse {
144 component_ids: vec![component],
145 },
146 );
147 }
148
149 fn to_mms_ast(
150 &self,
151 _world: &crate::engine::ecs::World,
152 ) -> crate::scripting::ast::ComponentExpression {
153 use crate::engine::ecs::component::ce_helpers::*;
154 let ctor = match self.mode {
155 KineticResponseMode::Slide => "slide",
156 KineticResponseMode::Push => "push",
157 };
158 ce_call("KineticResponse", ctor, vec![])
159 .with_call("enabled", vec![b(self.enabled)])
160 .with_call("max_iterations", vec![num(self.max_iterations as f64)])
161 .with_call("push_out_epsilon", vec![num(self.push_out_epsilon as f64)])
162 .with_call("push_strength", vec![num(self.push_strength as f64)])
163 .with_call("friction", vec![num(self.friction as f64)])
164 .with_call("friction_y", vec![num(self.friction_y as f64)])
165 .with_call("max_speed", vec![num(self.max_speed as f64)])
166 }
167}