delete src/chat_old.rs (\o/)
This commit is contained in:
parent
0b22494751
commit
43f67877a2
406
src/chat_old.rs
406
src/chat_old.rs
|
@ -1,406 +0,0 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_xpbd_3d::prelude::*;
|
||||
use bevy::math::DVec3;
|
||||
use crate::{actor, audio, hud, settings, world, effects};
|
||||
|
||||
pub struct ChatPlugin;
|
||||
impl Plugin for ChatPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.register_type::<ChatBranch>();
|
||||
app.add_systems(Update, (
|
||||
handle_new_conversations,
|
||||
handle_reply_keys,
|
||||
handle_send_messages,
|
||||
handle_conversations,
|
||||
handle_chat_scripts,
|
||||
));
|
||||
app.add_systems(PostUpdate, despawn_old_choices);
|
||||
app.add_event::<StartConversationEvent>();
|
||||
app.add_event::<SendMessageEvent>();
|
||||
app.add_event::<ChatScriptEvent>();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct StartConversationEvent {
|
||||
pub talker: Talker,
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct SendMessageEvent {
|
||||
pub conv_id: String,
|
||||
pub conv_label: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Event)]
|
||||
pub struct ChatScriptEvent {
|
||||
name: String,
|
||||
param: String,
|
||||
param2: String,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Component, Reflect, Default)]
|
||||
#[reflect(Component)]
|
||||
pub struct ChatBranch {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub label: String,
|
||||
pub delay: f64,
|
||||
pub sound: String,
|
||||
pub level: String,
|
||||
pub reply: String,
|
||||
pub goto: String,
|
||||
pub choice: String,
|
||||
pub script: String,
|
||||
pub script_parameter: String,
|
||||
pub script_parameter2: String,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Chat {
|
||||
pub id: String,
|
||||
pub label: String,
|
||||
pub timer: f64,
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct ChoiceAvailable {
|
||||
pub conv_id: String,
|
||||
pub conv_label: String,
|
||||
pub recipient: String,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Component)]
|
||||
#[derive(Clone)]
|
||||
pub struct Talker {
|
||||
pub pronoun: String,
|
||||
pub conv_id: String,
|
||||
}
|
||||
impl Default for Talker { fn default() -> Self { Self {
|
||||
pronoun: "they/them".to_string(),
|
||||
conv_id: "error".to_string(),
|
||||
}}}
|
||||
|
||||
pub fn handle_new_conversations(
|
||||
mut commands: Commands,
|
||||
mut er_conv: EventReader<StartConversationEvent>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
q_conv: Query<&Chat>,
|
||||
time: Res<Time>,
|
||||
) {
|
||||
let label = "INIT";
|
||||
for event in er_conv.read() {
|
||||
// check for existing chats with this id
|
||||
let id = &event.talker.conv_id;
|
||||
let chats: Vec<&Chat> = q_conv.iter().filter(|c| c.id == *id).collect();
|
||||
if chats.len() > 0 {
|
||||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Ping));
|
||||
continue;
|
||||
}
|
||||
|
||||
// no existing chats yet, let's create a new one
|
||||
commands.spawn((
|
||||
Chat {
|
||||
id: id.to_string(),
|
||||
label: label.to_string(),
|
||||
timer: time.elapsed_seconds_f64(),
|
||||
},
|
||||
world::DespawnOnPlayerDeath,
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_reply_keys(
|
||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||
settings: ResMut<settings::Settings>,
|
||||
q_choices: Query<&ChoiceAvailable>,
|
||||
mut evwriter_sendmsg: EventWriter<SendMessageEvent>,
|
||||
mut evwriter_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
) {
|
||||
let mut selected_choice = 1;
|
||||
'outer: for key in settings.get_reply_keys() {
|
||||
if keyboard_input.just_pressed(key) {
|
||||
let mut count = 1;
|
||||
for choice in &q_choices {
|
||||
if count == selected_choice {
|
||||
evwriter_sfx.send(audio::PlaySfxEvent(audio::Sfx::Click));
|
||||
evwriter_sendmsg.send(SendMessageEvent {
|
||||
conv_id: choice.conv_id.clone(),
|
||||
conv_label: choice.conv_label.clone(),
|
||||
text: choice.text.clone(),
|
||||
});
|
||||
break 'outer;
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
selected_choice += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_send_messages(
|
||||
mut commands: Commands,
|
||||
mut er_sendmsg: EventReader<SendMessageEvent>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
mut ew_chatscript: EventWriter<ChatScriptEvent>,
|
||||
mut q_conv: Query<(Entity, &mut Chat)>,
|
||||
time: Res<Time>,
|
||||
chat_branches: Query<&ChatBranch>,
|
||||
mut log: ResMut<hud::Log>,
|
||||
) {
|
||||
let now = time.elapsed_seconds_f64();
|
||||
|
||||
for event in er_sendmsg.read() {
|
||||
for (entity, mut chat) in &mut q_conv {
|
||||
if chat.id != event.conv_id {
|
||||
continue;
|
||||
}
|
||||
if event.conv_label == "EXIT" {
|
||||
info!("Despawning chat.");
|
||||
commands.entity(entity).despawn();
|
||||
continue;
|
||||
}
|
||||
|
||||
let branches: Vec<&ChatBranch> = chat_branches.iter()
|
||||
.filter(|branch| branch.id == event.conv_id
|
||||
&& branch.label == event.conv_label
|
||||
&& branch.choice == event.text)
|
||||
.collect();
|
||||
if branches.len() != 1 {
|
||||
error!("Expected 1 branch with ID '{}', label '{}', choice '{}', but got {}! Aborting conversation.", event.conv_id, event.conv_label, event.text, branches.len());
|
||||
continue;
|
||||
}
|
||||
let branch = branches[0];
|
||||
// TODO despawn the choices
|
||||
|
||||
if !branch.reply.is_empty() {
|
||||
match branch.level.as_str() {
|
||||
"chat" => log.chat(branch.reply.clone(), branch.name.clone()),
|
||||
"info" => log.info(branch.reply.clone()),
|
||||
"warn" => log.warning(branch.reply.clone()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
chat.label = branch.goto.clone();
|
||||
chat.timer = now + branch.delay;
|
||||
if branch.sound != "" {
|
||||
let sfx = audio::str2sfx(branch.sound.as_str());
|
||||
ew_sfx.send(audio::PlaySfxEvent(sfx));
|
||||
}
|
||||
let choices: Vec<&ChatBranch> = chat_branches.iter()
|
||||
.filter(|branch| branch.id == chat.id && branch.label == chat.label)
|
||||
.collect();
|
||||
for choice in choices {
|
||||
if choice.choice.as_str() != hud::CHOICE_NONE {
|
||||
commands.spawn((
|
||||
ChoiceAvailable {
|
||||
conv_id: choice.id.clone(),
|
||||
conv_label: choice.label.clone(),
|
||||
recipient: choice.name.clone(),
|
||||
text: choice.choice.clone(),
|
||||
},
|
||||
world::DespawnOnPlayerDeath,
|
||||
));
|
||||
}
|
||||
}
|
||||
if !branch.script.is_empty() {
|
||||
ew_chatscript.send(ChatScriptEvent {
|
||||
name: branch.script.clone(),
|
||||
param: branch.script_parameter.clone(),
|
||||
param2: branch.script_parameter2.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
break; // let's only handle one of these per frame
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_conversations(
|
||||
mut commands: Commands,
|
||||
mut log: ResMut<hud::Log>,
|
||||
mut q_conv: Query<(Entity, &mut Chat)>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
mut ew_chatscript: EventWriter<ChatScriptEvent>,
|
||||
time: Res<Time>,
|
||||
chat_branches: Query<&ChatBranch>, // TODO: use Table for faster iteration?
|
||||
) {
|
||||
let now = time.elapsed_seconds_f64();
|
||||
for (entity, mut chat) in &mut q_conv {
|
||||
if chat.label == "EXIT" {
|
||||
info!("Despawning chat.");
|
||||
commands.entity(entity).despawn();
|
||||
continue;
|
||||
}
|
||||
if now < chat.timer {
|
||||
continue;
|
||||
}
|
||||
|
||||
let branches: Vec<&ChatBranch> = chat_branches.iter()
|
||||
.filter(|branch| branch.id == chat.id
|
||||
&& branch.label == chat.label
|
||||
&& branch.choice == "")
|
||||
.collect();
|
||||
if branches.len() != 1 {
|
||||
error!("Expected 1 branch with ID '{}' and label '{}', but got {}! Aborting conversation.", chat.id, chat.label, branches.len());
|
||||
continue;
|
||||
}
|
||||
let branch = branches[0];
|
||||
|
||||
if !branch.reply.is_empty() {
|
||||
match branch.level.as_str() {
|
||||
"chat" => log.chat(branch.reply.clone(), branch.name.clone()),
|
||||
"info" => log.info(branch.reply.clone()),
|
||||
"warn" => log.warning(branch.reply.clone()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
if chat.label == "EXIT" {
|
||||
// TODO: isn't this dead code?
|
||||
continue;
|
||||
}
|
||||
chat.label = branch.goto.clone();
|
||||
if branch.sound != "" {
|
||||
let sfx = audio::str2sfx(branch.sound.as_str());
|
||||
ew_sfx.send(audio::PlaySfxEvent(sfx));
|
||||
}
|
||||
chat.timer = now + branch.delay;
|
||||
|
||||
let choices: Vec<&ChatBranch> = chat_branches.iter()
|
||||
.filter(|branch| branch.id == chat.id && branch.label == chat.label)
|
||||
.collect();
|
||||
for choice in choices {
|
||||
if choice.choice.as_str() != hud::CHOICE_NONE {
|
||||
commands.spawn((
|
||||
ChoiceAvailable {
|
||||
conv_id: choice.id.clone(),
|
||||
conv_label: choice.label.clone(),
|
||||
recipient: choice.name.clone(),
|
||||
text: choice.choice.clone(),
|
||||
},
|
||||
world::DespawnOnPlayerDeath,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if !branch.script.is_empty() {
|
||||
ew_chatscript.send(ChatScriptEvent {
|
||||
name: branch.script.clone(),
|
||||
param: branch.script_parameter.clone(),
|
||||
param2: branch.script_parameter2.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_chat_scripts(
|
||||
mut er_chatscript: EventReader<ChatScriptEvent>,
|
||||
mut q_actor: Query<(&mut actor::Actor, &mut actor::Suit), Without<actor::Player>>,
|
||||
mut q_player: Query<(&mut actor::Actor, &mut actor::Suit, &mut actor::ExperiencesGForce), With<actor::Player>>,
|
||||
mut q_playercam: Query<(&mut Position, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
mut ew_effect: EventWriter<effects::SpawnEffectEvent>,
|
||||
) {
|
||||
for script in er_chatscript.read() {
|
||||
match script.name.as_str() {
|
||||
"refilloxygen" => if let Ok(mut amount) = script.param.parse::<f32>() {
|
||||
for (_, mut suit, _) in q_player.iter_mut() {
|
||||
if script.param2.is_empty() {
|
||||
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 {
|
||||
error!("Invalid parameter for command `{}`: `{}`", script.name, script.param);
|
||||
}
|
||||
"cryotrip" => {
|
||||
if script.param.is_empty() {
|
||||
error!("Chat script cryotrip needs a parameter");
|
||||
}
|
||||
else {
|
||||
if let Ok((mut pos, mut v)) = q_playercam.get_single_mut() {
|
||||
if script.param == "oscillation".to_string() {
|
||||
*pos = Position(DVec3::new(147e6, 165e6, 336e6));
|
||||
v.0 = DVec3::ZERO;
|
||||
}
|
||||
else if script.param == "metisprime".to_string() {
|
||||
*pos = Position(DVec3::new(27643e3, -47e3, -124434e3));
|
||||
v.0 = DVec3::ZERO;
|
||||
}
|
||||
else if script.param == "serenity".to_string() {
|
||||
*pos = Position(DVec3::new(-121095e3, 582e3, -190816e3));
|
||||
v.0 = DVec3::ZERO;
|
||||
}
|
||||
else {
|
||||
error!("Invalid destination for cryotrip chat script: '{}'", script.param);
|
||||
}
|
||||
}
|
||||
if let Ok((_, mut suit, mut gforce)) = q_player.get_single_mut() {
|
||||
suit.oxygen = suit.oxygen_max;
|
||||
gforce.ignore_gforce_seconds = 1.0;
|
||||
}
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn despawn_old_choices(
|
||||
mut commands: Commands,
|
||||
q_conv: Query<&Chat>,
|
||||
q_choices: Query<(Entity, &ChoiceAvailable)>,
|
||||
) {
|
||||
let chats: Vec<&Chat> = q_conv.iter().collect();
|
||||
'outer: for (entity, choice) in &q_choices {
|
||||
// Let's see if this choice still has a chat in the appropriate state
|
||||
for chat in &chats {
|
||||
if choice.conv_id == chat.id && choice.conv_label == chat.label {
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
|
||||
// Despawn the choice, since no matching chat was found
|
||||
commands.entity(entity).despawn();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue