skullball/rust/src/killbox.rs
2026-07-27 01:36:20 +03:00

84 lines
2.2 KiB
Rust

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<Area3D>,
}
#[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<Node3D>) {
if let Ok(mut player) = node.clone().try_dynify::<dyn IPlayer>() {
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::<Ball>() {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().respawn_ball();
}
}
}
}