Spell Warrior's Rage

NoobImbaPro

You can change this now in User CP.
Reaction score
60
Warrior's Rage
[Active]:The Warrior enchants his weapon for 5 attacks. Fades after 10 seconds without attacking.

Damage Bonus: 50 +2 per level
AS bonus: 25% +2% per level
Last Hit Bonus: Slow target by 30% for 4 seconds


Pros:
1)Simple and useful
2)You can modify it how you want it easily
3)Fully MUI
4)Leakless, well-optimized code, bug free

Cons:
1)Screenshot sucks
2)Maybe too simple effects

Importing:Requires JassNewGenPack, IDDS, Table, DummyCaster
Copy any buffs/units/spells needed depending from their rawcodes.

Spell Code: v1.2
JASS:

scope WarriorsThoughness initializer init
//==========================Configurables====================================

private keyword UnitData

globals
  private constant  integer ASBonus  = 'ATTS' //Damage Bonus
  private constant  integer ABIL_ID  = 'WABL' //Actual Spell
  private constant  integer DmgBonus = 'WATT' //Attack Speed Bonus
  private constant  integer Slow     = 'DSLO' //Dummy Slow Ability for last attack
  private constant  integer AttMax   = 5      //Max Number of Attacks
  private constant  integer BuffMax  = 10     //Buff Duration time at every attack
  private constant  real    Interval = 0.2    //Timer interval for buff duration checking
  private constant  string  slow     = "slow" //Order string for DUMMY
  
//===============Don't Edit Unless you know what are you doing===============

  private timer             T  = CreateTimer()//Timer for for buff duration checking
  private integer           j  = 0            //Index number for making the spell MUI
  private integer           a  = 0            //Index number for grouping stucts in BuffDurCheck function
  private UnitData  array   UD
endglobals

//===========================================================================

struct UnitData
    unit    Caster
    integer Attacks
    real    BonusStatDur

    static method create takes unit caster, integer lvl returns UnitData
        local UnitData ud    = UnitData.allocate()
        set ud.Caster        = caster
        set ud.Attacks       = AttMax
        set ud.BonusStatDur  = BuffMax
        call UnitAddAbility(caster, ASBonus)
        call UnitAddAbility(caster, DmgBonus)
        call SetUnitAbilityLevel(caster, ASBonus, lvl)
        call SetUnitAbilityLevel(caster, DmgBonus, lvl)
        return ud
    endmethod
endstruct

//===========================================================================

private function recycle takes integer int returns nothing
local integer a
if int == j then
    call UnitRemoveAbility(UD[j].Caster, ASBonus)
    call UnitRemoveAbility(UD[j].Caster, DmgBonus)
    call UD[j].destroy()
else
    set a = int
    loop
        set a = a + 1
        set UD[int] = UD[a] 
        call UnitRemoveAbility(UD[a].Caster, ASBonus)
        call UnitRemoveAbility(UD[a].Caster, DmgBonus)
        call UD[a].destroy()
    exitwhen a == j
    endloop
endif
set j = j - 1
endfunction

//===========================Check Who's Casting=============================    

private function Check takes unit b returns integer
        local integer i = 0
        local boolean found = false
        loop
            set i = i + 1
            if b == UD<i>.Caster then
                set found = true
            endif
        exitwhen found == true
        endloop
        return i
endfunction

//===========================================================================

private function BuffDurCheck takes nothing returns nothing
loop
    exitwhen a &gt;= j
    set a = a + 1
    set UD[a].BonusStatDur = UD[a].BonusStatDur - Interval
    if UD[a].BonusStatDur &lt;= 0 then
        call recycle(a)
    endif
endloop
set a = 0
endfunction

//===========================================================================

private function FirstCastCond takes nothing returns boolean
    local  integer lvl
    local   unit   ut
    if GetSpellAbilityId() == ABIL_ID and not(GetUnitAbilityLevel(GetTriggerUnit(), DmgBonus) &gt; 0) then
        set j = j + 1
        set ut    = GetTriggerUnit()
        set lvl   = GetUnitAbilityLevel(ut,ABIL_ID)
        set UD[j] = UnitData.create(ut, lvl)
        if j == 1 then
            call TimerStart(T,Interval,true,function BuffDurCheck)
        endif
    endif
    set ut = null
    return false
endfunction

//===========================================================================

private function AttackCond takes nothing returns boolean
local unit ut
local integer d
if (GetTriggerDamageType() == DAMAGE_TYPE_ATTACK) and (GetUnitAbilityLevel(GetEventDamageSource(), DmgBonus) &gt; 0) then
    set ut = GetEventDamageSource()
    set d = Check(ut)
    set UD[d].BonusStatDur = BuffMax
    set UD[d].Attacks = UD[d].Attacks - 1
    if UD[d].Attacks == 0 then
        call IssueTargetOrder(DUMMY, slow, GetTriggerUnit())
        call recycle(d)
    endif
endif
set ut = null
return false
endfunction
//===========================================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition(t, function FirstCastCond)
    set t = null

    set t = CreateTrigger()
    call TriggerRegisterDamageEvent(t, 2)
    call TriggerAddCondition(t, function AttackCond)
    set t = null

    call UnitAddAbility(DUMMY, ASBonus)
    call UnitRemoveAbility(DUMMY, ASBonus)
    call UnitAddAbility(DUMMY, DmgBonus)
    call UnitRemoveAbility(DUMMY, DmgBonus)
    call UnitAddAbility(DUMMY, Slow)
endfunction
endscope</i>

v1.0 Initial Release
v1.1 Removed Leaks and Modified Trigger using stucts and timers
v1.2 UPDATED and optimized code
 

Attachments

  • Screenshot.jpg
    Screenshot.jpg
    262.5 KB · Views: 376
  • Warrior's Toughness v1.2.w3x
    38.1 KB · Views: 337
JASS:
private function init takes nothing returns nothing
    local trigger df51 = CreateTrigger()
    local trigger df53 = CreateTrigger()
    local trigger df54 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( df51, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerRegisterDamageEvent(df53, 2)
    call TriggerRegisterTimerEventPeriodic( df54, 0.10 )
    call TriggerAddAction(df51, function actions)
    call TriggerAddAction(df53, function actions2)
    call TriggerAddAction(df54, function fading)
    call TriggerAddCondition(df51, function conditions)
    call TriggerAddCondition(df53, function conditions2)
    call PA(AS) //Preload Ability (PA) I just made it to reduce lag from first cast
    call PA(AD)
    call UnitAddAbility(DUMMY, SL) //Adding Slow Ability to our DUMMY
endfunction


could be

JASS:
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction(t, function actions)
    call TriggerAddCondition(t, function conditions)

    set t = CreateTrigger()
    call TriggerRegisterDamageEvent(t, 2)
    call TriggerAddAction(t, function actions2)
    call TriggerAddCondition(t, function conditions2)

    set t = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( t, 0.10 )
    call TriggerAddAction(t, function fading)

    //You dont need to preload simple abilities... because they dont lag as much (you even notice)
    call UnitAddAbility(DUMMY, PA)
    call UnitRemoveAbility(DUMMY, PA)
    call UnitAddAbility(DUMMY, AD)
    call UnitRemoveAbility(DUMMY, AD)
    call UnitAddAbility(DUMMY, SL)
    call UnitRemoveAbility(DUMMY, SL)
endfunction



and the library is useless... the scope name is stupid, use something more intelligence, you leak some locals unit.


JASS:
private function Check takes unit b returns integer
you don't need a function to do this
JASS:
private function RegUnit takes unit a returns nothing
for what this?

I think you should use AIDS.

Also you should use timer instead of that event periodic
 
I said the map wasn't for demonstation, and the preload library was for preloading a bunch of abilities. I just posted it for you to see what it does. Thank you for feedback, I will try to make it with AIDS and TimerUtils but they seem too complex for me...

EDIT: And what problem you have with the scope name?
 
> And what problem you have with the scope name?

scope warriorsrage initializer init

> I said the map wasn't for demonstation, and the preload library was for preloading a bunch of abilities. I just posted it for you to see what it does.

That's the whole point of a demo map. There is even a demo map template for you to use in one of the stickies inside the Spells forum!
 
A question: Why should I use AIDS and Timer32 as asked when I don't use structs?
Isn't it pointless? I just made "my" system to make it work. Its more efficient.
Now I will make another map instead of that sh*t.
Thank you Daxtreme
 
JASS:
private function init takes nothing returns nothing
    local trigger df51 = CreateTrigger()
    local trigger df53 = CreateTrigger()
    local trigger df54 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( df51, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerRegisterDamageEvent(df53, 2)
    call TriggerRegisterTimerEventPeriodic( df54, 0.10 )
    call TriggerAddAction(df51, function actions)
    call TriggerAddAction(df53, function actions2)
    call TriggerAddAction(df54, function fading)
    call TriggerAddCondition(df51, function conditions)
    call TriggerAddCondition(df53, function conditions2)
    call PA(AS) //Preload Ability (PA) I just made it to reduce lag from first cast
    call PA(AD)
    call UnitAddAbility(DUMMY, SL) //Adding Slow Ability to our DUMMY
endfunction


could be

JASS:
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction(t, function actions)
    call TriggerAddCondition(t, function conditions)

    set t = CreateTrigger()
    call TriggerRegisterDamageEvent(t, 2)
    call TriggerAddAction(t, function actions2)
    call TriggerAddCondition(t, function conditions2)

    set t = CreateTrigger()
    call TriggerRegisterTimerEventPeriodic( t, 0.10 )
    call TriggerAddAction(t, function fading)

    //You dont need to preload simple abilities... because they dont lag as much (you even notice)
    call UnitAddAbility(DUMMY, PA)
    call UnitRemoveAbility(DUMMY, PA)
    call UnitAddAbility(DUMMY, AD)
    call UnitRemoveAbility(DUMMY, AD)
    call UnitAddAbility(DUMMY, SL)
    call UnitRemoveAbility(DUMMY, SL)
endfunction
This isn't solution, you made it worse, it leaks too much.

UPDATED MAP AND CODE

@Daxtreme
It may not seem efficient but it is simpler and exactly what I want
 
your init function leak too... i just clear it for eye candy... but who cares about local trigger leak?..
 
This isn't solution, you made it worse, it leaks too much.

What do you mean it leaks too much. It leaks once, which is when you don't null the local trigger at the end. This can be ignored as initialization obviously only occurs once, which is on map initialization. Still, you could null the trigger variable at the end for good coding practicing.

It may not seem efficient but it is simpler and exactly what I want

Sometimes, you shouldn't sacrifice efficiency for simplicity.

Alright, on with my comments.

Firstly, I suggest you change the way you name things:
Extra tip for you, use better naming convention, good for your and others' eyes.
Use CAPITAL_LETTER and _ for constant globals.
Use Capital letter for globals and functions. (First alphabets)
Use small letter for locals. (Some will just use globals as locals(Can ignore nulling :p), like Jesus4Lyf, then just put them as small letters.)
Use camelCase for struct members, methods.

Secondly, why do you use a periodic event? vJASS is much better to use timers and not periodic events. This isn't GUI, you can to wacky things with timers. TimerUtils is fairly simple to use. All it does is that it attaches a data to a timer, and you can retrieve this data. I suggest you don't avoid timers and structs, they are extremely useful.

Thirdly, as mentioned above, null your locals where necessary.

Fourthly, you could work on naming your variables and functions better. I mean, what is "AC"? You could change it to something like "ABILID" or something. Similarly, for your functions, you could name them better. Instead of "conditions2", you could name it something like "DamageConditions".

Fifthly, you could just not use the actions and use the condition straight. For example:
JASS:
private function Actions takes nothing returns nothing
    // your actions
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == ABILID
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, function Conditions)
    call TriggerAddAction(t, function Actions)
    set t = null
endfunction


This is how you're doing it currently. Instead, you could do:
JASS:
private function Actions takes nothing returns boolean
    if GetSpellAbilityId() == ABILID then
        // your actions
    endif
    return false
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, function Actions)
    set t = null
endfunction
 
@Ayanami
Thanks, I learned now struct's and timers usefulness

CODE UPDATED, map too

Soon Better Ability
 
>Soon Better Ability
Any progress?

Graveyarded for now, seeing as this is clearly not in active development.
 
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