New spell, and more trouble

Komaqtion

You can change this now in User CP.
Reaction score
469
I'll try :D But I'm not in there so often :(

Nobody else knows anything about this ?? :S
 

Jesus4Lyf

Good Idea™
Reaction score
397
Ah, this is a question for me to address.

Two options. Choose a period of 0.25 seconds, or change KT's period threshold (one of KT's constants) to 0.51 (from the default 0.3). I recommend using a period of 0.25 (but I haven't actually looked at the spell).

That will make the spell's timer things fire exactly together for every instance. It's a perk of how KT works. :)

Hope that's the effect you're looking for.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Do you mean the damage period or the period of which the effects are created ?

EDIT: Ok, just noticed that it is damaging each second, but since the effects are so close to eachother, they pick units which the effect next to them has already damaged.
This makes it look like they get damaged like each 0.1 seconds or something, because there is a slight delay between each damage.

So what I want now, is how to make a unit onlu be able to get damaged bu one effect :S

I've tried to add a unit group check, but haven't really figured out when to clear ot, so that the unit can get damaged next period (the next second I mean).
I tried putting the GroupClear action here:

JASS:
private function Damage_Period takes nothing returns boolean
    local Dam dd = KT_GetData()
    if dd.tick > 0 then
        set TempStruct = dd
        call GroupEnumUnitsInRange(g, dd.x, dd.y, Range(),Filterz)
        call ForGroup(g,function Deal_Damage)
        set dd.tick = dd.tick - 1
        call GroupClear(gr)
        return false
    else
        call dd.destroy()
    endif
    return true
endfunction


But didn't work :(

Any ideas ?



EDIT: I've now tried to implement a Knockback for units that the caster runs into, but of course Iäve run into some trouble XD

I'm using kenny!'s knockback system, just because no systems are needed. (If you suggest otherwise, please tell me !)

So here's what I've got so far:

JASS:
scope SearingDash initializer init

globals
    private constant integer ABIL_ID = 'A000' // The rawcode of the ability!
    private constant integer CARGO_ID = 'Abun' // The rawcode of the "Cargo Hold" ability!
    
    private constant string EFFECT_1 = "Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl"
    private constant string ATTACH_POINT = "origin"
    private constant real PERIOD = .1 //Time between effects being created.
    private constant real DAMAGE_PERIOD = 1. // How often the effects deal damage.
    private constant real EFFECT_DURATION = 1.5 // How long each effect lasts.
    
    private constant string DMG_EFFECT = "Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl"
    private constant string ATTACH_POINT2 = "chest"
    
    private constant real DURATION = 5 //How long the spell lasts
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  // Same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
    
    private constant real DMG_FACTOR = 1. // An easy way of changing the damage!
    private constant real RNG_FACTOR = 1. // An easy way of changing the damage range!
    
    private constant real TRANSPARENCY = 45. // In %, how transparent the caster becomes!
    private constant real SCALE = 1.65 // How much bigger the caster becomes when casting this spell. (Has to end with 0 or 5!)
endglobals

globals
    private group g = CreateGroup()
    private group gr = CreateGroup()
    private integer TempStruct
    private filterfunc Filterz
endglobals

private struct Data
    real speed
    real time = 1
    unit caster
    player owner
    integer lvl
    //Moving checksum
    real origX
    real origY
    real x
    real y
    real angle
    real scale = 1.
    
    static method create takes unit u returns Data
        local Data d = Data.allocate()
        set d.caster = u
        set d.owner = GetOwningPlayer(d.caster)
        set d.speed = GetUnitMoveSpeed(u)
        set d.lvl = GetUnitAbilityLevel(d.caster, ABIL_ID)
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call SetUnitMoveSpeed(.caster, .speed)
        call SetUnitPathing(.caster,true)
        call SetUnitVertexColor(.caster,255,255,255,255)
        call SetPlayerAbilityAvailable(.owner, ABIL_ID, true)
        call UnitRemoveAbility(.caster, CARGO_ID)
    endmethod
endstruct

private struct Dam
    unit caster
    player owner
    real x
    real y
    integer lv
    integer tick
endstruct

private function Damage takes nothing returns real
    return I2R(Dam(TempStruct).lv) * DMG_FACTOR * 50.
endfunction

private function Range takes nothing returns real
    return RNG_FACTOR * 100.
endfunction

private function Range_Big takes nothing returns real
    return RNG_FACTOR *150.
endfunction

private function Filters takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), Dam(TempStruct).owner) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Filters_Enum takes nothing returns boolean
    return GetWidgetLife(GetEnumUnit()) &gt; 0.405 and IsUnitEnemy(GetEnumUnit(), Dam(TempStruct).owner)
endfunction

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_ID
endfunction

private function Deal_Damage takes nothing returns nothing
    call UnitDamageTarget(Dam(TempStruct).caster, GetEnumUnit(), Damage(), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
    call DestroyEffect(AddSpecialEffectTarget(DMG_EFFECT, GetEnumUnit(), ATTACH_POINT2))
endfunction

private function Damage_Period takes nothing returns boolean
    local Dam dd = KT_GetData()
    if dd.tick &gt; 0 then
        set TempStruct = dd
        call GroupEnumUnitsInRange(g, dd.x, dd.y, Range(),Filterz)
        call ForGroup(g,function Deal_Damage)
        set dd.tick = dd.tick - 1
        return false
    else
        call dd.destroy()
    endif
    return true
endfunction

private function Descaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &gt; 1. then
        set d.scale = d.scale - 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Scaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &lt; SCALE then
        set d.scale = d.scale + 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Knockback takes nothing returns nothing
    local Dam d
    local unit u = GetEnumUnit()
    local real angle = bj_RADTODEG * Atan2(GetUnitY(u) - GetUnitY(d.caster), GetUnitX(u) - GetUnitX(d.caster))
    call BJDebugMsg(&quot;Hello!&quot;)
    if KBS_IsUnitSliding(u) then
        call KBS_StopUnitSliding(u)
    elseif Filters_Enum() then
        call KBS_BeginCommon(u,300,4,angle)
    endif
endfunction

private function Periodic takes nothing returns boolean
    local Data d = KT_GetData()
    local Dam dd
    if d.time &lt; DURATION - PERIOD then
        set d.time = d.time + PERIOD
        set dd = Dam.create()
        set dd.caster = d.caster
        set dd.owner = d.owner
        set dd.x = GetUnitX(d.caster)
        set dd.y = GetUnitY(d.caster)
        set dd.lv = d.lvl
        set dd.tick = R2I(EFFECT_DURATION / DAMAGE_PERIOD)
        call KT_Add(function Damage_Period, dd, DAMAGE_PERIOD)
        call TE_TimedEffect(AddSpecialEffect(EFFECT_1,dd.x,dd.y), EFFECT_DURATION)
        set d.angle = GetUnitFacing(d.caster)
        set d.x = d.origX - dd.x
        set d.y = d.origY - dd.y
        if (d.x * d.x + d.y * d.y) &gt; 20. then
            set d.x = dd.x + 5. * Cos(d.angle * 0.017453278)
            set d.y = dd.y + 5. * Sin(d.angle * 0.017453278)
            call SetUnitX(d.caster,d.x)
            call SetUnitY(d.caster,d.y)
            set d.origX = d.x
            set d.origY = d.y
        endif
        call GroupEnumUnitsInRange(gr, GetUnitX(d.caster), GetUnitY(d.caster), Range_Big(), Filterz)
        call ForGroup(g, function Knockback)
        return false
    else
        call d.destroy()
        call KT_Add( function Descaling, d, PERIOD)
        return true
    endif
endfunction

private function Spell takes nothing returns nothing
    local Data D = Data.create(GetTriggerUnit())
    call SetUnitPathing(D.caster,false)
    call SetUnitVertexColor(D.caster,255,255,255,R2I(255. * TRANSPARENCY / 100.))
    call UnitAddAbility(D.caster, CARGO_ID)
    call SetPlayerAbilityAvailable(D.owner, ABIL_ID, false)
    call KT_Add(function Periodic, D, PERIOD)
    call KT_Add(function Scaling, D, PERIOD)
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition (function Spell_Check))
    call TriggerAddAction(t, function Spell)
    set Filterz = Filter(function Filters)
endfunction
endscope


And as you can see, in the function "Knockback" I've added a debug msg, but it doesn't show :(

Any ideas to why the functions doesn't even run ?

Note: Also, I've removed the attempt to use a group to make the units get damages once, as I wanted help with before ... And that help is still needed :D
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Well, how should I initialize it ?? :S
And, does that stop the whole function ?
 

Komaqtion

You can change this now in User CP.
Reaction score
469
But what value ? It's a struct, so setting it to a regular integer/real/string or something won't do much :(
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Test it :

JASS:

scope SearingDash initializer init

globals
    private constant integer ABIL_ID = &#039;A000&#039; // The rawcode of the ability!
    private constant integer CARGO_ID = &#039;Abun&#039; // The rawcode of the &quot;Cargo Hold&quot; ability!
    
    private constant string EFFECT_1 = &quot;Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl&quot;
    private constant string ATTACH_POINT = &quot;origin&quot;
    private constant real PERIOD = .1 //Time between effects being created.
    private constant real DAMAGE_PERIOD = 1. // How often the effects deal damage.
    private constant real EFFECT_DURATION = 1.5 // How long each effect lasts.
    
    private constant string DMG_EFFECT = &quot;Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl&quot;
    private constant string ATTACH_POINT2 = &quot;chest&quot;
    
    private constant real DURATION = 5 //How long the spell lasts
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  // Same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
    
    private constant real DMG_FACTOR = 1. // An easy way of changing the damage!
    private constant real RNG_FACTOR = 1. // An easy way of changing the damage range!
    
    private constant real TRANSPARENCY = 45. // In %, how transparent the caster becomes!
    private constant real SCALE = 1.65 // How much bigger the caster becomes when casting this spell. (Has to end with 0 or 5!)
endglobals

globals
    private group g = CreateGroup()
    private group gr = CreateGroup()
    private integer TempStruct
    private filterfunc Filterz
endglobals

private struct Data
    real speed
    real time = 1
    unit caster
    player owner
    integer lvl
    //Moving checksum
    real origX
    real origY
    real x
    real y
    real angle
    real scale = 1.
    
    static method create takes unit u returns Data
        local Data d = Data.allocate()
        set d.caster = u
        set d.owner = GetOwningPlayer(d.caster)
        set d.speed = GetUnitMoveSpeed(u)
        set d.lvl = GetUnitAbilityLevel(d.caster, ABIL_ID)
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call SetUnitMoveSpeed(.caster, .speed)
        call SetUnitPathing(.caster,true)
        call SetUnitVertexColor(.caster,255,255,255,255)
        call SetPlayerAbilityAvailable(.owner, ABIL_ID, true)
        call UnitRemoveAbility(.caster, CARGO_ID)
    endmethod
endstruct

private struct Dam
    unit caster
    player owner
    real x
    real y
    integer lv
    integer tick
endstruct

private function Damage takes nothing returns real
    return I2R(Dam(TempStruct).lv) * DMG_FACTOR * 50.
endfunction

private function Range takes nothing returns real
    return RNG_FACTOR * 100.
endfunction

private function Range_Big takes nothing returns real
    return RNG_FACTOR *150.
endfunction

private function Filters takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), Dam(TempStruct).owner) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Filters_Enum takes nothing returns boolean
    return GetWidgetLife(GetEnumUnit()) &gt; 0.405 and IsUnitEnemy(GetEnumUnit(), Dam(TempStruct).owner)
endfunction

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_ID
endfunction

private function Deal_Damage takes nothing returns nothing
    call UnitDamageTarget(Dam(TempStruct).caster, GetEnumUnit(), Damage(), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
    call DestroyEffect(AddSpecialEffectTarget(DMG_EFFECT, GetEnumUnit(), ATTACH_POINT2))
endfunction

private function Damage_Period takes nothing returns boolean
    local Dam dd = KT_GetData()
    if dd.tick &gt; 0 then
        set TempStruct = dd
        call GroupEnumUnitsInRange(g, dd.x, dd.y, Range(),Filterz)
        call ForGroup(g,function Deal_Damage)
        set dd.tick = dd.tick - 1
        return false
    else
        call dd.destroy()
    endif
    return true
endfunction

private function Descaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &gt; 1. then
        set d.scale = d.scale - 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Scaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &lt; SCALE then
        set d.scale = d.scale + 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Knockback takes nothing returns nothing
    local unit u = GetEnumUnit()
    local real angle = 57.2958 * Atan2(GetUnitY(u) - GetUnitY(Data(TempStruct).caster), GetUnitX(u) - GetUnitX(Data(TempStruct).caster))
    call BJDebugMsg(&quot;Hello!&quot;)
    if KBS_IsUnitSliding(u) then
        call KBS_StopUnitSliding(u)
    elseif Filters_Enum() then
        call KBS_BeginCommon(u,300,4,angle)
    endif
endfunction

private function Periodic takes nothing returns boolean
    local Data d = KT_GetData()
    local Dam dd
    if d.time &lt; DURATION - PERIOD then
        set d.time = d.time + PERIOD
        set dd = Dam.create()
        set dd.caster = d.caster
        set dd.owner = d.owner
        set dd.x = GetUnitX(d.caster)
        set dd.y = GetUnitY(d.caster)
        set dd.lv = d.lvl
        set dd.tick = R2I(EFFECT_DURATION / DAMAGE_PERIOD)
        call KT_Add(function Damage_Period, dd, DAMAGE_PERIOD)
        call TE_TimedEffect(AddSpecialEffect(EFFECT_1,dd.x,dd.y), EFFECT_DURATION)
        set d.angle = GetUnitFacing(d.caster)
        set d.x = d.origX - dd.x
        set d.y = d.origY - dd.y
        if (d.x * d.x + d.y * d.y) &gt; 20. then
            set d.x = dd.x + 5. * Cos(d.angle * 0.0175)
            set d.y = dd.y + 5. * Sin(d.angle * 0.0175)
            call SetUnitX(d.caster,d.x)
            call SetUnitY(d.caster,d.y)
            set d.origX = d.x
            set d.origY = d.y
        endif
        set TempStruct = d
        call GroupEnumUnitsInRange(gr, GetUnitX(d.caster), GetUnitY(d.caster), Range_Big(), Filterz)
        call ForGroup(g, function Knockback)
        return false
    else
        call d.destroy()
        call KT_Add( function Descaling, d, PERIOD)
        return true
    endif
endfunction

private function Spell takes nothing returns nothing
    local Data D = Data.create(GetTriggerUnit())
    call SetUnitPathing(D.caster,false)
    call SetUnitVertexColor(D.caster,255,255,255,R2I(255. * TRANSPARENCY / 100.))
    call UnitAddAbility(D.caster, CARGO_ID)
    call SetPlayerAbilityAvailable(D.owner, ABIL_ID, false)
    call KT_Add(function Periodic, D, PERIOD)
    call KT_Add(function Scaling, D, PERIOD)
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition (function Spell_Check))
    call TriggerAddAction(t, function Spell)
    set Filterz = Filter(function Filters)
endfunction
endscope
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Ok, that didn't help either the knockback, or the "damage each unit only once each second" things :(

Now like 1 unit gets knockbacked quite randomly, and the damage is still more times on each unit :(

EDIT: Ok, just figured out that now the units get knockbacked (Yay), but not when the caster reaches them, but at the flames and periodicly, each second :S
Hope you understand what I'm saying XD

Any ideas ?
 

Komaqtion

You can change this now in User CP.
Reaction score
469
BumP !

And I have now figured out how to make the fires only damage once, and each second... Here's my code:

JASS:
scope SearingDash initializer init

globals
    private constant integer ABIL_ID = &#039;A000&#039; // The rawcode of the ability!
    private constant integer CARGO_ID = &#039;Abun&#039; // The rawcode of the &quot;Cargo Hold&quot; ability!
    
    private constant string EFFECT_1 = &quot;Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl&quot;
    private constant string ATTACH_POINT = &quot;origin&quot;
    private constant real PERIOD = .1 //Time between effects being created.
    private constant real DAMAGE_PERIOD = 1. // How often the effects deal damage.
    private constant real EFFECT_DURATION = 1.5 // How long each effect lasts.
    
    private constant string DMG_EFFECT = &quot;Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl&quot;
    private constant string ATTACH_POINT2 = &quot;chest&quot;
    
    private constant real DURATION = 5 //How long the spell lasts
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  // Same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
    
    private constant real DMG_FACTOR = 1. // An easy way of changing the damage!
    private constant real RNG_FACTOR = 1. // An easy way of changing the damage range!
    
    private constant real TRANSPARENCY = 45. // In %, how transparent the caster becomes!
    private constant real SCALE = 1.65 // How much bigger the caster becomes when casting this spell. (Has to end with 0 or 5!)
endglobals

globals
    private group g = CreateGroup()
    private group gr = CreateGroup()
    private integer TempStruct
    private filterfunc Filterz
    private real tick = 0
endglobals

private struct Data
    real speed
    real time = 1
    unit caster
    player owner
    integer lvl
    //Moving checksum
    real origX
    real origY
    real x
    real y
    real angle
    real scale = 1.
    
    static method create takes unit u returns Data
        local Data d = Data.allocate()
        set d.caster = u
        set d.owner = GetOwningPlayer(d.caster)
        set d.speed = GetUnitMoveSpeed(u)
        set d.lvl = GetUnitAbilityLevel(d.caster, ABIL_ID)
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call SetUnitMoveSpeed(.caster, .speed)
        call SetUnitPathing(.caster,true)
        call SetUnitVertexColor(.caster,255,255,255,255)
        call SetPlayerAbilityAvailable(.owner, ABIL_ID, true)
        call UnitRemoveAbility(.caster, CARGO_ID)
    endmethod
endstruct

private struct Dam
    unit caster
    player owner
    real x
    real y
    integer lv
    integer tick
endstruct

private function Damage takes nothing returns real
    return I2R(Dam(TempStruct).lv) * DMG_FACTOR * 50.
endfunction

private function Range takes nothing returns real
    return RNG_FACTOR * 100.
endfunction

private function Range_Big takes nothing returns real
    return RNG_FACTOR *150.
endfunction

private function Filters takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), Dam(TempStruct).owner) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Filters_Enum takes nothing returns boolean
    return GetWidgetLife(GetEnumUnit()) &gt; 0.405 and IsUnitEnemy(GetEnumUnit(), Dam(TempStruct).owner)
endfunction

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_ID
endfunction

private function Deal_Damage takes nothing returns nothing
    call UnitDamageTarget(Dam(TempStruct).caster, GetEnumUnit(), Damage(), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
    call DestroyEffect(AddSpecialEffectTarget(DMG_EFFECT, GetEnumUnit(), ATTACH_POINT2))
endfunction

private function Damage_Period takes nothing returns boolean
    local Dam dd = KT_GetData()
    set tick = tick + PERIOD
    if dd.tick &gt; 1 and (tick == 1. or tick == 2. or tick == 3. or tick == 4. or tick == 5.) then
        set TempStruct = dd
        call GroupEnumUnitsInRange(g, dd.x, dd.y, Range(),Filterz)
        call ForGroup(g,function Deal_Damage)
        set dd.tick = dd.tick - 1
        return false
    else
        call dd.destroy()
    endif
    return true
endfunction

private function Descaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &gt; 1. then
        set d.scale = d.scale - 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Scaling takes nothing returns boolean
    local Data d = KT_GetData()
    if d.scale &lt; SCALE then
        set d.scale = d.scale + 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        return false
    else
        return true
    endif
endfunction

private function Knockback takes nothing returns nothing
    local unit u = GetEnumUnit()
    local real angle = 57.2958 * Atan2(GetUnitY(u) - GetUnitY(Data(TempStruct).caster), GetUnitX(u) - GetUnitX(Data(TempStruct).caster))
    if KBS_IsUnitSliding(u) == false and Filters_Enum() then
        call KBS_BeginCommon(u,300,4,angle)
    endif
endfunction

private function Periodic takes nothing returns boolean
    local Data d = KT_GetData()
    local Dam dd
    if d.time &lt; DURATION - PERIOD then
        set d.time = d.time + PERIOD
        set dd = Dam.create()
        set dd.caster = d.caster
        set dd.owner = d.owner
        set dd.x = GetUnitX(d.caster)
        set dd.y = GetUnitY(d.caster)
        set dd.lv = d.lvl
        set dd.tick = R2I(EFFECT_DURATION / DAMAGE_PERIOD)
        call KT_Add(function Damage_Period, dd, DAMAGE_PERIOD)
        call TE_TimedEffect(AddSpecialEffect(EFFECT_1,dd.x,dd.y), EFFECT_DURATION)
        set d.angle = GetUnitFacing(d.caster)
        set d.x = d.origX - dd.x
        set d.y = d.origY - dd.y
        if (d.x * d.x + d.y * d.y) &gt; 20. then
            set d.x = dd.x + 5. * Cos(d.angle * 0.0175)
            set d.y = dd.y + 5. * Sin(d.angle * 0.0175)
            call SetUnitX(d.caster,d.x)
            call SetUnitY(d.caster,d.y)
            set d.origX = d.x
            set d.origY = d.y
        endif
        set TempStruct = d
        call GroupEnumUnitsInRange(gr, GetUnitX(d.caster), GetUnitY(d.caster), Range_Big(), Filterz)
        call ForGroup(g, function Knockback)
        call GroupClear(gr)
        return false
    else
        call d.destroy()
        call KT_Add( function Descaling, d, PERIOD)
        return true
    endif
endfunction

private function Spell takes nothing returns nothing
    local Data D = Data.create(GetTriggerUnit())
    call SetUnitPathing(D.caster,false)
    call SetUnitVertexColor(D.caster,255,255,255,R2I(255. * TRANSPARENCY / 100.))
    call UnitAddAbility(D.caster, CARGO_ID)
    call SetPlayerAbilityAvailable(D.owner, ABIL_ID, false)
    call KT_Add(function Periodic, D, PERIOD)
    call KT_Add(function Scaling, D, PERIOD)
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition (function Spell_Check))
    call TriggerAddAction(t, function Spell)
    set Filterz = Filter(function Filters)
endfunction
endscope


The only problem, still, is that it knockbackes the units around the fires and not around the caster :(

Any ideas on this mindblowing issue ??? :S
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Got everything working fine now, exept one thing ...

The spell keeps damaging units around the point where the fires were, once they've faded away :(

And also, that's when the spells starts to lag like @$%%... What could be wrong ? :S

JASS:
scope SearingDash initializer init

globals
    private constant integer ABIL_ID = &#039;A000&#039; // The rawcode of the ability!
    private constant integer CARGO_ID = &#039;Abun&#039; // The rawcode of the &quot;Cargo Hold&quot; ability!
    
    private constant string EFFECT_1 = &quot;Environment\\LargeBuildingFire\\LargeBuildingFire2.mdl&quot;
    private constant string ATTACH_POINT = &quot;origin&quot;
    private constant real PERIOD = .1 //Time between effects being created.
    private constant real DAMAGE_PERIOD = 0.03125 // How often the effects deal damage.
    private constant real EFFECT_DURATION = 1.5 // How long each effect lasts.
    
    private constant string DMG_EFFECT = &quot;Abilities\\Spells\\Items\\AIfb\\AIfbSpecialArt.mdl&quot;
    private constant string ATTACH_POINT2 = &quot;chest&quot;
    
    private constant real DURATION = 5. //How long the spell lasts
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  // Same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS// And same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />
    
    private constant real DMG_FACTOR = 1. // An easy way of changing the damage!
    private constant real RNG_FACTOR = 1. // An easy way of changing the damage range!
    
    private constant real TRANSPARENCY = 45. // In %, how transparent the caster becomes!
    private constant real SCALE = 1.65 // How much bigger the caster becomes when casting this spell. (Has to end with 0 or 5!)
    
    private constant boolean KNOCKBACK = true // Wether it should knockback units or not!
    private constant real DISTANCE = 200 // How far the get &quot;knockbacked&quot;.
    private constant real SPEED = 1 // How long the knockback takes.
    
    private constant boolean EXTRA_MOVEMENT = true // If the caster should have movement-speed above 522.
    private constant real EXTRA_MOVE_SPEED = 7.5 // How far the caster is moves each PERIOD... Increased movement-speed above 522 !
    private constant real MOVE_SPEED = 522. // How fast the caster should move if EXTRA_MOVEMENT = false !
    private constant real MOVE_PERIOD = 0.03125
    
endglobals

globals
    private group g = CreateGroup()
    private group gr = CreateGroup()
    private integer TempStruct
    private filterfunc Filterz
    private real tick = 0
endglobals

private struct Data
    real speed
    real time = 1
    unit caster
    player owner
    integer lvl
    //Moving checksum
    real origX
    real origY
    real x
    real y
    real angle
    real scale = 1.
    boolean on
    
    static method create takes unit u returns Data
        local Data d = Data.allocate()
        set d.caster = u
        set d.owner = GetOwningPlayer(d.caster)
        set d.speed = GetUnitMoveSpeed(u)
        set d.lvl = GetUnitAbilityLevel(d.caster, ABIL_ID)
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        if EXTRA_MOVEMENT == false then
            call SetUnitMoveSpeed(.caster, .speed)
        endif
        call SetUnitPathing(.caster,true)
        call SetUnitVertexColor(.caster,255,255,255,255)
        call SetPlayerAbilityAvailable(.owner, ABIL_ID, true)
        call UnitRemoveAbility(.caster, CARGO_ID)
        set .on = false
    endmethod
endstruct

private struct Dam
    unit caster
    player owner
    real x
    real y
    integer lv
    real tick
endstruct

private function Damage takes nothing returns real
    return I2R(Dam(TempStruct).lv) * DMG_FACTOR * 1.171875
endfunction

private function Range takes nothing returns real
    return RNG_FACTOR * 100.
endfunction

private function Range_Big takes nothing returns real
    return RNG_FACTOR *150.
endfunction

private function Filters takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), Dam(TempStruct).owner) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Filters_Enum takes nothing returns boolean
    return GetWidgetLife(GetEnumUnit()) &gt; 0.405 and IsUnitEnemy(GetEnumUnit(), Dam(TempStruct).owner)
endfunction

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == ABIL_ID
endfunction

private function Deal_Damage takes nothing returns nothing
    call UnitDamageTarget(Dam(TempStruct).caster, GetEnumUnit(), Damage(), true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
    call DestroyEffect(AddSpecialEffectTarget(DMG_EFFECT, GetEnumUnit(), ATTACH_POINT2))
    call BJDebugMsg(&quot;Damage!&quot;)
endfunction

private function Damage_Period takes nothing returns boolean
    local Dam dd = KT_GetData()
    local boolean b
    if dd.tick &gt; 0 then
        set TempStruct = dd
        call GroupEnumUnitsInRange(g, dd.x, dd.y, Range(),Filterz)
        if FirstOfGroup(g) != null then
            call ForGroup(g,function Deal_Damage)
            set dd.tick = dd.tick - DAMAGE_PERIOD
        endif
        set b = false
    else
        set b = true
        call dd.destroy()
    endif
    return b
endfunction

private function Descaling takes nothing returns boolean
    local Data d = KT_GetData()
    local boolean b
    if d.scale &gt; 1. then
        set d.scale = d.scale - 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)
        set b = false
    else
        set b = true
    endif
    return b
endfunction

private function Scaling takes nothing returns boolean
    local Data d = KT_GetData()
    local boolean b
    if d.scale &lt; SCALE then
        set d.scale = d.scale + 0.05
        call SetUnitScale(d.caster, d.scale, d.scale, d.scale)        
        set b = false
    else
        set b = true
    endif
    return b
endfunction

private function Movement takes nothing returns boolean
    local Data d = KT_GetData()
    local Dam dd = TempStruct
    local boolean b
    if d.on == true then
        set dd.caster = d.caster
        set dd.x = GetUnitX(d.caster)
        set dd.y = GetUnitY(d.caster)
        set d.angle = GetUnitFacing(d.caster)
        set d.x = d.origX - dd.x
        set d.y = d.origY - dd.y
        if (d.x * d.x + d.y * d.y) &gt; 20. and EXTRA_MOVEMENT == true then
            set d.x = dd.x + EXTRA_MOVE_SPEED * Cos(d.angle * 0.0175)
            set d.y = dd.y + EXTRA_MOVE_SPEED * Sin(d.angle * 0.0175)
            call SetUnitX(d.caster,d.x)
            call SetUnitY(d.caster,d.y)
            set d.origX = d.x
            set d.origY = d.y
       endif
        set b = false
    else
        set b = true
    endif
    return b
endfunction

private function Knockback takes nothing returns nothing
    local unit u = GetEnumUnit()
    local real angle = 57.2958 * Atan2(GetUnitY(u) - GetUnitY(Data(TempStruct).caster), GetUnitX(u) - GetUnitX(Data(TempStruct).caster))
    if KBS_IsUnitSliding(u) == false and Filters_Enum() and (angle &gt;= GetUnitFacing(Data(TempStruct).caster) + 25. or angle &lt;= GetUnitFacing(Data(TempStruct).caster) - 25.) then
        call KBS_BeginCommon(u,DISTANCE,SPEED,angle)
    elseif angle &gt;= GetUnitFacing(Data(TempStruct).caster) + 25. then
        set angle = angle + 25.
        call KBS_BeginCommon(u,DISTANCE,SPEED,angle)
    elseif angle &lt;= GetUnitFacing(Data(TempStruct).caster) - 25. then
        set angle = angle - 25.
        call KBS_BeginCommon(u,DISTANCE,SPEED,angle)
    endif
endfunction

private function Periodic takes nothing returns boolean
    local Data d = KT_GetData()
    local Dam dd
    local boolean b
    if d.time &lt;= DURATION - PERIOD then
        set d.time = d.time + PERIOD
        set dd = Dam.create()
        set dd.caster = d.caster
        set dd.owner = d.owner
        set dd.x = GetUnitX(d.caster)
        set dd.y = GetUnitY(d.caster)
        set dd.tick = R2I(EFFECT_DURATION / DAMAGE_PERIOD)
        call KT_Add(function Damage_Period, dd, DAMAGE_PERIOD)
        call TE_TimedEffect(AddSpecialEffect(EFFECT_1,dd.x,dd.y), EFFECT_DURATION)
        set d.angle = GetUnitFacing(d.caster)
        set TempStruct = d
        if KNOCKBACK == true then
            set TempStruct = d
            call GroupEnumUnitsInRange(gr, GetUnitX(d.caster), GetUnitY(d.caster), Range_Big(), Filterz)
            call ForGroup(gr, function Knockback)
            call GroupClear(gr)
        endif
        set b = false
    else
        call d.destroy()
        
        if SCALE != 1. then 
            call KT_Add(function Descaling, d, MOVE_PERIOD)
        endif
        set b = true
    endif
    return b
endfunction

private function Spell takes nothing returns nothing
    local Data D = Data.create(GetTriggerUnit())
    set D.on = true
    call SetUnitPathing(D.caster,false)
    call SetUnitVertexColor(D.caster,255,255,255,R2I(TRANSPARENCY * 2.55))
    call UnitAddAbility(D.caster, CARGO_ID)
    call SetPlayerAbilityAvailable(D.owner, ABIL_ID, false)
    if EXTRA_MOVEMENT == false then
        call SetUnitMoveSpeed(D.caster, MOVE_SPEED)
    else
        call KT_Add(function Movement,D, MOVE_PERIOD)
    endif
    call KT_Add(function Periodic, D, PERIOD)
    if SCALE != 1. then 
        call KT_Add(function Scaling, D, MOVE_PERIOD)
    endif
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t,EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition (function Spell_Check))
    call TriggerAddAction(t, function Spell)
    set Filterz = Filter(function Filters)
endfunction
endscope


And also, atm the spell is using 4, yes I said it, 4 systems !!!!
Is there any ways of decreasing that value ? :D

The systems used atm is:
KeyTimers 2
Knockback System (KBS)
BoundSentinel

And my very own:
TimedEffect
JASS:
library TE requires KT

private struct SFX
    effect sfx

    method onDestroy takes nothing returns nothing
        call DestroyEffect(.sfx)
    endmethod
endstruct

private function Destroy takes nothing returns boolean
    call SFX(KT_GetData()).destroy()
    return true
endfunction

public function TimedEffect takes effect e, real duration returns nothing
    local SFX d = SFX.create()
    set d.sfx = e
    call KT_Add(function Destroy,d,duration)
endfunction

endlibrary


This, as you may understand, seems like alot of systems for one spell XD

EDIT: OH, one more thing I need help with... I only want to knockback units which comes within like +-25 degrees of the casters facing :D
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Well, any other suggestions then ? :S

EDIT: Though this lag didn't happen a few days ago, and I was still using the knockback system then...
So don't think it's the system, but something in my code that screws things up XD
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top