#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use weasel::ability::AbilityId;
use weasel::rules::ability::SimpleAbility;
use weasel::{
battle_rules, battle_rules_with_actor, rules::empty::*, Actor, ActorRules, AlterAbilities,
BattleRules, BattleState, Entropy, EventQueue, EventTrigger, WriteMetrics,
};
pub(crate) static PUNCH: AbilityId<CustomRules> = 1;
pub(crate) static POWER_UP: AbilityId<CustomRules> = 2;
pub(crate) const PUNCH_START_POWER: u32 = 10;
battle_rules_with_actor! {
CustomActorRules
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum AbilityPower {
Passive,
Attack(u32),
}
#[derive(Default)]
pub struct CustomActorRules {}
impl ActorRules<CustomRules> for CustomActorRules {
type Ability = SimpleAbility<u32, AbilityPower>;
type AbilitiesSeed = Vec<AbilityId<CustomRules>>;
type Activation = ();
type AbilitiesAlteration = (u32, AbilityPower);
fn generate_abilities(
&self,
seed: &Option<Self::AbilitiesSeed>,
_entropy: &mut Entropy<CustomRules>,
_metrics: &mut WriteMetrics<CustomRules>,
) -> Box<dyn Iterator<Item = Self::Ability>> {
let mut v = Vec::new();
if let Some(seed) = seed {
for id in seed {
if *id == PUNCH {
v.push(SimpleAbility::new(
*id,
AbilityPower::Attack(PUNCH_START_POWER),
));
} else if *id == POWER_UP {
v.push(SimpleAbility::new(*id, AbilityPower::Passive));
}
}
}
Box::new(v.into_iter())
}
fn alter_abilities(
&self,
actor: &mut dyn Actor<CustomRules>,
alteration: &Self::AbilitiesAlteration,
_entropy: &mut Entropy<CustomRules>,
_metrics: &mut WriteMetrics<CustomRules>,
) {
let id_to_alter = alteration.0;
let new_power = alteration.1;
if let Some(ability) = actor.ability_mut(&id_to_alter) {
ability.set_power(new_power);
}
}
fn on_turn_end(
&self,
state: &BattleState<CustomRules>,
actor: &dyn Actor<CustomRules>,
event_queue: &mut Option<EventQueue<CustomRules>>,
_entropy: &mut Entropy<CustomRules>,
_metrics: &mut WriteMetrics<CustomRules>,
) {
if actor.ability(&POWER_UP).is_some() {
let count = state.entities().creatures().count();
if let Some(punch) = actor.ability(&PUNCH) {
let current_power = if let AbilityPower::Attack(p) = punch.power() {
p
} else {
0
};
let new_power = current_power + count as u32;
let alteration = (PUNCH, AbilityPower::Attack(new_power));
AlterAbilities::trigger(event_queue, *actor.entity_id(), alteration).fire();
}
}
}
}