Make fireworks recursively shoot more fireworks (95% average replication).

This commit is contained in:
Avi Weinstock 2021-03-06 14:03:21 -05:00
parent e6f5f04c8e
commit 22fcc6417c
10 changed files with 80 additions and 10 deletions

View File

@ -62,6 +62,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- "Quest" given to new players converted to being a short tutorial
- Items can be requested from the counterparty's inventory during trade.
- Savanna grasses restricted to savanna, cacti to desert.
- Fireworks recursively shoot more fireworks.
### Removed

View File

@ -1,4 +1,4 @@
use crate::make_case_elim;
use crate::{comp::item::Reagent, make_case_elim};
use rand::{seq::SliceRandom, thread_rng};
use serde::{Deserialize, Serialize};
@ -227,4 +227,14 @@ impl Body {
Body::Coins => "coins",
}
}
pub fn for_firework(reagent: Reagent) -> Body {
match reagent {
Reagent::Blue => Body::FireworkBlue,
Reagent::Green => Body::FireworkGreen,
Reagent::Purple => Body::FireworkPurple,
Reagent::Red => Body::FireworkRed,
Reagent::Yellow => Body::FireworkYellow,
}
}
}

View File

@ -65,6 +65,7 @@ pub enum ServerEvent {
projectile: comp::Projectile,
gravity: Option<comp::Gravity>,
speed: f32,
object: Option<comp::Object>,
},
Shockwave {
properties: comp::shockwave::Properties,

View File

@ -95,6 +95,7 @@ impl CharacterBehavior for Data {
light: self.static_data.projectile_light,
gravity: self.static_data.projectile_gravity,
speed: self.static_data.projectile_speed,
object: None,
});
update.character = CharacterState::BasicRanged(Data {

View File

@ -149,6 +149,7 @@ impl CharacterBehavior for Data {
gravity: self.static_data.projectile_gravity,
speed: self.static_data.initial_projectile_speed
+ charge_frac * self.static_data.scaled_projectile_speed,
object: None,
});
update.character = CharacterState::ChargedRanged(Data {

View File

@ -163,6 +163,7 @@ impl CharacterBehavior for Data {
light: self.static_data.projectile_light,
gravity: self.static_data.projectile_gravity,
speed: self.static_data.projectile_speed,
object: None,
});
// Shoot projectiles

View File

@ -10,7 +10,7 @@ use common::{
group,
inventory::loadout::Loadout,
shockwave, Agent, Alignment, Body, Gravity, Health, HomeChunk, Inventory, Item, ItemDrop,
LightEmitter, Ori, Poise, Pos, Projectile, Scale, Stats, Vel, WaypointArea,
LightEmitter, Object, Ori, Poise, Pos, Projectile, Scale, Stats, Vel, WaypointArea,
},
outcome::Outcome,
rtsim::RtSimEntity,
@ -120,6 +120,7 @@ pub fn handle_shoot(
projectile: Projectile,
gravity: Option<Gravity>,
speed: f32,
object: Option<Object>,
) {
let state = server.state_mut();
@ -152,6 +153,9 @@ pub fn handle_shoot(
if let Some(gravity) = gravity {
builder = builder.with(gravity)
}
if let Some(object) = object {
builder = builder.with(object)
}
builder.build();
}

View File

@ -644,13 +644,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
let mut new_entity = state
.create_object(Default::default(), match kind {
item::Throwable::Bomb => comp::object::Body::Bomb,
item::Throwable::Firework(reagent) => match reagent {
item::Reagent::Blue => comp::object::Body::FireworkBlue,
item::Reagent::Green => comp::object::Body::FireworkGreen,
item::Reagent::Purple => comp::object::Body::FireworkPurple,
item::Reagent::Red => comp::object::Body::FireworkRed,
item::Reagent::Yellow => comp::object::Body::FireworkYellow,
},
item::Throwable::Firework(reagent) => comp::object::Body::for_firework(reagent),
item::Throwable::TrainingDummy => comp::object::Body::TrainingDummy,
})
.with(comp::Pos(pos.0 + Vec3::unit_z() * 0.25))

View File

@ -74,7 +74,10 @@ impl Server {
projectile,
gravity,
speed,
} => handle_shoot(self, entity, dir, body, light, projectile, gravity, speed),
object,
} => handle_shoot(
self, entity, dir, body, light, projectile, gravity, speed, object,
),
ServerEvent::Shockwave {
properties,
pos,

View File

@ -68,6 +68,60 @@ impl<'a> System<'a> for Sys {
},
Object::Firework { owner, reagent } => {
if vel.0.z < 0.0 {
const ENABLE_RECURSIVE_FIREWORKS: bool = true;
if ENABLE_RECURSIVE_FIREWORKS {
use common::{
comp::{object, Body, Gravity, LightEmitter, Projectile},
util::Dir,
};
use rand::Rng;
use std::{f32::consts::PI, time::Duration};
use vek::{Rgb, Vec3};
let mut rng = rand::thread_rng();
// Note that if the expected fireworks per firework is > 1, this will
// eventually cause enough server lag that more players can't log in.
// 0.25 * 2 + (0.70 - 0.25) * 1 = 0.5 + 0.45 = 0.95
let num_fireworks = match rng.gen_range(0.0..1.0) {
x if x < 0.25 => 2,
x if x < 0.70 => 1,
_ => 0,
};
for _ in 0..num_fireworks {
let speed: f32 = rng.gen_range(40.0..80.0);
let theta: f32 = rng.gen_range(0.0..2.0 * PI);
let phi: f32 = rng.gen_range(0.25 * PI..0.5 * PI);
let dir = Dir::from_unnormalized(Vec3::new(
theta.cos(),
theta.sin(),
phi.sin(),
))
.expect("nonzero vector should normalize");
server_emitter.emit(ServerEvent::Shoot {
entity,
dir,
body: Body::Object(object::Body::for_firework(*reagent)),
light: Some(LightEmitter {
animated: true,
flicker: 2.0,
strength: 2.0,
col: Rgb::new(1.0, 1.0, 0.0),
}),
projectile: Projectile {
hit_solid: Vec::new(),
hit_entity: Vec::new(),
time_left: Duration::from_secs(60),
owner: *owner,
ignore_group: true,
},
gravity: Some(Gravity(1.0)),
speed,
object: Some(Object::Firework {
owner: *owner,
reagent: *reagent,
}),
});
}
}
server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::Suicide,