Merge branch 'master' of ssh://cryps.gg:40022/~/cryps into battleui
This commit is contained in:
commit
6302e2c362
@ -17,10 +17,14 @@
|
|||||||
|
|
||||||
* skills
|
* skills
|
||||||
* offensive -> choose target ✔
|
* offensive -> choose target ✔
|
||||||
|
* ensure cryp untargetable and doesn't resolve when KO
|
||||||
|
* calculate
|
||||||
|
* hp increase/decrease
|
||||||
|
* spell/phys dmg
|
||||||
* private fields for opponents
|
* private fields for opponents
|
||||||
* cooldowns reduce each turn ✔
|
* cooldowns reduce each turn ✔
|
||||||
* statuses reduce each turn
|
* statuses reduce each turn
|
||||||
* teach cyps skills
|
* teach cyps skills ✔
|
||||||
* can you attack yourself?
|
* can you attack yourself?
|
||||||
* fetch existing battles
|
* fetch existing battles
|
||||||
* check for game participation
|
* check for game participation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use failure::err_msg;
|
|||||||
|
|
||||||
use account::Account;
|
use account::Account;
|
||||||
use rpc::{CrypSpawnParams};
|
use rpc::{CrypSpawnParams};
|
||||||
use skill::{Skill, Cooldown, Effect, Tick};
|
use skill::{Skill, Cooldown, Effect, Cast, Source};
|
||||||
use game::{Log};
|
use game::{Log};
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
@ -33,14 +33,7 @@ impl CrypSkill {
|
|||||||
pub struct CrypEffect {
|
pub struct CrypEffect {
|
||||||
pub effect: Effect,
|
pub effect: Effect,
|
||||||
pub duration: u8,
|
pub duration: u8,
|
||||||
pub tick: Option<Tick>,
|
pub tick: Option<Cast>,
|
||||||
}
|
|
||||||
|
|
||||||
impl CrypEffect {
|
|
||||||
pub fn tick(&self, cryp: &mut Cryp, log: &mut Log) -> &CrypEffect {
|
|
||||||
self.effect.tick(self, cryp, log);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
@ -48,31 +41,31 @@ pub enum Stat {
|
|||||||
Str,
|
Str,
|
||||||
Agi,
|
Agi,
|
||||||
Int,
|
Int,
|
||||||
PhysicalDmg,
|
PhysDmg,
|
||||||
SpellPower,
|
SpellDmg,
|
||||||
Hp,
|
Hp,
|
||||||
Stam,
|
Stam,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
pub struct CrypStat {
|
pub struct CrypStat {
|
||||||
pub value: u64,
|
base: u64,
|
||||||
pub stat: Stat,
|
pub stat: Stat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CrypStat {
|
impl CrypStat {
|
||||||
pub fn set(&mut self, v: u64) -> &CrypStat {
|
pub fn set(&mut self, v: u64) -> &CrypStat {
|
||||||
self.value = v;
|
self.base = v;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reduce(&mut self, amt: u64) -> &mut CrypStat {
|
pub fn reduce(&mut self, amt: u64) -> &mut CrypStat {
|
||||||
self.value = self.value.saturating_sub(amt);
|
self.base = self.base.saturating_sub(amt);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn increase(&mut self, amt: u64) -> &mut CrypStat {
|
pub fn increase(&mut self, amt: u64) -> &mut CrypStat {
|
||||||
self.value = self.value.saturating_add(amt);
|
self.base = self.base.saturating_add(amt);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,10 +97,10 @@ impl Cryp {
|
|||||||
return Cryp {
|
return Cryp {
|
||||||
id,
|
id,
|
||||||
account: id,
|
account: id,
|
||||||
phys_dmg: CrypStat { value: 0, stat: Stat::Str },
|
phys_dmg: CrypStat { base: 0, stat: Stat::Str },
|
||||||
spell_dmg: CrypStat { value: 0, stat: Stat::Int },
|
spell_dmg: CrypStat { base: 0, stat: Stat::Int },
|
||||||
stamina: CrypStat { value: 0, stat: Stat::Stam },
|
stamina: CrypStat { base: 0, stat: Stat::Stam },
|
||||||
hp: CrypStat { value: 0, stat: Stat::Hp },
|
hp: CrypStat { base: 0, stat: Stat::Hp },
|
||||||
lvl: 0,
|
lvl: 0,
|
||||||
xp: 0,
|
xp: 0,
|
||||||
skills: vec![CrypSkill::new(Skill::Attack)],
|
skills: vec![CrypSkill::new(Skill::Attack)],
|
||||||
@ -126,7 +119,6 @@ impl Cryp {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn level(mut self, lvl: u8) -> Cryp {
|
pub fn level(mut self, lvl: u8) -> Cryp {
|
||||||
self.lvl = check_lvl(lvl);
|
self.lvl = check_lvl(lvl);
|
||||||
self
|
self
|
||||||
@ -167,17 +159,26 @@ impl Cryp {
|
|||||||
self.phys_dmg.set(rng.gen_range(min, max));
|
self.phys_dmg.set(rng.gen_range(min, max));
|
||||||
self.spell_dmg.set(rng.gen_range(min, max));
|
self.spell_dmg.set(rng.gen_range(min, max));
|
||||||
self.stamina.set(rng.gen_range(min, max));
|
self.stamina.set(rng.gen_range(min, max));
|
||||||
self.hp.set(self.stamina.value);
|
self.hp.set(self.stamina.base);
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_ko(&self) -> bool {
|
pub fn is_ko(&self) -> bool {
|
||||||
self.hp.value == 0
|
self.hp.base == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn immune(&self, skill: Skill) -> bool {
|
pub fn immune(&self, skill: Skill) -> (bool, Vec<Effect>) {
|
||||||
self.effects.iter().any(|e| e.effect.immune(skill))
|
let immunities = self.effects.iter()
|
||||||
|
.filter(|e| e.effect.immune(skill))
|
||||||
|
.map(|e| e.effect)
|
||||||
|
.collect::<Vec<Effect>>();
|
||||||
|
|
||||||
|
if immunities.len() > 0 {
|
||||||
|
return (true, immunities);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false, vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_stunned(&self) -> bool {
|
pub fn is_stunned(&self) -> bool {
|
||||||
@ -210,7 +211,7 @@ impl Cryp {
|
|||||||
if let Some(cd) = skill.skill.cd() {
|
if let Some(cd) = skill.skill.cd() {
|
||||||
// if the cd is 1 it becomes none
|
// if the cd is 1 it becomes none
|
||||||
if cd == 1 {
|
if cd == 1 {
|
||||||
println!("{:?} is now off cd", skill.skill);
|
// println!("{:?} is now off cd", skill.skill);
|
||||||
skill.cd = None;
|
skill.cd = None;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -226,7 +227,6 @@ impl Cryp {
|
|||||||
pub fn reduce_effect_durations(&mut self, log: &mut Log) -> &mut Cryp {
|
pub fn reduce_effect_durations(&mut self, log: &mut Log) -> &mut Cryp {
|
||||||
self.effects = self.effects.clone().into_iter().filter_map(|mut effect| {
|
self.effects = self.effects.clone().into_iter().filter_map(|mut effect| {
|
||||||
|
|
||||||
effect.tick(self, log);
|
|
||||||
effect.duration = effect.duration.saturating_sub(1);
|
effect.duration = effect.duration.saturating_sub(1);
|
||||||
|
|
||||||
if effect.duration == 0 {
|
if effect.duration == 0 {
|
||||||
@ -241,9 +241,67 @@ impl Cryp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn rez(&mut self) -> &mut Cryp {
|
pub fn rez(&mut self) -> &mut Cryp {
|
||||||
self.hp.set(self.stamina.value);
|
self.hp.set(self.stamina.base);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stats
|
||||||
|
pub fn phys_dmg(&self) -> u64 {
|
||||||
|
let phys_dmg_mods = self.effects.iter()
|
||||||
|
.filter(|e| e.effect.modifications().contains(&Stat::PhysDmg))
|
||||||
|
.map(|cryp_effect| cryp_effect.effect)
|
||||||
|
.collect::<Vec<Effect>>();
|
||||||
|
println!("{:?} phys_dmg mods : {:?}", self.name, phys_dmg_mods);
|
||||||
|
let modified_phys_dmg = phys_dmg_mods.iter().fold(self.phys_dmg.base, |acc, m| m.apply(acc));
|
||||||
|
println!("{:?} phys_dmg : {:?}", self.name, modified_phys_dmg);
|
||||||
|
return modified_phys_dmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spell_dmg(&self) -> u64 {
|
||||||
|
let spell_dmg_mods = self.effects.iter()
|
||||||
|
.filter(|e| e.effect.modifications().contains(&Stat::SpellDmg))
|
||||||
|
.map(|cryp_effect| cryp_effect.effect)
|
||||||
|
.collect::<Vec<Effect>>();
|
||||||
|
println!("{:?} spell_dmg mods : {:?}", self.name, spell_dmg_mods);
|
||||||
|
let modified_spell_dmg = spell_dmg_mods.iter().fold(self.spell_dmg.base, |acc, m| m.apply(acc));
|
||||||
|
println!("{:?} spell_dmg : {:?}", self.name, modified_spell_dmg);
|
||||||
|
return modified_spell_dmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hp(&self) -> u64 {
|
||||||
|
self.hp.base
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stamina(&self) -> u64 {
|
||||||
|
self.stamina.base
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat modifications
|
||||||
|
pub fn heal(&mut self, amount: u64) -> (u64, u64) {
|
||||||
|
let current_hp = self.hp();
|
||||||
|
let new_hp = *[
|
||||||
|
self.hp().saturating_add(amount),
|
||||||
|
self.stamina()
|
||||||
|
].iter().min().unwrap();
|
||||||
|
|
||||||
|
self.hp.set(new_hp);
|
||||||
|
|
||||||
|
let healing = new_hp - current_hp;
|
||||||
|
let overhealing = amount - healing;
|
||||||
|
return (healing, overhealing);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deal_phys_dmg(&mut self, amount: u64) -> (u64, u64) {
|
||||||
|
self.hp.reduce(amount);
|
||||||
|
println!("{:?} dealt {:?} phys dmg", self.name, amount);
|
||||||
|
return (amount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deal_spell_dmg(&mut self, amount: u64) -> (u64, u64) {
|
||||||
|
self.hp.reduce(amount);
|
||||||
|
return (amount, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Cryp, Error> {
|
pub fn cryp_get(tx: &mut Transaction, id: Uuid, account_id: Uuid) -> Result<Cryp, Error> {
|
||||||
@ -348,7 +406,7 @@ mod tests {
|
|||||||
// ,final_str
|
// ,final_str
|
||||||
// ,self.name
|
// ,self.name
|
||||||
// ,blocked
|
// ,blocked
|
||||||
// ,self.hp.value));
|
// ,self.hp.base));
|
||||||
|
|
||||||
// plr_t.log.push(format!(""));
|
// plr_t.log.push(format!(""));
|
||||||
// self
|
// self
|
||||||
@ -368,9 +426,9 @@ mod tests {
|
|||||||
|
|
||||||
// // finally combine with CrypStat
|
// // finally combine with CrypStat
|
||||||
// log.push(format!("{:064b} <- finalised", roll.result));
|
// log.push(format!("{:064b} <- finalised", roll.result));
|
||||||
// roll.result = roll.result & self.value;
|
// roll.result = roll.result & self.base;
|
||||||
|
|
||||||
// log.push(format!("{:064b} & <- attribute roll", self.value));
|
// log.push(format!("{:064b} & <- attribute roll", self.base));
|
||||||
// log.push(format!("{:064b} = {:?}", roll.result, roll.result));
|
// log.push(format!("{:064b} = {:?}", roll.result, roll.result));
|
||||||
// log.push(format!(""));
|
// log.push(format!(""));
|
||||||
|
|
||||||
|
|||||||
@ -30,7 +30,7 @@ impl Team {
|
|||||||
|
|
||||||
fn skills_required(&self) -> usize {
|
fn skills_required(&self) -> usize {
|
||||||
let required = self.cryps.iter().filter(|c| c.available_skills().len() > 0).collect::<Vec<&Cryp>>().len();
|
let required = self.cryps.iter().filter(|c| c.available_skills().len() > 0).collect::<Vec<&Cryp>>().len();
|
||||||
println!("{:?} requires {:?} skills this turn", self.id, required);
|
// println!("{:?} requires {:?} skills this turn", self.id, required);
|
||||||
return required;
|
return required;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +130,15 @@ impl Game {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn all_cryps(&self) -> Vec<Cryp> {
|
||||||
|
self.teams.clone()
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(
|
||||||
|
|t| t.cryps
|
||||||
|
.into_iter())
|
||||||
|
.collect::<Vec<Cryp>>()
|
||||||
|
}
|
||||||
|
|
||||||
fn update_cryp(&mut self, cryp: &mut Cryp) -> &mut Game {
|
fn update_cryp(&mut self, cryp: &mut Cryp) -> &mut Game {
|
||||||
match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == cryp.id)) {
|
match self.teams.iter_mut().find(|t| t.cryps.iter().any(|c| c.id == cryp.id)) {
|
||||||
Some(team) => {
|
Some(team) => {
|
||||||
@ -332,15 +341,7 @@ impl Game {
|
|||||||
self.phase = Phase::Resolve;
|
self.phase = Phase::Resolve;
|
||||||
self.log.push("<Resolve Phase>".to_string());
|
self.log.push("<Resolve Phase>".to_string());
|
||||||
|
|
||||||
self.resolve_skills();
|
self.resolve_skills()
|
||||||
|
|
||||||
if self.is_finished() {
|
|
||||||
return self.finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.skill_phase_start();
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_skills(&mut self) -> &mut Game {
|
fn resolve_skills(&mut self) -> &mut Game {
|
||||||
@ -348,6 +349,18 @@ impl Game {
|
|||||||
panic!("game not in Resolve phase");
|
panic!("game not in Resolve phase");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find their statuses with ticks
|
||||||
|
let mut ticks = self.all_cryps()
|
||||||
|
.iter()
|
||||||
|
.flat_map(
|
||||||
|
|c| c.effects
|
||||||
|
.iter()
|
||||||
|
.filter_map(|e| e.tick))
|
||||||
|
.collect::<Vec<Cast>>();
|
||||||
|
|
||||||
|
// add them to the stack
|
||||||
|
self.stack.append(&mut ticks);
|
||||||
|
|
||||||
self.stack.sort_unstable_by_key(|s| s.skill.speed());
|
self.stack.sort_unstable_by_key(|s| s.skill.speed());
|
||||||
self.stack.reverse();
|
self.stack.reverse();
|
||||||
|
|
||||||
@ -371,16 +384,16 @@ impl Game {
|
|||||||
// handle cooldowns and statuses
|
// handle cooldowns and statuses
|
||||||
self.progress_durations();
|
self.progress_durations();
|
||||||
|
|
||||||
self
|
if self.is_finished() {
|
||||||
|
return self.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.skill_phase_start()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn progress_durations(&mut self) -> &mut Game {
|
fn progress_durations(&mut self) -> &mut Game {
|
||||||
// do it once for every cryp
|
for mut cryp in self.all_cryps() {
|
||||||
for mut cryp in self.stack.clone().iter()
|
// println!("progressing durations for {:?}", cryp.name);
|
||||||
.map(|s| self.cryp_by_id(s.source_cryp_id).unwrap().clone())
|
|
||||||
.collect::<Vec<Cryp>>() {
|
|
||||||
|
|
||||||
println!("progressing durations for {:?}", cryp.name);
|
|
||||||
|
|
||||||
// only reduce cooldowns if no cd was used
|
// only reduce cooldowns if no cd was used
|
||||||
// have to borrow self for the skill check
|
// have to borrow self for the skill check
|
||||||
@ -401,7 +414,6 @@ impl Game {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn is_finished(&self) -> bool {
|
fn is_finished(&self) -> bool {
|
||||||
self.teams.iter().any(|t| t.cryps.iter().all(|c| c.is_ko()))
|
self.teams.iter().any(|t| t.cryps.iter().all(|c| c.is_ko()))
|
||||||
}
|
}
|
||||||
@ -606,7 +618,7 @@ pub fn game_pve(params: GamePveParams, tx: &mut Transaction, account: &Account)
|
|||||||
let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?;
|
let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?;
|
||||||
|
|
||||||
// TEMP
|
// TEMP
|
||||||
if plr.hp.value == 0 {
|
if plr.is_ko() {
|
||||||
return Err(err_msg("cryp is ko"));
|
return Err(err_msg("cryp is ko"));
|
||||||
// plr.rez();
|
// plr.rez();
|
||||||
}
|
}
|
||||||
@ -707,6 +719,7 @@ mod tests {
|
|||||||
.learn(Skill::TestStun)
|
.learn(Skill::TestStun)
|
||||||
.learn(Skill::TestTouch)
|
.learn(Skill::TestTouch)
|
||||||
.learn(Skill::TestBlock)
|
.learn(Skill::TestBlock)
|
||||||
|
.learn(Skill::TestDrain)
|
||||||
.learn(Skill::Block)
|
.learn(Skill::Block)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
@ -716,6 +729,7 @@ mod tests {
|
|||||||
.learn(Skill::TestStun)
|
.learn(Skill::TestStun)
|
||||||
.learn(Skill::TestTouch)
|
.learn(Skill::TestTouch)
|
||||||
.learn(Skill::TestBlock)
|
.learn(Skill::TestBlock)
|
||||||
|
.learn(Skill::TestDrain)
|
||||||
.learn(Skill::Block)
|
.learn(Skill::Block)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
@ -801,7 +815,6 @@ mod tests {
|
|||||||
// should auto progress back to skill phase
|
// should auto progress back to skill phase
|
||||||
assert!(game.phase == Phase::Skill);
|
assert!(game.phase == Phase::Skill);
|
||||||
|
|
||||||
println!("{:#?}", game);
|
|
||||||
assert!(game.team_by_id(y_team.id).cryps[0].is_stunned());
|
assert!(game.team_by_id(y_team.id).cryps[0].is_stunned());
|
||||||
assert!(game.team_by_id(y_team.id).skills_required() == 0);
|
assert!(game.team_by_id(y_team.id).skills_required() == 0);
|
||||||
}
|
}
|
||||||
@ -830,6 +843,7 @@ mod tests {
|
|||||||
|
|
||||||
// after 1 turn block should be off cooldown
|
// after 1 turn block should be off cooldown
|
||||||
assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
assert!(game.team_by_id(y_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
||||||
|
assert!(game.team_by_id(x_team.id).cryps[0].skill_on_cd(Skill::Block).is_none());
|
||||||
|
|
||||||
// second round
|
// second round
|
||||||
// now we block and it should go back on cd
|
// now we block and it should go back on cd
|
||||||
@ -872,6 +886,36 @@ mod tests {
|
|||||||
|
|
||||||
// should not be stunned because of block
|
// should not be stunned because of block
|
||||||
assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
|
assert!(game.team_by_id(x_team.id).cryps[0].is_stunned() == false);
|
||||||
println!("{:#?}", game.log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn drain_test() {
|
||||||
|
let mut game = create_test_game();
|
||||||
|
|
||||||
|
let x_team = game.teams[0].clone();
|
||||||
|
let y_team = game.teams[1].clone();
|
||||||
|
|
||||||
|
let x_cryp = x_team.cryps[0].clone();
|
||||||
|
let y_cryp = y_team.cryps[0].clone();
|
||||||
|
|
||||||
|
let x_drain_id = game.add_skill(x_team.id, x_cryp.id, Some(y_team.id), Skill::TestDrain).unwrap();
|
||||||
|
let y_touch_id = game.add_skill(y_team.id, y_cryp.id, Some(x_team.id), Skill::TestTouch).unwrap();
|
||||||
|
|
||||||
|
game.target_phase_start();
|
||||||
|
|
||||||
|
game.add_target(x_team.id, x_cryp.id, y_touch_id).unwrap();
|
||||||
|
game.add_target(y_team.id, y_cryp.id, x_drain_id).unwrap();
|
||||||
|
|
||||||
|
game.resolve_phase_start();
|
||||||
|
|
||||||
|
game.add_skill(x_team.id, x_cryp.id, None, Skill::TestBlock).unwrap();
|
||||||
|
game.add_skill(y_team.id, y_cryp.id, None, Skill::TestBlock).unwrap();
|
||||||
|
|
||||||
|
game.target_phase_start();
|
||||||
|
|
||||||
|
assert!(game.resolved.iter().any(|r| r.skill == Skill::DrainTick));
|
||||||
|
|
||||||
|
// println!("{:#?}", game);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,17 +2,15 @@ use rand::{thread_rng, Rng};
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use game::{Log};
|
use game::{Log};
|
||||||
use cryp::{Cryp, CrypEffect};
|
use cryp::{Cryp, CrypEffect, Stat};
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
pub struct Cast {
|
pub struct Cast {
|
||||||
pub id: Uuid,
|
pub id: Uuid,
|
||||||
pub skill: Skill,
|
pub skill: Skill, pub source_team_id: Uuid,
|
||||||
pub source_team_id: Uuid,
|
|
||||||
pub source_cryp_id: Uuid,
|
pub source_cryp_id: Uuid,
|
||||||
pub target_cryp_id: Option<Uuid>,
|
pub target_cryp_id: Option<Uuid>,
|
||||||
pub target_team_id: Uuid,
|
pub target_team_id: Uuid,
|
||||||
pub resolution: Resolution,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cast {
|
impl Cast {
|
||||||
@ -30,12 +28,17 @@ impl Cast {
|
|||||||
target_cryp_id,
|
target_cryp_id,
|
||||||
target_team_id,
|
target_team_id,
|
||||||
skill,
|
skill,
|
||||||
resolution: Resolution { base: 0, result: None },
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_tick(source: &mut Cryp, target: &mut Cryp, skill: Skill) -> Cast {
|
||||||
|
let mut cast = Cast::new(source.id, source.account, Some(target.account), skill);
|
||||||
|
cast.set_target(target.id);
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> &mut Cast {
|
pub fn set_resolution(&mut self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> &mut Cast {
|
||||||
self.resolution = self.skill.resolve(cryp, target, log);
|
self.skill.resolve(cryp, target, log);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,23 +76,27 @@ pub enum Effect {
|
|||||||
Blind,
|
Blind,
|
||||||
Snare,
|
Snare,
|
||||||
|
|
||||||
|
Empower,
|
||||||
|
|
||||||
// magic
|
// magic
|
||||||
Hex,
|
Hex,
|
||||||
|
Curse,
|
||||||
Banish,
|
Banish,
|
||||||
Slow,
|
Slow,
|
||||||
Haste,
|
Haste,
|
||||||
Enslave,
|
Enslave,
|
||||||
Mesmerise,
|
Mesmerise,
|
||||||
Amplify,
|
Amplify,
|
||||||
|
Silence,
|
||||||
|
|
||||||
// magic immunity
|
// magic immunity
|
||||||
Immune,
|
Shield,
|
||||||
|
|
||||||
// effects over time
|
// effects over time
|
||||||
Triage,
|
Triage,
|
||||||
Decay,
|
Decay,
|
||||||
Regen,
|
Regen,
|
||||||
Degen,
|
Drain,
|
||||||
|
|
||||||
SpeedDrain,
|
SpeedDrain,
|
||||||
SpeedIncrease,
|
SpeedIncrease,
|
||||||
@ -100,28 +107,109 @@ impl Effect {
|
|||||||
match self {
|
match self {
|
||||||
Effect::Block => match skill {
|
Effect::Block => match skill {
|
||||||
Skill::Stun |
|
Skill::Stun |
|
||||||
|
Skill::TestStun |
|
||||||
Skill::Attack => true,
|
Skill::Attack => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
Effect::Shield => match skill.cast_type() {
|
||||||
|
Damage::Magic => true,
|
||||||
|
Damage::Physical => false,
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prevents_casting(&self, skill: Skill) -> bool {
|
||||||
|
match self {
|
||||||
|
Effect::Stun => true,
|
||||||
|
Effect::Silence => match skill.cast_type() {
|
||||||
|
Damage::Magic => true,
|
||||||
|
Damage::Physical => false,
|
||||||
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick(&self, cryp_effect: &CrypEffect, target: &mut Cryp, log: &mut Log) -> &Effect {
|
pub fn modifications(&self) -> Vec<Stat> {
|
||||||
match self {
|
match self {
|
||||||
Effect::Decay => decay_tick(target, cryp_effect, log),
|
Effect::Amplify => vec![Stat::SpellDmg],
|
||||||
Effect::Triage => triage_tick(target, cryp_effect, log),
|
Effect::Empower => vec![Stat::PhysDmg],
|
||||||
_ => (),
|
_ => vec![],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
// maybe increase by rng
|
||||||
|
// roll little endian bits
|
||||||
|
// and OR with base stat
|
||||||
|
pub fn apply(&self, value: u64) -> u64 {
|
||||||
|
match self {
|
||||||
|
Effect::Amplify => value << 1,
|
||||||
|
Effect::Empower => value << 1,
|
||||||
|
_ => panic!("{:?} does not have a mod effect", self),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn source(&self) -> Source {
|
||||||
|
match self {
|
||||||
|
// physical
|
||||||
|
Effect::Stun => Source::Debuff,
|
||||||
|
Effect::Block => Source::Buff,
|
||||||
|
Effect::Bleed => Source::Debuff,
|
||||||
|
Effect::Leech => Source::Debuff,
|
||||||
|
Effect::Airborne => Source::Buff,
|
||||||
|
Effect::Untouchable => Source::Buff,
|
||||||
|
Effect::Deadly => Source::Buff,
|
||||||
|
Effect::Vulnerable => Source::Debuff,
|
||||||
|
Effect::Fury => Source::Buff,
|
||||||
|
Effect::Evasion => Source::Buff,
|
||||||
|
Effect::Blind => Source::Debuff,
|
||||||
|
Effect::Snare => Source::Debuff,
|
||||||
|
|
||||||
|
Effect::Empower => Source::Buff,
|
||||||
|
|
||||||
|
// magic
|
||||||
|
Effect::Hex => Source::Debuff,
|
||||||
|
Effect::Curse => Source::Debuff,
|
||||||
|
Effect::Banish => Source::Debuff, // todo randomise
|
||||||
|
Effect::Slow => Source::Debuff,
|
||||||
|
Effect::Haste => Source::Buff,
|
||||||
|
Effect::Enslave => Source::Debuff,
|
||||||
|
Effect::Mesmerise => Source::Debuff,
|
||||||
|
Effect::Amplify => Source::Buff,
|
||||||
|
Effect::Silence => Source::Debuff,
|
||||||
|
|
||||||
|
// magic immunity
|
||||||
|
Effect::Shield => Source::Buff,
|
||||||
|
|
||||||
|
// effects over time
|
||||||
|
Effect::Triage => Source::Buff,
|
||||||
|
Effect::Decay => Source::Debuff,
|
||||||
|
Effect::Regen => Source::Buff,
|
||||||
|
Effect::Drain => Source::Debuff,
|
||||||
|
|
||||||
|
Effect::SpeedDrain => Source::Debuff,
|
||||||
|
Effect::SpeedIncrease => Source::Buff,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
pub struct Tick {
|
pub enum Damage {
|
||||||
amount: u64
|
Physical,
|
||||||
|
Magic,
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
|
// enum Style {
|
||||||
|
// Offensive,
|
||||||
|
// Defensive,
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
|
pub enum Source {
|
||||||
|
Buff,
|
||||||
|
Debuff,
|
||||||
|
Stat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
@ -158,6 +246,7 @@ pub enum Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
Heal,
|
Heal,
|
||||||
Triage, // hot
|
Triage, // hot
|
||||||
|
TriageTick,
|
||||||
Throw, // no dmg stun, adds vulnerable
|
Throw, // no dmg stun, adds vulnerable
|
||||||
Charm,
|
Charm,
|
||||||
Calm,
|
Calm,
|
||||||
@ -169,7 +258,9 @@ pub enum Skill {
|
|||||||
Blast,
|
Blast,
|
||||||
Amplify,
|
Amplify,
|
||||||
Decay, // dot
|
Decay, // dot
|
||||||
|
DecayTick, // dot
|
||||||
Drain,
|
Drain,
|
||||||
|
DrainTick,
|
||||||
Curse,
|
Curse,
|
||||||
Plague, // aoe dot
|
Plague, // aoe dot
|
||||||
Ruin, // aoe
|
Ruin, // aoe
|
||||||
@ -177,13 +268,14 @@ pub enum Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
// Purity
|
// Purity
|
||||||
// -----------------
|
// -----------------
|
||||||
Precision,
|
Empower,
|
||||||
Inspire,
|
|
||||||
Slay,
|
Slay,
|
||||||
Shield,
|
Shield,
|
||||||
Silence,
|
Silence,
|
||||||
Inquiry,
|
Inquiry,
|
||||||
Purify,
|
Purify,
|
||||||
|
Purge,
|
||||||
|
// Precision,
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Chaos
|
// Chaos
|
||||||
@ -198,6 +290,7 @@ pub enum Skill {
|
|||||||
TestTouch,
|
TestTouch,
|
||||||
TestStun,
|
TestStun,
|
||||||
TestBlock,
|
TestBlock,
|
||||||
|
TestDrain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Skill {
|
impl Skill {
|
||||||
@ -235,6 +328,7 @@ impl Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
Skill::Heal => Some(1),
|
Skill::Heal => Some(1),
|
||||||
Skill::Triage => Some(1), // hot
|
Skill::Triage => Some(1), // hot
|
||||||
|
Skill::TriageTick => None,
|
||||||
Skill::Throw => Some(2), // no dmg stun, adds vulnerable
|
Skill::Throw => Some(2), // no dmg stun, adds vulnerable
|
||||||
Skill::Charm => Some(2),
|
Skill::Charm => Some(2),
|
||||||
Skill::Calm => Some(2),
|
Skill::Calm => Some(2),
|
||||||
@ -246,7 +340,9 @@ impl Skill {
|
|||||||
Skill::Blast => Some(1),
|
Skill::Blast => Some(1),
|
||||||
Skill::Amplify => Some(2),
|
Skill::Amplify => Some(2),
|
||||||
Skill::Decay => Some(1), // dot
|
Skill::Decay => Some(1), // dot
|
||||||
|
Skill::DecayTick => None,
|
||||||
Skill::Drain => Some(2),
|
Skill::Drain => Some(2),
|
||||||
|
Skill::DrainTick => None,
|
||||||
Skill::Curse => Some(2),
|
Skill::Curse => Some(2),
|
||||||
Skill::Plague => Some(2), // aoe dot
|
Skill::Plague => Some(2), // aoe dot
|
||||||
Skill::Ruin => Some(3), // aoe
|
Skill::Ruin => Some(3), // aoe
|
||||||
@ -254,13 +350,14 @@ impl Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
// Purity
|
// Purity
|
||||||
// -----------------
|
// -----------------
|
||||||
Skill::Precision => Some(1),
|
// Skill::Precision => Some(1),
|
||||||
Skill::Inspire => Some(2),
|
Skill::Empower => Some(2),
|
||||||
Skill::Slay => Some(1),
|
Skill::Slay => Some(1),
|
||||||
Skill::Shield => Some(1),
|
Skill::Shield => Some(1),
|
||||||
Skill::Silence => Some(2),
|
Skill::Silence => Some(2),
|
||||||
Skill::Inquiry => Some(2),
|
Skill::Inquiry => Some(2),
|
||||||
Skill::Purify => Some(1),
|
Skill::Purify => Some(1),
|
||||||
|
Skill::Purge => Some(1),
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Chaos
|
// Chaos
|
||||||
@ -277,6 +374,92 @@ impl Skill {
|
|||||||
Skill::TestTouch => None,
|
Skill::TestTouch => None,
|
||||||
Skill::TestStun => None,
|
Skill::TestStun => None,
|
||||||
Skill::TestBlock => None,
|
Skill::TestBlock => None,
|
||||||
|
Skill::TestDrain => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cast_type(&self) -> Damage {
|
||||||
|
match self {
|
||||||
|
Skill::Attack => Damage::Physical,
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Nature
|
||||||
|
// -----------------
|
||||||
|
Skill::Block => Damage::Physical, // reduce dmg
|
||||||
|
Skill::Evade => Damage::Physical,
|
||||||
|
Skill::Parry => Damage::Physical, // avoid all dmg
|
||||||
|
Skill::Snare => Damage::Physical,
|
||||||
|
|
||||||
|
Skill::Paralyse => Damage::Physical,
|
||||||
|
Skill::Strangle => Damage::Physical,
|
||||||
|
|
||||||
|
// Strangle
|
||||||
|
|
||||||
|
Skill::Stun => Damage::Physical,
|
||||||
|
Skill::Evasion => Damage::Physical, // additional layer of dmg avoidance
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Technology
|
||||||
|
// -----------------
|
||||||
|
Skill::Replicate => Damage::Physical,
|
||||||
|
Skill::Swarm => Damage::Physical,
|
||||||
|
Skill::Orbit => Damage::Physical,
|
||||||
|
Skill::Repair => Damage::Physical,
|
||||||
|
Skill::Scan => Damage::Physical, // track?
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Preservation
|
||||||
|
// -----------------
|
||||||
|
Skill::Heal => Damage::Physical,
|
||||||
|
Skill::Triage => Damage::Physical, // hot
|
||||||
|
Skill::TriageTick => Damage::Physical, // hot
|
||||||
|
Skill::Throw => Damage::Physical, // no dmg stun, adds vulnerable
|
||||||
|
Skill::Charm => Damage::Physical,
|
||||||
|
Skill::Calm => Damage::Physical,
|
||||||
|
Skill::Rez => Damage::Physical,
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Destruction
|
||||||
|
// -----------------
|
||||||
|
Skill::Blast => Damage::Magic,
|
||||||
|
Skill::Amplify => Damage::Magic,
|
||||||
|
Skill::Decay => Damage::Magic, // dot
|
||||||
|
Skill::DecayTick => Damage::Magic, // hot
|
||||||
|
Skill::Drain => Damage::Magic,
|
||||||
|
Skill::DrainTick => Damage::Magic, // hot
|
||||||
|
Skill::Curse => Damage::Magic,
|
||||||
|
Skill::Plague => Damage::Magic, // aoe dot
|
||||||
|
Skill::Ruin => Damage::Magic, // aoe
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Purity
|
||||||
|
// -----------------
|
||||||
|
// Skill::Precision => 1,
|
||||||
|
Skill::Empower => Damage::Physical,
|
||||||
|
Skill::Slay => Damage::Physical,
|
||||||
|
Skill::Shield => Damage::Magic,
|
||||||
|
Skill::Silence => Damage::Magic,
|
||||||
|
Skill::Inquiry => Damage::Magic,
|
||||||
|
Skill::Purify => Damage::Magic,
|
||||||
|
Skill::Purge => Damage::Magic,
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Chaos
|
||||||
|
// -----------------
|
||||||
|
Skill::Banish => Damage::Magic,
|
||||||
|
Skill::Hex => Damage::Magic,
|
||||||
|
Skill::Fear => Damage::Magic,
|
||||||
|
Skill::Taunt => Damage::Magic,
|
||||||
|
Skill::Pause => Damage::Magic, // extend durations
|
||||||
|
// Skill::Lag => 2, //
|
||||||
|
|
||||||
|
// -----------------
|
||||||
|
// Test
|
||||||
|
// -----------------
|
||||||
|
Skill::TestTouch => Damage::Physical,
|
||||||
|
Skill::TestStun => Damage::Physical,
|
||||||
|
Skill::TestBlock => Damage::Physical,
|
||||||
|
Skill::TestDrain => Damage::Magic,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +497,7 @@ impl Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
Skill::Heal => 1,
|
Skill::Heal => 1,
|
||||||
Skill::Triage => 1, // hot
|
Skill::Triage => 1, // hot
|
||||||
|
Skill::TriageTick => 1, // hot
|
||||||
Skill::Throw => 2, // no dmg stun, adds vulnerable
|
Skill::Throw => 2, // no dmg stun, adds vulnerable
|
||||||
Skill::Charm => 2,
|
Skill::Charm => 2,
|
||||||
Skill::Calm => 2,
|
Skill::Calm => 2,
|
||||||
@ -325,7 +509,9 @@ impl Skill {
|
|||||||
Skill::Blast => 1,
|
Skill::Blast => 1,
|
||||||
Skill::Amplify => 2,
|
Skill::Amplify => 2,
|
||||||
Skill::Decay => 1, // dot
|
Skill::Decay => 1, // dot
|
||||||
|
Skill::DecayTick => 2, // hot
|
||||||
Skill::Drain => 2,
|
Skill::Drain => 2,
|
||||||
|
Skill::DrainTick => 2, // hot
|
||||||
Skill::Curse => 2,
|
Skill::Curse => 2,
|
||||||
Skill::Plague => 2, // aoe dot
|
Skill::Plague => 2, // aoe dot
|
||||||
Skill::Ruin => 3, // aoe
|
Skill::Ruin => 3, // aoe
|
||||||
@ -333,13 +519,14 @@ impl Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
// Purity
|
// Purity
|
||||||
// -----------------
|
// -----------------
|
||||||
Skill::Precision => 1,
|
// Skill::Precision => 1,
|
||||||
Skill::Inspire => 2,
|
Skill::Empower => 2,
|
||||||
Skill::Slay => 1,
|
Skill::Slay => 1,
|
||||||
Skill::Shield => 1,
|
Skill::Shield => 1,
|
||||||
Skill::Silence => 2,
|
Skill::Silence => 2,
|
||||||
Skill::Inquiry => 2,
|
Skill::Inquiry => 2,
|
||||||
Skill::Purify => 1,
|
Skill::Purify => 1,
|
||||||
|
Skill::Purge => 1,
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Chaos
|
// Chaos
|
||||||
@ -348,7 +535,8 @@ impl Skill {
|
|||||||
Skill::Hex => 1,
|
Skill::Hex => 1,
|
||||||
Skill::Fear => 1,
|
Skill::Fear => 1,
|
||||||
Skill::Taunt => 2,
|
Skill::Taunt => 2,
|
||||||
Skill::Pause => 2, // speed slow
|
Skill::Pause => 2, // extend durations
|
||||||
|
// Skill::Lag => 2, //
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Test
|
// Test
|
||||||
@ -356,25 +544,32 @@ impl Skill {
|
|||||||
Skill::TestTouch => 10,
|
Skill::TestTouch => 10,
|
||||||
Skill::TestStun => 5,
|
Skill::TestStun => 5,
|
||||||
Skill::TestBlock => 10,
|
Skill::TestBlock => 10,
|
||||||
|
Skill::TestDrain => 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) -> Resolution {
|
pub fn resolve(&self, cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let base: u64 = rng.gen();
|
let base: u64 = rng.gen();
|
||||||
|
|
||||||
let res = Resolution { base, result: None };
|
// let res = Resolution { base, result: None };
|
||||||
|
|
||||||
// println!("{:?}'s stats", self.name);
|
// println!("{:?}'s stats", self.name);
|
||||||
// println!("{:064b} <- finalised", roll.result);
|
// println!("{:064b} <- finalised", roll.result);
|
||||||
// roll.result = roll.result & stat.value;
|
// roll.result = roll.result & stat();
|
||||||
|
|
||||||
// println!("{:064b} & <- attribute roll", stat.value);
|
// println!("{:064b} & <- attribute roll", stat());
|
||||||
// println!("{:064b} = {:?}", roll.result, roll.result);
|
// println!("{:064b} = {:?}", roll.result, roll.result);
|
||||||
// println!("");
|
// println!("");
|
||||||
|
|
||||||
// return Some(roll);
|
// return Some(roll);
|
||||||
|
|
||||||
|
let (immune, reason) = target.immune(*self);
|
||||||
|
if immune {
|
||||||
|
log.push(format!("{:?} -> {:?} | {:?} immune: {:?}", cryp.name, target.name, self, reason));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Skill::Attack => attack(cryp, target, log),
|
Skill::Attack => attack(cryp, target, log),
|
||||||
// -----------------
|
// -----------------
|
||||||
@ -405,40 +600,44 @@ impl Skill {
|
|||||||
// -----------------
|
// -----------------
|
||||||
Skill::Heal => heal(cryp, target, log),
|
Skill::Heal => heal(cryp, target, log),
|
||||||
Skill::Triage => triage(cryp, target, log), // hot
|
Skill::Triage => triage(cryp, target, log), // hot
|
||||||
|
Skill::TriageTick => triage_tick(cryp, target, log), // hot
|
||||||
Skill::Throw => throw(cryp, target, log), // no dmg stun, adds vulnerable
|
Skill::Throw => throw(cryp, target, log), // no dmg stun, adds vulnerable
|
||||||
Skill::Charm => panic!("nyi"),
|
Skill::Charm => panic!("nyi"), // target casts random spell on teammate
|
||||||
Skill::Calm => panic!("nyi"),
|
Skill::Calm => panic!("nyi"), // physical fear, taunt removal
|
||||||
Skill::Rez => panic!("nyi"),
|
Skill::Rez => panic!("nyi"),
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Destruction
|
// Destruction
|
||||||
// -----------------
|
// -----------------
|
||||||
Skill::Blast => blast(cryp, target, log),
|
Skill::Blast => blast(cryp, target, log),
|
||||||
Skill::Amplify => amplify(cryp, target, log), // TODO increase magic dmg
|
Skill::Amplify => amplify(cryp, target, log), // increase magic dmg
|
||||||
Skill::Decay => decay(cryp, target, log), // dot
|
Skill::Decay => decay(cryp, target, log), // dot
|
||||||
Skill::Drain => panic!("nyi"),
|
Skill::DecayTick => decay_tick(cryp, target, log), // hot
|
||||||
Skill::Curse => panic!("nyi"),
|
Skill::Drain => drain(cryp, target, log),
|
||||||
Skill::Plague => panic!("nyi"), // aoe dot
|
Skill::DrainTick => drain_tick(cryp, target, log), // hot
|
||||||
Skill::Ruin => panic!("nyi"), // aoe
|
Skill::Curse => curse(cryp, target, log),
|
||||||
|
Skill::Plague => panic!("nyi"), // dot that spreads every turn
|
||||||
|
Skill::Ruin => panic!("nyi"), // aoe version of blast
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Purity
|
// Purity
|
||||||
// -----------------
|
// -----------------
|
||||||
Skill::Precision => panic!("nyi"),
|
// Skill::Precision => panic!("nyi"),
|
||||||
Skill::Inspire => panic!("nyi"),
|
Skill::Empower => empower(cryp, target, log), // increased phys dmg
|
||||||
Skill::Slay => panic!("nyi"),
|
Skill::Slay => panic!("nyi"), // phys dmg mult by target magic dmg
|
||||||
Skill::Shield => panic!("nyi"),
|
Skill::Shield => shield(cryp, target, log), // target is immune to magic dmg and fx
|
||||||
Skill::Silence => panic!("nyi"),
|
Skill::Silence => silence(cryp, target, log), // target cannot cast spells
|
||||||
Skill::Inquiry => panic!("nyi"),
|
Skill::Inquiry => panic!("nyi"), //
|
||||||
Skill::Purify => panic!("nyi"),
|
Skill::Purify => purify(cryp, target, log), // dispel all debuffs
|
||||||
|
Skill::Purge => purge(cryp, target, log), // dispel all buffs
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Chaos
|
// Chaos
|
||||||
// -----------------
|
// -----------------
|
||||||
Skill::Banish => banish(cryp, target, log), // TODO prevent all actions
|
Skill::Banish => banish(cryp, target, log), // TODO prevent all actions
|
||||||
Skill::Hex => hex(cryp, target, log), // todo prevent casting
|
Skill::Hex => hex(cryp, target, log), // todo prevent casting
|
||||||
Skill::Fear => panic!("nyi"),
|
Skill::Fear => panic!("nyi"), // cast random spell on self
|
||||||
Skill::Taunt => panic!("nyi"),
|
Skill::Taunt => panic!("nyi"), // target forced to attack
|
||||||
Skill::Pause => panic!("nyi"), // speed slow
|
Skill::Pause => panic!("nyi"), // speed slow
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
@ -447,9 +646,8 @@ impl Skill {
|
|||||||
Skill::TestTouch => (),
|
Skill::TestTouch => (),
|
||||||
Skill::TestStun => stun(cryp, target, log),
|
Skill::TestStun => stun(cryp, target, log),
|
||||||
Skill::TestBlock => block(cryp, target, log),
|
Skill::TestBlock => block(cryp, target, log),
|
||||||
|
Skill::TestDrain => drain(cryp, target, log),
|
||||||
};
|
};
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn duration(&self) -> u8 {
|
pub fn duration(&self) -> u8 {
|
||||||
@ -458,9 +656,15 @@ impl Skill {
|
|||||||
Skill::Stun => 2,
|
Skill::Stun => 2,
|
||||||
Skill::Block => 1,
|
Skill::Block => 1,
|
||||||
|
|
||||||
|
Skill::Empower => 2,
|
||||||
|
|
||||||
Skill::Decay => 3,
|
Skill::Decay => 3,
|
||||||
|
Skill::Drain => 3,
|
||||||
Skill::Triage => 3,
|
Skill::Triage => 3,
|
||||||
|
|
||||||
|
Skill::Amplify => 2,
|
||||||
|
Skill::Silence => 3,
|
||||||
|
|
||||||
Skill::TestBlock => 1,
|
Skill::TestBlock => 1,
|
||||||
Skill::TestStun => 2,
|
Skill::TestStun => 2,
|
||||||
_ => panic!("{:?} does not have a duration", self),
|
_ => panic!("{:?} does not have a duration", self),
|
||||||
@ -476,63 +680,51 @@ impl Skill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn castable(&self, cryp: &Cryp) -> bool {
|
pub fn castable(&self, cryp: &Cryp) -> bool {
|
||||||
if cryp.is_stunned() {
|
!cryp.effects.iter().any(|e| e.effect.prevents_casting(*self))
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn attack(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
target.deal_phys_dmg(cryp.phys_dmg());
|
||||||
log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, cryp.phys_dmg));
|
log.push(format!("{:?} -> {:?} | Attack for {:?}", cryp.name, target.name, cryp.phys_dmg));
|
||||||
target.hp.reduce(cryp.phys_dmg.value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn stun(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
if !target.immune(Skill::Stun) {
|
|
||||||
let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None };
|
let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None };
|
||||||
target.effects.push(stun);
|
target.effects.push(stun);
|
||||||
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration));
|
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration));
|
||||||
} else {
|
|
||||||
log.push(format!("{:?} -> {:?} | {:?} immune", cryp.name, target.name, target.name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn throw(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
if !target.immune(Skill::Throw) {
|
|
||||||
let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None };
|
let stun = CrypEffect { effect: Effect::Stun, duration: Skill::Stun.duration(), tick: None };
|
||||||
let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Skill::Stun.duration(), tick: None };
|
let vulnerable = CrypEffect { effect: Effect::Vulnerable, duration: Skill::Stun.duration(), tick: None };
|
||||||
target.effects.push(stun);
|
target.effects.push(stun);
|
||||||
target.effects.push(vulnerable);
|
target.effects.push(vulnerable);
|
||||||
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration));
|
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, stun.effect, stun.duration));
|
||||||
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, vulnerable.effect, vulnerable.duration));
|
log.push(format!("{:?} -> {:?} | {:?} for {:?}T", cryp.name, target.name, vulnerable.effect, vulnerable.duration));
|
||||||
} else {
|
|
||||||
log.push(format!("{:?} -> {:?} | {:?} immune", cryp.name, target.name, target.name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn block(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration(), tick: None };
|
let effect = CrypEffect { effect: Effect::Block, duration: Skill::Block.duration(), tick: None };
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snare(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn snare(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect { effect: Effect::Snare, duration: Skill::Snare.duration(), tick: None };
|
let effect = CrypEffect { effect: Effect::Snare, duration: Skill::Snare.duration(), tick: None };
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn empower(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
let effect = CrypEffect { effect: Effect::Empower, duration: Skill::Empower.duration(), tick: None };
|
||||||
|
target.effects.push(effect);
|
||||||
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn heal(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let new_hp = *[
|
let (healing, overhealing) = target.heal(cryp.phys_dmg());
|
||||||
target.hp.value.saturating_add(cryp.spell_dmg.value),
|
|
||||||
target.stamina.value
|
|
||||||
].iter().min().unwrap();
|
|
||||||
|
|
||||||
let healing = new_hp.saturating_sub(target.hp.value);
|
|
||||||
let overhealing = target.hp.value.saturating_add(cryp.phys_dmg.value).saturating_sub(target.stamina.value);
|
|
||||||
target.hp.value = new_hp;
|
|
||||||
log.push(format!("{:?} -> {:?} | Heal for {:?} ({:?} OH)", cryp.name, target.name, healing, overhealing));
|
log.push(format!("{:?} -> {:?} | Heal for {:?} ({:?} OH)", cryp.name, target.name, healing, overhealing));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,63 +732,111 @@ fn triage(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
|||||||
let effect = CrypEffect {
|
let effect = CrypEffect {
|
||||||
effect: Effect::Triage,
|
effect: Effect::Triage,
|
||||||
duration: Skill::Triage.duration(),
|
duration: Skill::Triage.duration(),
|
||||||
tick: Some(Tick { amount: cryp.spell_dmg.value.wrapping_div(2) })
|
tick: Some(Cast::new_tick(cryp, target, Skill::TriageTick)),
|
||||||
};
|
};
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triage_tick(target: &mut Cryp, effect: &CrypEffect, log: &mut Log) {
|
fn triage_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let tick = effect.tick.expect("no tick for triage");
|
let amount = cryp.spell_dmg().wrapping_div(2);
|
||||||
let new_hp = *[
|
let (healing, overhealing) = target.heal(amount);
|
||||||
target.hp.value.saturating_add(tick.amount),
|
log.push(format!("{:?} -> {:?} | Triage for {:?} ({:?} OH)", cryp.name, target.name, healing, overhealing));
|
||||||
target.stamina.value
|
|
||||||
].iter().min().unwrap();
|
|
||||||
|
|
||||||
let healing = new_hp.saturating_sub(target.hp.value);
|
|
||||||
let overhealing = target.hp.value + tick.amount - target.stamina.value;
|
|
||||||
log.push(format!("{:?} | Triage healing for {:?} ({:?} OH)", target.name, healing, overhealing));
|
|
||||||
target.hp.value = new_hp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn blast(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let amount = cryp.spell_dmg.value;
|
let amount = cryp.spell_dmg();
|
||||||
log.push(format!("{:?} -> {:?} | Blast for {:?}", cryp.name, target.name, amount));
|
log.push(format!("{:?} -> {:?} | Blast for {:?}", cryp.name, target.name, amount));
|
||||||
target.hp.reduce(amount);
|
target.deal_spell_dmg(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn amplify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn amplify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect { effect: Effect::Amplify, duration: Skill::Amplify.duration(), tick: None };
|
let effect = CrypEffect { effect: Effect::Amplify, duration: Skill::Amplify.duration(), tick: None };
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn decay(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect {
|
let effect = CrypEffect {
|
||||||
effect: Effect::Decay,
|
effect: Effect::Decay,
|
||||||
duration: Skill::Decay.duration(),
|
duration: Skill::Decay.duration(),
|
||||||
tick: Some(Tick { amount: cryp.spell_dmg.value.wrapping_div(2) })
|
tick: Some(Cast::new_tick(cryp, target, Skill::DecayTick)),
|
||||||
};
|
};
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decay_tick(target: &mut Cryp, effect: &CrypEffect, log: &mut Log) {
|
fn decay_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let tick = effect.tick.expect("no tick for decay");
|
let amount = cryp.spell_dmg();
|
||||||
target.hp.reduce(tick.amount);
|
log.push(format!("{:?} -> {:?} | Decay for {:?}", cryp.name, target.name, amount));
|
||||||
log.push(format!("{:?} | Decay damage for {:?}", target.name, tick.amount));
|
target.deal_spell_dmg(amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hex(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn hex(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect { effect: Effect::Hex, duration: Skill::Hex.duration(), tick: None };
|
let effect = CrypEffect { effect: Effect::Hex, duration: Skill::Hex.duration(), tick: None };
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn curse(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
let effect = CrypEffect { effect: Effect::Curse, duration: Skill::Curse.duration(), tick: None };
|
||||||
|
target.effects.push(effect);
|
||||||
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drain(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
let effect = CrypEffect {
|
||||||
|
effect: Effect::Drain,
|
||||||
|
duration: Skill::Drain.duration(),
|
||||||
|
tick: Some(Cast::new_tick(cryp, target, Skill::DrainTick)),
|
||||||
|
};
|
||||||
|
target.effects.push(effect);
|
||||||
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn drain_tick(cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
// Damage part
|
||||||
|
let (damage, _) = target.deal_spell_dmg(cryp.spell_dmg().wrapping_div(2));
|
||||||
|
log.push(format!("{:?} | Drain Damage {:?}", target.name, damage));
|
||||||
|
|
||||||
|
let (healing, overhealing) = target.heal(damage);
|
||||||
|
log.push(format!("{:?} | Drain healing {:?} ({:?} OH)", cryp.name, healing, overhealing));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shield(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
let effect = CrypEffect { effect: Effect::Shield, duration: Skill::Shield.duration(), tick: None };
|
||||||
|
target.effects.push(effect);
|
||||||
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn silence(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
let effect = CrypEffect { effect: Effect::Silence, duration: Skill::Silence.duration(), tick: None };
|
||||||
|
target.effects.push(effect);
|
||||||
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn purge(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
|
||||||
|
if ce.effect.source() == Source::Buff {
|
||||||
|
target.effects.remove(i);
|
||||||
|
log.push(format!("{:?} < {:?} purged", target.name, ce.effect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn purify(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
|
for (i, ce) in target.effects.clone().iter_mut().enumerate() {
|
||||||
|
if ce.effect.source() == Source::Debuff {
|
||||||
|
target.effects.remove(i);
|
||||||
|
log.push(format!("{:?} < {:?} purified", target.name, ce.effect));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn banish(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
fn banish(_cryp: &mut Cryp, target: &mut Cryp, log: &mut Log) {
|
||||||
let effect = CrypEffect { effect: Effect::Banish, duration: Skill::Banish.duration(), tick: None };
|
let effect = CrypEffect { effect: Effect::Banish, duration: Skill::Banish.duration(), tick: None };
|
||||||
target.effects.push(effect);
|
target.effects.push(effect);
|
||||||
log.push(format!("{:?} is {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
log.push(format!("{:?} < {:?} for {:?}T", target.name, effect.effect, effect.duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -618,12 +858,10 @@ mod tests {
|
|||||||
.learn(Skill::Heal)
|
.learn(Skill::Heal)
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
x.hp.reduce(5);
|
x.deal_phys_dmg(5);
|
||||||
|
|
||||||
let mut log = vec![];
|
let mut log = vec![];
|
||||||
heal(&mut y, &mut x, &mut log);
|
heal(&mut y, &mut x, &mut log);
|
||||||
|
|
||||||
println!("{:?}", log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -645,7 +883,7 @@ mod tests {
|
|||||||
|
|
||||||
y.reduce_effect_durations(&mut log);
|
y.reduce_effect_durations(&mut log);
|
||||||
let decay = y.effects.iter().find(|e| e.effect == Effect::Decay);
|
let decay = y.effects.iter().find(|e| e.effect == Effect::Decay);
|
||||||
assert!(y.hp.value == y.stamina.value.saturating_sub(decay.unwrap().tick.unwrap().amount));
|
// assert!(y.hp() == y.stamina().saturating_sub(decay.unwrap().tick.unwrap().amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -663,17 +901,60 @@ mod tests {
|
|||||||
let mut log = vec![];
|
let mut log = vec![];
|
||||||
|
|
||||||
// ensure it doesn't have 0 sd
|
// ensure it doesn't have 0 sd
|
||||||
x.spell_dmg.value = 50;
|
x.spell_dmg.set(50);
|
||||||
y.hp.reduce(5);
|
y.deal_phys_dmg(5);
|
||||||
|
let prev_hp = y.hp();
|
||||||
let prev_hp = y.hp.value;
|
|
||||||
|
|
||||||
triage(&mut x, &mut y, &mut log);
|
triage(&mut x, &mut y, &mut log);
|
||||||
|
|
||||||
assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
|
assert!(y.effects.iter().any(|e| e.effect == Effect::Triage));
|
||||||
|
|
||||||
y.reduce_effect_durations(&mut log);
|
triage_tick(&mut x, &mut y, &mut log);
|
||||||
assert!(y.hp.value > prev_hp);
|
assert!(y.hp() > prev_hp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn silence_test() {
|
||||||
|
let mut x = Cryp::new()
|
||||||
|
.named(&"muji".to_string())
|
||||||
|
.level(8)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let mut log = vec![];
|
||||||
|
|
||||||
|
silence(&mut x.clone(), &mut x, &mut log);
|
||||||
|
assert!(x.effects.iter().any(|e| e.effect == Effect::Silence));
|
||||||
|
assert!(!Skill::Decay.castable(&x));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn amplify_test() {
|
||||||
|
let mut x = Cryp::new()
|
||||||
|
.named(&"muji".to_string())
|
||||||
|
.level(8)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
x.spell_dmg.set(50);
|
||||||
|
|
||||||
|
let mut log = vec![];
|
||||||
|
amplify(&mut x.clone(), &mut x, &mut log);
|
||||||
|
assert!(x.effects.iter().any(|e| e.effect == Effect::Amplify));
|
||||||
|
assert_eq!(x.spell_dmg(), 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn purify_test() {
|
||||||
|
let mut x = Cryp::new()
|
||||||
|
.named(&"muji".to_string())
|
||||||
|
.level(8)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
let mut log = vec![];
|
||||||
|
decay(&mut x.clone(), &mut x, &mut log);
|
||||||
|
assert!(x.effects.iter().any(|e| e.effect == Effect::Decay));
|
||||||
|
|
||||||
|
purify(&mut x.clone(), &mut x, &mut log);
|
||||||
|
assert!(!x.effects.iter().any(|e| e.effect == Effect::Decay));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user