Skip to content

Commit

Permalink
Add periodically spawning powerups to FFA and CTF (#156)
Browse files Browse the repository at this point in the history
Now that support for powerups has been implemented we can start adding them to the game modes. This PR adds all the normal periodically-spawning powerups for both FFA and CTF (the 3 infernos, and the base shields for FFA).
  • Loading branch information
steamroller-airmash committed May 23, 2022
1 parent 783ffef commit c874876
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
29 changes: 28 additions & 1 deletion ctf/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use airmash::AirmashGame;
use std::time::Duration;

use airmash::{util::PeriodicPowerupSpawner, AirmashGame, Vector2};
use serde_deserialize_over::DeserializeOver;

fn set_default_var(name: &str, value: &str) {
Expand Down Expand Up @@ -61,5 +63,30 @@ fn main() {

airmash_server_ctf::setup_ctf_server(&mut game);

// Inferno in Europe
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(920.0, -2800.0),
Duration::from_secs(105),
));
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(-7440.0, -1360.0),
Duration::from_secs(105),
));
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(6565.0, -935.0),
Duration::from_secs(105),
));

// Blue base shield
game.register(PeriodicPowerupSpawner::shield(
Vector2::new(-9300.0, -1480.0),
Duration::from_secs(90),
));
// Red base shield
game.register(PeriodicPowerupSpawner::shield(
Vector2::new(8350.0, -935.0),
Duration::from_secs(90),
));

game.run_until_shutdown();
}
16 changes: 16 additions & 0 deletions ffa/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::env;
use std::fs::File;
use std::time::Duration;

use clap::arg;
use serde_deserialize_over::DeserializeOver;
Expand All @@ -8,6 +9,7 @@ use server::*;
use server::{
protocol::GameType,
resource::{Config, RegionName},
util::PeriodicPowerupSpawner,
};

mod systems;
Expand Down Expand Up @@ -48,6 +50,20 @@ fn main() {
// Use the provided FFA scoreboard systems.
server::system::ffa::register_all(&mut game);

// Inferno in Europe
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(920.0, -2800.0),
Duration::from_secs(105),
));
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(-7440.0, -1360.0),
Duration::from_secs(105),
));
game.register(PeriodicPowerupSpawner::inferno(
Vector2::new(6565.0, -935.0),
Duration::from_secs(105),
));

if let Some(path) = matches.value_of("config") {
let file = match File::open(path) {
Ok(x) => x,
Expand Down
3 changes: 3 additions & 0 deletions server-next/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ use nalgebra::vector;
use std::time::{Duration, Instant};

pub(crate) mod escapes;
mod powerup_spawner;
pub mod spectate;

pub use self::powerup_spawner::PeriodicPowerupSpawner;

pub fn convert_time(dur: Duration) -> Time {
dur.as_secs_f32() * 60.0
}
Expand Down
56 changes: 56 additions & 0 deletions server-next/src/util/powerup_spawner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::time::{Duration, Instant};

use crate::protocol::{MobType, Position};
use crate::{event::Frame, Entity, EventHandler};

#[derive(Copy, Clone)]
enum SpawnerState {
Spawned(Entity),
Unspawned(Instant),
}

pub struct PeriodicPowerupSpawner {
state: SpawnerState,
interval: Duration,
mob: MobType,
pos: Position,
}

impl PeriodicPowerupSpawner {
pub fn new(mob: MobType, pos: Position, interval: Duration) -> Self {
Self {
mob,
pos,
interval,
state: SpawnerState::Unspawned(Instant::now()),
}
}

pub fn inferno(pos: Position, interval: Duration) -> Self {
Self::new(MobType::Inferno, pos, interval)
}

pub fn shield(pos: Position, interval: Duration) -> Self {
Self::new(MobType::Shield, pos, interval)
}
}

impl EventHandler<Frame> for PeriodicPowerupSpawner {
fn on_event(&mut self, _: &Frame, game: &mut crate::AirmashGame) {
let frame = game.this_frame();

match self.state {
SpawnerState::Spawned(entity) => {
if !game.world.contains(entity) {
self.state = SpawnerState::Unspawned(frame + self.interval);
}
}
SpawnerState::Unspawned(next) => {
if frame > next {
let entity = game.spawn_mob(self.mob, self.pos, Duration::from_secs(60));
self.state = SpawnerState::Spawned(entity);
}
}
}
}
}

0 comments on commit c874876

Please sign in to comment.