Merge branch 'core' of ssh://git.mnml.gg:40022/~/mnml into core
This commit is contained in:
commit
0ed186cde3
@ -2,6 +2,5 @@
|
|||||||
check silence skill multiplier
|
check silence skill multiplier
|
||||||
game ready not auto starting resolve phase
|
game ready not auto starting resolve phase
|
||||||
|
|
||||||
infinite counter loop
|
|
||||||
cooldowns set after cast
|
cooldowns set after cast
|
||||||
cooldowns reduced after 1 complete cast
|
cooldowns reduced after 1 complete cast
|
||||||
|
|||||||
@ -435,9 +435,13 @@ impl Construct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn skill_set_cd(&mut self, skill: Skill) -> &mut Construct {
|
pub fn skill_set_cd(&mut self, skill: Skill) -> &mut Construct {
|
||||||
let i = self.skills.iter().position(|s| s.skill == skill).unwrap();
|
// tests force resolve some skills
|
||||||
self.skills.remove(i);
|
// which cause the game to attempt to put them on cd
|
||||||
self.skills.push(ConstructSkill::new(skill));
|
// even though the construct doesn't know the skill
|
||||||
|
if let Some(i) = self.skills.iter().position(|s| s.skill == skill) {
|
||||||
|
self.skills.remove(i);
|
||||||
|
self.skills.push(ConstructSkill::new(skill));
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,6 +110,12 @@ impl Effect {
|
|||||||
Skill::TriageTick,
|
Skill::TriageTick,
|
||||||
].contains(&skill),
|
].contains(&skill),
|
||||||
|
|
||||||
|
Effect::Countered => [
|
||||||
|
Skill::CounterAttack,
|
||||||
|
Skill::CounterAttackPlus,
|
||||||
|
Skill::CounterAttackPlusPlus,
|
||||||
|
].contains(&skill),
|
||||||
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +206,7 @@ impl Effect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Old colour matching system for buffs / debuffs
|
// Old colour matching system for buffs / debuffs
|
||||||
// Had issues as some effects will be considered as both a buff and debuff e.g. invert,
|
// Had issues as some effects will be considered as both a buff and debuff e.g. invert,
|
||||||
// Ended up being confusing with mismatch skills that have red / blue e.g. amplify, haste, hybrid
|
// Ended up being confusing with mismatch skills that have red / blue e.g. amplify, haste, hybrid
|
||||||
/* pub fn colour(&self) -> Option<Colour> {
|
/* pub fn colour(&self) -> Option<Colour> {
|
||||||
match self {
|
match self {
|
||||||
|
|||||||
@ -536,6 +536,7 @@ impl Game {
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maybe this should be done with a status immunity
|
||||||
if self.construct(cast.target).affected(Effect::Reflect) && cast.skill.colours().contains(&Colour::Blue) && !cast.skill.is_tick() {
|
if self.construct(cast.target).affected(Effect::Reflect) && cast.skill.colours().contains(&Colour::Blue) && !cast.skill.is_tick() {
|
||||||
self.add_resolution(&cast, &Event::Reflection { construct: cast.target });
|
self.add_resolution(&cast, &Event::Reflection { construct: cast.target });
|
||||||
|
|
||||||
@ -578,7 +579,10 @@ impl Game {
|
|||||||
let casts = match event {
|
let casts = match event {
|
||||||
Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } =>
|
Event::Damage { construct, colour: _, amount: _, mitigation: _, display: _ } =>
|
||||||
self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event),
|
self.construct_by_id(construct).unwrap().damage_trigger_casts(&cast, &event),
|
||||||
// Event::Cast {} => set_cooldown()
|
Event::Cast { construct, skill, player: _, target: _, direction: _ } => {
|
||||||
|
self.construct_by_id(construct).unwrap().skill_set_cd(skill);
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
Event::Ko { construct } =>
|
Event::Ko { construct } =>
|
||||||
self.construct_by_id(construct).unwrap().on_ko(&cast, &event),
|
self.construct_by_id(construct).unwrap().on_ko(&cast, &event),
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
@ -718,25 +722,26 @@ impl Game {
|
|||||||
|
|
||||||
fn progress_durations(&mut self) -> &mut Game {
|
fn progress_durations(&mut self) -> &mut Game {
|
||||||
let last = self.resolutions.len() - 1;
|
let last = self.resolutions.len() - 1;
|
||||||
|
|
||||||
|
let casters = self.resolutions[last].iter()
|
||||||
|
.filter_map(|r| match r.event {
|
||||||
|
Event::Cast { construct: caster, player: _, direction: _, skill, target: _ } =>
|
||||||
|
match skill.base_cd().is_some() {
|
||||||
|
true => Some(caster),
|
||||||
|
false => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<Uuid>>();
|
||||||
|
|
||||||
for player in self.players.iter_mut() {
|
for player in self.players.iter_mut() {
|
||||||
for construct in player.constructs.iter_mut() {
|
for construct in player.constructs.iter_mut() {
|
||||||
if construct.is_ko() {
|
if construct.is_ko() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cooldown = self.resolutions[last].iter()
|
// cooldowns are set at the end of a resolution
|
||||||
.find_map(|r| match r.event {
|
if !casters.contains(&construct.id) {
|
||||||
Event::Cast { construct: caster, player: _, direction: _, skill, target: _ } =>
|
|
||||||
match caster == construct.id && skill.base_cd().is_some() {
|
|
||||||
true => Some(r.skill),
|
|
||||||
false => None,
|
|
||||||
},
|
|
||||||
_ => None,
|
|
||||||
});
|
|
||||||
|
|
||||||
if let Some(skill) = cooldown {
|
|
||||||
construct.skill_set_cd(skill);
|
|
||||||
} else {
|
|
||||||
construct.reduce_cooldowns();
|
construct.reduce_cooldowns();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1915,8 +1920,7 @@ mod tests {
|
|||||||
assert!(game.players[1].constructs[0].is_ko() == false);
|
assert!(game.players[1].constructs[0].is_ko() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// refer fixme.md (infinite counterattack loop)
|
#[test]
|
||||||
/*#[test]
|
|
||||||
fn multi_counter_test() {
|
fn multi_counter_test() {
|
||||||
let mut game = create_2v2_test_game();
|
let mut game = create_2v2_test_game();
|
||||||
let player_id = game.players[0].id;
|
let player_id = game.players[0].id;
|
||||||
@ -1931,11 +1935,10 @@ mod tests {
|
|||||||
|
|
||||||
assert!(game.players[0].constructs[0].is_ko() == false);
|
assert!(game.players[0].constructs[0].is_ko() == false);
|
||||||
assert!(game.players[1].constructs[0].is_ko() == false);
|
assert!(game.players[1].constructs[0].is_ko() == false);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn intercept_test() {
|
fn intercept_test() {
|
||||||
|
|
||||||
let mut game = create_2v2_test_game();
|
let mut game = create_2v2_test_game();
|
||||||
|
|
||||||
let player_id = game.players[0].id;
|
let player_id = game.players[0].id;
|
||||||
|
|||||||
@ -1407,6 +1407,13 @@ fn counter_plus_plus(cast: Cast, game: &mut Game) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn counter_attack(cast: Cast, game: &mut Game) {
|
fn counter_attack(cast: Cast, game: &mut Game) {
|
||||||
|
// effect has to be first so that the loop doesn't occur
|
||||||
|
game.action(cast,
|
||||||
|
Action::Effect {
|
||||||
|
construct: cast.target,
|
||||||
|
effect: ConstructEffect { effect: Effect::Countered, duration: 1, meta: None }, // immunity to additional hits
|
||||||
|
}
|
||||||
|
);
|
||||||
game.action(cast,
|
game.action(cast,
|
||||||
Action::Damage {
|
Action::Damage {
|
||||||
construct: cast.target,
|
construct: cast.target,
|
||||||
@ -1414,12 +1421,6 @@ fn counter_attack(cast: Cast, game: &mut Game) {
|
|||||||
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }).pct(cast.skill.multiplier()),
|
amount: game.value(Value::Stat { construct: cast.source, stat: Stat::RedPower }).pct(cast.skill.multiplier()),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
game.action(cast,
|
|
||||||
Action::Effect {
|
|
||||||
construct: cast.target,
|
|
||||||
effect: ConstructEffect { effect: Effect::Countered, duration: 1, meta: None }, // immunity to additional hits
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user