Commit c0e64b00 authored by Ruby's avatar Ruby

Change power grants and redirects to ensure all are included in a chain

parent b5636daa
Pipeline #162931135 passed with stages
in 4 minutes and 56 seconds
......@@ -103,7 +103,7 @@ dependencies = [
[[package]]
name = "powers"
version = "2.0.3"
version = "2.0.4"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
......
[package]
name = "powers"
version = "2.0.3"
version = "2.0.4"
authors = ["Ruby <[email protected]>"]
edition = "2018"
......
......@@ -179,7 +179,8 @@ fn resolve_entity_defs_and_power_grants(
power_cats: &mut Keyed<PowerCategory>,
power_sets: &mut Keyed<BasePowerSet>,
powers: &mut Keyed<BasePower>,
) {
) -> usize {
let mut count_resolved = 0;
unsafe {
// This is probably the only non-obvious Rust-y thing you'll see in this code base.
// I'm mutating a hashmap of powers that I'm also reading from at the
......@@ -191,14 +192,12 @@ fn resolve_entity_defs_and_power_grants(
if power.include_in_output {
let power = Rc::get_mut_unchecked(power);
// check effect groups for attrib mod params we're interested in
// TODO: this needs to be made recursive -- if we include powers that themselves
// have entcreate / power attrib mods, we'll need to include those powers as well
for egroup in &mut power.pp_effects {
let egroup = Rc::get_mut_unchecked(egroup);
for attrib_mod in &mut egroup.pp_templates {
for param in &mut attrib_mod.p_params {
match param {
AttribModParam::EntCreate(e) => {
AttribModParam::EntCreate(e) if !e.resolved => {
if let Some(entity_def_name) = &e.pch_entity_def {
if let Some(entity_def) = villains.get(entity_def_name) {
// copy entity def data into the mod param
......@@ -213,8 +212,10 @@ fn resolve_entity_defs_and_power_grants(
);
}
}
e.resolved = true;
count_resolved += 1;
}
AttribModParam::Power(p) => {
AttribModParam::Power(p) if !p.resolved => {
// copy powers referred to by this param into it
mark_powers_in_power_param(
p,
......@@ -223,6 +224,8 @@ fn resolve_entity_defs_and_power_grants(
power_sets,
*p_powers.get(),
);
p.resolved = true;
count_resolved += 1;
}
_ => (),
}
......@@ -232,6 +235,7 @@ fn resolve_entity_defs_and_power_grants(
}
}
}
count_resolved
}
/// Mark the three parts represented by `power_ref` (category, set, power) to be included
......@@ -286,12 +290,14 @@ fn resolve_power_redirects(
powers: &mut Keyed<BasePower>,
power_cats: &mut Keyed<PowerCategory>,
power_sets: &mut Keyed<BasePowerSet>,
) {
) -> usize {
let mut count_resolved = 0;
// See above for note on unsafe.
unsafe {
let p_powers = UnsafeCell::new(powers);
for power in (*p_powers.get()).values() {
if power.include_in_output {
for power in (*p_powers.get()).values_mut() {
if power.include_in_output && !power.redirects_resolved {
let power = Rc::get_mut_unchecked(power);
// inspect redirects and look at what we need to keep
for redirect in &power.pp_redirect {
if let Some(power_name) = &redirect.pch_name {
......@@ -304,9 +310,12 @@ fn resolve_power_redirects(
);
}
}
power.redirects_resolved = true;
count_resolved += 1;
}
}
}
count_resolved
}
/// Read all .bin files and merge them into a single powers dictionary.
......@@ -384,19 +393,22 @@ pub fn load_powers_dictionary(config: &PowersConfig) -> Result<PowersDictionary,
}
});
// copy pet entity defs into powers
println!("Resolving entity defs and power grants ...");
resolve_entity_defs_and_power_grants(
&villains,
&villain_archetypes,
&mut power_categories,
&mut power_sets,
&mut powers,
);
// look for redirects and make sure the referenced powers are included in the output data
println!("Resolving power redirects ...");
resolve_power_redirects(&mut powers, &mut power_categories, &mut power_sets);
println!("Resolving entity defs, power grants, and redirects ...");
loop {
// copy pet entity defs into powers
let mut count = resolve_entity_defs_and_power_grants(
&villains,
&villain_archetypes,
&mut power_categories,
&mut power_sets,
&mut powers,
);
// look for redirects and make sure the referenced powers are included in the output data
count += resolve_power_redirects(&mut powers, &mut power_categories, &mut power_sets);
if count == 0 {
break;
}
}
let elapsed = Instant::now().duration_since(begin_time);
println!("Done.");
......
......@@ -730,6 +730,8 @@ pub struct AttribModParam_EntCreate {
pub villain_def: Option<Rc<VillainDef>>,
/// reference to entity's powers (not inline)
pub power_refs: Vec<NameKey>,
/// have we resolved this already? (not inline)
pub resolved: bool,
}
default_new!(AttribModParam_EntCreate);
......@@ -740,6 +742,8 @@ pub struct AttribModParam_Power {
pub ppch_category_names: Vec<NameKey>,
pub ppch_powerset_names: Vec<NameKey>,
pub ppch_power_names: Vec<NameKey>,
/// have we resolved this already? not inline
pub resolved: bool,
}
default_new!(AttribModParam_Power);
......
......@@ -1345,6 +1345,8 @@ pub struct BasePower {
pub include_in_output: bool,
/// Archetypes associated with this power.
pub archetypes: Vec<Rc<Archetype>>,
/// Have we resolved redirects on this power already?
pub redirects_resolved: bool,
}
impl BasePower {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment