Complete section 5.26
This commit is contained in:
parent
051be94bc9
commit
a40f43b839
@ -521,3 +521,8 @@ pub struct TileSize {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
#[derive(Component, Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct OnDeath {
|
||||
pub abilities: Vec<SpecialAbility>,
|
||||
}
|
||||
|
@ -51,3 +51,6 @@ pub struct ProvidesIdentification {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Confusion {}
|
||||
|
||||
#[derive(Component, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct AlwaysTargetsSelf {}
|
||||
|
@ -1,10 +1,13 @@
|
||||
use ::rltk::RandomNumberGenerator;
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use crate::components::{Equipped, InBackpack, LootTable, Name, Player, Pools, Position};
|
||||
use crate::components::{
|
||||
AreaOfEffect, Equipped, InBackpack, LootTable, Name, OnDeath, Player, Pools, Position,
|
||||
};
|
||||
use crate::effects::*;
|
||||
use crate::game_log::GameLog;
|
||||
use crate::raws::{self, SpawnType, RAWS};
|
||||
use crate::RunState;
|
||||
use crate::{Map, RunState};
|
||||
|
||||
pub fn delete_the_dead(ecs: &mut World) {
|
||||
let mut dead: Vec<Entity> = Vec::new();
|
||||
@ -101,6 +104,42 @@ pub fn delete_the_dead(ecs: &mut World) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fire death events
|
||||
for victim in dead.iter() {
|
||||
let death_effects = ecs.read_storage::<OnDeath>();
|
||||
if let Some(death_effect) = death_effects.get(*victim) {
|
||||
let mut rng = ecs.fetch_mut::<RandomNumberGenerator>();
|
||||
for effect in death_effect.abilities.iter() {
|
||||
if rng.roll_dice(1, 100) <= (effect.chance * 100.0) as i32 {
|
||||
let map = ecs.fetch::<Map>();
|
||||
if let Some(pos) = ecs.read_storage::<Position>().get(*victim) {
|
||||
let spell_entity =
|
||||
crate::raws::find_spell_entity(ecs, &effect.spell).unwrap();
|
||||
let tile_idx = map.xy_idx(pos.x, pos.y);
|
||||
let target = if let Some(aoe) =
|
||||
ecs.read_storage::<AreaOfEffect>().get(spell_entity)
|
||||
{
|
||||
Targets::Tiles {
|
||||
tiles: aoe_tiles(&map, rltk::Point::new(pos.x, pos.y), aoe.radius),
|
||||
}
|
||||
} else {
|
||||
Targets::Tile {
|
||||
tile_idx: tile_idx as i32,
|
||||
}
|
||||
};
|
||||
add_effect(
|
||||
None,
|
||||
EffectType::SpellUse {
|
||||
spell: crate::raws::find_spell_entity(ecs, &effect.spell).unwrap(),
|
||||
},
|
||||
target,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for victim in dead {
|
||||
ecs.delete_entity(victim)
|
||||
.expect("Unable to delete the dead");
|
||||
|
@ -1,15 +1,17 @@
|
||||
use ::rltk::Point;
|
||||
use ::specs::prelude::*;
|
||||
|
||||
use super::{add_effect, EffectType, Targets};
|
||||
use crate::components::{
|
||||
AttributeBonus, Confusion, Consumable, DamageOverTime, Duration, Hidden, InflictsDamage,
|
||||
MagicMapper, Name, Pools, ProvidesFood, ProvidesHealing, ProvidesIdentification, ProvidesMana,
|
||||
ProvidesRemoveCurse, SingleActivation, Slow, SpawnParticleBurst, SpawnParticleLine,
|
||||
SpellTemplate, TeachesSpell, TeleportTo, TownPortal,
|
||||
AlwaysTargetsSelf, AreaOfEffect, AttributeBonus, Confusion, Consumable, DamageOverTime,
|
||||
Duration, Hidden, InflictsDamage, KnownSpell, KnownSpells, MagicMapper, Name, Pools, Position,
|
||||
ProvidesFood, ProvidesHealing, ProvidesIdentification, ProvidesMana, ProvidesRemoveCurse,
|
||||
SingleActivation, Slow, SpawnParticleBurst, SpawnParticleLine, SpellTemplate, TeachesSpell,
|
||||
TeleportTo, TownPortal,
|
||||
};
|
||||
use crate::effects::{entity_position, targeting};
|
||||
use crate::effects::{aoe_tiles, entity_position, targeting};
|
||||
use crate::raws::find_spell_entity;
|
||||
use crate::{colors, GameLog, KnownSpell, KnownSpells, Map, RunState};
|
||||
use crate::{colors, GameLog, Map, RunState};
|
||||
|
||||
pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ecs: &mut World) {
|
||||
// Check charges
|
||||
@ -44,6 +46,8 @@ pub fn item_trigger(creator: Option<Entity>, item: Entity, targets: &Targets, ec
|
||||
}
|
||||
|
||||
pub fn spell_trigger(creator: Option<Entity>, spell: Entity, targets: &Targets, ecs: &mut World) {
|
||||
let mut targeting = targets.clone();
|
||||
let mut self_destruct = false;
|
||||
if let Some(template) = ecs.read_storage::<SpellTemplate>().get(spell) {
|
||||
let mut pools = ecs.write_storage::<Pools>();
|
||||
if let Some(caster) = creator {
|
||||
@ -52,10 +56,33 @@ pub fn spell_trigger(creator: Option<Entity>, spell: Entity, targets: &Targets,
|
||||
pool.mana.current -= template.mana_cost;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle self-targeting override
|
||||
if ecs.read_storage::<AlwaysTargetsSelf>().get(spell).is_some() {
|
||||
if let Some(pos) = ecs.read_storage::<Position>().get(caster) {
|
||||
let map = ecs.fetch::<Map>();
|
||||
targeting = if let Some(aoe) = ecs.read_storage::<AreaOfEffect>().get(spell) {
|
||||
Targets::Tiles {
|
||||
tiles: aoe_tiles(&map, Point::new(pos.x, pos.y), aoe.radius),
|
||||
}
|
||||
} else {
|
||||
Targets::Tile {
|
||||
tile_idx: map.xy_idx(pos.x, pos.y) as i32,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(_destruct) = ecs.read_storage::<SingleActivation>().get(spell) {
|
||||
self_destruct = true;
|
||||
}
|
||||
}
|
||||
|
||||
event_trigger(creator, spell, targets, ecs);
|
||||
event_trigger(creator, spell, &targeting, ecs);
|
||||
if self_destruct && creator.is_some() {
|
||||
ecs.entities()
|
||||
.delete(creator.unwrap())
|
||||
.expect("Unable to delete owner");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trigger(creator: Option<Entity>, trigger: Entity, targets: &Targets, ecs: &mut World) {
|
||||
@ -320,7 +347,7 @@ fn event_trigger(
|
||||
}
|
||||
|
||||
fn spawn_line_particles(ecs: &World, start: i32, end: i32, part: &SpawnParticleLine) {
|
||||
use ::rltk::{LineAlg, Point};
|
||||
use ::rltk::LineAlg;
|
||||
|
||||
let map = ecs.fetch::<Map>();
|
||||
let start_pt = Point::new(start % map.width, end / map.width);
|
||||
|
@ -81,6 +81,7 @@ fn init_state() -> State {
|
||||
|
||||
register!(
|
||||
state <-
|
||||
AlwaysTargetsSelf,
|
||||
ApplyMove,
|
||||
ApplyTeleport,
|
||||
AreaOfEffect,
|
||||
@ -120,6 +121,7 @@ fn init_state() -> State {
|
||||
Name,
|
||||
NaturalAttackDefense,
|
||||
ObfuscatedName,
|
||||
OnDeath,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
|
@ -25,6 +25,7 @@ pub struct Mob {
|
||||
pub gold: Option<String>,
|
||||
pub vendor: Option<Vec<String>>,
|
||||
pub abilities: Option<Vec<MobAbility>>,
|
||||
pub on_death: Option<Vec<MobAbility>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
@ -337,6 +337,7 @@ macro_rules! apply_effects {
|
||||
damage: effect.1.parse::<i32>().unwrap(),
|
||||
})
|
||||
}
|
||||
"target_self" => $eb = $eb.with(AlwaysTargetsSelf {}),
|
||||
_ => {
|
||||
console::log(format!(
|
||||
"WARNING: consumable effect '{}' not implemented.",
|
||||
@ -667,6 +668,20 @@ pub fn spawn_named_mob(
|
||||
eb = eb.with(a);
|
||||
}
|
||||
|
||||
if let Some(ability_list) = &mob_template.on_death {
|
||||
let mut a = OnDeath::default();
|
||||
for ability in ability_list.iter() {
|
||||
a.abilities.push(SpecialAbility {
|
||||
chance: ability.chance,
|
||||
spell: ability.spell.clone(),
|
||||
range: ability.range,
|
||||
min_range: ability.min_range,
|
||||
});
|
||||
}
|
||||
|
||||
eb = eb.with(a);
|
||||
}
|
||||
|
||||
let new_mob = eb.build();
|
||||
|
||||
// Are they wielding anything?
|
||||
|
@ -60,6 +60,7 @@ pub fn save_game(ecs: &mut World) {
|
||||
ecs,
|
||||
serializer,
|
||||
data,
|
||||
AlwaysTargetsSelf,
|
||||
ApplyMove,
|
||||
ApplyTeleport,
|
||||
AreaOfEffect,
|
||||
@ -99,6 +100,7 @@ pub fn save_game(ecs: &mut World) {
|
||||
Name,
|
||||
NaturalAttackDefense,
|
||||
ObfuscatedName,
|
||||
OnDeath,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
@ -192,6 +194,7 @@ pub fn load_game(ecs: &mut World) {
|
||||
ecs,
|
||||
de,
|
||||
d,
|
||||
AlwaysTargetsSelf,
|
||||
ApplyMove,
|
||||
ApplyTeleport,
|
||||
AreaOfEffect,
|
||||
@ -231,6 +234,7 @@ pub fn load_game(ecs: &mut World) {
|
||||
Name,
|
||||
NaturalAttackDefense,
|
||||
ObfuscatedName,
|
||||
OnDeath,
|
||||
OtherLevelPosition,
|
||||
ParticleLifetime,
|
||||
Player,
|
||||
|
Loading…
Reference in New Issue
Block a user