implement bus stops (no riding yet)
This commit is contained in:
parent
db3545e9a3
commit
a6f6b8b582
BIN
assets/models/orb_busstop.glb
Normal file
BIN
assets/models/orb_busstop.glb
Normal file
Binary file not shown.
22
src/chat.rs
22
src/chat.rs
|
@ -1,5 +1,5 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use crate::{actor, audio, hud, settings, world};
|
use crate::{actor, audio, hud, settings, world, effects};
|
||||||
|
|
||||||
pub struct ChatPlugin;
|
pub struct ChatPlugin;
|
||||||
impl Plugin for ChatPlugin {
|
impl Plugin for ChatPlugin {
|
||||||
|
@ -301,6 +301,8 @@ pub fn handle_chat_scripts(
|
||||||
mut er_chatscript: EventReader<ChatScriptEvent>,
|
mut er_chatscript: EventReader<ChatScriptEvent>,
|
||||||
mut q_actor: Query<(&mut actor::Actor, &mut actor::Suit), Without<actor::Player>>,
|
mut q_actor: Query<(&mut actor::Actor, &mut actor::Suit), Without<actor::Player>>,
|
||||||
mut q_player: Query<(&mut actor::Actor, &mut actor::Suit), With<actor::Player>>,
|
mut q_player: Query<(&mut actor::Actor, &mut actor::Suit), With<actor::Player>>,
|
||||||
|
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||||
|
mut ew_effect: EventWriter<effects::SpawnEffectEvent>,
|
||||||
) {
|
) {
|
||||||
for script in er_chatscript.read() {
|
for script in er_chatscript.read() {
|
||||||
match script.name.as_str() {
|
match script.name.as_str() {
|
||||||
|
@ -334,7 +336,23 @@ pub fn handle_chat_scripts(
|
||||||
} else {
|
} else {
|
||||||
error!("Invalid parameter for command `{}`: `{}`", script.name, script.param);
|
error!("Invalid parameter for command `{}`: `{}`", script.name, script.param);
|
||||||
}
|
}
|
||||||
_ => {}
|
"cryotrip" => {
|
||||||
|
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::WakeUp));
|
||||||
|
ew_effect.send(effects::SpawnEffectEvent {
|
||||||
|
class: effects::Effects::FadeIn(Color::CYAN),
|
||||||
|
duration: 1.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"cryofadeout" => {
|
||||||
|
ew_effect.send(effects::SpawnEffectEvent {
|
||||||
|
class: effects::Effects::FadeOut(Color::CYAN),
|
||||||
|
duration: 5.1,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let script_name = &script.name;
|
||||||
|
error!("Error, undefined chat script {script_name}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ struct ParserState {
|
||||||
script: String,
|
script: String,
|
||||||
script_parameter: String,
|
script_parameter: String,
|
||||||
script_parameter2: String,
|
script_parameter2: String,
|
||||||
|
sound: Option<String>,
|
||||||
}
|
}
|
||||||
impl Default for ParserState {
|
impl Default for ParserState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -134,6 +135,7 @@ impl Default for ParserState {
|
||||||
script: "".to_string(),
|
script: "".to_string(),
|
||||||
script_parameter: "".to_string(),
|
script_parameter: "".to_string(),
|
||||||
script_parameter2: "".to_string(),
|
script_parameter2: "".to_string(),
|
||||||
|
sound: Some("chat".to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,6 +148,10 @@ impl ParserState {
|
||||||
self.level = default.level;
|
self.level = default.level;
|
||||||
self.text = default.text;
|
self.text = default.text;
|
||||||
self.is_choice = default.is_choice;
|
self.is_choice = default.is_choice;
|
||||||
|
self.script = default.script;
|
||||||
|
self.script_parameter = default.script_parameter;
|
||||||
|
self.script_parameter2 = default.script_parameter2;
|
||||||
|
self.sound = default.sound;
|
||||||
}
|
}
|
||||||
fn as_chatbranch(&self) -> chat::ChatBranch {
|
fn as_chatbranch(&self) -> chat::ChatBranch {
|
||||||
return chat::ChatBranch {
|
return chat::ChatBranch {
|
||||||
|
@ -153,7 +159,7 @@ impl ParserState {
|
||||||
name: self.name.clone().unwrap_or("".to_string()),
|
name: self.name.clone().unwrap_or("".to_string()),
|
||||||
label: self.label.clone(),
|
label: self.label.clone(),
|
||||||
delay: self.delay.clone(),
|
delay: self.delay.clone(),
|
||||||
sound: if self.is_choice { "".to_string() } else { "chat".to_string() },
|
sound: if self.is_choice || self.sound.is_none() { "".to_string() } else { "chat".to_string() },
|
||||||
level: self.level.clone(),
|
level: self.level.clone(),
|
||||||
reply: if self.is_choice { "".to_string() } else { self.text.clone() },
|
reply: if self.is_choice { "".to_string() } else { self.text.clone() },
|
||||||
choice: if self.is_choice { self.text.clone() } else { "".to_string() },
|
choice: if self.is_choice { self.text.clone() } else { "".to_string() },
|
||||||
|
@ -228,6 +234,8 @@ pub fn load_defs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
["relativeto", id] => {
|
["relativeto", id] => {
|
||||||
|
// NOTE: call this command before "id", otherwise actors that
|
||||||
|
// set their position relative to this actor will get the wrong offset
|
||||||
match id2pos.get(&id.to_string()) {
|
match id2pos.get(&id.to_string()) {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
state.pos += *pos;
|
state.pos += *pos;
|
||||||
|
@ -542,6 +550,11 @@ pub fn load_defs(
|
||||||
debug!("Registering level: {}", level);
|
debug!("Registering level: {}", level);
|
||||||
state.level = level.to_string();
|
state.level = level.to_string();
|
||||||
}
|
}
|
||||||
|
["script", scriptname] => {
|
||||||
|
state.script = scriptname.to_string();
|
||||||
|
state.script_parameter = "".to_string();
|
||||||
|
state.script_parameter2 = "".to_string();
|
||||||
|
}
|
||||||
["script", scriptname, parameter] => {
|
["script", scriptname, parameter] => {
|
||||||
state.script = scriptname.to_string();
|
state.script = scriptname.to_string();
|
||||||
state.script_parameter = parameter.to_string();
|
state.script_parameter = parameter.to_string();
|
||||||
|
@ -552,6 +565,9 @@ pub fn load_defs(
|
||||||
state.script_parameter = parameter.to_string();
|
state.script_parameter = parameter.to_string();
|
||||||
state.script_parameter2 = parameter2.to_string();
|
state.script_parameter2 = parameter2.to_string();
|
||||||
}
|
}
|
||||||
|
["sound", "none"] => {
|
||||||
|
state.sound = None;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
error!("No match for [{}]", parts.join(","));
|
error!("No match for [{}]", parts.join(","));
|
||||||
}
|
}
|
||||||
|
|
79
src/defs.txt
79
src/defs.txt
|
@ -361,6 +361,85 @@ actor -300 0 40 suit
|
||||||
script refilloxygen 1 drifter
|
script refilloxygen 1 drifter
|
||||||
msg 0 outcold EXIT ""
|
msg 0 outcold EXIT ""
|
||||||
|
|
||||||
|
actor 100 -18000 2000 "orb_busstop"
|
||||||
|
relativeto player
|
||||||
|
id "busstop"
|
||||||
|
name "StarTrans Bus Station 'River of Time'"
|
||||||
|
scale 100
|
||||||
|
wants maxrotation 0
|
||||||
|
wants maxvelocity 0
|
||||||
|
actor 120 864 150 clippy
|
||||||
|
relativeto "busstop"
|
||||||
|
id "busstopclippy"
|
||||||
|
name "StarTrans Clippy™"
|
||||||
|
armodel clippy_ar
|
||||||
|
angularmomentum 0 0 0
|
||||||
|
wants maxrotation 0
|
||||||
|
wants maxvelocity 0
|
||||||
|
thrust 15 6 3 400 0.5
|
||||||
|
rotationy -0.5
|
||||||
|
scale 3
|
||||||
|
chatid "busstopclippy"
|
||||||
|
chat "busstopclippy"
|
||||||
|
name "StarTrans Clippy™"
|
||||||
|
msg 2 INIT question "You have reached the bus station 'River of Time'"
|
||||||
|
msg 2 question wait "Ready for a trip? Available stops: Oscillation Station, J-Prime Station"
|
||||||
|
msg 40 wait answer ""
|
||||||
|
sound none
|
||||||
|
choice 2 answer how1 "Bus stop?! How does this work?"
|
||||||
|
msg 6 how1 how2 "StarTrans Cargo Service is the most convenient way to travel the vast distances of space."
|
||||||
|
msg 6 how2 how3 "Just activate your suit's built-in cryostasis. A StarTrans carrier will pick you up and you will wake up at your destination in the blink of an eye."
|
||||||
|
msg 40 how3 answer "Of course we will supply you with free oxygen and ensure your safety."
|
||||||
|
choice 1 answer stopA1 "Take me to Oscillation Station, please."
|
||||||
|
msg 5 stopA1 stopA2 "StarTrans wishes you a pleasant journey."
|
||||||
|
script cryofadeout
|
||||||
|
msg 0 stopA2 EXIT ""
|
||||||
|
script cryotrip oscillation
|
||||||
|
sound none
|
||||||
|
choice 1 answer stopB1 "Take me to J-Prime Station, please."
|
||||||
|
msg 5 stopB1 stopB2 "StarTrans wishes you a pleasant journey."
|
||||||
|
script cryofadeout
|
||||||
|
msg 0 stopB2 EXIT ""
|
||||||
|
script cryotrip jprime
|
||||||
|
choice 1 answer oxy "Can you please fill up my oxygen tank without taking me anywhere?"
|
||||||
|
msg 2 oxy EXIT "Acceptable."
|
||||||
|
script refilloxygen 1000
|
||||||
|
sound none
|
||||||
|
choice 2 answer bye "No, thank you."
|
||||||
|
msg 2 bye EXIT "Feel free to come back any time."
|
||||||
|
msg 0 answer EXIT "Connection terminated."
|
||||||
|
actor 40 10 40 "orb_busstop"
|
||||||
|
name "Light Orb"
|
||||||
|
relativeto busstopclippy
|
||||||
|
light "47FF00" 1000000
|
||||||
|
actor 30 60 -10 "orb_busstop"
|
||||||
|
name "Light Orb"
|
||||||
|
relativeto busstopclippy
|
||||||
|
light "47FF00" 1000000
|
||||||
|
actor -10 -60 20 "orb_busstop"
|
||||||
|
name "Light Orb"
|
||||||
|
relativeto busstopclippy
|
||||||
|
light "47FF00" 1000000
|
||||||
|
actor -40 20 30 "orb_busstop"
|
||||||
|
name "Light Orb"
|
||||||
|
relativeto busstopclippy
|
||||||
|
light "47FF00" 1000000
|
||||||
|
actor 8 2 0 suit
|
||||||
|
relativeto "busstopclippy"
|
||||||
|
name "Mayhem"
|
||||||
|
wants maxrotation 0.2
|
||||||
|
wants maxvelocity 0
|
||||||
|
thrust 1.2 1 1 400 1.5
|
||||||
|
scale 2
|
||||||
|
collider capsule 1 0.5
|
||||||
|
chatid "busstop1clippynpc1"
|
||||||
|
chat "busstop1clippynpc1"
|
||||||
|
name "Rudy"
|
||||||
|
msg 3 INIT cryo "Error: No response"
|
||||||
|
lvl info
|
||||||
|
msg 0 cryo EXIT "Lifeform in cryostasis detected."
|
||||||
|
lvl info
|
||||||
|
|
||||||
chat error
|
chat error
|
||||||
name ERROR
|
name ERROR
|
||||||
msg 0 INIT EXIT "Unspecified conversation ID"
|
msg 0 INIT EXIT "Unspecified conversation ID"
|
||||||
|
|
|
@ -8,7 +8,8 @@ impl Plugin for EffectsPlugin {
|
||||||
app.add_systems(Startup, setup);
|
app.add_systems(Startup, setup);
|
||||||
app.add_systems(Startup, spawn_effects.after(setup).after(camera::setup_camera));
|
app.add_systems(Startup, spawn_effects.after(setup).after(camera::setup_camera));
|
||||||
app.add_systems(Update, spawn_effects);
|
app.add_systems(Update, spawn_effects);
|
||||||
app.add_systems(Update, update_fadeblack);
|
app.add_systems(Update, update_fadein);
|
||||||
|
app.add_systems(Update, update_fadeout);
|
||||||
// Blackout disabled for now
|
// Blackout disabled for now
|
||||||
//app.add_systems(Update, update_blackout);
|
//app.add_systems(Update, update_blackout);
|
||||||
app.add_event::<SpawnEffectEvent>();
|
app.add_event::<SpawnEffectEvent>();
|
||||||
|
@ -18,12 +19,14 @@ impl Plugin for EffectsPlugin {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum Effects {
|
pub enum Effects {
|
||||||
FadeIn(Color),
|
FadeIn(Color),
|
||||||
|
FadeOut(Color),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blackout disabled for now
|
// Blackout disabled for now
|
||||||
//#[derive(Component)] pub struct BlackOutOverlay;
|
//#[derive(Component)] pub struct BlackOutOverlay;
|
||||||
|
|
||||||
#[derive(Component)] pub struct FadeBlack;
|
#[derive(Component)] pub struct FadeIn;
|
||||||
|
#[derive(Component)] pub struct FadeOut;
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct Effect {
|
pub struct Effect {
|
||||||
pub class: Effects,
|
pub class: Effects,
|
||||||
|
@ -76,7 +79,7 @@ pub fn spawn_effects(
|
||||||
duration: effect.duration,
|
duration: effect.duration,
|
||||||
start_time: now,
|
start_time: now,
|
||||||
},
|
},
|
||||||
FadeBlack,
|
FadeIn,
|
||||||
NodeBundle {
|
NodeBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
width: Val::Vw(100.0),
|
width: Val::Vw(100.0),
|
||||||
|
@ -91,14 +94,36 @@ pub fn spawn_effects(
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
Effects::FadeOut(color) => {
|
||||||
|
commands.spawn((
|
||||||
|
Effect {
|
||||||
|
class: effect.class.clone(),
|
||||||
|
duration: effect.duration,
|
||||||
|
start_time: now,
|
||||||
|
},
|
||||||
|
FadeOut,
|
||||||
|
NodeBundle {
|
||||||
|
style: Style {
|
||||||
|
width: Val::Vw(100.0),
|
||||||
|
height: Val::Vh(100.0),
|
||||||
|
position_type: PositionType::Absolute,
|
||||||
|
top: Val::Px(0.0),
|
||||||
|
left: Val::Px(0.0),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
background_color: color.with_a(0.0).into(),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
},
|
||||||
//_ => {},
|
//_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_fadeblack(
|
pub fn update_fadein(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut q_effect: Query<(Entity, &Effect, &mut BackgroundColor), With<FadeBlack>>,
|
mut q_effect: Query<(Entity, &Effect, &mut BackgroundColor), With<FadeIn>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
) {
|
) {
|
||||||
for (entity, effect, mut bgcolor) in &mut q_effect {
|
for (entity, effect, mut bgcolor) in &mut q_effect {
|
||||||
|
@ -112,6 +137,22 @@ pub fn update_fadeblack(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_fadeout(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut q_effect: Query<(Entity, &Effect, &mut BackgroundColor), With<FadeOut>>,
|
||||||
|
time: Res<Time>,
|
||||||
|
) {
|
||||||
|
for (entity, effect, mut bgcolor) in &mut q_effect {
|
||||||
|
let now = time.elapsed_seconds_f64();
|
||||||
|
if effect.start_time + effect.duration < now {
|
||||||
|
commands.entity(entity).despawn();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let alpha = ((now - effect.start_time) / effect.duration).clamp(0.0, 1.0);
|
||||||
|
bgcolor.0.set_a(alpha as f32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Blackout disabled for now
|
// Blackout disabled for now
|
||||||
//pub fn update_blackout(
|
//pub fn update_blackout(
|
||||||
// mut q_effect: Query<&mut BackgroundColor, With<BlackOutOverlay>>,
|
// mut q_effect: Query<&mut BackgroundColor, With<BlackOutOverlay>>,
|
||||||
|
|
|
@ -30,6 +30,8 @@ pub fn asset_name_to_path(name: &str) -> &'static str {
|
||||||
"moonlet" => "models/moonlet.glb#Scene0",
|
"moonlet" => "models/moonlet.glb#Scene0",
|
||||||
"monolith" => "models/monolith_neon.glb#Scene0",
|
"monolith" => "models/monolith_neon.glb#Scene0",
|
||||||
"lightorb" => "models/lightorb.glb#Scene0",
|
"lightorb" => "models/lightorb.glb#Scene0",
|
||||||
|
"orb_busstop" => "models/orb_busstop.glb#Scene0",
|
||||||
|
"orb_busstop_dim" => "models/orb_busstop_dim.glb#Scene0",
|
||||||
"MeteorAceGT" => "models/MeteorAceGT.glb#Scene0",
|
"MeteorAceGT" => "models/MeteorAceGT.glb#Scene0",
|
||||||
"satellite" => "models/satellite.glb#Scene0",
|
"satellite" => "models/satellite.glb#Scene0",
|
||||||
"pizzeria" => "models/pizzeria2.glb#Scene0",
|
"pizzeria" => "models/pizzeria2.glb#Scene0",
|
||||||
|
|
Loading…
Reference in a new issue