implement actor ids, actor oxygen tanks, clamp harvested oxygen

Conflicts:
	src/world.rs
This commit is contained in:
yuni 2024-03-23 21:26:56 +01:00
parent bfa6a463d3
commit cc285a7548
3 changed files with 59 additions and 5 deletions

View file

@ -41,10 +41,12 @@ pub struct SendMessageEvent {
pub struct ChatScriptEvent { pub struct ChatScriptEvent {
name: String, name: String,
param: String, param: String,
param2: String,
} }
#[derive(Component)] #[derive(Component)]
pub struct Actor { pub struct Actor {
pub id: String,
pub hp: f32, pub hp: f32,
pub m: f32, // mass pub m: f32, // mass
pub v: Vec3, // velocity pub v: Vec3, // velocity
@ -55,6 +57,7 @@ pub struct Actor {
impl Default for Actor { impl Default for Actor {
fn default() -> Self { fn default() -> Self {
Self { Self {
id: "".to_string(),
hp: 100.0, hp: 100.0,
m: 100.0, m: 100.0,
v: Vec3::ZERO, v: Vec3::ZERO,
@ -340,6 +343,7 @@ pub fn handle_send_messages(
ew_chatscript.send(ChatScriptEvent { ew_chatscript.send(ChatScriptEvent {
name: branch.script.clone(), name: branch.script.clone(),
param: branch.script_parameter.clone(), param: branch.script_parameter.clone(),
param2: branch.script_parameter2.clone(),
}); });
} }
} }
@ -416,6 +420,7 @@ pub fn handle_conversations(
ew_chatscript.send(ChatScriptEvent { ew_chatscript.send(ChatScriptEvent {
name: branch.script.clone(), name: branch.script.clone(),
param: branch.script_parameter.clone(), param: branch.script_parameter.clone(),
param2: branch.script_parameter2.clone(),
}); });
} }
} }
@ -423,14 +428,38 @@ pub fn handle_conversations(
pub fn handle_chat_scripts( pub fn handle_chat_scripts(
mut er_chatscript: EventReader<ChatScriptEvent>, mut er_chatscript: EventReader<ChatScriptEvent>,
mut q_actor: Query<(&mut Actor, &mut Suit), Without<Player>>,
mut q_player: Query<(&mut Actor, &mut Suit), With<Player>>, mut q_player: Query<(&mut Actor, &mut Suit), With<Player>>,
) { ) {
for script in er_chatscript.read() { for script in er_chatscript.read() {
match script.name.as_str() { match script.name.as_str() {
"refilloxygen" => if let Ok(amount) = script.param.parse::<f32>() { "refilloxygen" => if let Ok(mut amount) = script.param.parse::<f32>() {
for (mut _actor, mut suit) in q_player.iter_mut() { for (mut _actor, mut suit) in q_player.iter_mut() {
if script.param2.is_empty() {
suit.oxygen = (suit.oxygen + amount).clamp(0.0, suit.oxygen_max); suit.oxygen = (suit.oxygen + amount).clamp(0.0, suit.oxygen_max);
} }
else {
let mut found_other = false;
info!("param2={}", script.param2);
for (other_actor, mut other_suit) in q_actor.iter_mut() {
if !other_actor.id.is_empty() {
info!("ID={}", other_actor.id);
}
if other_actor.id == script.param2 {
found_other = true;
amount = amount
.clamp(0.0, other_suit.oxygen)
.clamp(0.0, suit.oxygen_max - suit.oxygen);
other_suit.oxygen = other_suit.oxygen - amount;
suit.oxygen = (suit.oxygen + amount).clamp(0.0, suit.oxygen_max);
break;
}
}
if !found_other {
error!("Script error: could not find actor with ID `{}`", script.param2);
}
}
}
} else { } else {
error!("Invalid parameter for command `{}`: `{}`", script.name, script.param); error!("Invalid parameter for command `{}`: `{}`", script.name, script.param);
} }

View file

@ -122,8 +122,10 @@ actor 10 0 70 suit
lvl info lvl info
actor -300 0 40 suit actor -300 0 40 suit
id drifter
name "Drifter" name "Drifter"
chatid drifter chatid drifter
oxygen 0.08
chat drifter chat drifter
name "Drifter" name "Drifter"
msg 5 INIT noresponse "Requesting permission to communicate..." msg 5 INIT noresponse "Requesting permission to communicate..."
@ -134,7 +136,7 @@ actor -300 0 40 suit
lvl info lvl info
choice 0 outcold EXIT "Damn, it's gotta be moldy in that suit. How long has it been drifting?" choice 0 outcold EXIT "Damn, it's gotta be moldy in that suit. How long has it been drifting?"
choice 0 outcold EXIT "Harvest some oxygen" choice 0 outcold EXIT "Harvest some oxygen"
script refilloxygen 0.08 script refilloxygen 1 drifter
msg 0 outcold EXIT "" msg 0 outcold EXIT ""
chat error chat error

View file

@ -231,6 +231,7 @@ struct ParserState {
chat: String, chat: String,
// Actor fields // Actor fields
id: String,
pos: Vec3, pos: Vec3,
model: String, model: String,
model_scale: f32, model_scale: f32,
@ -245,6 +246,7 @@ struct ParserState {
thrust_sideways: f32, thrust_sideways: f32,
thrust_back: f32, thrust_back: f32,
reaction_wheels: f32, reaction_wheels: f32,
oxygen: f32,
// Chat fields // Chat fields
delay: f64, delay: f64,
@ -267,6 +269,7 @@ impl Default for ParserState {
name: "NONAME".to_string(), name: "NONAME".to_string(),
chat: "".to_string(), chat: "".to_string(),
id: "".to_string(),
pos: Vec3::new(0.0, 0.0, 0.0), pos: Vec3::new(0.0, 0.0, 0.0),
model: "".to_string(), model: "".to_string(),
model_scale: 1.0, model_scale: 1.0,
@ -281,6 +284,7 @@ impl Default for ParserState {
thrust_sideways: default_engine.thrust_forward, thrust_sideways: default_engine.thrust_forward,
thrust_back: default_engine.thrust_back, thrust_back: default_engine.thrust_back,
reaction_wheels: default_engine.reaction_wheels, reaction_wheels: default_engine.reaction_wheels,
oxygen: nature::OXY_D,
delay: 0.0, delay: 0.0,
text: "".to_string(), text: "".to_string(),
@ -339,6 +343,7 @@ impl ParserState {
fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) { fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
let component_actor = actor::Actor { let component_actor = actor::Actor {
angular_momentum: self.angular_momentum, angular_momentum: self.angular_momentum,
id: self.id.clone(),
..default() ..default()
}; };
let component_lifeform = actor::LifeForm::default(); let component_lifeform = actor::LifeForm::default();
@ -353,7 +358,11 @@ impl ParserState {
thrust_sideways: self.thrust_sideways, thrust_sideways: self.thrust_sideways,
reaction_wheels: self.reaction_wheels, reaction_wheels: self.reaction_wheels,
}; };
let component_suit = actor::Suit::default(); let component_suit = actor::Suit {
oxygen: self.oxygen,
oxygen_max: nature::OXY_D,
..default()
};
let component_model = SceneBundle { let component_model = SceneBundle {
transform: Transform { transform: Transform {
translation: self.pos, translation: self.pos,
@ -367,7 +376,7 @@ impl ParserState {
// TODO: is there a more dynamic way to construct this...? // TODO: is there a more dynamic way to construct this...?
info!("Spawning actor {} with model {} at {}/{}/{}", info!("Spawning actor {} with model {} at {}/{}/{}",
self.name, self.model, self.pos.x, self.pos.y, self.pos.z); self.name, self.model, self.pos.x, self.pos.y, self.pos.z);
if self.is_alive { if self.is_lifeform {
if !self.chat.is_empty() { if !self.chat.is_empty() {
commands.spawn(( commands.spawn((
component_actor, component_actor,
@ -484,6 +493,9 @@ pub fn load_defs(
continue; continue;
} }
} }
["id", id] => {
state.id = id.to_string();
}
["alive", "yes"] => { ["alive", "yes"] => {
state.is_alive = true; state.is_alive = true;
state.is_lifeform = true; state.is_lifeform = true;
@ -492,6 +504,17 @@ pub fn load_defs(
["vehicle", "yes"] => { ["vehicle", "yes"] => {
state.is_vehicle = true; state.is_vehicle = true;
} }
["oxygen", amount] => {
if let Ok(amount) = amount.parse::<f32>() {
state.is_lifeform = true;
state.is_suited = true;
state.oxygen = amount;
}
else {
error!("Can't parse float: {line}");
continue;
}
}
["pronoun", pronoun] => { ["pronoun", pronoun] => {
state.pronoun = pronoun.to_string(); state.pronoun = pronoun.to_string();
} }