• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Magic absorption - v1.1

  • Like
Reactions: maddeem
E6udK.png


Changelog:
• Code fixed.
• Ability optimization.
• Cast models changed.


JASS:
//*************************************************************
//TEST THE SPELL FIRST TO CONFIGURE ANYTHING BELOW THIS
//*************************************************************

function MA_HeroAbility takes nothing returns integer
    return 'A001'
//Rawcode of the hero spell
endfunction

function MA_DMGBonusAbilityInfo takes nothing returns integer
    return 'A002'
//Rawcode of the damage bonus ability for the hero
endfunction

function MA_SPDBonusAbilityInfo takes nothing returns integer
    return 'A003'
//Rawcode of the speed bonus ability for the hero
endfunction

function MA_DamageAbility takes nothing returns integer
    return 'A005'
//Rawcode of the ability that gives the damage bonus to the hero
endfunction

function MA_SpeedAbility takes nothing returns integer
    return 'A004'
//Rawcode of the ability that gives the speed bonus to the hero
endfunction

function MA_Dummy takes nothing returns integer
    return 'u000'
//Rawcode of the dummy that cast the bonus spells
endfunction

function MA_DamageOrder takes nothing returns string
    return "innerfire"
//The order to cast the damage bonus spell
endfunction

function MA_SpeedOrder takes nothing returns string
    return "bloodlust"
//The order to cast the speed bonus spell
endfunction

function MA_ChargesPerLevel takes integer level returns integer
    return 5 + 15 * level
//Max charges per level, you can change this relationated with the bonus spells on the object editor
endfunction

//*************************************************************
//TOUCH ANYTHING BELOW THIS ONLY IF YOU KNOW JASS
//*************************************************************

function MA1_Actions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    if GetLearnedSkill() == MA_HeroAbility() and GetLearnedSkillLevel() == 1 then
        call UnitAddAbility(u, MA_DMGBonusAbilityInfo())
        call UnitAddAbility(u, MA_SPDBonusAbilityInfo())
    endif
    set u = null
    return false
endfunction

function MA2_Actions takes nothing returns boolean
    local unit a = udg_DamageEventSource
    local unit t = udg_DamageEventTarget
    local texttag tt
    local integer i
    local integer level
    local string st
    if IsUnitEnemy(a, GetOwningPlayer(t)) and GetUnitAbilityLevel(a, MA_HeroAbility()) > 0 and not IsUnitType(t, UNIT_TYPE_DEAD) and not IsUnitType(t, UNIT_TYPE_STRUCTURE) and not IsUnitType(t, UNIT_TYPE_MAGIC_IMMUNE) then
        set i = GetUnitUserData(a)
        set level = GetUnitAbilityLevel(a, MA_HeroAbility())
        if udg_MA_MagicCount[i] < MA_ChargesPerLevel(level) then
            set udg_MA_MagicCount[i] = udg_MA_MagicCount[i] + 1
            if GetLocalPlayer() == GetOwningPlayer(a) then
                set st = I2S(udg_MA_MagicCount[i])
            endif
            set tt = CreateTextTag()
            call SetTextTagText(tt, st, 0.028)
            call SetTextTagPos(tt, GetUnitX(a), GetUnitY(a) + 75, 160)
            call SetTextTagColor(tt, 100, 180, 255, 255)
            call SetTextTagVisibility(tt, true)
            call SetTextTagVelocity(tt, 0, 0.03)
            call SetTextTagFadepoint(tt, 0.25)
            call SetTextTagLifespan(tt, 0.4)
            call SetTextTagPermanent(tt, false)
        endif
    endif
    set a = null
    set t = null
    return false
endfunction

function MA3_Actions takes nothing returns boolean
    local unit caster = GetTriggerUnit()
    local integer unitId = GetUnitUserData(caster)
    local integer abilityId
    local unit dummy
    
    if udg_MA_MagicCount[unitId] > 0 then
        set abilityId = GetSpellAbilityId()

        if abilityId == MA_DMGBonusAbilityInfo() then

            set dummy = CreateUnit(GetOwningPlayer(caster), MA_Dummy(), GetUnitX(caster), GetUnitY(caster), 0)
            call UnitAddAbility(dummy, MA_DamageAbility())
            call SetUnitAbilityLevel(dummy, MA_DamageAbility(), udg_MA_MagicCount[unitId])
            call IssueTargetOrder(dummy, MA_DamageOrder(), caster)
            call UnitApplyTimedLife(dummy, 'BTLF', 0.5)
            set udg_MA_MagicCount[unitId] = 0
            set dummy = null

        elseif abilityId == MA_SPDBonusAbilityInfo() then

            set dummy = CreateUnit(GetOwningPlayer(caster), MA_Dummy(), GetUnitX(caster), GetUnitY(caster), 0)
            call UnitAddAbility(dummy, MA_SpeedAbility())
            call SetUnitAbilityLevel(dummy, MA_SpeedAbility(), udg_MA_MagicCount[unitId])
            call IssueTargetOrder(dummy, MA_SpeedOrder(), caster)
            call UnitApplyTimedLife(dummy, 'BTLF', 0.5)
            set udg_MA_MagicCount[unitId] = 0
            set dummy = null

        endif

    endif

    set caster = null
    return false
endfunction

function InitTrig_MA takes nothing returns nothing
    local trigger t = CreateTrigger()
    local unit u = CreateUnit(Player(0), MA_Dummy(), 0, 0, 0)
    call UnitAddAbility(u, MA_DMGBonusAbilityInfo())
    call UnitAddAbility(u, MA_SPDBonusAbilityInfo())
    call UnitAddAbility(u, MA_SpeedAbility())
    call UnitAddAbility(u, MA_DamageAbility())
    call RemoveUnit(u)
    set u = null
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
    call TriggerAddCondition(t, Condition(function MA1_Actions))
    set t = CreateTrigger()
    call TriggerRegisterVariableEvent(t, "udg_DamageEvent", EQUAL, 1.00)
    call TriggerAddCondition(t, Condition(function MA2_Actions))
    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function MA3_Actions))
    set t = null
endfunction


Keywords:
magic, absorption, fatal, sword, khaosmachine, blizzlike spell, spell, ability, nice, swet, cute, util, usable, useful
Contents

Fatal sword (Map)

Reviews
21st May 2012 Bribe: Looks good. Approved!
You should really indent your code :/
If it isn't indented, it's much harder to read. (Don't listen to maddeem and his wacky anti-indentation movement =P)

If you don't like indenting your code, you can use this: http://www.hiveworkshop.com/forums/tools-560/script-language-aligner-jass-vjass-zinc-186353/

That tool will align the script for you <:

Or, instead of wasting time, clicking that link, downloading the application and inputting the code, then pasting it, here, I did it for you manually:

JASS:
//*************************************************************
//TEST THE SPELL FIRST TO CONFIGURE ANYTHING BELOW THIS
//*************************************************************


function MA_HeroAbility takes nothing returns integer
    return                                          'A001'
                                                    //Rawcode of the hero spell
endfunction

function MA_DMGBonusAbilityInfo takes nothing returns integer
    return                                          'A002'
                                                    //Rawcode of the damage bonus ability for the hero
endfunction

function MA_SPDBonusAbilityInfo takes nothing returns integer
    return                                          'A003'
                                                    //Rawcode of the speed bonus ability for the hero
endfunction

function MA_DamageAbility takes nothing returns integer
    return                                          'A005'
                                                    //Rawcode of the ability that gives the damage bonus to the hero
endfunction

function MA_SpeedAbility takes nothing returns integer
    return                                          'A004'
                                                    //Rawcode of the ability that gives the speed bonus to the hero
endfunction

function MA_Dummy takes nothing returns integer
    return                                          'u000'
                                                    //Rawcode of the dummy that cast the bonus spells
endfunction

function MA_DamageOrder takes nothing returns string
    return                                          "innerfire"
                                                    //The order to cast the damage bonus spell
endfunction

function MA_SpeedOrder takes nothing returns string
    return                                          "bloodlust"
                                                    //The order to cast the speed bonus spell
endfunction

function MA_ChargesPerLevel takes integer level returns integer
    return                                          5 + 15 * level
                                                    //Max charges per level, you can change this relationated with the bonus spells on the object editor
endfunction


//*************************************************************
//TOUCH ANYTHING BELOW THIS ONLY IF YOU KNOW JASS
//*************************************************************


function MA1_Actions takes nothing returns boolean
    local unit u=GetTriggerUnit()

    if GetLearnedSkill() == MA_HeroAbility() and GetLearnedSkillLevel() == 1 then
        call UnitAddAbility(u,MA_DMGBonusAbilityInfo())
        call UnitAddAbility(u,MA_SPDBonusAbilityInfo())
        set udg_MA_CustomValue=udg_MA_CustomValue+1
        @call SetUnitUserData(u,udg_MA_CustomValue)@ // You shouldn't be doing this >:|
    endif

    set u=null
    return false
endfunction

function MA2_Actions takes nothing returns boolean
    local unit a=udg_DamageEventSource
    local unit t=udg_DamageEventTarget
    local texttag tt
    local integer i
    local integer level
    local string st

    if udg_DamageTypeDOT > 0 and IsUnitEnemy(a,GetOwningPlayer(t)) and GetUnitAbilityLevel(a,MA_HeroAbility()) > 0 and not IsUnitType(t,UNIT_TYPE_DEAD) and not IsUnitType(t,UNIT_TYPE_STRUCTURE) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE) then

        set i = GetUnitUserData(a)
        set level = GetUnitAbilityLevel(a,MA_HeroAbility())

        if udg_MA_MagicCount[i] < MA_ChargesPerLevel(level) then

            set udg_MA_MagicCount[i]=udg_MA_MagicCount[i]+1

            if GetLocalPlayer() == GetOwningPlayer(a) then
                set st=I2S(udg_MA_MagicCount[i])
            endif

            set tt=CreateTextTag()
            call SetTextTagText(tt,st,0.028)
            call SetTextTagPos(tt,GetUnitX(a),GetUnitY(a)+75,160)
            call SetTextTagColor(tt,100,180,255,255)
            call SetTextTagVisibility(tt,true)
            call SetTextTagVelocity(tt,0,0.03)
            call SetTextTagFadepoint(tt,0.25)
            call SetTextTagLifespan(tt,0.4)
            call SetTextTagPermanent(tt,false)
        endif
    endif

    set a=null
    set t=null
    return false
endfunction

function MA3_Actions takes nothing returns boolean
    local unit c=GetTriggerUnit()
    local unit d
    local integer i
    local integer ud=GetUnitUserData(c)

    if GetSpellAbilityId() == MA_DMGBonusAbilityInfo() and udg_MA_MagicCount[ud] > 0 then
        set i=udg_MA_MagicCount[ud]
        set d=CreateUnit(GetOwningPlayer(c),MA_Dummy(),GetUnitX(c),GetUnitY(c),0)
        call UnitAddAbility(d,MA_DamageAbility())
        call SetUnitAbilityLevel(d,MA_DamageAbility(),i)
        call IssueTargetOrder(d,MA_DamageOrder(),c)
        call UnitApplyTimedLife(d,'BTLF',0.5)
        set udg_MA_MagicCount[ud]=0
    elseif GetSpellAbilityId() == MA_SPDBonusAbilityInfo() and udg_MA_MagicCount[ud] > 0 then
        set i=udg_MA_MagicCount[ud]
        set d=CreateUnit(GetOwningPlayer(c),MA_Dummy(),GetUnitX(c),GetUnitY(c),0)
        call UnitAddAbility(d,MA_SpeedAbility())
        call SetUnitAbilityLevel(d,MA_SpeedAbility(),i)
        call IssueTargetOrder(d,MA_SpeedOrder(),c)
        call UnitApplyTimedLife(d,'BTLF',0.5)
        set udg_MA_MagicCount[ud]=0
    endif

    set c=null
    set d=null
    return false
endfunction

function InitTrig_MA takes nothing returns nothing
    local trigger t=CreateTrigger()
    local unit u=CreateUnit(Player(0),MA_Dummy(),0,0,0)
    call UnitAddAbility(u,MA_DMGBonusAbilityInfo())
    call UnitAddAbility(u,MA_SPDBonusAbilityInfo())
    call UnitAddAbility(u,MA_SpeedAbility())
    call UnitAddAbility(u,MA_DamageAbility())
    call UnitApplyTimedLife(u,'BTLF',0.5)
    set u=null
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_HERO_SKILL)
    call TriggerAddCondition(t,Condition(function MA1_Actions))
    set t=CreateTrigger()
    call TriggerRegisterVariableEvent(t,"udg_DamageEvent",EQUAL,1.00)
    call TriggerAddCondition(t,Condition(function MA2_Actions))
    set t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function MA3_Actions))
    set t=null
endfunction

Also, here's a tip:
Your MA3_Actions function could be optimized and cleaned to look like this:
JASS:
function MA3_Actions takes nothing returns boolean
    local unit caster = GetTriggerUnit()
    local integer unitId = GetUnitUserData(caster)
    local integer abilityId
    local unit dummy
    
    if udg_MA_MagicCount[unitId] > 0 then
        set abilityId = GetSpellAbilityId()

        if abilityId == MA_DMGBonusAbilityInfo() then

            set dummy = CreateUnit(GetOwningPlayer(caster), MA_Dummy(), GetUnitX(caster), GetUnitY(caster), 0)
            call UnitAddAbility(dummy, MA_DamageAbility())
            call SetUnitAbilityLevel(dummy, MA_DamageAbility(), udg_MA_MagicCount[unitId])
            call IssueTargetOrder(dummy, MA_DamageOrder(), caster)
            call UnitApplyTimedLife(dummy, 'BTLF', 0.5)
            set udg_MA_MagicCount[unitId] = 0
            set dummy = null

        elseif abilityId == MA_SPDBonusAbilityInfo() then

            set dummy = CreateUnit(GetOwningPlayer(caster), MA_Dummy(), GetUnitX(caster), GetUnitY(caster), 0)
            call UnitAddAbility(dummy, MA_SpeedAbility())
            call SetUnitAbilityLevel(dummy, MA_SpeedAbility(), udg_MA_MagicCount[unitId])
            call IssueTargetOrder(dummy, MA_SpeedOrder(), caster)
            call UnitApplyTimedLife(dummy, 'BTLF', 0.5)
            set udg_MA_MagicCount[unitId] = 0
            set dummy = null

        endif

    endif

    set caster = null
    return false
endfunction

edit
I just noticed the lack of spacing on both sides of the and keyword :|
I'm surprised that even compiled :|

I fixed the code in this post.
 
Level 10
Joined
Sep 19, 2011
Messages
527
udg_DamageTypeDOT > 0 and IsUnitEnemy(a,GetOwningPlayer(t)) and GetUnitAbilityLevel(a,MA_HeroAbility()) > 0 and not IsUnitType(t,UNIT_TYPE_DEAD) and not IsUnitType(t,UNIT_TYPE_STRUCTURE) and not IsUnitType(t,UNIT_TYPE_MAGIC_IMMUNE)

Mmm, I think that this filter should be configurable.

Instead of using UserData, you can use hashtables :). In some maps, the people use IndexUnit (bad choise by the way) and this can result in a bug.

In the ability's preload:

call UnitApplyTimedLife(u,'BTLF',0.5)

You don't need these, just remove it >:).

Good job ;).

Greetings.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
- Use http://www.hiveworkshop.com/forums/...-0-a-212660/?prev=d=list&r=20&u=Magtheridon96 by Magtheridon, its for GUI and jass...
- You need to reset the MagicCount if it's getting debuffed, not only when it's used...
- Put the "set t = null" in the set tt = CreateTextTag() line...

EDIT:
the people use IndexUnit (bad choise by the way) and this can result in a bug
UnitIndexer is faster than hashtables, but if you're talking about people making manual indexing of a unit then my bad :)...
 
Top