Complete section 5.24
This commit is contained in:
parent
52235a571e
commit
408f9e6ab9
@ -1,9 +1,11 @@
|
|||||||
|
use ::rltk::RandomNumberGenerator;
|
||||||
use ::specs::prelude::*;
|
use ::specs::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::components::{
|
||||||
Chasing, Faction, MyTurn, Position, Viewshed, WantsToApproach, WantsToFlee,
|
Chasing, Faction, MyTurn, Name, Position, SpecialAbilities, SpellTemplate, Viewshed,
|
||||||
|
WantsToApproach, WantsToCastSpell, WantsToFlee,
|
||||||
};
|
};
|
||||||
use crate::raws::{self, Reaction, RAWS};
|
use crate::raws::{self, find_spell_entity_by_name, Reaction, RAWS};
|
||||||
use crate::{spatial, Map};
|
use crate::{spatial, Map};
|
||||||
|
|
||||||
pub struct VisibleAI {}
|
pub struct VisibleAI {}
|
||||||
@ -21,9 +23,15 @@ impl<'a> System<'a> for VisibleAI {
|
|||||||
ReadExpect<'a, Entity>,
|
ReadExpect<'a, Entity>,
|
||||||
ReadStorage<'a, Viewshed>,
|
ReadStorage<'a, Viewshed>,
|
||||||
WriteStorage<'a, Chasing>,
|
WriteStorage<'a, Chasing>,
|
||||||
|
ReadStorage<'a, SpecialAbilities>,
|
||||||
|
WriteExpect<'a, RandomNumberGenerator>,
|
||||||
|
WriteStorage<'a, WantsToCastSpell>,
|
||||||
|
ReadStorage<'a, Name>,
|
||||||
|
ReadStorage<'a, SpellTemplate>,
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(&mut self, data: Self::SystemData) {
|
fn run(&mut self, data: Self::SystemData) {
|
||||||
|
use ::rltk::{DistanceAlg, Point};
|
||||||
let (
|
let (
|
||||||
turns,
|
turns,
|
||||||
factions,
|
factions,
|
||||||
@ -35,6 +43,11 @@ impl<'a> System<'a> for VisibleAI {
|
|||||||
player,
|
player,
|
||||||
viewsheds,
|
viewsheds,
|
||||||
mut chasing,
|
mut chasing,
|
||||||
|
abilities,
|
||||||
|
mut rng,
|
||||||
|
mut casting,
|
||||||
|
names,
|
||||||
|
spells,
|
||||||
) = data;
|
) = data;
|
||||||
|
|
||||||
for (entity, _turn, my_faction, pos, viewshed) in
|
for (entity, _turn, my_faction, pos, viewshed) in
|
||||||
@ -55,18 +68,56 @@ impl<'a> System<'a> for VisibleAI {
|
|||||||
for reaction in reactions.iter() {
|
for reaction in reactions.iter() {
|
||||||
match reaction.1 {
|
match reaction.1 {
|
||||||
Reaction::Attack => {
|
Reaction::Attack => {
|
||||||
want_approach
|
if let Some(abilities) = abilities.get(entity) {
|
||||||
.insert(
|
let range = DistanceAlg::Pythagoras.distance2d(
|
||||||
entity,
|
Point::from(*pos),
|
||||||
WantsToApproach {
|
Point::new(
|
||||||
idx: reaction.0 as i32,
|
reaction.0 as i32 % map.width,
|
||||||
},
|
reaction.0 as i32 / map.width,
|
||||||
)
|
),
|
||||||
.expect("Unable to insert intent to approach");
|
);
|
||||||
chasing
|
for ability in abilities.abilities.iter() {
|
||||||
.insert(entity, Chasing { target: reaction.2 })
|
if range >= ability.min_range
|
||||||
.expect("Unable to insert intent to chase");
|
&& range <= ability.range
|
||||||
done = true;
|
&& rng.roll_dice(1, 100) >= (ability.chance * 100.0) as i32
|
||||||
|
{
|
||||||
|
casting
|
||||||
|
.insert(
|
||||||
|
entity,
|
||||||
|
WantsToCastSpell {
|
||||||
|
spell: find_spell_entity_by_name(
|
||||||
|
&ability.spell,
|
||||||
|
&names,
|
||||||
|
&spells,
|
||||||
|
&entities,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
target: Some(Point::new(
|
||||||
|
reaction.0 as i32 % map.width,
|
||||||
|
reaction.0 as i32 / map.width,
|
||||||
|
)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Unable to insert intent to cast spell");
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !done {
|
||||||
|
want_approach
|
||||||
|
.insert(
|
||||||
|
entity,
|
||||||
|
WantsToApproach {
|
||||||
|
idx: reaction.0 as i32,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.expect("Unable to insert intent to approach");
|
||||||
|
chasing
|
||||||
|
.insert(entity, Chasing { target: reaction.2 })
|
||||||
|
.expect("Unable to insert intent to chase");
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reaction::Flee => {
|
Reaction::Flee => {
|
||||||
flee.push(reaction.0);
|
flee.push(reaction.0);
|
||||||
|
@ -445,3 +445,16 @@ pub struct Slow {
|
|||||||
pub struct DamageOverTime {
|
pub struct DamageOverTime {
|
||||||
pub damage: i32,
|
pub damage: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SpecialAbility {
|
||||||
|
pub spell: String,
|
||||||
|
pub chance: f32,
|
||||||
|
pub range: f32,
|
||||||
|
pub min_range: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
|
pub struct SpecialAbilities {
|
||||||
|
pub abilities: Vec<SpecialAbility>,
|
||||||
|
}
|
||||||
|
@ -140,6 +140,7 @@ fn init_state() -> State {
|
|||||||
Slow,
|
Slow,
|
||||||
SpawnParticleBurst,
|
SpawnParticleBurst,
|
||||||
SpawnParticleLine,
|
SpawnParticleLine,
|
||||||
|
SpecialAbilities,
|
||||||
SpellTemplate,
|
SpellTemplate,
|
||||||
StatusEffect,
|
StatusEffect,
|
||||||
TeachesSpell,
|
TeachesSpell,
|
||||||
|
@ -24,6 +24,15 @@ pub struct Mob {
|
|||||||
pub faction: Option<String>,
|
pub faction: Option<String>,
|
||||||
pub gold: Option<String>,
|
pub gold: Option<String>,
|
||||||
pub vendor: Option<Vec<String>>,
|
pub vendor: Option<Vec<String>>,
|
||||||
|
pub abilities: Option<Vec<MobAbility>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct MobAbility {
|
||||||
|
pub spell: String,
|
||||||
|
pub chance: f32,
|
||||||
|
pub range: f32,
|
||||||
|
pub min_range: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -647,6 +647,20 @@ pub fn spawn_named_mob(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(ability_list) = &mob_template.abilities {
|
||||||
|
let mut a = SpecialAbilities::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();
|
let new_mob = eb.build();
|
||||||
|
|
||||||
// Are they wielding anything?
|
// Are they wielding anything?
|
||||||
@ -821,3 +835,18 @@ pub fn find_spell_entity(ecs: &World, name: &str) -> Option<Entity> {
|
|||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_spell_entity_by_name(
|
||||||
|
name: &str,
|
||||||
|
names: &ReadStorage<Name>,
|
||||||
|
spell_templates: &ReadStorage<SpellTemplate>,
|
||||||
|
entities: &Entities,
|
||||||
|
) -> Option<Entity> {
|
||||||
|
for (entity, sname, _template) in (entities, names, spell_templates).join() {
|
||||||
|
if name == sname.name {
|
||||||
|
return Some(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
@ -118,6 +118,7 @@ pub fn save_game(ecs: &mut World) {
|
|||||||
Slow,
|
Slow,
|
||||||
SpawnParticleBurst,
|
SpawnParticleBurst,
|
||||||
SpawnParticleLine,
|
SpawnParticleLine,
|
||||||
|
SpecialAbilities,
|
||||||
SpellTemplate,
|
SpellTemplate,
|
||||||
StatusEffect,
|
StatusEffect,
|
||||||
TeachesSpell,
|
TeachesSpell,
|
||||||
@ -248,6 +249,7 @@ pub fn load_game(ecs: &mut World) {
|
|||||||
Skills,
|
Skills,
|
||||||
SpawnParticleBurst,
|
SpawnParticleBurst,
|
||||||
SpawnParticleLine,
|
SpawnParticleLine,
|
||||||
|
SpecialAbilities,
|
||||||
SpellTemplate,
|
SpellTemplate,
|
||||||
StatusEffect,
|
StatusEffect,
|
||||||
TeachesSpell,
|
TeachesSpell,
|
||||||
|
Loading…
Reference in New Issue
Block a user