Spell needs to refer to caster somehow

Embrace_It

New Member
Reaction score
9
I had an idea for a spell where the enemy is afflicted with a debuff for x seconds, and during this period, will take damage if the afflicted unit tries to cast a spell.

I already made the spell but there is one problem...
The other trigger (that is responsible for damaging units) needs to refer to the source of the debuff somehow, so the original caster can get the kill. One solution that comes to mind is an array containing casters or the structs and then use GetUnitUserData(...) to index it.

Does anyone have other ideas?

CODE:
JASS:

scope CorruptMana initializer Init

//  -------------
// | START SETUP |
//  -------------
globals
    private integer Total = 0
    private trigger buffchecker = CreateTrigger()
    
    // Constants
    private constant integer ABILITY_CODE = 'A00N'
    private constant integer DUMMY_CODE   = 'A00P'
    private constant integer BUFF_CODE    = 'B004'
    private constant integer DUMMY_UNIT   = 'h00G'
    private constant string CAST_EFFECT    = "Abilities\\Spells\\Items\\AIvi\\AIviTarget.mdl"
    private constant string DAMAGE_EFFECT1 = "ShadowTrap.mdx"
    private constant string DAMAGE_EFFECT2 = "Abilities\\Weapons\\Bolt\\BoltImpact.mdl"
endglobals

private function DurationPerLevel takes integer lvl returns real
    return I2R( ((lvl - 1) * 6) + 20)
endfunction

private function FeedbackPerLevel takes integer lvl returns real
    return I2R( ((lvl - 1) * 15) + 35)
endfunction
//  -----------
// | END SETUP |
//  -----------

private struct Data
    unit source
    unit target
    real fbd // Feedback damage
    

    static method create takes unit source, unit target, real fbd returns Data
        local Data d = Data.allocate()
        
        set d.source = source
        set d.target = target
        set d.fbd = fbd
        
        return d
    endmethod

    method onDestroy takes nothing returns nothing
        set .source = null
        set .target = null
    endmethod
endstruct

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

private function UnitHasBuff takes nothing returns boolean
    return GetUnitAbilityLevel(GetTriggerUnit(), BUFF_CODE) > 0
endfunction

private function Update takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Data d = Data(GetTimerData(t))

    call d.destroy()
    set Total = Total - 1
    if (Total == 0) then
        call DisableTrigger(buffchecker)
    endif
    
    call ReleaseTimer(t)
    set t = null
endfunction

private function AddBuff takes nothing returns nothing
    local unit source = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit dummy
    local integer lvl = GetUnitAbilityLevel(source, ABILITY_CODE)
    local real fbd = FeedbackPerLevel(lvl)
    local Data d
    local timer t
    
    
    call DestroyEffect(AddSpecialEffectTarget(CAST_EFFECT, target, "chest"))
    set d = Data.create(source, target, fbd)
    set t = NewTimer()
    call SetTimerData(t, integer(d))
    if (Total == 0) then
        call EnableTrigger(buffchecker)
    endif
    set Total = Total + 1
    call TimerStart(t, DurationPerLevel(lvl), false, function Update)    
    
    set source = null
    set target = null
    set dummy = null
endfunction

private function DamageUnit takes nothing returns nothing
    local unit target = GetTriggerUnit()
    local real x = GetUnitX(target)
    local real y = GetUnitY(target)
    
    call CreateFloatingDamagePos(50.0, x, y, DARK_MAGIC)
    call UnitDamageTarget(null, target, 50.0, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
    call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT1, target, "origin"))
    call DestroyEffect(AddSpecialEffectTarget(DAMAGE_EFFECT2, target, "chest"))
    
    set target = null
endfunction

private function Actions takes nothing returns nothing
    if not (GetUnitAbilityLevel(GetTriggerUnit(), BUFF_CODE) > 0) then
        call AddBuff()
    endif
endfunction

// Main function
private function Init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    
    call TriggerRegisterAnyUnitEventBJ(trig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(trig, Condition(function Conditions))
    call TriggerAddAction(trig, function Actions)
    
    call TriggerRegisterAnyUnitEventBJ(buffchecker, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(buffchecker, Condition(function UnitHasBuff))
    call TriggerAddAction(buffchecker, function DamageUnit)
    
    call DisableTrigger(buffchecker)
    
    set trig = null
endfunction

endscope
 
Reaction score
341
An indexing system would probably be the best solution.

Unless the other trigger is called instantly after, you can just store the unit into a global.

Post in the jass help next time.
 

Embrace_It

New Member
Reaction score
9
Thanks for the reply! I'll see what I can do with the indexing system then, since the global unit solution wont make it MUI (i think? :))

I'm pretty sure this IS the Jass Help section...

EDIT: I sat down...Thought hard about how the indexing system should work and bam! It has been solved! =)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      • Ghan
        Administrator - Servers are fun

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top