[Solved] Issue with Healing units.

Status
Not open for further replies.
Level 1
Joined
Jun 25, 2018
Messages
3
Hello there. I am working on my custom campaign. However, I am having issues with one of my custom abilities. The ability is supposed to heal random friendly units close to the caster, every second, up to a maximum of five seconds, meaning only five units to be healed.

The ability starts correctly, lasts correctly amount of time, correctly gets the units to be healed, stops after correct amount of time. The issue however. The units are not healed. They are instead put down to the amount of health (ish) the ability should heal them for. (The special effect doesn't work either, but that is not a big deal at the moment.

I can provide a test map as well if it is completely necessary, I will just need some time to transfer the ability and so on to a testing map. However if someone is able to just tell by my trigger why it isn't working, that would be awesome. Thanks in advance.
  • AoL Effect
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Special Effect - Create a special effect at ((Position of AoL_Caster) offset by 100.00 towards AoL_Number degrees) using Abilities\Spells\Human\HolyBolt\HolyBoltSpecialArt.mdl
      • Set AoL_Counter = (AoL_Counter + 1)
      • Set AoL_Number = (AoL_Number + 20.00)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AoL_Counter Equal to 10
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Aura of Light for AoL_Caster) Equal to 1
            • Then - Actions
              • Unit - Set life of (Random unit from (Units within 200.00 of (Position of AoL_Caster) matching (((Matching unit) is in (Units owned by (Owner of AoL_Caster))) Equal to True))) to ((Life of (Matching unit)) + 40.00)
              • Set AoL_Counter = 0
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Aura of Light for AoL_Caster) Equal to 2
                • Then - Actions
                  • Unit - Set life of (Random unit from (Units within 200.00 of (Position of AoL_Caster) matching (((Matching unit) is in (Units owned by (Owner of AoL_Caster))) Equal to True))) to ((Life of (Matching unit)) + 95.00)
                  • Set AoL_Counter = 0
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Level of Aura of Light for AoL_Caster) Equal to 3
                    • Then - Actions
                      • Unit - Set life of (Random unit from (Units within 200.00 of (Position of AoL_Caster) matching (((Matching unit) is in (Units owned by (Owner of AoL_Caster))) Equal to True))) to ((Life of (Matching unit)) + 120.00)
                      • Unit - Cause AoL_Caster to damage (Random unit from (Units within 200.00 of (Position of AoL_Caster) matching (((Matching unit) belongs to an enemy of (Owner of AoL_Caster)) Equal to True))), dealing 70.00 damage of attack type Spells and damage type Divine
                      • Set AoL_Counter = 0
                    • Else - Actions
        • Else - Actions
 
Level 2
Joined
Feb 27, 2019
Messages
14
Code:
Unit - Set life of (Random unit from
    (Units within 200.00 of (Position of AoL_Caster)
             matching (((Matching unit) is in (Units owned by (Owner of AoL_Caster))) Equal to True)))
to ((Life of (Matching unit)) + 40.00)
(This is just your code so it's easier to follow)

I'm supposing AoL_Caster is being set somewhere. It wouldn't find any units otherwise.

It seems like you can't use Matching unit in Life of (last line). Resulting matching unit is null, its HP is 0 and the result is then as you described, life set exactly to 40. See for yourself by trying to print out its name or its current HP.

Perhaps some other default function would work (e.g. picked unit) (I'm not well versed enough to know from top of my head but go give it a couple of tests), or if no default function suits your need you can save the units to be healed in a variable beforehand. E.g.
Code:
Set variable = (Random unit from
    (Units within 200.00 of (Position of AoL_Caster)
             matching (((Matching unit) is in (Units owned by (Owner of AoL_Caster))) Equal to True)))
Unit - Set life of (variable) to ((Life of (variable)) + 40.00)
Also consider not searching five times for all units of player and instead find once, save them to a variable, pick five random units from it (and then destroy the group). I'm unsure if that's what you want, but that could still pick the same unit twice (or proportionately rarely one unit five times), set their hp above maximum etc. The best way to check for all that is: get a group of units that are not at full health, of player of caster etc. > loop 5 times > pick a random unit > heal it and remove it from the group (and destroy the group at the end)

And btw that's f**kton of stuff. If you're testing code and are unsure why something doesn't work, good practice is to put the problem at the bare minimum reproducible. (Or really, start at the bare minimum and make that work before adding special effects.) It'll be easier to spot the problem, and sometimes it simply goes away so you know it was in some of the code you removed. The quicker and cleaner you can do it, the better at debugging you are.

Cheers
 
Last edited:
Level 41
Joined
Feb 27, 2007
Messages
5,240
@inspicous is correct that Matching Unit does not refer to the random unit. There is no other way to do it, you will have to assign the unit to a variable beforehand exactly as they described. Additionally, you are leaking two unit groups and a point each time you pick a random unit. Your series of if-trees could be massively simplified by using some arrays involving the level of the ability. There's a SFX leak and 2 more point leaks in the first line. You should generally check if things are >= or <= rather than just == in case something happens and your counter went from 9 to 11 this spell would break (not likely, just example). You could introduce some Modulo logic so AoL_Number goes back to 0 after it gets > 360 (though that doesn't really matter, if the ability is never toggled off _Number will go up by 200 per second... indefinitely).

In the random unit line you used "matching unit is in (units owned by...)" which actually leaks the second group. Instead you just check if the unit is owned by the player: "(Owner of (Matching Unit)) equal to (Owner of AoL_Caster)". You're also not checking to make sure the target picked is alive. This spell is not currently MUI; if that matters to you I suggest you learn how to dynamically index: Visualize: Dynamic Indexing

  • -------- set these on map init --------
  • AoL_Heal[1] = 40.00
  • AoL_Heal[2] = 95.00
  • AoL_Heal[3] = 120.00
  • AoL Effect
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Set TempPoint[1] = (Position of AoL_Caster)
      • Set TempPoint[2] = (TempPoint[1] offset by 100.00 towards AoL_Number degrees)
      • Special Effect - Create a special effect TempPoint[2] at using Abilities\Spells\Human\HolyBolt\HolyBoltSpecialArt.mdl
      • Special Effect - Destroy (Last created special effect) //this plays the effect's death animation or its stand animation depending on if it has any animations at all
      • Set AoL_Counter = (AoL_Counter + 1)
      • Set AoL_Number = Modulo((AoL_Number + 20.00), 360.00)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AoL_Counter Greater than or equal to 10
        • Then - Actions
          • Set TempInt = (Level of Aura of Light for AoL_Caster)
          • Set TempPlayer = (Owner of AoL_Caster)
          • Set TempGroup = (Units within 200.00 of TempPoint[1] matching (((Matching Unit) is alive equal to true) and ((Owner of (Matching Unit) equal to TempPlayer)))
          • Set TempUnit = Random unit from TempGroup
          • Unit - Set life of TempUnit to ((Life of TempUnit) + AoL_Heal[TempInt])
          • Custom script: call DestroyGroup(udg_TempGroup) //change the name to match your variable, but keep the udg_ prefix
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TempInt Equal to 3
            • Then - Actions
              • Set TempGroup = (Units within 200.00 of TempPoint[1] matching (((Matching Unit) is alive equal to true) and (((Matching Unit) belongs to an enemy of TempPlayer) equal to true)))
              • Set TempUnit = Random unit from TempGroup
              • Unit - Cause AoL_Caster to damage TempUnit, dealing 70.00 damage of attack type Spells and damage type Divine
              • Custom script: call DestroyGroup(udg_TempGroup) //same here
            • Else - Actions
          • Set AoL_Counter = 0
        • Else - Actions
      • Custom script: call RemoveLocation(udg_TempPoint[1]) //same here
      • Custom script: call RemoveLocation(udg_TempPoint[2]) //same here
 
Level 1
Joined
Jun 25, 2018
Messages
3
Thanks for the feedback guys! I will have a full in depth look at your answers in a bit after I have eaten, then I will change my trigger with your feedback and edit this reply with the outcome.

Edit:

Awesome! This works now! Thanks a lot for the help you two! :) I will work on all my abilities etc now to prevent leaks and Dynamic Indexing :)
 
Last edited:
Status
Not open for further replies.
Top