• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[Spell] Help on a Skill!

Status
Not open for further replies.
Level 4
Joined
Jun 2, 2012
Messages
746
Hello, hivers! I need again your help on the skill Im creating. Its quite hard for me because Im not good at triggered skills. So here is the description of the skill:

The name of the skill is Soul Pierce. When the unit with this skill attacks an enemy, every attack slows the enemies Attack speed and movespeed by 5% but it is only up to 50%. When the unit who is slowed in this skill is not attacked by the enemy, he will instantly recover 5% Attack Speed and Movespeed each 2 seconds.

How do I do that? Im really not good at triggering skill as I said. I need your help! +REP for those who will help!:thumbs_up:
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
The "easy" way is is creating an aura ability based on Command (i think it allows increasing attack/movement speed) with 11 levels. Level 1 has 0/0 values, and then increase by 5% every level (from lvl 2 being 5%, and lvl 11 being 50%) Add this aura to all units, and remove the buff it displays on level 1.

Now create the Passive ability (based on anything passive with 0 values, it's dummy, does nothing)

Now, detect damage (use a Damage Detection System), and level of "SoulPierce" for DamageSource, and increase the level of the SoulPearce for DamagedUnit by 1, and save 2 on the unit ID in a Hashtable. Add it to a Group, and in a periodic loop every 0.1 seconds, reduce that "2" by 0.1; if that "2" reaches 0, set level of ability to level-1, and save 2 again, repeat as long as the level of ability is greater than 1.

If there's no units in the group, turn off the loop trigger.
 
Level 4
Joined
Jun 2, 2012
Messages
746
The "easy" way is is creating an aura ability based on Command (i think it allows increasing attack/movement speed) with 11 levels. Level 1 has 0/0 values, and then increase by 5% every level (from lvl 2 being 5%, and lvl 11 being 50%) Add this aura to all units, and remove the buff it displays on level 1.

Now create the Passive ability (based on anything passive with 0 values, it's dummy, does nothing)

Now, detect damage (use a Damage Detection System), and level of "SoulPierce" for DamageSource, and increase the level of the SoulPearce for DamagedUnit by 1, and save 2 on the unit ID in a Hashtable. Add it to a Group, and in a periodic loop every 0.1 seconds, reduce that "2" by 0.1; if that "2" reaches 0, set level of ability to level-1, and save 2 again, repeat as long as the level of ability is greater than 1.

If there's no units in the group, turn off the loop trigger.

m only good at understanding it on trigger. I learned from it.:thumbs_up:
 
Level 4
Joined
Jun 2, 2012
Messages
746
Tell me something; what's the influence on the attacking unit "SoulcePierce" ability level?

As I say on my first post, the attacking unit with this skill can slow the attacked unit by 5% on attack speed and move speed. But if the unit being inflicted with slow is not attacked, each 2 seconds it will recover 5% attack speed and move speed until the status of the unit comes back to normal again.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
And how does that answer my question?...

I mean.. if the attacking unit has the ability on lvl 500 the effect will be the same than having the ability on lvl 2...
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
And how does that answer my question?...

I mean.. if the attacking unit has the ability on lvl 500 the effect will be the same than having the ability on lvl 2...

i'd have played his map spartipillo, the character didn't have a leveled ability, all the points went for strength, agility, and inteligence.. and usually he want to give the skill to a boss enemies..
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
Code:

It's a unit skill so it has only level.... Even it reach any level same effect.

still don't quite get what you mean :/

Allain55X, i have a question.. what type of ability is this? passive or active ? passive means whenever the unit with this skill attacks, the ability would always apply.. active means the ability would be applied only if the unit is casting this skill..
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
It's passive, happens when a unit is attacked.

so, i managed to make the ability..
  • [TRIGGER]Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set hash = (Last created hashtable)
      • Unit Group - Pick every unit in (Units owned by Neutral Hostile) and do (Actions)
        • Loop - Actions
          • Unit - Add Soul Pierce to (Picked unit)
  • Soul Pierce
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Level of Soul Pierce (Neutral Hostile) for (Attacking unit)) Not equal to 0
    • Actions
      • Unit - Set level of Soul Pierce for (Triggering unit) to ((Level of Soul Pierce for (Triggering unit)) + 1)
      • Set SP_DUR = 2.00
      • Hashtable - Save SP_DUR as 0 of (Key (Triggering unit)) in hash
      • Unit Group - Add (Triggering unit) to tempGroup
      • Trigger - Turn on SP Loop<gen>

A unit is attacked should be replaced with DDS

  • SP Loop
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Set SP_DUR = ((Load 0 of (Key (Picked unit)) from hash) - 0.10)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SP_DUR Less than or equal to 0.00
            • Then - Actions
              • Unit - Set level of Soul Pierce for (Picked unit) to ((Level of Soul Pierce for (Picked unit)) - 1)
              • Set SP_DUR = 2.00
              • Hashtable - Save SP_DUR as 0 of (Key (Picked unit)) in hash
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Soul Pierce for (Picked unit)) Equal to 0
                • Then - Actions
                  • Unit Group - Remove (Picked unit) from tempGroup
                • Else - Actions
            • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Number of units in tempGroup) Equal to 0
          • Then - Actions
            • Trigger - Turn off (This trigger)
          • Else - Actions
how do i check if there is no unit on the group ?
Edit : yeah, i found them... anything wrong ?
Edit2 : WOOPSS.. it turned out to be wrong.. now the unit attacked with this skill get 5% movementspeed every attack they received...
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
sorry for double post, here is your test map if you don't want to post your map here..

EDIT : the Soul Pierce.w3x is a wrong attachment..
the real one is Fixed Soul Pierce.w3x..
tell me if the skill didn't work..
i get the skill worked perfectly :thumbs_up:


EDIT 2 : you really need to PM your map to me.. because there is a variable settings and any other things that's needed to be done..
 

Attachments

  • Soul Pierce.w3x
    26.2 KB · Views: 39
  • Fixed Soul Pierce.w3x
    26.7 KB · Views: 38
Last edited:
Level 4
Joined
Jun 2, 2012
Messages
746
sorry for double post, here is your test map if you don't want to post your map here..

EDIT : the Soul Pierce.w3x is a wrong attachment..
the real one is Fixed Soul Pierce.w3x..
tell me if the skill didn't work..
i get the skill worked perfectly :thumbs_up:


EDIT 2 : you really need to PM your map to me.. because there is a variable settings and any other things that's needed to be done..

Hey your first post of the map.... the first one has some script errors that disables my triggers..... Good thing I have a backup...LOL!:grin:
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
Code:
Dont take it seriously. Just making sure!

I am now putting the map in Pastebin Ill send you the link of the pastebin a PM later.:thumbs_up:

you should trust me because i'm YOUR SUPPORTER :ogre_love:
you could always SHOUT on this website if i do something wrong with your map and later i would get banned :)

and i have one more question, Allain55X..

who will get this ability ? Siris or his enemies ? i need to know this to put a right trigger and abilities :)
 
Level 4
Joined
Jun 2, 2012
Messages
746
Code:

you should trust me because i'm YOUR SUPPORTER :ogre_love:
you could always SHOUT on this website if i do something wrong with your map and later i would get banned :)

and i have one more question, Allain55X..

who will get this ability ? Siris or his enemies ? i need to know this to put a right trigger and abilities :)

The God King will have the ability. :thumbs_up:

LOL, I know I can trust you!:grin:
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
I would rather use Bribe's Unit Indexer and 2 global arrays "SP_Units" and "SP_DUR" and a unit group SP_Group

When the unit is attacked you set it to SP_Units[Custom value of attacked unit] and you set SP_Dur[Custom value of attacked unit] = 2.00, and you increase the level of the ability, you also add it to SP_Group

On a periodic trigger you pick every unit in SP_Group and take it's custom value, reduce SP_Dur[Custom value of Picked Unit] by 0.1; if it's 0, reduce the level and set it to 2 again, if level is 1, remove the unit from the group.

It's the same, but avoiding the creation of a Hashtable just for this ability, wich can be done easily with these globals.

I think the Unit Group can be avoided by indexin the units into an array (since looping Unit arrays are faster than Unit Groups) but I'm not sure how :)
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
I would rather use Bribe's Unit Indexer and 2 global arrays "SP_Units" and "SP_DUR" and a unit group SP_Group

When the unit is attacked you set it to SP_Units[Custom value of attacked unit] and you set SP_Dur[Custom value of attacked unit] = 2.00, and you increase the level of the ability, you also add it to SP_Group

On a periodic trigger you pick every unit in SP_Group and take it's custom value, reduce SP_Dur[Custom value of Picked Unit] by 0.1; if it's 0, reduce the level and set it to 2 again, if level is 1, remove the unit from the group.

It's the same, but avoiding the creation of a Hashtable just for this ability, wich can be done easily with these globals.

I think the Unit Group can be avoided by indexin the units into an array (since looping Unit arrays are faster than Unit Groups) but I'm not sure how :)

does this "creation of a Hashtable just for this ability" is really a bad thing ? or even the worst thing to do ? couldn't we use these created hashtable for other spells too ? i've tested the map several times and it worked fine.. those are the last updated triggers..

  • Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set hash = (Last created hashtable)
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Disable Spell Book for (Picked player)
  • Soul Pierce
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
      • (Level of Soul Pierce (Neutral Hostile) for GDD_DamageSource) Not equal to 0
    • Actions
      • Unit - Set level of Soul Pierce for GDD_DamagedUnit to ((Level of Soul Pierce for GDD_DamagedUnit) + 1)
      • Set SP_DUR = 2.00
      • Custom script: set bj_lastLoadedUnit = udg_GDD_DamageSource
      • Custom script: set bj_lastReplacedUnit = udg_GDD_DamagedUnit
      • Hashtable - Save SP_DUR as 0 of (Key (Last replaced unit)) in hash
      • Unit Group - Add GDD_DamagedUnit to tempGroup
      • Trigger - Turn on SP Loop <gen>
  • SP Loop
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Set SP_DUR = ((Load 0 of (Key (Picked unit)) from hash) - 0.10)
          • Hashtable - Save SP_DUR as 0 of (Key (Picked unit)) in hash
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • SP_DUR Equal to 0.00
            • Then - Actions
              • Game - Display to (All players) the text: time is up.. regain...
              • Unit - Set level of Soul Pierce for (Picked unit) to ((Level of Soul Pierce for (Picked unit)) - 1)
              • Set SP_DUR = 2.00
              • Hashtable - Save SP_DUR as 0 of (Key (Picked unit)) in hash
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Soul Pierce for (Picked unit)) Equal to 1
                • Then - Actions
                  • Unit Group - Remove (Picked unit) from tempGroup
                • Else - Actions
            • Else - Actions
              • Set SP_DUR = ((Load 0 of (Key (Picked unit)) from hash) - 0.10)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in tempGroup) Equal to 0
        • Then - Actions
          • Game - Display to (All players) the text: regain completed.. ...
          • Trigger - Turn off (This trigger)
        • Else - Actions
already included with Weep's GDD :)
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
It works, but Hashtables takes more memory than globals, saving values on it requires 4 arguments, loading requires 3, they extend handle, so, they're slower. They're better for greater purposes, but slower. Globals, instead, requires 1 argument to save, and 1 argument to load.

See here. These 2 scripts have already removed all the GUI BJ's, including Hashtable GUI save/load wich is also a BJ, also avoids using the Hashtable, improves the code in general, avoids unnecessary GUI functions (wich can't be avoided) making this a lot faster

You just need to create 2 triggers, one called "SP Set" and another one called "SP Loop", you also have to replace the 'xxxx' with the raw id of the ability your enemies have (the ones that get slowed), and replace 'zzzz' with the raw id of the ability your attacker has (to slow down enemies) and import this system >> http://www.hiveworkshop.com/forums/...97329/?prev=search=Unit%20Indexer&d=list&r=20 << to your map. You might consider that importing an aditional system would be "too much", but you'll eventually will use it; everyone does, and you'll find it pretty usefull later.


SP Set trigger
JASS:
globals
    group SP_Group
    real array SP_Dur
endglobals

function Trig_SP_Set_Actions takes nothing returns nothing
    local unit u = GetAttacker()
    if GetUnitAbilityLevel(u, 'zzzz') > 0 then
        set u = GetTriggerUnit() // The attacked unit
        set SP_Dur[GetUnitUserData(u)] = 2 // 2 is the duration of SP
        call GroupAddUnit(SP_Group, u) // Add attacked unit to Group
        call IncUnitAbilityLevel(u, 'xxxx') // Increase SP for attacked unit
        call EnableTrigger(gg_trg_SP_Loop) // Turn on the loop
    endif
    set u = null
endfunction

//===========================================================================
function InitTrig_SP_Set takes nothing returns nothing
    set gg_trg_SP_Set = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_SP_Set, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddAction( gg_trg_SP_Set, function Trig_SP_Set_Actions )
endfunction

SP Loop trigger
JASS:
function SP_Loop_Group_Actions takes nothing returns nothing
    local unit u = GetEnumUnit() // Picked Unit
    local integer cv = GetUnitUserData(u) // Custom Value of Picked Unit
    set SP_Dur[cv] = SP_Dur[cv] - .1 // Reduce the SP timer by 0.1
    
    if SP_Dur[cv] <= 0 then // If SP Timer is 0 then
        call DecUnitAbilityLevel(u, 'xxxx') // Reduce ability level
        if GetUnitAbilityLevel(u, 'xxxx') > 1 then // If ability lvl is greater than 1
            set SP_Dur[cv] = 2 // Set SP timer again to 2.
        else 
            call GroupRemoveUnit(SP_Group, u) // Remove unit from the group
        endif
    endif
    
    set u = null
endfunction

function SP_Loop_Actions takes nothing returns nothing
    set bj_groupCountUnits = 0
    call ForGroup(g, function CountUnitsInGroupEnum) // Check if the Group is empty.
    if bj_groupCountUnits > 0 then
        call ForGroup( udg_SP_Group, function SP_Loop_Group_Actions ) // Do Group actions
    else
        call DisableTrigger(gg_trg_SP_Loop) // Turn off loop if group is empty.
    endif
endfunction

//===========================================================================
function InitTrig_SP_Loop takes nothing returns nothing
    set gg_trg_SP_Loop = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_SP_Loop, 0.10 )
    call TriggerAddAction( gg_trg_SP_Loop, function SP_Loop_Actions )
endfunction
 
Last edited:
Level 12
Joined
Sep 11, 2011
Messages
1,176
Spartipilo let's wait until Allain55X get consciousness..
because i don't own the map, it's his map..
i would change it after i get approval from him :)

and what the xxxx ability would like ? cause what the one i made have is a 11 levels Endurance Aura with 5% reduction movement for each level.. should i get it to 5% reduction or 5% increased movement and attack speed to fullfill your suggestion?

Allain55X would you like me to put Spartipilo's suggestion ? it's better and faster than the one i made. you could get a better result :thumbs_up:
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
The same result, less requirements. It's like working half of the time, and get the same payment :p

Btw, it's the first time I work with Unit Indexer... and now I notice how convenient it is.
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
The same result, less requirements. It's like working half of the time, and get the same payment :p

Btw, it's the first time I work with Unit Indexer... and now I notice how convenient it is.

so, when we use UnitIndexer, we wouldn't need Weep's GDD? or we need both of them ?

and i want to know whether your custom damage/resistance system is ready to use or still needs some fixing or optimizing..
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Hashtable requires a Hash, a ParentKey, and a ChildKey. UnitIndexer just replaces the Hashtable with the variable, the parent-key with the Unit Custom value, nullifying the need of the ChildKey. So, it has nothing to do with Weep's system :p

I prefer to use "A unit is attacked" event; it can be abused, but managing Damage in an efficient way to separate magic/skill from default attack damage is a pain in the ass.

My Dmg system is working already; haven't tested in multiplayer tough. What i'm trying to do now is avoiding the Hashtable and use UnitIndexer instead; but it's quite difficult, since requires too many configurations for the user.
 
Level 12
Joined
Sep 11, 2011
Messages
1,176
Hashtable requires a Hash, a ParentKey, and a ChildKey. UnitIndexer just replaces the Hashtable with the variable, the parent-key with the Unit Custom value, nullifying the need of the ChildKey. So, it has nothing to do with Weep's system :p

i see, when we move onto another trigger, we could just load from it's custom values and no need to use something like this, am i right ?
  • Unit Group - Pick every unit in tempGroup and do (Actions)
    • Loop - Actions
      • Set SP_DUR = ((Load 0 of (Key (Picked unit)) from hash) - 0.10)
I prefer to use "A unit is attacked" event; it can be abused, but managing Damage in an efficient way to separate magic/skill from default attack damage is a pain in the ass.

i used "A unit is attacked" too from the first place, but then i saw this..
http://www.hiveworkshop.com/forums/world-editor-help-zone-98/passive-trigger-abilities-how-123099/

Xarwin said:
Remember that by using the 'unit is attacked' event it won't be so accurate since you can just pretend you are attacking, and then fall back so there would be no damage but the trigger is activated.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Yes, you're right. Instead of using GUI hash function call LoadRealBJ(ParenteId, ChildId, Hashtable)
to make it call another function
call LoadReal(Hash, ParenteId, ChildId)
we just do
  • Set u = (Picked Unit)
  • set cv = (Custom value of u)
  • Set SP_Dur[cv] = SP_Dur[cv] - 0.1
Setting values to variables doesn't require calling functions neither require arguments to handle and process within that function. It's really faster :)

About the attack thing, yes it's a pain in the ass, but most users just attack without preventing attack to get triggered bonuses; in fact, most players doesn't even know that can be done and, in this case, it doesn't seem too abuseable. If he wants to trigger all his Magic Damage and leave all other damage be attack damage, then he wouldn't even ask anyone to help him with this xD
 
Status
Not open for further replies.
Top