From 93163b2c066d9827e2bdd2ae1f3633329a3aaa15 Mon Sep 17 00:00:00 2001 From: Maksim Chugunov Date: Tue, 19 Mar 2024 16:55:30 +0300 Subject: [PATCH] Fire trigger list containers; Trigger support replacement description; Editor spawn from pool buttons; Always show cards setting; --- assets/ron/custom.battle.ron | 54 +---- assets/ron/heroes/almsgiver.unit.ron | 6 +- assets/ron/heroes/bat.unit.ron | 11 +- assets/ron/heroes/battlemage.unit.ron | 16 +- assets/ron/heroes/bolla.unit.ron | 18 +- assets/ron/heroes/caster.unit.ron | 12 +- assets/ron/heroes/coach.unit.ron | 6 +- assets/ron/heroes/crusader.unit.ron | 24 +- assets/ron/heroes/custodian.unit.ron | 6 +- assets/ron/heroes/director.unit.ron | 6 +- assets/ron/heroes/doppelganger.unit.ron | 11 +- assets/ron/heroes/enhancer.unit.ron | 10 +- assets/ron/heroes/equalizer.unit.ron | 6 +- assets/ron/heroes/experimenter.unit.ron | 15 +- assets/ron/heroes/famin.unit.ron | 6 +- assets/ron/heroes/fertilizer.unit.ron | 6 +- assets/ron/heroes/fruiter.unit.ron | 18 +- assets/ron/heroes/fungoid.unit.ron | 30 ++- assets/ron/heroes/gardener.unit.ron | 12 +- assets/ron/heroes/gnat.unit.ron | 6 +- assets/ron/heroes/guardian.unit.ron | 11 +- assets/ron/heroes/hag.unit.ron | 6 +- assets/ron/heroes/harvest.unit.ron | 10 +- assets/ron/heroes/henchman.unit.ron | 6 +- assets/ron/heroes/inciter.unit.ron | 11 +- assets/ron/heroes/injector.unit.ron | 6 +- assets/ron/heroes/leech.unit.ron | 11 +- assets/ron/heroes/lilith.unit.ron | 6 +- assets/ron/heroes/master.unit.ron | 16 +- assets/ron/heroes/mentalist.unit.ron | 11 +- assets/ron/heroes/mesmerist.unit.ron | 6 +- assets/ron/heroes/morbid.unit.ron | 8 +- assets/ron/heroes/plaguedoctor.unit.ron | 15 +- assets/ron/heroes/planter.unit.ron | 8 +- assets/ron/heroes/priest.unit.ron | 11 +- assets/ron/heroes/protector.unit.ron | 13 +- assets/ron/heroes/rat.unit.ron | 9 +- assets/ron/heroes/ritualist.unit.ron | 6 +- assets/ron/heroes/rot.unit.ron | 6 +- assets/ron/heroes/ruin.unit.ron | 6 +- assets/ron/heroes/sanctifier.unit.ron | 6 +- assets/ron/heroes/scavenger.unit.ron | 7 +- assets/ron/heroes/trimmer.unit.ron | 6 +- assets/ron/heroes/victim.unit.ron | 6 +- assets/ron/heroes/virus.unit.ron | 6 +- assets/ron/heroes/wizard.unit.ron | 6 +- assets/ron/heroes/zombiebat.unit.ron | 8 +- assets/ron/houses/alchemists.house.ron | 2 +- assets/ron/houses/death_knights.house.ron | 16 +- assets/ron/houses/druids.house.ron | 6 +- assets/ron/houses/mages.house.ron | 6 +- assets/ron/houses/paladins.house.ron | 5 +- assets/ron/houses/warlocks.house.ron | 36 ++- assets/ron/main.options.ron | 5 +- ...mesia_stop_other_battle_start.scenario.ron | 12 +- .../scenarios/kill_after_death.scenario.ron | 6 +- .../ron/scenarios/magic_missile.scenario.ron | 6 +- assets/ron/scenarios/strength.scenario.ron | 2 +- assets/ron/unit.rep.ron | 17 +- assets/ron/vfx/text.vfx.ron | 6 +- src/plugins/hero_editor.rs | 200 ++++++++--------- src/plugins/settings.rs | 21 +- src/plugins/unit.rs | 9 +- src/resourses/effect.rs | 96 ++++++-- src/resourses/expression.rs | 206 +++++++++--------- src/resourses/packed_unit.rs | 159 +++++++++++--- src/resourses/trigger.rs | 130 +++++++---- src/resourses/vars.rs | 1 + src/utils.rs | 13 +- 69 files changed, 937 insertions(+), 529 deletions(-) diff --git a/assets/ron/custom.battle.ron b/assets/ron/custom.battle.ron index 09f8c6272..d8ae08b28 100644 --- a/assets/ron/custom.battle.ron +++ b/assets/ron/custom.battle.ron @@ -1,54 +1,2 @@ #![enable(implicit_some)] -( - left: ( - units: [ - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ], - ), - right: ( - units: [ - (name: "Priest", hp: 1, atk: 1, houses: "Holy"), - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ( - name: "Wizard", - hp: 3, - atk: 1, - houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), - ), - ], - ), -) \ No newline at end of file +(left: (units: []), right: (units: [])) \ No newline at end of file diff --git a/assets/ron/heroes/almsgiver.unit.ron b/assets/ron/heroes/almsgiver.unit.ron index 825df5858..f41a68577 100644 --- a/assets/ron/heroes/almsgiver.unit.ron +++ b/assets/ron/heroes/almsgiver.unit.ron @@ -3,7 +3,11 @@ hp: 3, atk: 1, houses: "Holy", - trigger: Fire(trigger: AllySummon, target: Target, effect: UseAbility("Blessing", 0)), + trigger: Fire( + triggers: [(AllySummon, None)], + targets: [(Target, None)], + effects: [(UseAbility("Blessing", 0), None)], + ), representation: ( material: Shape( shape: Circle( diff --git a/assets/ron/heroes/bat.unit.ron b/assets/ron/heroes/bat.unit.ron index 913362b35..e14afa739 100644 --- a/assets/ron/heroes/bat.unit.ron +++ b/assets/ron/heroes/bat.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Vampires", - description: "%trigger → use %effect on killer", - trigger: Fire(trigger: AllyDeath, target: TargetStateLast(LastAttacker), effect: UseAbility("Siphon", 2)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(AllyDeath, None)], + targets: [(TargetStateLast(LastAttacker), Some("killer"))], + effects: [(UseAbility("Siphon", 2), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Sum(Float(0.81), Mul(Index, Float(-0.17))), Mul(Beat, Float(0.05)))), @@ -19,6 +23,7 @@ ), alpha: Float(1.0), ), + children: [], mapping: { Offset: Vec2EE( Zero, @@ -27,4 +32,6 @@ }, count: 3, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/battlemage.unit.ron b/assets/ron/heroes/battlemage.unit.ron index c07cd333b..c675349b9 100644 --- a/assets/ron/heroes/battlemage.unit.ron +++ b/assets/ron/heroes/battlemage.unit.ron @@ -5,11 +5,16 @@ stacks: 1, level: 1, houses: "Mages", - description: "%trigger → %effectx3 on %target", + description: "%trigger → %effect", trigger: Fire( - trigger: AfterStrike, - target: RandomEnemy, - effect: Repeat(Int(3), WithTarget(RandomEnemy, UseAbility("Magic Missile", 0))), + triggers: [(AfterStrike, None)], + targets: [], + effects: [ + ( + Repeat(Int(3), WithTarget(RandomEnemy, UseAbility("Magic Missile", 0))), + Some("use [Magic Missile] ({Level}) on random enemy 3 times"), + ), + ], ), representation: ( material: Shape( @@ -18,6 +23,7 @@ fill: Solid(color: OwnerState(Color)), alpha: Float(1.0), ), + children: [], mapping: { Offset: Mul( UnitVec(Sum(Index, Mul(Sin(Sum(GameTime, Mul(Index, Float(10.0)))), PI2))), @@ -26,4 +32,6 @@ }, count: 3, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/bolla.unit.ron b/assets/ron/heroes/bolla.unit.ron index 40a2095c2..cabe390eb 100644 --- a/assets/ron/heroes/bolla.unit.ron +++ b/assets/ron/heroes/bolla.unit.ron @@ -1,12 +1,24 @@ -#![enable(implicit_some)] ( name: "Bolla", hp: 1, atk: 1, + stacks: 1, + level: 1, houses: "Dragons", - trigger: Fire(trigger: TurnEnd, effect: UseAbility("Grow", 0)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(TurnEnd, None)], + targets: [(Owner, Some("self"))], + effects: [(UseAbility("Grow", 0), None)], + ), representation: ( - material: Shape(shape: Circle(radius: Float(0.5)), shape_type: Opaque, alpha: Float(0.2)), + material: Shape( + shape: Circle(radius: Float(0.5)), + shape_type: Opaque, + fill: Solid(color: OwnerState(Color)), + alpha: Float(0.2), + ), + children: [], mapping: { Offset: Mul( UnitVec( diff --git a/assets/ron/heroes/caster.unit.ron b/assets/ron/heroes/caster.unit.ron index 6c965d6b3..cfda30c69 100644 --- a/assets/ron/heroes/caster.unit.ron +++ b/assets/ron/heroes/caster.unit.ron @@ -5,11 +5,11 @@ stacks: 1, level: 1, houses: "Mages", - description: "%trigger → %effect on killer", + description: "%trigger → %effect on %target", trigger: Fire( - trigger: AllyDeath, - target: TargetStateLast(LastAttacker), - effect: UseAbility("Magic Missile", 2), + triggers: [(AllyDeath, None)], + targets: [(TargetStateLast(LastAttacker), Some("killer"))], + effects: [(UseAbility("Magic Missile", 2), None)], ), representation: ( material: Shape( @@ -26,6 +26,8 @@ fill: Solid(color: OwnerState(Color)), alpha: Float(1.0), ), + children: [], + mapping: {}, count: 0, ), ], @@ -37,4 +39,6 @@ }, count: 2, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/coach.unit.ron b/assets/ron/heroes/coach.unit.ron index 749cc08b6..39917635f 100644 --- a/assets/ron/heroes/coach.unit.ron +++ b/assets/ron/heroes/coach.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Warriors", description: "%trigger → %effect on %target", - trigger: Fire(trigger: AllySummon, target: Target, effect: UseAbility("Strength", 0)), + trigger: Fire( + triggers: [(AllySummon, None)], + targets: [(Target, None)], + effects: [(UseAbility("Strength", 0), None)], + ), representation: ( material: Shape( shape: Rectangle( diff --git a/assets/ron/heroes/crusader.unit.ron b/assets/ron/heroes/crusader.unit.ron index 633f5b63a..559023018 100644 --- a/assets/ron/heroes/crusader.unit.ron +++ b/assets/ron/heroes/crusader.unit.ron @@ -5,20 +5,26 @@ stacks: 1, level: 1, houses: "Holy", - description: "%trigger → gain {Level} [Blessing] per enemy", + description: "%trigger → %effect on %target", trigger: Fire( - trigger: BattleStart, - target: Owner, - effect: WithVar( - Faction, - OppositeFaction, - WithVar(Charges, UnitCount(Bool(true)), UseAbility("Blessing", 0)), - ), + triggers: [(BattleStart, None)], + targets: [(Owner, None)], + effects: [ + ( + WithVar( + Faction, + OppositeFaction, + WithVar(Charges, UnitCount(Bool(true)), UseAbility("Blessing", 0)), + ), + Some("use [Blessing] ({Level}) per enemy"), + ), + ], ), representation: ( material: Shape( shape: Rectangle(size: Vec2(0.5, 1.82)), shape_type: Line(thickness: Float(3.0)), + fill: Solid(color: OwnerState(Color)), alpha: Float(0.3), ), children: [], @@ -31,4 +37,6 @@ }, count: 8, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/custodian.unit.ron b/assets/ron/heroes/custodian.unit.ron index fb389cb33..a924db9d1 100644 --- a/assets/ron/heroes/custodian.unit.ron +++ b/assets/ron/heroes/custodian.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Paladins", description: "%trigger → %effect on %target", - trigger: Fire(trigger: AllySummon, target: Target, effect: UseAbility("Shield", 0)), + trigger: Fire( + triggers: [(AllySummon, None)], + targets: [(Target, None)], + effects: [(UseAbility("Shield", 0), None)], + ), representation: ( material: Shape( shape: Circle( diff --git a/assets/ron/heroes/director.unit.ron b/assets/ron/heroes/director.unit.ron index 37fd294fd..ca11865a1 100644 --- a/assets/ron/heroes/director.unit.ron +++ b/assets/ron/heroes/director.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Mages", description: "%trigger → %effect on %target", - trigger: Fire(trigger: AllySummon, target: RandomEnemy, effect: UseAbility("Magic Missile", 3)), + trigger: Fire( + triggers: [(AllySummon, None)], + targets: [(RandomEnemy, None)], + effects: [(UseAbility("Magic Missile", 3), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.15)), diff --git a/assets/ron/heroes/doppelganger.unit.ron b/assets/ron/heroes/doppelganger.unit.ron index f645dfa49..bba3ac240 100644 --- a/assets/ron/heroes/doppelganger.unit.ron +++ b/assets/ron/heroes/doppelganger.unit.ron @@ -4,7 +4,11 @@ hp: 2, atk: 3, houses: "Shifters", - trigger: Fire(trigger: BattleStart, target: RandomAdjacentUnit, effect: UseAbility("Copy", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(RandomAdjacentUnit, None)], + effects: [(UseAbility("Copy", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.72)), @@ -13,7 +17,10 @@ ), children: [], mapping: { - Offset: Mul(UnitVec(Mul(IntFloat(OwnerState(Index)), Mul(PI, Float(0.5)))), Mul(Beat, Float(0.5))), + Offset: Mul( + UnitVec(Mul(IntFloat(OwnerState(Index)), Mul(PI, Float(0.5)))), + Mul(Beat, Float(0.5)), + ), }, count: 4, ), diff --git a/assets/ron/heroes/enhancer.unit.ron b/assets/ron/heroes/enhancer.unit.ron index 33aa92d4f..5bf706910 100644 --- a/assets/ron/heroes/enhancer.unit.ron +++ b/assets/ron/heroes/enhancer.unit.ron @@ -5,11 +5,11 @@ stacks: 1, level: 1, houses: "Mages", - description: "%trigger → [Magic Missile] {+1} {DMG}", + description: "%trigger → %effect", trigger: Fire( - trigger: BattleStart, - target: Owner, - effect: AbilityStateAddVar("Magic Missile", Value, Int(1)), + triggers: [(BattleStart, None)], + targets: [], + effects: [(AbilityStateAddVar("Magic Missile", Damage, Context(Level)), None)], ), representation: ( material: Shape( @@ -27,4 +27,6 @@ mapping: {T: Sin(Sum(GameTime, Index))}, count: 4, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/equalizer.unit.ron b/assets/ron/heroes/equalizer.unit.ron index 4489d4038..82a367da8 100644 --- a/assets/ron/heroes/equalizer.unit.ron +++ b/assets/ron/heroes/equalizer.unit.ron @@ -7,7 +7,11 @@ level: 1, houses: "Alchemists", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllUnits, effect: UseAbility("Petrify", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllUnits, None)], + effects: [(UseAbility("Petrify", 0), None)], + ), representation: ( material: None, children: [ diff --git a/assets/ron/heroes/experimenter.unit.ron b/assets/ron/heroes/experimenter.unit.ron index 2fa175d52..218164534 100644 --- a/assets/ron/heroes/experimenter.unit.ron +++ b/assets/ron/heroes/experimenter.unit.ron @@ -5,11 +5,16 @@ stacks: 1, level: 1, houses: "Death Knights", - description: "[Skeleton] apply [Plague] on damage dealt", + description: "%trigger → %effect", trigger: Fire( - trigger: BattleStart, - target: Owner, - effect: AbilityStateAddVar("Summon Skeleton", T, String("Plague on damage dealt")), + triggers: [(BattleStart, None)], + targets: [], + effects: [ + ( + AbilityStateAddVar("Summon Skeleton", T, String("Plague on damage dealt")), + Some("[Skeleton] applies [Plague] on attack"), + ), + ], ), representation: ( material: Shape( @@ -27,4 +32,6 @@ mapping: {T: Sin(Sum(GameTime, Index))}, count: 4, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/famin.unit.ron b/assets/ron/heroes/famin.unit.ron index fde777322..b2f5fcab8 100644 --- a/assets/ron/heroes/famin.unit.ron +++ b/assets/ron/heroes/famin.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: Period(0, 4, TurnEnd), target: AllEnemyUnits, effect: UseAbility("Plague", 0)), + trigger: Fire( + triggers: [(Period(0, 4, TurnEnd), Some("Every 5 Turns"))], + targets: [(AllEnemyUnits, None)], + effects: [(UseAbility("Plague", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.12)), diff --git a/assets/ron/heroes/fertilizer.unit.ron b/assets/ron/heroes/fertilizer.unit.ron index 3037a235c..e3bbd49fa 100644 --- a/assets/ron/heroes/fertilizer.unit.ron +++ b/assets/ron/heroes/fertilizer.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Druids", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllAllyUnits, effect: UseAbility("Thorns", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllAllyUnits, None)], + effects: [(UseAbility("Thorns", 0), None)], + ), representation: ( material: Shape( shape: Rectangle(size: Vec2E(Float(1.0))), diff --git a/assets/ron/heroes/fruiter.unit.ron b/assets/ron/heroes/fruiter.unit.ron index a9a0eb8db..77eacf5e5 100644 --- a/assets/ron/heroes/fruiter.unit.ron +++ b/assets/ron/heroes/fruiter.unit.ron @@ -5,16 +5,14 @@ stacks: 1, level: 1, houses: "Druids", - description: "%trigger → [Summon Treant] gains +{Level}/+{Level}", + description: "%trigger → %effect", trigger: Fire( - trigger: BattleStart, - target: Owner, - effect: List( - [ - AbilityStateAddVar("Treant", Hp, Context(Level)), - AbilityStateAddVar("Treant", Atk, Context(Level)), - ], - ), + triggers: [(BattleStart, None)], + targets: [], + effects: [ + (AbilityStateAddVar("Treant", Atk, Context(Level)), None), + (AbilityStateAddVar("Treant", Hp, Context(Level)), None), + ], ), representation: ( material: Shape( @@ -37,4 +35,6 @@ }, count: 2, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/fungoid.unit.ron b/assets/ron/heroes/fungoid.unit.ron index 09f07d01d..7731c9c5a 100644 --- a/assets/ron/heroes/fungoid.unit.ron +++ b/assets/ron/heroes/fungoid.unit.ron @@ -7,17 +7,27 @@ houses: "Druids", description: "%trigger → %effect (max 3)", trigger: Fire( - trigger: AllyDeath, - target: Owner, - effect: List( - [ - If( - LessThen(ToInt(OwnerStateLast(Charges)), Int(3)), - List([StateAddVar(Charges, Owner, Int(1)), UseAbility("Summon Treant", 0)]), - Noop, + triggers: [(AllyDeath, None)], + targets: [], + effects: [ + ( + List( + [ + If( + LessThen(ToInt(OwnerStateLast(Charges)), Int(3)), + List( + [ + StateAddVar(Charges, Owner, Int(1)), + UseAbility("Summon Treant", 0), + ], + ), + Noop, + ), + ], ), - ], - ), + Some("[Summon Treant]"), + ), + ], ), representation: ( material: Shape( diff --git a/assets/ron/heroes/gardener.unit.ron b/assets/ron/heroes/gardener.unit.ron index 8d18b9c50..bcd98d5cd 100644 --- a/assets/ron/heroes/gardener.unit.ron +++ b/assets/ron/heroes/gardener.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Druids", - description: "%trigger → %effect on front ally", - trigger: Fire(trigger: TurnEnd, target: SlotUnit(Int(1)), effect: UseAbility("Thorns", 0)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(TurnEnd, None)], + targets: [(SlotUnit(Int(1)), Some("front ally"))], + effects: [(UseAbility("Thorns", 0), None)], + ), representation: ( material: Shape( shape: Rectangle( @@ -21,8 +25,8 @@ fill: GradientLinear( point1: UnitVec(Mul(GameTime, Float(0.3))), point2: UnitVec(Sum(Mul(GameTime, Float(0.3)), PI)), - colors: [OwnerState(Color), Hex("101010ff")], parts: [Float(0.5), Float(0.51)], + colors: [OwnerState(Color), Hex("101010ff")], ), alpha: Float(1.0), ), @@ -30,4 +34,6 @@ mapping: {Rotation: Mul(Index, Float(0.18))}, count: 8, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/gnat.unit.ron b/assets/ron/heroes/gnat.unit.ron index feb1ea972..ebe152b80 100644 --- a/assets/ron/heroes/gnat.unit.ron +++ b/assets/ron/heroes/gnat.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Vampires", description: "%trigger → %effect on %target", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Siphon", 0)), + trigger: Fire( + triggers: [(TurnEnd, None)], + targets: [(RandomEnemy, None)], + effects: [(UseAbility("Siphon", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Mul(Index, Float(-0.14)), Sum(Float(0.9), Mul(Beat, Float(0.05))))), diff --git a/assets/ron/heroes/guardian.unit.ron b/assets/ron/heroes/guardian.unit.ron index 4599a004f..d382b2726 100644 --- a/assets/ron/heroes/guardian.unit.ron +++ b/assets/ron/heroes/guardian.unit.ron @@ -5,16 +5,17 @@ stacks: 1, level: 1, houses: "Paladins", - description: "%trigger → %effect on ally that doesn\'t have [Shield]", + description: "%trigger → %effect on %target", trigger: Fire( - trigger: Period(0, 1, TurnEnd), - target: FindUnit(Equals(StatusCharges(String("Shield")), Zero)), - effect: UseAbility("Shield", 0), + triggers: [(Period(0, 1, TurnEnd), Some("Every 2 Turns"))], + targets: [(FindUnit(Equals(StatusCharges(String("Shield")), Zero)), Some("ally with no [Shield]"))], + effects: [(UseAbility("Shield", 0), None)], ), representation: ( material: Shape( shape: Circle(radius: Float(0.8)), shape_type: Line(thickness: Float(0.6)), + fill: Solid(color: OwnerState(Color)), alpha: Float(1.0), ), children: [], @@ -26,4 +27,6 @@ }, count: 9, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/hag.unit.ron b/assets/ron/heroes/hag.unit.ron index 61bd13115..0a4e3d2fd 100644 --- a/assets/ron/heroes/hag.unit.ron +++ b/assets/ron/heroes/hag.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Witches", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllEnemyUnits, effect: UseAbility("Weakness", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllEnemyUnits, None)], + effects: [(UseAbility("Weakness", 0), None)], + ), representation: ( material: Curve( thickness: Float(0.3), diff --git a/assets/ron/heroes/harvest.unit.ron b/assets/ron/heroes/harvest.unit.ron index 1db4527ac..674aaa535 100644 --- a/assets/ron/heroes/harvest.unit.ron +++ b/assets/ron/heroes/harvest.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Druids", - description: "{In 5 Turns} → %effect", - trigger: Fire(trigger: OnceAfter(4, TurnEnd), target: Owner, effect: UseAbility("Summon Treant", 2)), + description: "%trigger → %effect", + trigger: Fire( + triggers: [(OnceAfter(4, TurnEnd), Some("In 5 Turns"))], + targets: [], + effects: [(UseAbility("Summon Treant", 2), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.12)), @@ -27,4 +31,6 @@ }, count: 16, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/henchman.unit.ron b/assets/ron/heroes/henchman.unit.ron index 508633fd7..0a4f63436 100644 --- a/assets/ron/heroes/henchman.unit.ron +++ b/assets/ron/heroes/henchman.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Warlocks", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: Owner, effect: UseAbility("Doom", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(Owner, None)], + effects: [(UseAbility("Doom", 0), None)], + ), representation: ( material: Shape( shape: Circle( diff --git a/assets/ron/heroes/inciter.unit.ron b/assets/ron/heroes/inciter.unit.ron index 7dc83f2e9..855a7e436 100644 --- a/assets/ron/heroes/inciter.unit.ron +++ b/assets/ron/heroes/inciter.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Meta", - description: "%trigger → use %effect on killer", - trigger: Fire(trigger: AllyDeath, target: TargetStateLast(LastAttacker), effect: UseAbility("Betray", 0)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(AllyDeath, None)], + targets: [(TargetStateLast(LastAttacker), Some("killer"))], + effects: [(UseAbility("Betray", 0), None)], + ), representation: ( material: Shape( shape: Circle( @@ -16,6 +20,7 @@ ), ), shape_type: Line(thickness: Float(1.0)), + fill: Solid(color: OwnerState(Color)), alpha: Float(0.3), ), children: [], @@ -32,4 +37,6 @@ }, count: 10, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/injector.unit.ron b/assets/ron/heroes/injector.unit.ron index c0f75d4ca..c8305a118 100644 --- a/assets/ron/heroes/injector.unit.ron +++ b/assets/ron/heroes/injector.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: AfterDamageDealt, target: Target, effect: UseAbility("Plague", 0)), + trigger: Fire( + triggers: [(AfterDamageDealt, None)], + targets: [(Target, None)], + effects: [(UseAbility("Plague", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sub(Float(0.19), Mul(Index, Float(0.02)))), diff --git a/assets/ron/heroes/leech.unit.ron b/assets/ron/heroes/leech.unit.ron index 257968552..7c41f330a 100644 --- a/assets/ron/heroes/leech.unit.ron +++ b/assets/ron/heroes/leech.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Vampires", - description: "%trigger → use %effect on killer", - trigger: Fire(trigger: AfterDamageDealt, target: Target, effect: UseAbility("Siphon", 2)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(AfterDamageDealt, None)], + targets: [(Target, None)], + effects: [(UseAbility("Siphon", 2), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Sum(Float(0.7), Mul(Index, Float(0.08))), Mul(Beat, Float(0.05)))), @@ -19,10 +23,13 @@ ), alpha: Float(1.0), ), + children: [], mapping: { Offset: Vec2EE(Sum(Mul(Index, Float(-0.04)), Mul(Abs(Beat), Mul(Float(0.1), Index))), Zero), Rotation: Float(1.57), }, count: 2, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/lilith.unit.ron b/assets/ron/heroes/lilith.unit.ron index 2830cb471..e680d1667 100644 --- a/assets/ron/heroes/lilith.unit.ron +++ b/assets/ron/heroes/lilith.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Vampires", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllOtherUnits, effect: UseAbility("Siphon", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllOtherUnits, None)], + effects: [(UseAbility("Siphon", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Mul(Index, Float(-0.07)), Sum(Float(0.9), Mul(Beat, Float(0.05))))), diff --git a/assets/ron/heroes/master.unit.ron b/assets/ron/heroes/master.unit.ron index b104e6b2e..b4c3398ea 100644 --- a/assets/ron/heroes/master.unit.ron +++ b/assets/ron/heroes/master.unit.ron @@ -5,16 +5,14 @@ stacks: 1, level: 1, houses: "Death Knights", - description: "[Skeleton] HP +({Level}+1) ATK +({Level}+1)", + description: "%trigger → %effect", trigger: Fire( - trigger: BattleStart, - target: Owner, - effect: List( - [ - AbilityStateAddVar("Skeleton", Hp, Sum(Context(Level), Int(1))), - AbilityStateAddVar("Skeleton", Atk, Sum(Context(Level), Int(1))), - ], - ), + triggers: [(BattleStart, None)], + targets: [], + effects: [ + (AbilityStateAddVar("Skeleton", Atk, Sum(Context(Level), Int(1))), None), + (AbilityStateAddVar("Skeleton", Hp, Sum(Context(Level), Int(1))), None), + ], ), representation: ( material: Shape( diff --git a/assets/ron/heroes/mentalist.unit.ron b/assets/ron/heroes/mentalist.unit.ron index ea1a37b98..3ae24d315 100644 --- a/assets/ron/heroes/mentalist.unit.ron +++ b/assets/ron/heroes/mentalist.unit.ron @@ -4,7 +4,11 @@ hp: 1, atk: 2, houses: "Meta", - trigger: Fire(trigger: BattleStart, target: AllUnits, effect: UseAbility("Amnesia", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllUnits, None)], + effects: [(UseAbility("Amnesia", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.25)), @@ -14,7 +18,10 @@ children: [], mapping: { Offset: Mul(Vec2EE(Cos(OwnerState(T)), Sin(OwnerState(T))), Float(0.5)), - T: Sum(Sin(Sum(GameTime, Mul(IntFloat(OwnerState(Index)), Float(-0.15)))), Mul(PI, Float(1.5))), + T: Sum( + Sin(Sum(GameTime, Mul(IntFloat(OwnerState(Index)), Float(-0.15)))), + Mul(PI, Float(1.5)), + ), }, count: 8, ), diff --git a/assets/ron/heroes/mesmerist.unit.ron b/assets/ron/heroes/mesmerist.unit.ron index 9a49e742a..d6fd14aab 100644 --- a/assets/ron/heroes/mesmerist.unit.ron +++ b/assets/ron/heroes/mesmerist.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Meta", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: RandomEnemy, effect: UseAbility("Betray", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(RandomEnemy, None)], + effects: [(UseAbility("Betray", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Mul(Index, Mul(Float(0.1), Abs(Sin(Sum(GameTime, Index)))))), diff --git a/assets/ron/heroes/morbid.unit.ron b/assets/ron/heroes/morbid.unit.ron index bb534dfa3..35ca2a3e7 100644 --- a/assets/ron/heroes/morbid.unit.ron +++ b/assets/ron/heroes/morbid.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Death Knights", - description: "%trigger → %effect on killer", - trigger: Fire(trigger: AllyDeath, target: TargetStateLast(LastAttacker), effect: UseAbility("Decay", 2)), + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(AllyDeath, None)], + targets: [(TargetStateLast(LastAttacker), Some("killer"))], + effects: [(UseAbility("Decay", 2), None)], + ), representation: ( material: Shape( shape: Rectangle(size: Vec2E(Float(0.35))), diff --git a/assets/ron/heroes/plaguedoctor.unit.ron b/assets/ron/heroes/plaguedoctor.unit.ron index 510eadeea..aef6ffe73 100644 --- a/assets/ron/heroes/plaguedoctor.unit.ron +++ b/assets/ron/heroes/plaguedoctor.unit.ron @@ -5,11 +5,16 @@ stacks: 1, level: 1, houses: "Death Knights", - description: "%trigger → clear [Plague] from ally", + description: "%trigger → %effect on %target", trigger: Fire( - trigger: Period(0, 1, TurnEnd), - target: FindUnit(StatusCharges(String("Plague"))), - effect: List([ClearStatus("Plague"), Vfx("ron/vfx/apply_status.vfx.ron")]), + triggers: [(Period(0, 1, TurnEnd), Some("Every 2 Turns"))], + targets: [(FindUnit(StatusCharges(String("Plague"))), Some("ally"))], + effects: [ + ( + List([ClearStatus("Plague"), Vfx("ron/vfx/apply_status.vfx.ron")]), + Some("clear [Plague]"), + ), + ], ), representation: ( material: Shape( @@ -32,4 +37,6 @@ }, count: 12, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/planter.unit.ron b/assets/ron/heroes/planter.unit.ron index f5dd138b4..fc1cdad92 100644 --- a/assets/ron/heroes/planter.unit.ron +++ b/assets/ron/heroes/planter.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Druids", description: "%trigger → %effect", - trigger: Fire(trigger: BattleStart, target: Owner, effect: UseAbility("Summon Treant", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [], + effects: [(UseAbility("Summon Treant", 0), None)], + ), representation: ( material: Shape( shape: Circle( @@ -16,8 +20,8 @@ fill: GradientLinear( point1: UnitVec(Mul(GameTime, Float(0.3))), point2: UnitVec(Sum(Mul(GameTime, Float(0.3)), PI)), - colors: [OwnerState(Color), Hex("101010ff")], parts: [Float(0.5), Float(0.51)], + colors: [OwnerState(Color), Hex("101010ff")], ), alpha: Float(1.0), ), diff --git a/assets/ron/heroes/priest.unit.ron b/assets/ron/heroes/priest.unit.ron index f0088f4d3..d740ffa87 100644 --- a/assets/ron/heroes/priest.unit.ron +++ b/assets/ron/heroes/priest.unit.ron @@ -4,7 +4,11 @@ hp: 1, atk: 2, houses: "Holy", - trigger: Fire(trigger: BattleStart, target: AllAllyUnits, effect: UseAbility("Blessing", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllAllyUnits, None)], + effects: [(UseAbility("Blessing", 0), None)], + ), representation: ( count: 4, material: Shape( @@ -14,7 +18,10 @@ mapping: { Offset: Mul( UnitVec( - Mul(Sum(GameTime, Mul(Mul(PI, Float(0.5)), IntFloat(OwnerState(Index)))), Float(3.0)), + Mul( + Sum(GameTime, Mul(Mul(PI, Float(0.5)), IntFloat(OwnerState(Index)))), + Float(3.0), + ), ), Float(0.3), ), diff --git a/assets/ron/heroes/protector.unit.ron b/assets/ron/heroes/protector.unit.ron index 8e7c390dd..635db9468 100644 --- a/assets/ron/heroes/protector.unit.ron +++ b/assets/ron/heroes/protector.unit.ron @@ -2,13 +2,20 @@ name: "Protector", hp: 2, atk: 2, + stacks: 1, + level: 1, houses: "Paladins", - trigger: Fire(trigger: BattleStart, target: SlotUnit(Int(1)), effect: UseAbility("Shield", 0)), - description: "%trigger → use %effect on front ally", + description: "%trigger → %effect on %target", + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(SlotUnit(Int(1)), Some("front ally"))], + effects: [(UseAbility("Shield", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.67)), shape_type: Line(thickness: Float(0.37)), + fill: Solid(color: OwnerState(Color)), alpha: Float(0.36), ), children: [], @@ -25,4 +32,6 @@ }, count: 16, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/rat.unit.ron b/assets/ron/heroes/rat.unit.ron index bb18c6956..d99e276c6 100644 --- a/assets/ron/heroes/rat.unit.ron +++ b/assets/ron/heroes/rat.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: RandomEnemySubset(Int(2)), effect: UseAbility("Plague", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(RandomEnemySubset(Int(2)), None)], + effects: [(UseAbility("Plague", 0), None)], + ), representation: ( material: Shape( shape: Circle( @@ -16,6 +20,7 @@ fill: Solid(color: OwnerState(Color)), alpha: Context(T), ), + children: [], mapping: { T: Sin(Sum(GameTime, Index)), Offset: Mul( @@ -27,4 +32,6 @@ }, count: 4, ), + state: (history: {}, birth: 0.0), + statuses: [], ) \ No newline at end of file diff --git a/assets/ron/heroes/ritualist.unit.ron b/assets/ron/heroes/ritualist.unit.ron index b559cc7af..87564668e 100644 --- a/assets/ron/heroes/ritualist.unit.ron +++ b/assets/ron/heroes/ritualist.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Warlocks", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: SlotUnit(Int(1)), effect: UseAbility("Doom", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(SlotUnit(Int(1)), Some("front ally"))], + effects: [(UseAbility("Doom", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.5)), diff --git a/assets/ron/heroes/rot.unit.ron b/assets/ron/heroes/rot.unit.ron index 38dec70a3..a58e27f6d 100644 --- a/assets/ron/heroes/rot.unit.ron +++ b/assets/ron/heroes/rot.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Decay", 0)), + trigger: Fire( + triggers: [(TurnEnd, None)], + targets: [(RandomEnemy, None)], + effects: [(UseAbility("Decay", 0), None)], + ), representation: ( material: Shape( shape: Rectangle(size: Vec2E(Float(0.19))), diff --git a/assets/ron/heroes/ruin.unit.ron b/assets/ron/heroes/ruin.unit.ron index 7fb3c71c4..d9169f2ed 100644 --- a/assets/ron/heroes/ruin.unit.ron +++ b/assets/ron/heroes/ruin.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllEnemyUnits, effect: UseAbility("Decay", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllEnemyUnits, None)], + effects: [(UseAbility("Decay", 0), None)], + ), representation: ( material: Shape( shape: Rectangle(size: Vec2E(Float(0.94))), diff --git a/assets/ron/heroes/sanctifier.unit.ron b/assets/ron/heroes/sanctifier.unit.ron index 6a6032b01..7f9fe2198 100644 --- a/assets/ron/heroes/sanctifier.unit.ron +++ b/assets/ron/heroes/sanctifier.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Holy", description: "%trigger → %effect on %target", - trigger: Fire(trigger: AllyDeath, target: AdjacentUnits, effect: UseAbility("Blessing", 0)), + trigger: Fire( + triggers: [(AllyDeath, None)], + targets: [(AdjacentUnits, None)], + effects: [(UseAbility("Blessing", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Float(0.59), Mul(Beat, Float(0.05)))), diff --git a/assets/ron/heroes/scavenger.unit.ron b/assets/ron/heroes/scavenger.unit.ron index 6e466f216..08fb9e677 100644 --- a/assets/ron/heroes/scavenger.unit.ron +++ b/assets/ron/heroes/scavenger.unit.ron @@ -4,7 +4,7 @@ hp: 1, atk: 1, houses: "Dragons", - trigger: Fire(trigger: AnyDeath, effect: UseAbility("Grow", 0)), + trigger: Fire(triggers: [(AnyDeath, None)], effects: [(UseAbility("Grow", 0), None)]), representation: ( material: Shape( shape: Rectangle(size: Vec2E(Sum(Float(0.4), Mul(RandomFloat(Owner), Float(1.1))))), @@ -13,7 +13,10 @@ ), children: [], mapping: { - Rotation: Sum(IntFloat(OwnerState(Index)), Sin(Sum(GameTime, Mul(RandomFloat(Owner), Float(10.0))))), + Rotation: Sum( + IntFloat(OwnerState(Index)), + Sin(Sum(GameTime, Mul(RandomFloat(Owner), Float(10.0)))), + ), }, count: 10, ), diff --git a/assets/ron/heroes/trimmer.unit.ron b/assets/ron/heroes/trimmer.unit.ron index 863f7219f..484403516 100644 --- a/assets/ron/heroes/trimmer.unit.ron +++ b/assets/ron/heroes/trimmer.unit.ron @@ -7,7 +7,11 @@ level: 1, houses: "Alchemists", description: "%trigger → %effect on enemy with most HP", - trigger: Fire(trigger: BattleStart, target: FilterMaxEnemy(OwnerState(Hp)), effect: UseAbility("Petrify", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(FilterMaxEnemy(OwnerState(Hp)), None)], + effects: [(UseAbility("Petrify", 0), None)], + ), representation: ( material: None, children: [ diff --git a/assets/ron/heroes/victim.unit.ron b/assets/ron/heroes/victim.unit.ron index c3b89c7da..3032291b3 100644 --- a/assets/ron/heroes/victim.unit.ron +++ b/assets/ron/heroes/victim.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Paladins", description: "%trigger → %effect", - trigger: Fire(trigger: BeforeDeath, target: Owner, effect: UseAbility("Summon Guardian Angel", 0)), + trigger: Fire( + triggers: [(BeforeDeath, None)], + targets: [(Owner, None)], + effects: [(UseAbility("Summon Guardian Angel", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Float(0.2), Sub(Zero, Mul(Index, Float(0.03))))), diff --git a/assets/ron/heroes/virus.unit.ron b/assets/ron/heroes/virus.unit.ron index dc81a9fd4..709eb1eb6 100644 --- a/assets/ron/heroes/virus.unit.ron +++ b/assets/ron/heroes/virus.unit.ron @@ -6,7 +6,11 @@ level: 1, houses: "Death Knights", description: "%trigger → %effect on %target", - trigger: Fire(trigger: BattleStart, target: AllEnemyUnits, effect: UseAbility("Plague", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllEnemyUnits, None)], + effects: [(UseAbility("Plague", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Float(0.12)), diff --git a/assets/ron/heroes/wizard.unit.ron b/assets/ron/heroes/wizard.unit.ron index 35e7c7982..f2e5ded36 100644 --- a/assets/ron/heroes/wizard.unit.ron +++ b/assets/ron/heroes/wizard.unit.ron @@ -4,7 +4,11 @@ hp: 3, atk: 1, houses: "Mages", - trigger: Fire(trigger: TurnEnd, target: RandomEnemy, effect: UseAbility("Magic Missile", 0)), + trigger: Fire( + triggers: [(TurnEnd, None)], + targets: [(RandomEnemy, None)], + effects: [(UseAbility("Magic Missile", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Float(0.7), Mul(Beat, Float(0.3)))), diff --git a/assets/ron/heroes/zombiebat.unit.ron b/assets/ron/heroes/zombiebat.unit.ron index e729f552a..501a31a65 100644 --- a/assets/ron/heroes/zombiebat.unit.ron +++ b/assets/ron/heroes/zombiebat.unit.ron @@ -5,8 +5,12 @@ stacks: 1, level: 1, houses: "Death Knights", - description: "%trigger → use %effect on killer", - trigger: Fire(trigger: AllyDeath, target: TargetStateLast(LastAttacker), effect: UseAbility("Plague", 0)), + description: "%trigger → %effect on killer", + trigger: Fire( + triggers: [(AllyDeath, None)], + targets: [(TargetStateLast(LastAttacker), None)], + effects: [(UseAbility("Plague", 0), None)], + ), representation: ( material: Shape( shape: Circle(radius: Sum(Sum(Float(0.81), Mul(Index, Float(-0.17))), Mul(Beat, Float(0.05)))), diff --git a/assets/ron/houses/alchemists.house.ron b/assets/ron/houses/alchemists.house.ron index 4d107a5a2..95dca525b 100644 --- a/assets/ron/houses/alchemists.house.ron +++ b/assets/ron/houses/alchemists.house.ron @@ -6,7 +6,7 @@ ( name: "Petrify", description: "Next taken damage is lethal", - trigger: Fire(trigger: AfterDamageTaken, effect: Kill), + trigger: Fire(triggers: [(AfterDamageTaken, None)], effects: [(Kill, None)]), ), ], abilities: [ diff --git a/assets/ron/houses/death_knights.house.ron b/assets/ron/houses/death_knights.house.ron index a4a242e5a..161171aa9 100644 --- a/assets/ron/houses/death_knights.house.ron +++ b/assets/ron/houses/death_knights.house.ron @@ -9,8 +9,14 @@ description: "Take {Charges} DMG every turn, [Summon Skeleton] after death", trigger: List( [ - Fire(trigger: TurnEnd, effect: WithTarget(Owner, Damage(Context(Charges)))), - Fire(trigger: BeforeDeath, effect: UseAbility("Summon Skeleton", 0)), + Fire( + triggers: [(TurnEnd, None)], + effects: [(WithTarget(Owner, Damage(Context(Charges))), None)], + ), + Fire( + triggers: [(BeforeDeath, None)], + effects: [(UseAbility("Summon Skeleton", 0), None)], + ), ], ), ), @@ -47,9 +53,9 @@ houses: "Death Knights", description: "", trigger: Fire( - trigger: AfterDamageDealt, - target: Target, - effect: If(AbilityState("Summon Skeleton", T), UseAbility("Plague", 0), Noop), + triggers: [(AfterDamageDealt, None)], + targets: [(Target, None)], + effects: [(If(AbilityState("Summon Skeleton", T), UseAbility("Plague", 0), Noop), None)], ), representation: ( material: Shape( diff --git a/assets/ron/houses/druids.house.ron b/assets/ron/houses/druids.house.ron index b45b9ca73..1df5b4c0d 100644 --- a/assets/ron/houses/druids.house.ron +++ b/assets/ron/houses/druids.house.ron @@ -7,9 +7,9 @@ name: "Thorns", description: "Deal {Charges} DMG to attacker", trigger: Fire( - trigger: AfterDamageTaken, - target: OwnerStateLast(LastAttacker), - effect: Damage(Context(Charges)), + triggers: [(AfterDamageTaken, None)], + targets: [(OwnerStateLast(LastAttacker), None)], + effects: [(Damage(Context(Charges)), None)], ), ), ], diff --git a/assets/ron/houses/mages.house.ron b/assets/ron/houses/mages.house.ron index 26d7f6e43..07164e957 100644 --- a/assets/ron/houses/mages.house.ron +++ b/assets/ron/houses/mages.house.ron @@ -2,14 +2,14 @@ ( name: "Mages", color: ("#1E88E5"), - defaults: {"Magic Missile": {Value: Int(1)}}, + defaults: {"Magic Missile": {Damage: Int(1)}}, abilities: [ ( name: "Magic Missile", - description: "Deal {Value} DMG to random enemy", + description: "Deal {Damage} DMG to random enemy", effect: Repeat( Context(Charges), - List([Damage(AbilityContext("Magic Missile", Value)), Vfx("magic_missile")]), + List([Damage(AbilityContext("Magic Missile", Damage)), Vfx("magic_missile")]), ), ), ], diff --git a/assets/ron/houses/paladins.house.ron b/assets/ron/houses/paladins.house.ron index cbc286aba..c39a4e517 100644 --- a/assets/ron/houses/paladins.house.ron +++ b/assets/ron/houses/paladins.house.ron @@ -10,8 +10,8 @@ [ Change(trigger: IncomingDamage, expr: Mul(Context(Value), Int(-1))), Fire( - trigger: AfterIncomingDamage, - effect: WithVar(Charges, Int(-1), AddStatus("Shield")), + triggers: [(AfterIncomingDamage, None)], + effects: [(WithVar(Charges, Int(-1), AddStatus("Shield")), None)], ), ], ), @@ -38,7 +38,6 @@ level: 1, houses: "Paladins", description: "", - trigger: Fire(trigger: Noop, target: Owner, effect: Noop), representation: ( material: Shape( shape: Circle( diff --git a/assets/ron/houses/warlocks.house.ron b/assets/ron/houses/warlocks.house.ron index 9e251816d..96f4e7e0a 100644 --- a/assets/ron/houses/warlocks.house.ron +++ b/assets/ron/houses/warlocks.house.ron @@ -7,17 +7,27 @@ name: "Doom", description: "Die in {Charges} turns then summon Doomguard", trigger: Fire( - trigger: TurnEnd, - effect: List( - [ + triggers: [(TurnEnd, None)], + effects: [ + ( If( Equals(StatusCharges(String("Doom")), Int(1)), - List([Kill, WithVar(Faction, StateLast(Faction, Parent(Context(Caster))), Summon("Doomguard"))]), + List( + [ + Kill, + WithVar( + Faction, + StateLast(Faction, Parent(Context(Caster))), + Summon("Doomguard"), + ), + ], + ), Noop, ), - WithVar(Charges, Int(-1), AddStatus("Doom")), - ], - ), + None, + ), + (WithVar(Charges, Int(-1), AddStatus("Doom")), None), + ], ), ), ], @@ -25,10 +35,13 @@ ( name: "Doom", description: "Kill target in 5 turns then summon friendly [Doomguard]", - effect: List([ - WithVar(Charges, Int(5), AddStatus("Doom")), Vfx("apply_status"), - StateSetVar(Caster, StatusEntity("Doom", Target), Owner), - ]), + effect: List( + [ + WithVar(Charges, Int(5), AddStatus("Doom")), + Vfx("apply_status"), + StateSetVar(Caster, StatusEntity("Doom", Target), Owner), + ], + ), ), ], summons: [ @@ -40,7 +53,6 @@ level: 1, houses: "Warlocks", description: "", - trigger: Fire(trigger: Noop, target: Owner, effect: UseAbility("Doom", 0)), representation: ( material: Shape( shape: Circle( diff --git a/assets/ron/main.options.ron b/assets/ron/main.options.ron index 15b78f203..8339f6d20 100644 --- a/assets/ron/main.options.ron +++ b/assets/ron/main.options.ron @@ -1,4 +1 @@ -( - address: "http://localhost:3001", - server: "aoi_dev2", -) \ No newline at end of file +(address: "http://localhost:3001", server: "aoi_dev2") \ No newline at end of file diff --git a/assets/ron/scenarios/amesia_stop_other_battle_start.scenario.ron b/assets/ron/scenarios/amesia_stop_other_battle_start.scenario.ron index 2c1425b37..114eec4b2 100644 --- a/assets/ron/scenarios/amesia_stop_other_battle_start.scenario.ron +++ b/assets/ron/scenarios/amesia_stop_other_battle_start.scenario.ron @@ -3,7 +3,11 @@ left: ( units: [ ( - trigger: Fire(trigger: BattleStart, target: AllUnits, effect: UseAbility("Amnesia", 0)), + trigger: Fire( + triggers: [(BattleStart, None)], + targets: [(AllUnits, None)], + effects: [(UseAbility("Amnesia", 0), None)], + ), hp: 3, atk: 1, name: "left", @@ -13,19 +17,19 @@ right: ( units: [ ( - trigger: Fire(trigger: BattleStart, effect: UseAbility("Shield", 0)), + trigger: Fire(triggers: [(BattleStart, None)], effects: [(UseAbility("Shield", 0), None)]), hp: 1, atk: 1, name: "right", ), ( - trigger: Fire(trigger: BattleStart, effect: UseAbility("Vitality", 0)), + trigger: Fire(triggers: [(BattleStart, None)], effects: [(UseAbility("Vitality", 0), None)]), hp: 1, atk: 1, name: "right", ), ( - trigger: Fire(trigger: BattleStart, effect: UseAbility("Shield", 0)), + trigger: Fire(triggers: [(BattleStart, None)], effects: [(UseAbility("Shield", 0), None)]), hp: 1, atk: 1, name: "right", diff --git a/assets/ron/scenarios/kill_after_death.scenario.ron b/assets/ron/scenarios/kill_after_death.scenario.ron index 99d07f6f4..c19faad57 100644 --- a/assets/ron/scenarios/kill_after_death.scenario.ron +++ b/assets/ron/scenarios/kill_after_death.scenario.ron @@ -8,7 +8,11 @@ atk: 3, name: "right", description: "Kill after dealing any damage", - trigger: Fire(trigger: AfterDamageDealt, target: Target, effect: Kill), + trigger: Fire( + triggers: [(AfterDamageDealt, None)], + targets: [(Target, None)], + effects: [(Kill, None)], + ), ), ], ), diff --git a/assets/ron/scenarios/magic_missile.scenario.ron b/assets/ron/scenarios/magic_missile.scenario.ron index 7a9c3626a..665f6db04 100644 --- a/assets/ron/scenarios/magic_missile.scenario.ron +++ b/assets/ron/scenarios/magic_missile.scenario.ron @@ -6,9 +6,9 @@ hp: 3, atk: 1, trigger: Fire( - trigger: BeforeStrike, - target: WithVar(Faction, OppositeFaction, SlotUnit(Int(1))), - effect: Damage(Int(1)), + triggers: [(BeforeStrike, None)], + targets: [(WithVar(Faction, OppositeFaction, SlotUnit(Int(1))), None)], + effects: [(Damage(Int(1)), None)], ), ), ], diff --git a/assets/ron/scenarios/strength.scenario.ron b/assets/ron/scenarios/strength.scenario.ron index 2293726b5..93a716d8a 100644 --- a/assets/ron/scenarios/strength.scenario.ron +++ b/assets/ron/scenarios/strength.scenario.ron @@ -6,7 +6,7 @@ hp: 1, atk: 0, name: "left", - trigger: Fire(trigger: BattleStart, effect: UseAbility("Strength", 0)), + trigger: Fire(triggers: [(BattleStart, None)], effects: [(UseAbility("Strength", 0), None)]), ), ], ), diff --git a/assets/ron/unit.rep.ron b/assets/ron/unit.rep.ron index 0e5b65409..0a5d8d076 100644 --- a/assets/ron/unit.rep.ron +++ b/assets/ron/unit.rep.ron @@ -1,7 +1,10 @@ ( material: Shape( shape: Circle( - radius: Sum(Mul(If(Even(OwnerState(Slot)), Mul(Beat, Float(-1.0)), Beat), Float(0.1)), Float(1.0)), + radius: Sum( + Mul(If(Even(OwnerState(Slot)), Mul(Beat, Float(-1.0)), Beat), Float(0.1)), + Float(1.0), + ), ), shape_type: Line(thickness: Float(1.0)), fill: Solid(color: Hex("#B0BEC5")), @@ -14,7 +17,11 @@ shape_type: Line(thickness: Float(1.0)), ), mapping: {Offset: Vec2(0.9, -0.9)}, - children: [(material: Text(text: StringInt(OwnerState(Hp)), size: Float(0.6), color: Hex("#FF3D00")))], + children: [ + ( + material: Text(text: StringInt(OwnerState(Hp)), size: Float(0.6), color: Hex("#FF3D00")), + ), + ], ), ( material: Shape( @@ -23,7 +30,11 @@ shape_type: Line(thickness: Float(1.0)), ), mapping: {Offset: Vec2(-0.9, -0.9)}, - children: [(material: Text(text: StringInt(OwnerState(Atk)), size: Float(0.6), color: Hex("#FBC02D")))], + children: [ + ( + material: Text(text: StringInt(OwnerState(Atk)), size: Float(0.6), color: Hex("#FBC02D")), + ), + ], ), ], ) \ No newline at end of file diff --git a/assets/ron/vfx/text.vfx.ron b/assets/ron/vfx/text.vfx.ron index 55968fccd..ed074a8b6 100644 --- a/assets/ron/vfx/text.vfx.ron +++ b/assets/ron/vfx/text.vfx.ron @@ -15,6 +15,10 @@ ], ), representation: ( - material: Text(text: OwnerState(Text), size: Sub(Float(0.7), Mul(Age, Float(0.3))), alpha: OwnerState(Alpha)), + material: Text( + text: OwnerState(Text), + size: Sub(Float(0.7), Mul(Age, Float(0.3))), + alpha: OwnerState(Alpha), + ), ), ) \ No newline at end of file diff --git a/src/plugins/hero_editor.rs b/src/plugins/hero_editor.rs index 1ec78fe49..fe8e349c8 100644 --- a/src/plugins/hero_editor.rs +++ b/src/plugins/hero_editor.rs @@ -1,6 +1,4 @@ -use std::fmt::Display; - -use bevy_egui::egui::{DragValue, Frame, Key, ScrollArea, Sense, Shape, SidePanel}; +use bevy_egui::egui::{Frame, Key, ScrollArea, Sense, Shape, SidePanel}; use ron::ser::{to_string_pretty, PrettyConfig}; use serde::de::DeserializeOwned; @@ -230,9 +228,9 @@ impl HeroEditorPlugin { ); } ui.add_space(100.0); - const SELECTED_STATUS_KEY: &str = "selected status"; + const SELECTED_STATUS_KEY: &str = "selected_status"; let mut status = get_context_string(world, SELECTED_STATUS_KEY); - ComboBox::from_id_source("status select") + ComboBox::from_id_source(SELECTED_STATUS_KEY) .selected_text(status.clone()) .show_ui(ui, |ui| { for option in @@ -247,109 +245,64 @@ impl HeroEditorPlugin { } } }); - ui.set_enabled(!status.is_empty()); - if ui.button("Add Status").clicked() { - if let Some((i, _)) = - unit.statuses.iter().find_position(|(s, _)| status.eq(s)) - { - unit.statuses[i].1 += 1; - } else { - unit.statuses.push((status, 1)); - } - } - }); - ScrollArea::new([true, true]) - .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden) - .show(ui, |ui| { - let style = ui.style_mut(); - style.override_text_style = Some(TextStyle::Small); - style.drag_value_text_style = TextStyle::Small; - style.visuals.widgets.inactive.bg_stroke = Stroke { - width: 1.0, - color: dark_gray(), - }; - ui.horizontal(|ui| { - let name = &mut unit.name; - ui.label("name:"); - TextEdit::singleline(name).desired_width(60.0).ui(ui); - let atk = &mut unit.atk; - ui.label("atk:"); - DragValue::new(atk).clamp_range(0..=99).ui(ui); - let hp = &mut unit.hp; - ui.label("hp:"); - DragValue::new(hp).clamp_range(0..=99).ui(ui); - let lvl = &mut unit.level; - ui.label("lvl:"); - DragValue::new(lvl).clamp_range(1..=99).ui(ui); - }); - ui.horizontal(|ui| { - let houses: HashMap = HashMap::from_iter( - Pools::get(world) - .houses - .iter() - .map(|(k, v)| (k.clone(), v.color.clone().into())), - ); - ui.label("house:"); - let house = &mut unit.houses; - ComboBox::from_id_source("house") - .selected_text(house.clone()) - .width(140.0) - .show_ui(ui, |ui| { - for (h, _) in - houses.into_iter().sorted_by_key(|(k, _)| k.clone()) - { - ui.selectable_value(house, h.clone(), h.clone()); - } - }); - }); - ui.horizontal(|ui| { - ui.label("desc:"); - let description = &mut unit.description; - TextEdit::singleline(description) - .desired_width(ui.available_width().min(200.0)) - .ui(ui); - if ui.button("reset").clicked() { - *description = DEFAULT_UNIT_DESCRIPTION.to_owned(); + ui.add_enabled_ui(!status.is_empty(), |ui| { + if ui.button("Add Status").clicked() { + if let Some((i, _)) = + unit.statuses.iter().find_position(|(s, _)| status.eq(s)) + { + unit.statuses[i].1 += 1; + } else { + unit.statuses.push((status, 1)); } - }); + } + }); - let context = &Context::from_owner(entity, world); - ui.horizontal(|ui| { - let trigger = &mut unit.trigger; - match trigger { - Trigger::Fire { - trigger, - target, - effect, - } => { - CollapsingHeader::new("Trigger").default_open(true).show( - ui, - |ui| { - show_tree("", trigger, context, ui, world); - }, - ); - CollapsingHeader::new("Target").default_open(true).show( - ui, - |ui| { - show_tree("", target, context, ui, world); - }, - ); - - CollapsingHeader::new("Effect").default_open(true).show( - ui, - |ui| { - show_tree("", effect, context, ui, world); - }, - ); + ui.add_space(100.0); + const LOAD_HERO_KEY: &str = "load_hero"; + let mut hero = get_context_string(world, LOAD_HERO_KEY); + let heroes = Pools::get(world) + .heroes + .keys() + .sorted() + .cloned() + .collect_vec(); + + if ui.button("Next").clicked() { + let p = heroes.iter().position(|h| hero.eq(h)).unwrap_or_default(); + hero = heroes.get((p + 1) % heroes.len()).unwrap().clone(); + set_context_string(world, LOAD_HERO_KEY, hero.clone()); + unit = Pools::get(world).heroes.get(&hero).unwrap().clone(); + } + ComboBox::from_id_source(LOAD_HERO_KEY) + .selected_text(hero.clone()) + .show_ui(ui, |ui| { + for option in heroes { + let text = option.to_string(); + if ui + .selectable_value(&mut hero, option.to_owned(), text) + .changed() + { + set_context_string(world, LOAD_HERO_KEY, option); + unit = Pools::get(world).heroes.get(&hero).unwrap().clone(); } - Trigger::Change { .. } => todo!(), - Trigger::List(_) => todo!(), } }); + if ui.button("Load").clicked() { + unit = Pools::get(world).heroes.get(&hero).unwrap().clone(); + } - let rep = &mut unit.representation; - rep.show_editor(context, "root", ui, world); - ui.add_space(150.0); + ui.add_space(50.0); + ui.label("card:"); + let mut sd = SettingsData::get(world).clone(); + let card = &mut sd.always_show_card; + if ui.checkbox(card, "").changed() { + sd.save(world).unwrap(); + } + }); + ScrollArea::new([true, true]) + .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden) + .show(ui, |ui| { + unit.show_editor(entity, ui, world); }); }); @@ -487,6 +440,43 @@ pub fn show_value(value: &Result, ui: &mut Ui) { .ui(ui); } +pub fn show_trees_desc( + label: &str, + roots: &mut Vec<(impl EditorNodeGenerator, Option)>, + context: &Context, + ui: &mut Ui, + world: &mut World, +) { + ui.vertical(|ui| { + let mut delete = None; + for (i, (node, d)) in roots.iter_mut().enumerate() { + ui.horizontal(|ui| { + if ui.button_red("-").clicked() { + delete = Some(i); + } + let mut c = d.is_some(); + if ui.checkbox(&mut c, "").changed() { + if c { + *d = Some(default()); + } else { + *d = None; + } + } + if let Some(d) = d { + ui.add_sized([100.0, 20.0], TextEdit::singleline(d)); + } + }); + show_tree(&i.to_string(), node, context, ui, world); + } + if let Some(delete) = delete { + roots.remove(delete); + } + if ui.button("+").clicked() { + roots.push((default(), None)); + } + }); +} + pub fn show_tree( label: &str, root: &mut impl EditorNodeGenerator, @@ -524,7 +514,7 @@ pub fn show_node( } else { return; }; - let path = format!("{path}/{source}"); + let path = format!("{path}/{}", source.as_ref()); let InnerResponse { inner: name_resp, response: frame_resp, @@ -536,7 +526,7 @@ pub fn show_node( .fill(light_black()) .show(ui, |ui| { let name = source - .to_string() + .as_ref() .add_color(source.node_color()) .as_label(ui) .sense(Sense::click()) @@ -660,7 +650,7 @@ pub fn show_node( }); } -pub trait EditorNodeGenerator: Display + Sized + Serialize + DeserializeOwned { +pub trait EditorNodeGenerator: AsRef + Sized + Serialize + DeserializeOwned + Default { fn node_color(&self) -> Color32; fn show_children( &mut self, diff --git a/src/plugins/settings.rs b/src/plugins/settings.rs index af10bda3f..7303862de 100644 --- a/src/plugins/settings.rs +++ b/src/plugins/settings.rs @@ -6,6 +6,7 @@ pub struct SettingsPlugin; pub struct SettingsData { pub master_volume: f64, pub expanded_hint: bool, + pub always_show_card: bool, pub window_mode: WindowMode, } @@ -25,6 +26,7 @@ impl Default for SettingsData { master_volume: 0.5, expanded_hint: false, window_mode: default(), + always_show_card: default(), } } } @@ -50,7 +52,7 @@ impl SettingsPlugin { }; let mut data = *SettingsData::get(world); window("SETTINGS") - .set_width(600.0) + .set_width(400.0) .order(egui::Order::Foreground) .show(ctx, |ui| { frame(ui, |ui| { @@ -78,6 +80,23 @@ impl SettingsPlugin { }); }); }); + frame(ui, |ui| { + ui.columns(2, |ui| { + "always show card".to_colored().label(&mut ui[0]); + ui[1].vertical_centered_justified(|ui| { + let value = &mut data.always_show_card; + if ui + .button_or_primary( + if *value { "ENABLED" } else { "DISABLED" }, + *value, + ) + .clicked() + { + *value = !*value; + } + }); + }); + }); frame(ui, |ui| { let value = &mut data.window_mode; ui.columns(2, |ui| { diff --git a/src/plugins/unit.rs b/src/plugins/unit.rs index 2aa400102..5f665d928 100644 --- a/src/plugins/unit.rs +++ b/src/plugins/unit.rs @@ -357,13 +357,20 @@ impl UnitPlugin { } else { return; }; + let show_card = SettingsData::get(world).always_show_card; for (entity, state) in world .query_filtered::<(Entity, &VarState), Or<(&Unit, &Corpse)>>() .iter(world) { let statuses = Status::collect_statuses_name_charges(entity, GameTimer::get().play_head(), world); - state.show_entity_card_window(entity, statuses, hovered == Some(entity), ctx, world); + state.show_entity_card_window( + entity, + statuses, + show_card || hovered == Some(entity), + ctx, + world, + ); } } diff --git a/src/resourses/effect.rs b/src/resourses/effect.rs index 7f7451c0c..e154e9d7c 100644 --- a/src/resourses/effect.rs +++ b/src/resourses/effect.rs @@ -2,7 +2,7 @@ use std::{collections::VecDeque, ops::Deref}; use super::*; -#[derive(Serialize, Deserialize, Clone, Debug, Default, Display, PartialEq, EnumIter)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, EnumIter, AsRefStr)] pub enum Effect { #[default] Noop, @@ -36,8 +36,8 @@ impl Effect { debug!("Processing {:?}\n{}", self, context); match self { Effect::Damage(value) => { - let target = context.get_target().context("Target not found")?; - let owner = context.get_owner().context("Owner not found")?; + let target = context.get_target().context("No target")?; + let owner = context.get_owner().context("No owner")?; let mut value = match value { Some(value) => value.get_value(context, world)?, None => context @@ -73,19 +73,14 @@ impl Effect { } .send_with_context(context.clone(), world); Pools::get_vfx("pain", world) - .set_parent(context.target()) + .set_parent(target) .unpack(world)?; } let value = value.max(0); - Vfx::show_text( - format!("-{value}"), - Color::ORANGE_RED, - context.target(), - world, - )?; + Vfx::show_text(format!("-{value}"), Color::ORANGE_RED, target, world)?; } Effect::Kill => { - let target = context.get_target().context("Target not found")?; + let target = context.get_target().context("No target")?; VarState::get_mut(target, world) .push_back( VarName::LastAttacker, @@ -96,7 +91,7 @@ impl Effect { .clone() .set_var( VarName::Position, - VarValue::Vec2(UnitPlugin::get_unit_position(context.target(), world)?), + VarValue::Vec2(UnitPlugin::get_unit_position(target, world)?), ) .set_var(VarName::Text, VarValue::String("Kill".to_string())) .set_var(VarName::Color, VarValue::Color(Color::RED)) @@ -191,12 +186,13 @@ impl Effect { .unwrap_or(VarValue::Int(1)) .get_int()?; let color = Pools::get_color_by_name(status, world)?; - Status::change_charges(status, context.target(), charges, world)?; + let target = context.get_target().context("No target")?; + Status::change_charges(status, target, charges, world)?; Pools::get_vfx("text", world) .clone() .set_var( VarName::Position, - VarState::get(context.target(), world).get_value_last(VarName::Position)?, + VarState::get(target, world).get_value_last(VarName::Position)?, ) .set_var( VarName::Text, @@ -212,17 +208,18 @@ impl Effect { .unpack(world)?; } Effect::ClearStatus(status) => { - let charges = Status::get_status_charges(context.target(), status, world)?; + let target = context.get_target().context("No target")?; + let charges = Status::get_status_charges(target, status, world)?; if charges <= 0 { return Err(anyhow!("Charges <= 0: {status} ({charges})")); } let color = Pools::get_color_by_name(status, world)?; - Status::change_charges(status, context.target(), -charges, world)?; + Status::change_charges(status, target, -charges, world)?; Pools::get_vfx("text", world) .clone() .set_var( VarName::Position, - VarState::get(context.target(), world).get_value_last(VarName::Position)?, + VarState::get(target, world).get_value_last(VarName::Position)?, ) .set_var(VarName::Text, VarValue::String(format!("Clear {status}"))) .set_var(VarName::Color, VarValue::Color(color)) @@ -259,7 +256,8 @@ impl Effect { } Effect::Vfx(name) => { let owner_pos = UnitPlugin::get_unit_position(context.owner(), world)?; - let delta = UnitPlugin::get_unit_position(context.target(), world)? - owner_pos; + let target = context.get_target().context("No target")?; + let delta = UnitPlugin::get_unit_position(target, world)? - owner_pos; Pools::get_vfx(name, world) .clone() @@ -332,7 +330,7 @@ impl Effect { } Effect::FullCopy => { let owner = context.owner(); - let target = context.target(); + let target = context.get_target().context("No target")?; let history = VarState::get(target, world).history.clone(); for (var, history) in history.into_iter() { if var.eq(&VarName::Position) @@ -384,7 +382,7 @@ impl Effect { event.clone().send_with_context(context.clone(), world); } Effect::RemoveLocalTrigger => { - let target = context.target(); + let target = context.get_target().context("No target")?; let local_trigger = Status::collect_unit_statuses(target, world) .into_iter() .find(|e| { @@ -611,8 +609,8 @@ impl EditorNodeGenerator for Effect { fn show_replace_buttons(&mut self, lookup: &str, submit: bool, ui: &mut Ui) -> bool { for e in Effect::iter() { - if e.to_string().to_lowercase().contains(lookup) { - let btn = e.to_string().add_color(e.node_color()).rich_text(ui); + if e.as_ref().to_lowercase().contains(lookup) { + let btn = e.as_ref().add_color(e.node_color()).rich_text(ui); let btn = ui.button(btn); if btn.clicked() || submit { btn.request_focus(); @@ -777,3 +775,57 @@ impl EditorNodeGenerator for Effect { *self = Effect::List([Box::new(self.clone())].into()); } } + +impl std::fmt::Display for Effect { + fn fmt(&self, f: &mut __private::Formatter<'_>) -> std::fmt::Result { + match self { + Effect::RemoveLocalTrigger | Effect::FullCopy | Effect::Kill | Effect::Noop => { + write!(f, "{}", self.as_ref()) + } + Effect::Text(x) | Effect::Debug(x) => { + write!(f, "{}({x})", self.as_ref()) + } + Effect::Damage(x) => write!( + f, + "{}({})", + self.as_ref(), + x.as_ref() + .and_then(|x| Some(x.to_string())) + .unwrap_or_default() + ), + Effect::WithOwner(x, e) | Effect::WithTarget(x, e) | Effect::AoeFaction(x, e) => { + write!(f, "{} ({x}, {e})", self.as_ref()) + } + Effect::List(list) | Effect::ListSpread(list) => write!( + f, + "({})", + list.into_iter().map(|e| e.to_string()).join(" & ") + ), + Effect::WithVar(v, x, e) => write!(f, "{} ({v} -> {x}, {e})", self.as_ref()), + Effect::StateAddVar(var, t, v) | Effect::StateSetVar(var, t, v) => { + write!(f, "{} {t} ({var} -> {v})", self.as_ref()) + } + Effect::AbilityStateAddVar(ability, var, v) => { + write!(f, "[{ability}]: {var} add {v}") + } + Effect::UseAbility(name, base) => write!( + f, + "use [{name}] ({{Level}}{})", + if *base > 0 { + format!("+{base}") + } else { + default() + } + ), + Effect::SendEvent(name) => write!(f, "{} ({name})", self.as_ref()), + Effect::Vfx(name) + | Effect::ClearStatus(name) + | Effect::AddStatus(name) + | Effect::Summon(name) => { + write!(f, "{} ({name})", self.as_ref()) + } + Effect::If(c, t, e) => write!(f, "{} {c} ({t} else {e})", self.as_ref()), + Effect::Repeat(c, e) => write!(f, "{} ({e}) x {c}", self.as_ref()), + } + } +} diff --git a/src/resourses/expression.rs b/src/resourses/expression.rs index ffe886d61..ba6ffa870 100644 --- a/src/resourses/expression.rs +++ b/src/resourses/expression.rs @@ -11,7 +11,7 @@ use std::{collections::hash_map::DefaultHasher, f32::consts::PI}; use super::*; -#[derive(Serialize, Deserialize, Debug, Clone, Default, Display, PartialEq, EnumIter)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, EnumIter, AsRefStr)] pub enum Expression { #[default] Zero, @@ -603,109 +603,6 @@ impl Expression { pub fn get_color(&self, context: &Context, world: &mut World) -> Result { self.get_value(context, world)?.get_color() } - - pub fn get_description_string(&self) -> String { - match self { - Expression::Zero - | Expression::GameTime - | Expression::PI - | Expression::PI2 - | Expression::Age - | Expression::SlotPosition - | Expression::OwnerFaction - | Expression::OppositeFaction - | Expression::Beat - | Expression::Owner - | Expression::Caster - | Expression::Target - | Expression::RandomUnit - | Expression::RandomAdjacentUnit - | Expression::RandomAlly - | Expression::RandomEnemy - | Expression::AllAllyUnits - | Expression::AllEnemyUnits - | Expression::AllUnits - | Expression::AllOtherUnits - | Expression::Index - | Expression::AdjacentUnits => self.to_string().to_case(Case::Lower), - Expression::Float(v) => v.to_string(), - Expression::Int(v) => v.to_string(), - Expression::Bool(v) => v.to_string(), - Expression::String(v) => v.to_string(), - Expression::Hex(v) => v.to_string(), - Expression::Faction(v) => v.to_string(), - Expression::OwnerState(v) => format!("{self}({v})"), - Expression::OwnerStateLast(v) => format!("{self}({v})"), - Expression::TargetState(v) => format!("{self}({v})"), - Expression::TargetStateLast(v) => format!("{self}({v})"), - Expression::StateLast(v, t) => format!("{self} ({v}, {t})"), - Expression::Context(v) => format!("{self}({v})"), - Expression::StatusEntity(s, v) => format!("{self} ({s}, {v})"), - Expression::AbilityContext(a, v) | Expression::AbilityState(a, v) => { - format!("{self}({a}:{v})") - } - Expression::Value(v) => format!("{self}({v})"), - Expression::Vec2(x, y) => format!("({x}, {y})"), - Expression::Vec2E(x) => format!("({x}, {x})"), - Expression::StringInt(v) - | Expression::StringFloat(v) - | Expression::StringVec(v) - | Expression::IntFloat(v) - | Expression::ToInt(v) - | Expression::Sin(v) - | Expression::Cos(v) - | Expression::Sign(v) - | Expression::Fract(v) - | Expression::Floor(v) - | Expression::UnitVec(v) - | Expression::Even(v) - | Expression::Abs(v) - | Expression::SlotUnit(v) - | Expression::FactionCount(v) - | Expression::FilterMaxEnemy(v) - | Expression::FindUnit(v) - | Expression::Parent(v) - | Expression::UnitCount(v) - | Expression::RandomFloat(v) - | Expression::RandomFloatUnit(v) - | Expression::StatusCharges(v) => format!( - "{} ({})", - self.to_string().to_case(Case::Lower), - v.get_description_string().to_case(Case::Title) - ), - Expression::Vec2EE(x, y) - | Expression::Sum(x, y) - | Expression::Sub(x, y) - | Expression::Mul(x, y) - | Expression::Div(x, y) - | Expression::GreaterThen(x, y) - | Expression::LessThen(x, y) - | Expression::Min(x, y) - | Expression::Max(x, y) - | Expression::Equals(x, y) - | Expression::And(x, y) - | Expression::Or(x, y) => format!( - "{self}({}, {})", - x.get_description_string().to_case(Case::Title), - y.get_description_string().to_case(Case::Title) - ), - Expression::If(x, y, z) | Expression::Spread(x, y, z) => format!( - "{self}({}, {}, {})", - x.get_description_string().to_case(Case::Title), - y.get_description_string().to_case(Case::Title), - z.get_description_string().to_case(Case::Title), - ), - Expression::WithVar(var, val, e) => format!( - "{self}({}, {}, {})", - var.to_string().to_case(Case::Title), - val.get_description_string().to_case(Case::Title), - e.get_description_string().to_case(Case::Title), - ), - Expression::RandomEnemySubset(amount) => { - format!("{} random enemies", amount.get_description_string()) - } - } - } } impl EditorNodeGenerator for Expression { @@ -1027,7 +924,7 @@ impl EditorNodeGenerator for Expression { fn show_replace_buttons(&mut self, lookup: &str, submit: bool, ui: &mut Ui) -> bool { for (e, _) in Expression::iter() .filter_map(|e| { - let s = e.to_string().to_lowercase(); + let s = e.as_ref().to_lowercase(); match s.contains(lookup) { true => Some((e, s)), false => None, @@ -1035,7 +932,7 @@ impl EditorNodeGenerator for Expression { }) .sorted_by_key(|(_, s)| !s.starts_with(lookup)) { - let btn = e.to_string().add_color(e.node_color()).rich_text(ui); + let btn = e.as_ref().add_color(e.node_color()).rich_text(ui); let btn = ui.button(btn); if btn.clicked() || submit { btn.request_focus(); @@ -1052,3 +949,100 @@ impl EditorNodeGenerator for Expression { *self = Expression::Abs(Box::new(self.clone())) } } + +impl std::fmt::Display for Expression { + fn fmt(&self, f: &mut __private::Formatter<'_>) -> std::fmt::Result { + match self { + Expression::Zero + | Expression::GameTime + | Expression::PI + | Expression::PI2 + | Expression::Age + | Expression::SlotPosition + | Expression::OwnerFaction + | Expression::OppositeFaction + | Expression::Beat + | Expression::Owner + | Expression::Caster + | Expression::Target + | Expression::RandomUnit + | Expression::RandomAdjacentUnit + | Expression::RandomAlly + | Expression::RandomEnemy + | Expression::AllAllyUnits + | Expression::AllEnemyUnits + | Expression::AllUnits + | Expression::AllOtherUnits + | Expression::Index + | Expression::AdjacentUnits => write!(f, "{}", self.as_ref().to_case(Case::Title)), + Expression::Float(v) => write!(f, "{v}"), + Expression::Int(v) => write!(f, "{v}"), + Expression::Bool(v) => write!(f, "{v}"), + Expression::String(v) => write!(f, "{v}"), + Expression::Hex(v) => write!(f, "{v}"), + Expression::Faction(v) => write!(f, "{v}"), + Expression::OwnerState(v) => write!(f, "{}({v})", self.as_ref()), + Expression::OwnerStateLast(v) => write!(f, "{}({v})", self.as_ref()), + Expression::TargetState(v) => write!(f, "{}({v})", self.as_ref()), + Expression::TargetStateLast(v) => write!(f, "{}({v})", self.as_ref()), + Expression::StateLast(v, t) => write!(f, "{} ({v}, {t})", self.as_ref()), + Expression::Context(v) => write!(f, "{{{v}}}"), + Expression::StatusEntity(s, v) => write!(f, "{} ({s}, {v})", self.as_ref()), + Expression::AbilityContext(a, v) | Expression::AbilityState(a, v) => { + write!(f, "{}({a}:{v})", self.as_ref()) + } + Expression::Value(v) => write!(f, "{}({v})", self.as_ref()), + Expression::Vec2(x, y) => write!(f, "({x}, {y})"), + Expression::Vec2E(x) => write!(f, "({x}, {x})"), + Expression::StringInt(v) + | Expression::StringFloat(v) + | Expression::StringVec(v) + | Expression::IntFloat(v) + | Expression::ToInt(v) + | Expression::Sin(v) + | Expression::Cos(v) + | Expression::Sign(v) + | Expression::Fract(v) + | Expression::Floor(v) + | Expression::UnitVec(v) + | Expression::Even(v) + | Expression::Abs(v) + | Expression::SlotUnit(v) + | Expression::FactionCount(v) + | Expression::FilterMaxEnemy(v) + | Expression::FindUnit(v) + | Expression::Parent(v) + | Expression::UnitCount(v) + | Expression::RandomFloat(v) + | Expression::RandomFloatUnit(v) + | Expression::StatusCharges(v) => { + write!(f, "{} ({v})", self.as_ref().to_case(Case::Title),) + } + Expression::Vec2EE(x, y) + | Expression::Sub(x, y) + | Expression::Mul(x, y) + | Expression::Div(x, y) + | Expression::GreaterThen(x, y) + | Expression::LessThen(x, y) + | Expression::Min(x, y) + | Expression::Max(x, y) + | Expression::Equals(x, y) + | Expression::And(x, y) + | Expression::Or(x, y) => { + write!(f, "{}({x}, {y})", self.as_ref().to_case(Case::Title),) + } + Expression::Sum(x, y) => write!(f, "({x}+{y})"), + Expression::If(x, y, z) | Expression::Spread(x, y, z) => { + write!(f, "{}({x}, {y}, {z})", self.as_ref()) + } + Expression::WithVar(var, val, e) => write!( + f, + "{}({var}, {val}, {e})", + self.as_ref().to_case(Case::Title) + ), + Expression::RandomEnemySubset(amount) => { + write!(f, "{{{amount}}} random enemies") + } + } + } +} diff --git a/src/resourses/packed_unit.rs b/src/resourses/packed_unit.rs index eee8eb9b6..2b62399a5 100644 --- a/src/resourses/packed_unit.rs +++ b/src/resourses/packed_unit.rs @@ -236,50 +236,56 @@ impl PackedUnit { match (trigger_a, trigger_b) { ( Trigger::Fire { - trigger: trigger_a, - target: target_a, - effect: effect_a, + triggers: trigger_a, + targets: target_a, + effects: effect_a, }, Trigger::Fire { - trigger: trigger_b, - target: target_b, - effect: effect_b, + triggers: trigger_b, + targets: target_b, + effects: effect_b, }, ) => { - if !trigger_a.eq(trigger_b) { + { let trigger = Trigger::Fire { - trigger: FireTrigger::List( - [Box::new(trigger_a.clone()), Box::new(trigger_b.clone())].into(), + triggers: Vec::from_iter( + trigger_a.iter().cloned().chain(trigger_b.iter().cloned()), ), - target: target_a.clone(), - effect: effect_a.clone(), + targets: target_a.clone(), + effects: effect_a.clone(), }; - result.push(Self::fuse_base(&a, &b, trigger, world)); + result.push(Self::fuse_base(&a, &b, trigger, world)) + } + { let trigger = Trigger::Fire { - trigger: FireTrigger::List( - [Box::new(trigger_a.clone()), Box::new(trigger_b.clone())].into(), + triggers: Vec::from_iter( + trigger_a.iter().cloned().chain(trigger_b.iter().cloned()), ), - target: target_b.clone(), - effect: effect_b.clone(), + targets: target_b.clone(), + effects: effect_b.clone(), }; - result.push(Self::fuse_base(&b, &a, trigger, world)); + result.push(Self::fuse_base(&b, &a, trigger, world)) + } + { + let trigger = Trigger::Fire { + triggers: trigger_a.clone(), + targets: target_a.clone(), + effects: Vec::from_iter( + effect_a.iter().cloned().chain(effect_b.iter().cloned()), + ), + }; + result.push(Self::fuse_base(&a, &b, trigger, world)) + } + { + let trigger = Trigger::Fire { + triggers: trigger_b.clone(), + targets: target_b.clone(), + effects: Vec::from_iter( + effect_a.iter().cloned().chain(effect_b.iter().cloned()), + ), + }; + result.push(Self::fuse_base(&b, &a, trigger, world)) } - let trigger = Trigger::Fire { - trigger: trigger_a.clone(), - target: target_a.clone(), - effect: Effect::List( - [Box::new(effect_a.clone()), Box::new(effect_b.clone())].into(), - ), - }; - result.push(Self::fuse_base(&a, &b, trigger, world)); - let trigger = Trigger::Fire { - trigger: trigger_b.clone(), - target: target_b.clone(), - effect: Effect::List( - [Box::new(effect_a.clone()), Box::new(effect_b.clone())].into(), - ), - }; - result.push(Self::fuse_base(&b, &a, trigger, world)); } _ => { let trigger = Trigger::List( @@ -298,6 +304,93 @@ impl PackedUnit { .map(|(name, charges)| format!("{name} ({charges})")) .join(",") } + + pub fn show_editor(&mut self, entity: Entity, ui: &mut Ui, world: &mut World) { + let style = ui.style_mut(); + style.override_text_style = Some(TextStyle::Small); + style.drag_value_text_style = TextStyle::Small; + style.visuals.widgets.inactive.bg_stroke = Stroke { + width: 1.0, + color: dark_gray(), + }; + ui.horizontal(|ui| { + let name = &mut self.name; + ui.label("name:"); + TextEdit::singleline(name).desired_width(60.0).ui(ui); + let atk = &mut self.atk; + ui.label("atk:"); + DragValue::new(atk).clamp_range(0..=99).ui(ui); + let hp = &mut self.hp; + ui.label("hp:"); + DragValue::new(hp).clamp_range(0..=99).ui(ui); + let lvl = &mut self.level; + ui.label("lvl:"); + DragValue::new(lvl).clamp_range(1..=99).ui(ui); + }); + ui.horizontal(|ui| { + let houses: HashMap = HashMap::from_iter( + Pools::get(world) + .houses + .iter() + .map(|(k, v)| (k.clone(), v.color.clone().into())), + ); + ui.label("house:"); + let house = &mut self.houses; + ComboBox::from_id_source("house") + .selected_text(house.clone()) + .width(140.0) + .show_ui(ui, |ui| { + for (h, _) in houses.into_iter().sorted_by_key(|(k, _)| k.clone()) { + ui.selectable_value(house, h.clone(), h.clone()); + } + }); + }); + ui.horizontal(|ui| { + ui.label("desc:"); + let description = &mut self.description; + TextEdit::singleline(description) + .desired_width(ui.available_width().min(200.0)) + .ui(ui); + if ui.button("reset").clicked() { + *description = DEFAULT_UNIT_DESCRIPTION.to_owned(); + } + }); + + let context = &Context::from_owner(entity, world); + ui.horizontal(|ui| { + let trigger = &mut self.trigger; + match trigger { + Trigger::Fire { + triggers, + targets, + effects, + } => { + CollapsingHeader::new("Triggers") + .default_open(true) + .show(ui, |ui| { + show_trees_desc("triggers:", triggers, context, ui, world); + }); + CollapsingHeader::new("Targets") + .default_open(true) + .show(ui, |ui| { + show_trees_desc("targets:", targets, context, ui, world); + }); + + CollapsingHeader::new("Effects") + .default_open(true) + .show(ui, |ui| { + show_trees_desc("effects:", effects, context, ui, world); + }); + } + Trigger::Change { .. } => todo!(), + Trigger::List(_) => todo!(), + } + }); + + let rep = &mut self.representation; + rep.show_editor(context, "root", ui, world); + ui.add_space(150.0); + } } impl From for TableUnit { diff --git a/src/resourses/trigger.rs b/src/resourses/trigger.rs index 7d62e0da0..b8fafb5ee 100644 --- a/src/resourses/trigger.rs +++ b/src/resourses/trigger.rs @@ -1,16 +1,20 @@ use super::*; use bevy_egui::egui::ComboBox; +use convert_case::Casing; use event::Event; use strum_macros::Display; #[derive(Deserialize, Serialize, Clone, Debug, Display, PartialEq, EnumIter)] +#[serde(deny_unknown_fields)] pub enum Trigger { Fire { - trigger: FireTrigger, - #[serde(default = "owner")] - target: Expression, - effect: Effect, + #[serde(default)] + triggers: Vec<(FireTrigger, Option)>, + #[serde(default)] + targets: Vec<(Expression, Option)>, + #[serde(default)] + effects: Vec<(Effect, Option)>, }, Change { trigger: DeltaTrigger, @@ -30,7 +34,7 @@ pub enum DeltaTrigger { Var(VarName), } -#[derive(Deserialize, Serialize, Clone, Debug, Display, PartialEq, EnumIter, Default)] +#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, EnumIter, Default, AsRefStr)] pub enum FireTrigger { #[default] Noop, @@ -235,8 +239,8 @@ impl EditorNodeGenerator for FireTrigger { fn show_replace_buttons(&mut self, lookup: &str, submit: bool, ui: &mut Ui) -> bool { for e in FireTrigger::iter() { - if e.to_string().to_lowercase().contains(lookup) { - let btn = e.to_string().add_color(e.node_color()).rich_text(ui); + if e.as_ref().to_lowercase().contains(lookup) { + let btn = e.as_ref().add_color(e.node_color()).rich_text(ui); let btn = ui.button(btn); if btn.clicked() || submit { btn.request_focus(); @@ -267,9 +271,9 @@ impl DeltaTrigger { impl Default for Trigger { fn default() -> Self { Self::Fire { - trigger: FireTrigger::Noop, - target: Expression::Owner, - effect: Effect::Noop, + triggers: default(), + targets: default(), + effects: default(), } } } @@ -285,16 +289,27 @@ impl Trigger { result } Trigger::Fire { - trigger, - target, - effect, - .. + triggers, + targets, + effects, } => { - if !trigger.catch(event, context, world) { + if !triggers + .into_iter() + .any(|(trigger, _)| trigger.catch(event, context, world)) + { return false; } - let effect = Effect::WithTarget(target.clone(), Box::new(effect.clone())); - ActionPlugin::action_push_back(effect, context.clone(), world); + for (effect, _) in effects { + if targets.is_empty() { + ActionPlugin::action_push_back(effect.clone(), context.clone(), world); + } else { + for (target, _) in targets.iter() { + let effect = + Effect::WithTarget(target.clone(), Box::new(effect.clone())); + ActionPlugin::action_push_back(effect, context.clone(), world); + } + } + } true } Trigger::Change { .. } => false, @@ -359,42 +374,63 @@ impl Trigger { pub fn inject_description(&self, state: &mut VarState) { match self { Trigger::Fire { - trigger, - target, - effect, + triggers, + targets, + effects, } => { - let trigger = trigger.get_description_string(); + let trigger = triggers + .into_iter() + .map(|(t, s)| s.clone().unwrap_or_else(|| t.to_string())) + .join(" & "); + let effect = effects + .into_iter() + .map(|(e, s)| s.clone().unwrap_or_else(|| e.to_string())) + .join(" & "); + let target = targets + .into_iter() + .map(|(t, s)| s.clone().unwrap_or_else(|| t.to_string())) + .join(" & "); state .init(VarName::TriggerDescription, VarValue::String(trigger)) - .init( - VarName::EffectDescription, - VarValue::String( - effect - .find_all_abilities() - .into_iter() - .map(|a| match a { - Effect::UseAbility(ability, base) => { - format!( - "[{ability}] ({{Level}}{})", - if base > 1 { - format!("+{base}") - } else { - default() - } - ) - } - _ => default(), - }) - .join(" + "), - ), - ) - .init( - VarName::TargetDescription, - VarValue::String(target.get_description_string()), - ); + .init(VarName::EffectDescription, VarValue::String(effect)) + .init(VarName::TargetDescription, VarValue::String(target)); } Trigger::Change { .. } => {} Trigger::List(list) => list.iter().for_each(|t| t.inject_description(state)), } } } + +impl std::fmt::Display for FireTrigger { + fn fmt(&self, f: &mut __private::Formatter<'_>) -> std::fmt::Result { + match self { + FireTrigger::Noop + | FireTrigger::AfterIncomingDamage + | FireTrigger::AfterDamageTaken + | FireTrigger::AfterDamageDealt + | FireTrigger::BattleStart + | FireTrigger::TurnStart + | FireTrigger::TurnEnd + | FireTrigger::BeforeStrike + | FireTrigger::AfterStrike + | FireTrigger::AllyDeath + | FireTrigger::AnyDeath + | FireTrigger::AllySummon + | FireTrigger::BeforeDeath + | FireTrigger::AfterKill => { + write!(f, "{}", self.as_ref().to_case(convert_case::Case::Title)) + } + FireTrigger::List(list) => write!( + f, + "({})", + list.into_iter().map(|t| t.to_string()).join(" + ") + ), + FireTrigger::Period(_, delay, trigger) => { + write!(f, "{} ({delay} {trigger})", self.as_ref()) + } + FireTrigger::OnceAfter(delay, trigger) => { + write!(f, "{} ({delay} {trigger})", self.as_ref()) + } + } + } +} diff --git a/src/resourses/vars.rs b/src/resourses/vars.rs index 43cd46889..d95746125 100644 --- a/src/resourses/vars.rs +++ b/src/resourses/vars.rs @@ -67,6 +67,7 @@ pub enum VarName { Level, Id, Caster, + Damage, } #[derive(Serialize, Deserialize, Clone, Debug, Reflect, PartialEq, Default)] diff --git a/src/utils.rs b/src/utils.rs index d0f83a8bd..ee0dfbd86 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -132,11 +132,14 @@ impl<'a> StrExtensions for &'a str { let mut lines: Vec<(String, bool)> = default(); while let Some(opening) = self.find(pattern.0) { let left = &self[..opening]; - let closing = self.find(pattern.1).unwrap(); - let mid = &self[opening + 1..closing]; - lines.push((left.to_owned(), false)); - lines.push((mid.to_owned(), true)); - self = &self[closing + 1..]; + if let Some(closing) = self.find(pattern.1) { + let mid = &self[opening + 1..closing]; + lines.push((left.to_owned(), false)); + lines.push((mid.to_owned(), true)); + self = &self[closing + 1..]; + } else { + break; + } } lines.push((self.to_owned(), false)); lines