use godot::{ classes::{Area3D, IArea3D}, prelude::*, }; use serde::{Deserialize, Serialize}; use crate::{ game_manager::Game, net::network_manager::NetworkManager, player::{DamageSource, IPlayer, ball::Ball}, }; #[derive(Debug, Clone, Copy, GodotConvert, Default, Var, Serialize, Deserialize, Export)] #[godot(via = GString)] pub enum KillboxKind { #[default] Void, Spikes, Lava, SeaOfBlood, OuterSpace, Quicksand, LargeBoulder, ElectricFence, RadioactiveGoo, } impl KillboxKind { pub fn as_kill_text(&self) -> String { match self { KillboxKind::Void => " fell into the void", KillboxKind::Spikes => " got impailed by spikes", KillboxKind::Lava => " burned in lava", KillboxKind::SeaOfBlood => " went looking for the Iron Lung", KillboxKind::OuterSpace => " suffocated in outer space", KillboxKind::Quicksand => " drowned in a pit of sand", KillboxKind::LargeBoulder => { " was squished by a large boulder the size of a small boulder" } KillboxKind::ElectricFence => " got electrocuted by a fence", KillboxKind::RadioactiveGoo => { " turned into a mutant..! no, died of radiation poisoning." } } .to_string() } } #[derive(GodotClass)] #[class(base=Area3D, init)] pub struct Killbox { #[export] #[var] pub kind: KillboxKind, base: Base, } #[godot_api] impl IArea3D for Killbox { fn ready(&mut self) { self.base() .signals() .body_entered() .connect_other(self, |s, body| s.kill(body)); } } impl Killbox { pub fn kill(&mut self, node: Gd) { if let Ok(mut player) = node.clone().try_dynify::() { if NetworkManager::singleton().bind().is_host() { player .dyn_bind_mut() .take_damage(DamageSource::Killbox(self.kind), 1000, true); } } else if let Ok(_) = node.try_cast::() { if let Some(game) = &mut Game::singleton() { game.bind_mut().respawn_ball(); } } } }