diff --git a/.gut_editor_config.json b/.gut_editor_config.json index 5e7d6722..b5ac5469 100644 --- a/.gut_editor_config.json +++ b/.gut_editor_config.json @@ -15,7 +15,7 @@ "hide_orphans": false, "ignore_pause": true, "include_subdirs": false, - "inner_class": "TestDreamFragment", + "inner_class": "TestLashOut", "junit_xml_file": "", "junit_xml_timestamp": false, "log_level": 3, @@ -23,7 +23,7 @@ "post_run_script": "", "pre_run_script": "", "prefix": "test_", - "selected": "test_perturbations.gd", + "selected": "test_concentrations.gd", "should_exit": false, "should_exit_on_success": false, "should_maximize": true, diff --git a/src/dreamscape/CombatElements/CombatEffects/lash_out.gd b/src/dreamscape/CombatElements/CombatEffects/lash_out.gd index 1fa22b43..85240b30 100644 --- a/src/dreamscape/CombatElements/CombatEffects/lash_out.gd +++ b/src/dreamscape/CombatElements/CombatEffects/lash_out.gd @@ -18,7 +18,11 @@ func _on_entity_damaged(_entity, amount, _trigger: Node, _tags: Array) -> void: "name": "modify_damage", "subject": "trigger", "amount": amount * multiplier, - "tags": ["Attack", "Combat Effect", "Concentration"], + # The Reactive tag is used to avoid infinite loops between effects + # For example between this card and Thorns. + # As such, when this card is triggered by a reactive effect, + # that effect will not trigger again from this effect in turn. + "tags": ["Attack", "Combat Effect", "Concentration", "Reactive"], }] # Just in case all enemies died during execution... if all_enemies.size(): diff --git a/src/dreamscape/CombatElements/CombatEffects/thorns.gd b/src/dreamscape/CombatElements/CombatEffects/thorns.gd index e1ed17d9..c4c26166 100644 --- a/src/dreamscape/CombatElements/CombatEffects/thorns.gd +++ b/src/dreamscape/CombatElements/CombatEffects/thorns.gd @@ -4,9 +4,12 @@ func _ready(): # warning-ignore:return_value_discarded owning_entity.connect("entity_attacked", self, "_on_entity_attacked") -func _on_entity_attacked(_entity, _amount, trigger: Node, _tags: Array) -> void: +func _on_entity_attacked(_entity, _amount, trigger: Node, tags: Array) -> void: if is_delayed: return + # Thorns do not trigger from reactive effects, to avoid infinite loops + if "Reactive" in tags: + return if trigger.is_in_group("cards"): trigger = cfc.NMAP.board.dreamer if (entity_type == Terms.PLAYER diff --git a/tests/integration/cards/test_concentrations.gd b/tests/integration/cards/test_concentrations.gd index f938186a..e3f5fe5c 100644 --- a/tests/integration/cards/test_concentrations.gd +++ b/tests/integration/cards/test_concentrations.gd @@ -49,3 +49,31 @@ class TestExcuses: assert_eq(dreamer.damage, 7, "%s stops DoTs" % [effect]) + + +class TestLashOut: + extends "res://tests/HUT_Ordeal_DreamerEffectsTestClass.gd" + var effect: String = Terms.ACTIVE_EFFECTS.lash_out.name + var amount := 1 + func _init() -> void: + torments_amount = 1 + test_card_names = [ + "Interpretation", + ] + effects_to_play = [ + { + "name": effect, + "amount": amount, + } + ] + + + func test_lash_out_with_thorns(): + spawn_effect(test_torment, Terms.ACTIVE_EFFECTS.thorns.name, 10) + var sceng = snipexecute(card, test_torment) + if sceng is GDScriptFunctionState: + sceng = yield(sceng, "completed") + yield(yield_for(0.2), YIELD) + assert_eq(test_torment.damage, tdamage(36), "Torment should take damage, from lash out") + assert_eq(dreamer.damage, 10, "Dreamer should take damage from thorns") +