• 🏆 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!

How to make this spell MUI?

Status
Not open for further replies.
Level 3
Joined
Nov 26, 2009
Messages
35
  • Target Heal
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Test Ability (Neutral Hostile)
    • Actions
      • Custom script: local unit u
      • Custom script: local real r
      • Set VariableSet HoTHeal = (((Level of (Ability being cast) for (Casting unit)) x 10) + ((Intelligence of (Casting unit) (Include bonuses)) / 5))
      • Set VariableSet HoTTarget = (Target unit of ability being cast)
      • Custom script: set u = udg_HoTTarget
      • Custom script: set r = I2R(udg_HoTHeal)
      • For each (Integer A) from 1 to 250, do (Actions)
        • Loop - Actions
          • Custom script: call UnitDamageTargetBJ( GetSpellAbilityUnit(), u, r, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
          • Wait 0.10 game-time seconds
      • Custom script: set u = null
      • Custom script: set r = 0
 
Level 6
Joined
Dec 31, 2017
Messages
138
It's okay as in is.

I can see 3 issues however:

1) You might want to check if target is dead;

2) Waits are not aссurate;

3) Last but not least: this approach creates a lot of running trigger instances, which is not good in terms of performance.

Dynamic Indexing, that @Devalut posted the link to, can help to rid off these issues.
 
Level 12
Joined
Feb 5, 2018
Messages
521
It is fairly easy to create a heal over time spell with hashtables.

Hashtables and MUI

It is presented in this tutorial.
You can choose this, dynamic indexing or the suggestion from uncle. All three methods should work, since using locals will make the spell MUI anyways.
 
Level 3
Joined
Nov 26, 2009
Messages
35
Drop the Loop and use a timer.
Can you make a example from what i did how to use it with timer? It seems that im 2stupid to understand :C
I really want to get used to locals but i can't find a normal guide for that on my language(i don't know english on level where i can learn from guides).
It's okay as in is.

I can see 3 issues however:

1) You might want to check if target is dead;

2) Waits are not aссurate;

3) Last but not least: this approach creates a lot of running trigger instances, which is not good in terms of performance.

Well the main issue is that other instances are stopped when first one finishes.
 
Well the main issue is that other instances are stopped when first one finishes.
That happens cause the loop iteration integer variables are not locals. But Globals, Therefore each active trigger instance will increase the same Loop counter.
bj_forLoopAIndex
bj_forLoopAIndexEnd
 
Level 3
Joined
Nov 26, 2009
Messages
35
Well, i created this, still with loop and waits, but it seems working as inteded(tesed on five units and all had the same health after effect ends, now need remove leaks and add condition for unit state(alive/dead) but this is easy to do)
Code:
function Trig_Target_Heal_JASS_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A00C' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Target_Heal_JASS_Actions takes nothing returns nothing
    local real healing
    local unit target
    local unit caster
    local integer cycle
    local effect healeffect
    set udg_HoTCaster = GetSpellAbilityUnit()
    set udg_HoTTarget = GetSpellTargetUnit()
    set udg_HoTHeal = ( ( ( I2R(GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetSpellAbilityUnit())) * 0.05 ) * I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetSpellAbilityUnit(), true)) ) + ( I2R(GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetSpellAbilityUnit())) * 15.00 ) )
    set caster = udg_HoTCaster
    set target= udg_HoTTarget
    set healing = udg_HoTHeal
    set cycle = 1
    loop
        exitwhen cycle > 200
        if ( not ( cycle <= 0 ) ) then
            call AddSpecialEffectTargetUnitBJ( "overhead", target, "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl" )
            set healeffect = GetLastCreatedEffectBJ()
            call SetUnitLifeBJ( target,( GetUnitStateSwap(UNIT_STATE_LIFE, target)+ healing) )
            call TriggerSleepAction( 0.50 )
            call DestroyEffectBJ (healeffect)
        set cycle = (cycle + 1)
        else
            call DoNothing(  )
        endif
    endloop
endfunction

//===========================================================================
function InitTrig_Target_Heal_JASS takes nothing returns nothing
    set gg_trg_Target_Heal_JASS = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Target_Heal_JASS, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Target_Heal_JASS, Condition( function Trig_Target_Heal_JASS_Conditions ) )
    call TriggerAddAction( gg_trg_Target_Heal_JASS, function Trig_Target_Heal_JASS_Actions )
endfunction
 
Somehow sounds like you just want the nightelf spell that heals over time, but scaling with int. Since V1.31.1 one can change most data of abilities for only one unit, even right before the casting inside somehting like starts the effect of an ability event.
  • Unit SpellEffect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Regeneration Spell (Neutral Hostile)
    • Actions
      • Ability - Set Ability: (Ability Casted)'s Real Level Field: Hit Points Gained ('Rej1') of Level: 0 to 9000.00
 
Level 3
Joined
Nov 26, 2009
Messages
35
Somehow sounds like you just want the nightelf spell that heals over time, but scaling with int.
Yeah.
Finally i created this abomination
Code:
function Trig_Target_Heal_JASS_Actions takes nothing returns nothing
    local real healing
    local unit target
    local unit caster
    local unit dummy
    local integer cycle
    local effect healeffect
    local location casterpoint
    local location targetpoint
    set udg_HoTCaster = GetSpellAbilityUnit()
    set udg_HoTTarget = GetSpellTargetUnit()
    set udg_HoTHeal = ( ( ( I2R(GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetSpellAbilityUnit())) * 0.05 ) * I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetSpellAbilityUnit(), true)) ) + ( I2R(GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetSpellAbilityUnit())) * 15.00 ) )
    set caster = udg_HoTCaster
    set target= udg_HoTTarget
    set healing = udg_HoTHeal
    set cycle = 1
    set casterpoint = GetUnitLoc(caster)
    set targetpoint = GetUnitLoc(target)
        if ( ( UnitHasBuffBJ(target, 'B002') == true) ) then
            call RemoveLocation(casterpoint)
            call RemoveLocation(targetpoint)
            set caster = null
            set target= null
            set healing = 0
        return
        endif
    call CreateNUnitsAtLocFacingLocBJ( 1, 'h00A', GetOwningPlayer(caster), casterpoint, targetpoint )
    set dummy = GetLastCreatedUnit()
    call IssueTargetOrderBJ( dummy, "rejuvination", target)
    loop
        exitwhen cycle > 100
            if ( GetBooleanAnd (IsUnitAliveBJ(target) == true, UnitHasBuffBJ(target, 'B002') == true)) then
            call AddSpecialEffectTargetUnitBJ( "chest", target, "Abilities\\Spells\\Human\\Heal\\HealTarget.mdl" )
            set healeffect = GetLastCreatedEffectBJ()
            call SetUnitLifeBJ( target,( GetUnitStateSwap(UNIT_STATE_LIFE, target)+ healing) )
            call PolledWait( 0.5)
            call DestroyEffectBJ (healeffect)
        set cycle = (cycle + 1)
        else
            set cycle = 100
        endif
    endloop
    call RemoveUnit( dummy )
    call RemoveLocation(casterpoint)
    call RemoveLocation(targetpoint)
    set caster = null
    set target= null
    set healing = 0
endfunction
 
Status
Not open for further replies.
Top