New sceptre M2 is functional.

This commit is contained in:
Sam 2020-08-28 16:43:33 -05:00
parent 921d224ef6
commit 8b9202710f
10 changed files with 123 additions and 56 deletions

View File

@ -251,10 +251,10 @@ void main() {
);
} else if (inst_mode == HEALING_BEAM) {
attr = Attr(
vec3(rand0 * 0.2, rand1 * 0.2, rand2 * 0.2 + 1),
1,
vec3(rand0 * lifetime * 15, rand1 * lifetime * 15, rand2 * lifetime * 15 + 1),
1 + rand3,
vec4(vec3(0, 1, 0), 1),
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
spin_in_axis(vec3(1, 0, 0), 0)
);
} else {
attr = Attr(

View File

@ -313,14 +313,37 @@ impl Tool {
lifesteal_eff: 0.25,
energy_regen: 120,
},
BasicMelee {
energy_cost: 350,
buildup_duration: Duration::from_millis(0),
recover_duration: Duration::from_millis(1000),
base_healthchange: (150.0 * self.base_power()) as i32,
knockback: 0.0,
range: 100.0,
max_angle: 90.0,
BasicRanged {
energy_cost: 400,
holdable: true,
prepare_duration: Duration::from_millis(800),
recover_duration: Duration::from_millis(50),
projectile: Projectile {
hit_solid: vec![
projectile::Effect::Explode {
power: 1.4 * self.base_power(),
percent_damage: 0.2,
},
projectile::Effect::Vanish,
],
hit_entity: vec![
projectile::Effect::Explode {
power: 1.4 * self.base_power(),
percent_damage: 0.2,
},
projectile::Effect::Vanish,
],
time_left: Duration::from_secs(20),
owner: None,
ignore_group: true,
},
projectile_body: Body::Object(object::Body::BoltFireBig),
projectile_light: Some(LightEmitter {
col: (0.0, 1.0, 0.0).into(),
..Default::default()
}),
projectile_gravity: None,
projectile_speed: 25.0,
},
]
} else {
@ -368,12 +391,14 @@ impl Tool {
hit_solid: vec![
projectile::Effect::Explode {
power: 1.4 * self.base_power(),
percent_damage: 1.0,
},
projectile::Effect::Vanish,
],
hit_entity: vec![
projectile::Effect::Explode {
power: 1.4 * self.base_power(),
percent_damage: 1.0,
},
projectile::Effect::Vanish,
],

View File

@ -9,7 +9,7 @@ pub enum Effect {
Damage(i32),
Knockback(f32),
RewardEnergy(u32),
Explode { power: f32 },
Explode { power: f32, percent_damage: f32 },
Vanish,
Stick,
Possess,

View File

@ -33,6 +33,7 @@ pub enum ServerEvent {
owner: Option<Uid>,
friendly_damage: bool,
reagent: Option<Reagent>,
percent_damage: f32,
},
Damage {
uid: Uid,

View File

@ -133,13 +133,14 @@ impl<'a> System<'a> for Sys {
energy_mut.change_by(energy as i32, EnergySource::HitEnemy);
}
},
projectile::Effect::Explode { power } => {
projectile::Effect::Explode { power, percent_damage } => {
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,
power,
owner: projectile.owner,
friendly_damage: false,
reagent: None,
percent_damage,
})
},
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
@ -162,13 +163,14 @@ impl<'a> System<'a> for Sys {
if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling {
for effect in projectile.hit_solid.drain(..) {
match effect {
projectile::Effect::Explode { power } => {
projectile::Effect::Explode { power, percent_damage } => {
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,
power,
owner: projectile.owner,
friendly_damage: false,
reagent: None,
percent_damage,
})
},
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {

View File

@ -1120,6 +1120,7 @@ fn handle_explosion(
owner: ecs.read_storage::<Uid>().get(target).copied(),
friendly_damage: true,
reagent: None,
percent_damage: 1.0,
})
},
None => server.notify_client(

View File

@ -450,6 +450,7 @@ pub fn handle_explosion(
owner: Option<Uid>,
friendly_damage: bool,
reagent: Option<Reagent>,
percent_damage: f32,
) {
// Go through all other entities
let hit_range = 3.0 * power;
@ -483,18 +484,40 @@ pub fn handle_explosion(
if !stats_b.is_dead
// RADIUS
&& distance_squared < hit_range.powi(2)
// Skip if they are in the same group and friendly_damage is turned off for the
// explosion
&& (friendly_damage || !owner_entity
.and_then(|e| groups.get(e))
.map_or(false, |group_a| Some(group_a) == groups.get(entity_b)))
{
// See if entities are in the same group
let same_group = owner_entity
.and_then(|e| groups.get(e))
.map_or(false, |group_a| Some(group_a) == groups.get(entity_b));
// Don't heal if outside group
// Don't damage in the same group
let (mut is_heal, mut is_damage) = (false, false);
if (friendly_damage || !same_group) && (percent_damage > 0.0) {
is_damage = true;
}
if same_group && (percent_damage < 1.0) {
is_heal = true;
}
if !is_heal && !is_damage {
continue;
}
// Weapon gives base damage
let dmg = (1.0 - distance_squared / hit_range.powi(2)) * power * 130.0;
let source = if is_heal {
DamageSource::Healing
} else {
DamageSource::Explosion
};
let strength = (1.0 - distance_squared / hit_range.powi(2)) * power * 130.0;
let healthchange = if is_heal {
strength * (1.0 - percent_damage)
} else {
-strength * percent_damage
};
let mut damage = Damage {
healthchange: -dmg,
source: DamageSource::Explosion,
healthchange,
source,
};
let block = character_b.map(|c_b| c_b.is_block()).unwrap_or(false)
@ -520,24 +543,26 @@ pub fn handle_explosion(
const RAYS: usize = 500;
// Color terrain
let mut touched_blocks = Vec::new();
let color_range = power * 2.7;
for _ in 0..RAYS {
let dir = Vec3::new(
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
)
.normalized();
if percent_damage > 0.9 {
// Color terrain
let mut touched_blocks = Vec::new();
let color_range = power * 2.7;
for _ in 0..RAYS {
let dir = Vec3::new(
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
)
.normalized();
let _ = ecs
.read_resource::<TerrainGrid>()
.ray(pos, pos + dir * color_range)
// TODO: Faster RNG
.until(|_| rand::random::<f32>() < 0.05)
.for_each(|_: &Block, pos| touched_blocks.push(pos))
.cast();
let _ = ecs
.read_resource::<TerrainGrid>()
.ray(pos, pos + dir * color_range)
// TODO: Faster RNG
.until(|_| rand::random::<f32>() < 0.05)
.for_each(|_: &Block, pos| touched_blocks.push(pos))
.cast();
}
}
let terrain = ecs.read_resource::<TerrainGrid>();
@ -556,16 +581,6 @@ pub fn handle_explosion(
block_change.set(block_pos, Block::new(block.kind(), color));
}
}
}
// Destroy terrain
for _ in 0..RAYS {
let dir = Vec3::new(
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.15,
)
.normalized();
let terrain = ecs.read_resource::<TerrainGrid>();
let _ = terrain
@ -576,8 +591,29 @@ pub fn handle_explosion(
if block.is_explodable() {
block_change.set(pos, block.into_vacant());
}
})
.cast();
}
}
// Destroy terrain
for _ in 0..RAYS {
let dir = Vec3::new(
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.5,
rand::random::<f32>() - 0.15,
)
.normalized();
let terrain = ecs.read_resource::<TerrainGrid>();
let _ = terrain
.ray(pos, pos + dir * power)
.until(|block| block.is_fluid() || rand::random::<f32>() < 0.05)
.for_each(|block: &Block, pos| {
if block.is_explodable() {
block_change.set(pos, Block::empty());
}
})
.cast();
}
}
}

View File

@ -60,7 +60,8 @@ impl Server {
owner,
friendly_damage,
reagent,
} => handle_explosion(&self, pos, power, owner, friendly_damage, reagent),
percent_damage,
} => handle_explosion(&self, pos, power, owner, friendly_damage, reagent, percent_damage),
ServerEvent::Shoot {
entity,
dir,

View File

@ -50,6 +50,7 @@ impl<'a> System<'a> for Sys {
owner: *owner,
friendly_damage: true,
reagent: None,
percent_damage: 1.0,
});
}
},
@ -65,6 +66,7 @@ impl<'a> System<'a> for Sys {
owner: *owner,
friendly_damage: true,
reagent: Some(*reagent),
percent_damage: 1.0,
});
}
},

View File

@ -315,16 +315,15 @@ impl ParticleMgr {
{
if let CharacterState::BasicBeam(b) = character_state {
if b.buildup_duration == Duration::default() {
let scale = 5.0;
let particle_ori = b.particle_ori.unwrap_or(*ori.vec());
for _ in 0..self.scheduler.heartbeats(Duration::from_millis(10)) {
for d in 0..((b.range * scale) as i32) {
for d in 0..(b.range as i32) {
self.particles.push(
Particle::new(
Duration::from_millis(10),
Duration::from_millis(50),
time,
ParticleMode::HealingBeam,
pos.0 + particle_ori * (d as f32) / scale,
pos.0 + particle_ori * (d as f32),
),
);
}