HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell Issue

09-24-2006, 05:50 AM#1
ShadowDestroyer
I have Vexorian's spell system installed (latest version). I have designed a storm bolt ability, that pulls the targeted unit TOWARDS you.

Vile wrote the code for making the unit slide away from you, so I tried to reverse it, but it doesn't work. Instead, it SEEMS that it is randomly throwing the unit in a different direction each cast.

+Rep to the first person who finds and fixes my code.

Trigger:
Knockback Unit
Collapse Events
Unit - A unit Starts the effect of an ability
Collapse Conditions
(Ability being cast) Equal to Latch (RB)
Collapse Actions
-------- Set the angle manually to let the script know which direction should the unit get knocked back to. --------
Set casterloc = (Position of (Targeted unit))
Set targetloc = (Position of (Casting unit))
Set angle = (Angle from casterloc to targetloc)
-------- Remove leaks --------
Custom script: call RemoveLocation( udg_casterloc )
Custom script: call RemoveLocation( udg_targetloc )
-------- The level of the ability (storm bolt) --------
-------- 24 is the initial distance. Greater than 35 will cause the unit to move outside of cliffs... --------
Set dist = 24.00
-------- This is the break value. This is how much the distance is decreased in order to create a smooth break. --------
-------- Decreasing the break value causes greater range, increasing causes lesser, it all depends on the interval. --------
Set break = 1.00
-------- .04 is the interval --------
Custom script: call KnockbackFunctions_KBUnit(GetSpellTargetUnit(), udg_angle, udg_dist, udg_break, .04, udg_destroydestructables, true)

Collapse JASS:
//***************************************************************************
// Knockback Functions Configuration Section
//***************************************************************************

constant function KnockbackFunctions_WaterEffect takes nothing returns string
    return "MDX\\SlideWater.mdx" // The effect used when the unit slides on water
endfunction

constant function KnockbackFunctions_GroundEffect takes nothing returns string
    return "MDX\\Dust.mdx" // The effect used when the unit slides on the ground
endfunction

constant function KnockbackFunctions_Attachment takes nothing returns string
    return "right foot" // The part of the unit that the sliding effect is attached to
endfunction

constant function KnockbackFunctions_EffectCheckInterval takes nothing returns real
    return .33 // The interval of checking the unit's slide effects
endfunction

constant function KnockbackFunctions_GroupExcemptions takes nothing returns boolean
    return true
    // This function will excempt units who shouldn't be knocked back
    // like mechanical units or structures, or even flying units.
    // It's more relevant for the knockback group function.
    // Setting it to false will result mechanical, flying units, etc, to
    // be knocked back as well.
endfunction

constant function KnockbackFunctions_DestroyTreesOfTypes takes integer id returns boolean
    return id == 'ATtr' or id == 'ATtc'
    // The rawcode for the destructables to destroy while the unit is
    // being knocked back. These are examples of Ashenvale Tree Wall
    // and Ashenvale Cantropy Tree. To add more, go to the object
    // editor, click on the View tab, and select Display Values as
    // Raw codes, then in the destructables tab go and check your
    // destructable's raw code. Make sure you add an "or id == <rawcode"
    // in the above line, like in the example.
endfunction

//***************************************************************************
// Knockback Functions Code (Don't touch this unless you know jass)
//***************************************************************************

function KnockbackFunctions_UnitMoveExcemptions takes unit u returns boolean
    return not IsUnitType(u, ConvertUnitType(2)) and not IsUnitType(u, ConvertUnitType(3)) and not IsUnitType(u, ConvertUnitType(13)) and not IsUnitType(u, ConvertUnitType(15)) and not IsUnitType(u, ConvertUnitType(17)) and not IsUnitType(u, ConvertUnitType(18)) and GetUnitAbilityLevel(u, 'BEer') <= 0 and GetUnitAbilityLevel(u, 'Aloc') <= 0 and GetUnitAbilityLevel(u, 'Avul') <= 0 and GetUnitAbilityLevel(u, 'Bweb') <= 0
endfunction

function KnockbackFunctions_DestroySFXTimedTarget takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local string s = GetAttachmentTable(t)
    call DestroyEffect(GetTableEffect(s, "TempSFX"))
    call ClearTable(s)
    call DestroyTimer(t)
    //set t = null
endfunction

function KnockbackFunctions_AddSFXTimedTarget takes unit u, string modelpath, string attachment, real dur returns nothing
    local timer t = CreateTimer()
    local string s = GetAttachmentTable(t)
    call SetTableObject(s, "TempSFX", AddSpecialEffectTarget(modelpath, u, attachment))
    call TimerStart(t, dur, false, function KnockbackFunctions_DestroySFXTimedTarget)
    //set t = null
endfunction

function KnockbackFunctions_CheckSlideEffect_Child takes nothing returns nothing
    local timer tmr = GetExpiredTimer()
    local string s = GetAttachmentTable(tmr)
    local timer t = GetTableTimer(s, "Knockback_OriginalTimer")
    local unit u = GetTableUnit(s, "Knockback_CheckUnit")
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real check = KnockbackFunctions_EffectCheckInterval()
    local string eye = GetAttachmentTable(u)
    if GetTableBoolean(eye, "KnockbackFunctions_EffectBoolean") or GetTableBoolean(eye, "KnockbackFunctions_EffectBooleanGroup") then
        if IsTerrainPathable(x, y, ConvertPathingType(6)) then
            call KnockbackFunctions_AddSFXTimedTarget(u, KnockbackFunctions_GroundEffect(), KnockbackFunctions_Attachment(), check)
        elseif not IsTerrainPathable(GetUnitX(u), GetUnitY(u),ConvertPathingType(1)) then
            call KnockbackFunctions_AddSFXTimedTarget(u, KnockbackFunctions_WaterEffect(), KnockbackFunctions_Attachment(), check)
        endif
    else
        call ClearTable(s)
        call DestroyTimer(tmr)
    endif
    //set tmr = null
    //set t = null
    set u = null
endfunction

function KnockbackFunctions_CheckSlideEffect takes unit u, timer t returns nothing
    local timer tmr = CreateTimer()
    local string s = GetAttachmentTable(tmr)
    local real x = GetUnitX(u)
    local real y = GetUnitY(u)
    local real check = KnockbackFunctions_EffectCheckInterval()
    call SetTableObject(s, "Knockback_CheckUnit", u)
    call SetTableObject(s, "Knockback_OriginalTimer", t)
    call TimerStart(tmr, check, true, function KnockbackFunctions_CheckSlideEffect_Child)
    if IsTerrainPathable(x, y, ConvertPathingType(6)) then
        call KnockbackFunctions_AddSFXTimedTarget(u, KnockbackFunctions_GroundEffect(), KnockbackFunctions_Attachment(), check)
    elseif not IsTerrainPathable(GetUnitX(u), GetUnitY(u),ConvertPathingType(1)) then
        call KnockbackFunctions_AddSFXTimedTarget(u, KnockbackFunctions_WaterEffect(), KnockbackFunctions_Attachment(), check)
    endif
    //set tmr = null
endfunction

function KnockbackFunctions_DestroyDestructables takes nothing returns nothing
    local destructable d = GetEnumDestructable()
    local integer id = GetDestructableTypeId(d)
    if KnockbackFunctions_DestroyTreesOfTypes(id) then
        call KillDestructable(d)
    endif
    set d = null
endfunction

function KnockbackFunctions_KBGroupEffect takes nothing returns nothing
    local timer tmr = GetExpiredTimer()
    local string s = GetAttachmentTable(tmr)
    local unit t = GetEnumUnit()
    local real x1 = GetTableReal(s, "KnockbackFunctions_GroupX")
    local real y1 = GetTableReal(s, "KnockbackFunctions_GroupY")
    local real x2 = GetUnitX(t)
    local real y2 = GetUnitY(t)
    local real dist = GetTableReal(s, "KnockbackFunctions_Distance")
    local real a
    local real x
    local real y
    local rect r
    if GetTableBoolean(s, "KnockbackFunctions_Out") then
        set a = 57.29582*Atan2(y2-y1, x2-x1)
    else
        set a = 57.29582*Atan2(y1-y2, x1-x2)
    endif
    set x = x2+dist*Cos(a*.017453)
    set y = y2+dist*Sin(a*.017453)
    if GetTableBoolean(s, "KnockbackFunctions_DestroyDestructables") then
        set r = Rect(x-128, y-128, x+128, y+128)
        call EnumDestructablesInRect(r, null, function KnockbackFunctions_DestroyDestructables)
        call RemoveRect(r)
    endif
    call SetUnitPosition(t, x, y)
    set t = null
    set r = null
    //set tmr = null
endfunction

function KnockbackFunctions_ClearGroupEffects takes nothing returns nothing
    local string eye = GetAttachmentTable(GetEnumUnit())
    call SetTableBoolean(eye, "KnockbackFunctions_EffectBooleanGroup", false)
endfunction

function KnockbackFunctions_KBGroupTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local string s = GetAttachmentTable(t)
    local group g = GetTableGroup(s, "KnockbackFunctions_Group")
    local real dist = GetTableReal(s, "KnockbackFunctions_Distance")
    local real break = GetTableReal(s, "KnockbackFunctions_Break")
    if dist > 0 then
        call ForGroup(g, function KnockbackFunctions_KBGroupEffect)
        call SetTableReal(s, "KnockbackFunctions_Distance", dist-break)
    else
        call ForGroup(g, function KnockbackFunctions_ClearGroupEffects)
        if GetTableBoolean(s, "KnockbackFunctions_DestroyGroup") then
            call DestroyGroup(g)
        endif
        call ClearTable(s)
        call DestroyTimer(t)
    endif
    set g = null
    //set t = null
endfunction

function KnockbackFunctions_CheckSlideEffectGroup takes group g, timer t returns nothing
    local unit temp
    local group g2 = CreateGroup()
    local string eye
    call GroupAddGroup(g, g2)
    loop
        set temp = FirstOfGroup(g2)
        exitwhen temp == null
        set eye = GetAttachmentTable(temp)
        call SetTableBoolean(eye, "KnockbackFunctions_EffectBooleanGroup", true)
        call KnockbackFunctions_CheckSlideEffect(temp, t)
        call GroupRemoveUnit(g2, temp)
        set temp = null
    endloop
    call DestroyGroup(g2)
    set g2 = null
endfunction

function KnockbackFunctions_KBGroup takes group g, real x, real y, real speed, real break, real interval, boolean out, boolean destroygroup, boolean destroydestructables, boolean eyecandy returns nothing
    local timer t = CreateTimer()
    local string s = GetAttachmentTable(t)
    local unit u
    local group g2 = CreateGroup()
    call GroupAddGroup(g, g2)
    call SetTableObject(s, "KnockbackFunctions_Group", g)
    call SetTableReal(s, "KnockbackFunctions_GroupX", x)
    call SetTableReal(s, "KnockbackFunctions_GroupY", y)
    call SetTableReal(s, "KnockbackFunctions_Distance", speed)
    call SetTableReal(s, "KnockbackFunctions_Break", break)
    call SetTableBoolean(s, "KnockBackFunctions_Out", out)
    call SetTableBoolean(s, "KnockBackFunctions_DestroyGroup", destroygroup)
    call SetTableBoolean(s, "KnockBackFunctions_DestroyDestructables", destroydestructables)
    call SetTableBoolean(s, "KnockBackFunctions_EyeCandy", eyecandy)
    if KnockbackFunctions_GroupExcemptions() then
        loop
            set u = FirstOfGroup(g2)
            exitwhen u == null
            if not KnockbackFunctions_UnitMoveExcemptions(u) then
                call GroupRemoveUnit(g, u)
            endif
            call GroupRemoveUnit(g2, u)
            set u = null
        endloop
    endif
    call DestroyGroup(g2)
    if CountUnitsInGroup(g) > 0 then
        call TimerStart(t, interval, true, function KnockbackFunctions_KBGroupTimer)
        if eyecandy then
            call KnockbackFunctions_CheckSlideEffectGroup(g, t)
        endif
    else
        call ClearTable(s)
        call DestroyTimer(t)
    endif
    //set t = null
    set u = null
    set g2 = null
endfunction

function KnockbackFunctions_KBUnitTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local string s = GetAttachmentTable(t)
    local unit u = GetTableUnit(s, "Knockback_Target")
    local real cos = GetTableReal(s, "Knockback_Cos")
    local real sin = GetTableReal(s, "Knockback_Sin")
    local real dist = GetTableReal(s, "Knockback_Distance")
    local real break = GetTableReal(s, "Knockback_Break")
    local real x = GetUnitX(u)+dist*cos
    local real y = GetUnitY(u)+dist*sin
    local string eye = GetAttachmentTable(u)
    local rect r
    if dist > 0 then
        if GetTableBoolean(s, "Knockback_DestroyDestructables") then
            set r = Rect(x-128, y-128, x+128, y+128)
            call EnumDestructablesInRect(r, null, function KnockbackFunctions_DestroyDestructables)
            call RemoveRect(r)
        endif
        call SetUnitPosition(u, x, y)
        call SetTableReal(s, "Knockback_Distance", dist-break)
    else
        call SetTableBoolean(eye, "KnockbackFunctions_EffectBoolean", false)
        call ClearTable(s)
        call DestroyTimer(t)
    endif
    set u = null
    //set t = null
    set r = null
endfunction

function KnockbackFunctions_KBUnit takes unit u, real angle, real speed, real break, real interval, boolean destroydestructables, boolean eyecandy returns nothing
    local timer t = CreateTimer()
    local string s = GetAttachmentTable(t)
    local string eye = GetAttachmentTable(u)
    call SetTableReal(s, "Knockback_Cos", Cos(angle*.017453))
    call SetTableReal(s, "Knockback_Sin", Sin(angle*.017453))
    call SetTableObject(s, "Knockback_Target", u)
    call SetTableReal(s, "Knockback_Distance", speed)
    call SetTableReal(s, "Knockback_Break", break)
    call SetTableBoolean(s, "Knockback_DestroyDestructables", destroydestructables)
    call TimerStart(t, interval, true, function KnockbackFunctions_KBUnitTimer)
    if eyecandy then
        call SetTableBoolean(eye, "KnockbackFunctions_EffectBoolean", true)
        call KnockbackFunctions_CheckSlideEffect(u, t)
    endif
    //set t = null
    // I don't recommend setting t = null because of possible bugs.
endfunction

function InitTrig_KnockbackFunctions takes nothing returns nothing
    set gg_trg_KnockbackFunctions = CreateTrigger()
endfunction
09-24-2006, 06:57 AM#2
Jazradel
Where are GetAttachmentTable(u), etc from?
09-24-2006, 07:10 AM#3
Pheonix-IV
How did you manage to get an Else - Actions outside of an If/Then/Else?
09-24-2006, 01:58 PM#4
ShadowDestroyer
Well this spell partners with Vexorian's Spell System...
Sorry, I had a part of the spell that has no relation to it, and I didn't remove all of it...

Anyone see anything?

I really don't know how he did it... Maybe I also need to reverse the x-128, y-128, x+128, y+128? I really am lost on how to make this work.
09-24-2006, 05:22 PM#5
oNdizZ
how about just reversing the distance to the set x and set y?
assuming your current knockback actually knocks the unit backwards.
set x = x2+dist*Cos(a*.017453)
set y = y2+dist*Sin(a*.017453)
would be
set x = x2-dist*Cos(a*.017453)
set y = y2-dist*Sin(a*.017453)
09-24-2006, 06:59 PM#6
MeanMachine
Set casterloc = (Position of (Targeted unit))

Targeted unit is a responce to a unit aqquires a target. In this case it returns null. The correct is : "Event responce - Target unit of ability being cast"
09-24-2006, 08:10 PM#7
ShadowDestroyer
Thanks MeanMachine that fixed it... +rep