• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Raise Dead aura

Level 1
Joined
Sep 28, 2017
Messages
1
Hello everyone!

I have a custom item that provides an Unholy Aura. As a bonus effect, I wanted to make own units that die under the effect of the aura to be raised as skeletons.
I first tried to do this with GUI via Unit has a specific buff condition, but quickly figured out that it doesn't work with A unit dies event.
So my next step was trying to build a trigger around A unit dies event that checks for a presence of the item wielder in aura range. The result looks like this:
  • TabletRaisedead
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Dying unit) is Summoned) Equal to False
      • ((Dying unit) is Mechanical) Equal to False
      • ((Dying unit) is A Hero) Equal to False
      • ((Dying unit) is A flying unit) Equal to False
    • Actions
      • Unit Group - Add all units of (Units within 1200.00 of (Position of (Dying unit)) matching ((((Matching unit) has an item of type UnholyTablet) Equal to True) and ((Owner of (Matching unit)) Equal to (Owner of (Dying unit))))) to TestGroup1
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TestGroup1) Greater than or equal to 1
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Random integer number between 1 and 10) Less than or equal to 7
            • Then - Actions
              • Unit - Create 1 Skeleton for (Owner of (Dying unit)) at (Position of (Dying unit)) facing (Facing of (Dying unit)) degrees
              • Unit - Add classification of Summoned to (Last created unit)
              • Unit - Add a 120.00 second Raise Dead expiration timer to (Last created unit)
              • Special Effect - Create a special effect at (Position of (Dying unit)) using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
              • Unit - Create 1 Skeleton archer for (Owner of (Dying unit)) at (Position of (Dying unit)) facing (Facing of (Dying unit)) degrees
              • Unit - Add classification of Summoned to (Last created unit)
              • Unit - Add a 120.00 second Raise Dead expiration timer to (Last created unit)
              • Special Effect - Create a special effect at (Position of (Dying unit)) using Abilities\Spells\Undead\AnimateDead\AnimateDeadTarget.mdl
              • Special Effect - Destroy (Last created special effect)
        • Else - Actions
          • Do nothing
      • Unit Group - Remove all units from TestGroup1
On a small scale, this thing works with desired effect, but:
1) Since it uses a global variable, I'm afraid about it interfering with itself when used on a larger scale.
2) I might be mistaken, but Units withing radius matching condition can create leaks?

To address these issues, I tried to convert this trigger into JASS and tweak it a little.
Now, the important thing is — I have a very vague understanding of JASS and coding in general. The extent of my knowledge is an IT class in school, an entry-level course in C that I took years ago and never used it since, and some wandering around on the Hive.
With that starting point, I spent some time going back-and-forth from GUI to JASS and came up with this:
JASS:
function Trig_TabletRaisedeadCJ_Conditions takes nothing returns boolean
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_SUMMONED) == false ) ) then
        return false
    endif
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_MECHANICAL) == false ) ) then
        return false
    endif
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_HERO) == false ) ) then
        return false
    endif
    if ( not ( IsUnitType(GetDyingUnit(), UNIT_TYPE_FLYING) == false ) ) then
        return false
    endif
    return true
endfunction

function Trig_TabletRaisedeadCJ_Func002001003001 takes nothing returns boolean
    return ( UnitHasItemOfTypeBJ(GetFilterUnit(), 'I00A') == true )
endfunction

function Trig_TabletRaisedeadCJ_Func002001003002 takes nothing returns boolean
    return ( GetOwningPlayer(GetFilterUnit()) == GetOwningPlayer(GetDyingUnit()) )
endfunction

function Trig_TabletRaisedeadCJ_Func002001003 takes nothing returns boolean
    return GetBooleanAnd( Trig_TabletRaisedeadCJ_Func002001003001(), Trig_TabletRaisedeadCJ_Func002001003002() )
endfunction

function Trig_TabletRaisedeadCJ_Func006C takes nothing returns boolean
    if ( not ( GetRandomInt(1, 10) <= 7 ) ) then
        return false
    endif
    return true
endfunction

function Trig_TabletRaisedeadCJ_Func009C takes group CHK returns boolean
    if ( not ( CountUnitsInGroup(CHK) >= 1 ) ) then
        return false
    endif
    return true
endfunction

function Trig_TabletRaisedeadJ_Actions takes nothing returns nothing
    local unit DyingU = GetDyingUnit()
    local location DLoc = GetUnitLoc(GetDyingUnit())
    local real DAng = GetUnitFacing(GetDyingUnit())
    local group MatchG = GetUnitsInRangeOfLocMatching(1200.00, DLoc, Condition(function Trig_TabletRaisedeadCJ_Func002001003))
    if ( Trig_TabletRaisedeadJ_Func009C(MatchG) ) then
        if  ( Trig_TabletRaisedeadCJ_Func006C() ) then
            call CreateNUnitsAtLoc( 1, 'nskg', GetOwningPlayer(DyingU), DLoc, DAng )
            call UnitAddTypeBJ( UNIT_TYPE_SUMMONED, GetLastCreatedUnit() )
            call UnitApplyTimedLifeBJ( 120.00, 'Brai', GetLastCreatedUnit() )
            call AddSpecialEffectLocBJ( DLoc, "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" )
            call DestroyEffectBJ( GetLastCreatedEffectBJ() )
        else
            call CreateNUnitsAtLoc( 1, 'nskf', GetOwningPlayer(DyingU), DLoc, DAng )
            call UnitAddTypeBJ( UNIT_TYPE_SUMMONED, GetLastCreatedUnit() )
            call UnitApplyTimedLifeBJ( 120.00, 'Brai', GetLastCreatedUnit() )
            call AddSpecialEffectLocBJ( DLoc, "Abilities\\Spells\\Undead\\AnimateDead\\AnimateDeadTarget.mdl" )
            call DestroyEffectBJ( GetLastCreatedEffectBJ() )
        endif
    else
        call DoNothing(  )
    endif
    call RemoveLocation(DLoc)
    call DestroyGroup(MatchG)
    call RemoveUnit(DyingU)
endfunction

//===========================================================================
function InitTrig_TabletRaisedeadCJ takes nothing returns nothing
    set gg_trg_TabletRaisedeadCJ = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_TabletRaisedeadCJ, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_TabletRaisedeadCJ, Condition( function Trig_TabletRaisedeadCJ_Conditions ) )
    call TriggerAddAction( gg_trg_TabletRaisedeadCJ, function Trig_TabletRaisedeadCJ_Actions )
endfunction

When I try to run this, I get an "Expected a name" script error at this line:
JASS:
if ( Trig_TabletRaisedeadJ_Func009C(MatchG) ) then
This line calls a function that checks if the group has at least one hero which owns the item in question. When converted directly from GUI, the function looks like this:
JASS:
function Trig_TabletRaisedead_Func006C takes nothing returns boolean
    if ( not ( CountUnitsInGroup(udg_TestGroup1) >= 1 ) ) then
        return false
    endif
    return true
endfunction
The value that it checks is easily called from the global variable udg_TestGroup1, but I want to feed it the value stored in the local variable MatchG instead.
So I edited the function where it is declared and changed takes nothing into takes group CHK:
JASS:
function Trig_TabletRaisedeadCJ_Func009C takes group CHK returns boolean
    if ( not ( CountUnitsInGroup(CHK) >= 1 ) ) then
        return false
    endif
    return true
endfunction
Now in my (unfortunately limited) understanding, next time I call this function in my trigger, I need to feed it a group-type value, and that's what I do: in the main function, when this function is called, instead of "if ( Trig_TabletRaisedeadJ_Func009C() ) then" I now have a "if ( Trig_TabletRaisedeadJ_Func009C(MatchG) ) then", MatchG being a previously declared variable of type group and value "GetUnitsInRangeOfLocMatching(1200.00, DLoc, Condition(function Trig_TabletRaisedeadCJ_Func002001003))"
And this is where I get a script error.
What am I doing wrong?

Thanks in advance!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,911
I would avoid this design if possible, it's very inefficient. Especially if units die often in your map.

Instead, you could trigger your own Aura and have a variable acting like a "buff" which can be checked upon death:

Or, you could detect for lethal damage using Damage events:
  • RDA Lethal Damage
    • Events
      • Unit - A unit Takes damage
    • Conditions
      • ((Damage Target) has buff Devotion Aura) Equal to True
      • (Life of (Damage Target)) Less than or equal to ((Damage taken) + 0.41)
    • Actions
      • Set VariableSet RDA_Target = (Damage Target)
      • Unit Group - Add RDA_Target to RDA_Group
      • Trigger - Turn on RDA Check For Dead <gen>
  • RDA Check For Dead
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in RDA_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet RDA_Target = (Picked unit)
          • Unit Group - Remove RDA_Target from RDA_Group.
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (RDA_Target is alive) Equal to False
            • Then - Actions
              • Set VariableSet RDA_Point = (Position of RDA_Target)
              • Special Effect - Create a special effect at RDA_Point using Abilities\Spells\Undead\RaiseSkeletonWarrior\RaiseSkeleton.mdl
              • Special Effect - Destroy (Last created special effect)
              • -------- --------
              • -------- Create the skeleton: --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Random integer number between 1 and 10) Less than or equal to 7
                • Then - Actions
                  • Unit - Create 1 Skeleton Warrior for (Owner of RDA_Target) at RDA_Point facing Default building facing degrees
                • Else - Actions
                  • Unit - Create 1 Skeletal Mage for (Owner of RDA_Target) at RDA_Point facing Default building facing degrees
              • -------- --------
              • Custom script: call RemoveLocation( udg_RDA_Point )
              • -------- --------
              • -------- Modify the skeleton: --------
              • Unit - Add classification of Summoned to (Last created unit)
              • Unit - Add a 120.00 second Generic expiration timer to (Last created unit)
            • Else - Actions
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (RDA_Group is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
There's overhead with using Damage events but if your map already uses them, or something like Bribe's Damage Engine, then it's a great solution.
 

Attachments

  • Raise Dead Aura 1.w3m
    19 KB · Views: 0
Last edited:
Top