Lightning Shield Troubles

Jinxx

New Member
Reaction score
4
Ok, the vanilla Lightning Shield damages allies regardless of the fields I set, so I decided to just trigger my own version of it. Anyway, the problem is that I need this spell MUI/MPI, so global variables are a no-no!

The thing is, it fails miserably, and I think it's due to the considered unit being overwritten. "Picked Unit" seems to overwrite when the second group of units (the enemies around the shielded caster) is being considered. Anyway, I tried doing this with JASS, but as far as I know, there's no way to "share" local variables (in this case, the unit with the shield buff) between functions.

The only way I could think of was storing the shielded unit into a global, but as I said in the beginning, I need this MUI. :(

Here's the spell...

Trigger:
  • Lightning Shield Effects
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching (((Matching unit) has buff CustomLShield) Equal to True)) and do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in (Units within 250.00 of (Position of (Picked unit)) matching (((Matching unit) belongs to an enemy of (Owner of (Picked unit))) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Cause (Picked unit) to damage (Matching unit), dealing (5.00 x (Real((Hero level of (Picked unit))))) damage of attack type Hero and damage type Divine
              • Game - Display to (Player group((Owner of (Picked unit)))) for 5.00 seconds the text: DEBUGGING: Your Ele...
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
it will still be MUI if you save the first picked unit in a global variable, why do you thing it wont be MUI anymore?

and by the way your trigge does leak like hell and after some time your map will most probably start to lag, if you dont know what a memory leak is i would strictly recommend reading a turtorial about it!
 

Rushhour

New Member
Reaction score
46
Trigger:
  • Lightning Shield Effects
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching (((Matching unit) has buff CustomLShield) Equal to True)) and do (Actions)
        • Loop - Actions
          • Set TempUnit=Picked Unit
          • Unit Group - Pick every unit in (Units within 250.00 of (Position of (TempUnit)) matching (((Matching unit) belongs to an enemy of (Owner of (TempUnit))) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Cause (TempUnit) to damage (Picked unit), dealing (5.00 x (Real((Hero level of (TempUnit))))) damage of attack type Hero and damage type Divine
              • Game - Display to (Player group((Owner of (Picked unit)))) for 5.00 seconds the text: DEBUGGING: Your Ele...

one variable and it is still perfectly MUI. But as he said... it leaks.
You leak 1+X groups , X locations/points and X playergroups/forces (I'm pretty sure they leak as they are handles too) every 0.2 seconds with X being the amount of units that have the buff.
Groups are obvious, location is "Position of TempUnit", force is "Player group(Owner of Picked unit )"

So in this case I would say, clear them ;)
 

Jinxx

New Member
Reaction score
4
But how can it be multi-instancable? If two casters use the spell, won't the later overwrite the former in the variable? God, it's all so much easier with local variables in JASS... Also, I think DotA has a spell similar to this - it's that shield spell thing the Dark Seer hero has (only DotA's version isn't exclusively self-cast, he can use it on allies). Aren't all of DotA's spells MUI/MPI/leakless?

So in this case I would say, clear them ;)
I do most of my spells in JASS, but for some reason, I always thought GUI had some kind of built-in leak-clearing system. Why would anyone in their right mind use GUI if it leaks so much? Nulling unit variables and killing special effects is easy when they're all defined by locals, but how can I clear undefined GUI variables (picked unit, group, etc.)?

P.S. Thx for the tutorial Accname, it's quite good! :thup:

EDIT: Headache incoming... ><
 

Jedi

New Member
Reaction score
63
I can make this with jass if you want? - with the most retarded system you can ever seen :D(this skill like ion shield of dark seer right?)
How long skill's duration is?
 

Jinxx

New Member
Reaction score
4
I can make this with jass if you want?(this skill like ion shield of dark seer right?)
How long skill's duration is?

I don't really care about the duration, just put in some constant functions in the header if you want... I'm just interested in seeing this thing done, leakless and clean, whether in GUI or JASS. :eek:
 

Jedi

New Member
Reaction score
63
I tried to make without hashtables and VJass :D

JASS:
function LightningShieldCons takes nothing returns boolean
    return GetSpellAbilityId() == &#039;AOhx&#039; //Your Ability Id
endfunction

function LightningShieldAct takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local group g = CreateGroup()
    local integer i = 0
    local unit u
    loop
        exitwhen GetWidgetLife(target) &lt; 0.405 or i == 10
        call GroupEnumUnitsInRange(g, GetUnitX(target), GetUnitY(target), 200, null)
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            if IsUnitEnemy(u, GetOwningPlayer(caster)) then
                call UnitDamageTarget(caster, u, 5 * GetUnitLevel(u), true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_DIVINE, WEAPON_TYPE_WHOKNOWS)
            endif
            call GroupRemoveUnit(g, u)
        endloop
        set i = i + 1
        call PolledWait(0.01) //0.01 polled wait equal to 0.20 seconds of timer, you know.
    endloop
    call DestroyGroup(g)
    set caster = null
    set target = null
    set g = null
endfunction

//===========================================================================
function InitTrig_Lightning_Shield takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, Condition( function LightningShieldCons))
    call TriggerAddAction(t, function LightningShieldAct)
    set t = null
endfunction
 

Rushhour

New Member
Reaction score
46
But how can it be multi-instancable? If two casters use the spell, won't the later overwrite the former in the variable? God, it's all so much easier with local variables in JASS...
Well the variable will be overwritten hundred times in a second, but that is no problem. The reason why you can't use locals is -like you said- that GroupEnum functions mustn't take any arguments. But since these enumerations are 'instant' and ,well, enumerate through the group it is all done step by step and the information can be held by one global variable. The only problem would be if there is some delay like a Wait inside the action, but you can't do this in GroupEnumerations anyway.
There is no workaround for this. You also need a global for example to pass a structinstance to an enumeration function ;)


I do most of my spells in JASS, but for some reason, I always thought GUI had some kind of built-in leak-clearing system. Why would anyone in their right mind use GUI if it leaks so much? Nulling unit variables and killing special effects is easy when they're all defined by locals, but how can I clear undefined GUI variables (picked unit, group, etc.)?
Yep I also do most stuf in JASS for many reasons. Only short debugging or cheats for testing are faster to do in GUI. There is almost no included leak clearing in the BJ functions. Nulling isn't really needed in GUI since you don't work with local handles there.
And I think me (like most of the others) started with GUI because it is 'clearer' to read and easier to do simple things.

Happy mapping
 

Jinxx

New Member
Reaction score
4
I tried to make without hashtables and VJass :D
Thanks a bunch Jedi, I'll give this a go! :thup:

Well the variable will be overwritten hundred times in a second, but that is no problem. The reason why you can't use locals is -like you said- that GroupEnum functions mustn't take any arguments. But since these enumerations are 'instant' and ,well, enumerate through the group it is all done step by step and the information can be held by one global variable. The only problem would be if there is some delay like a Wait inside the action, but you can't do this in GroupEnumerations anyway.
There is no workaround for this. You also need a global for example to pass a structinstance to an enumeration function ;)
Thanks for clearing that up Rush. I just had some mixup in my head due to some GUI tutorials I read a while back... :nuts:

Anyway, thanks to everyone for helping, my headache is going away now! :D
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top