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

Need to modify this JASS a bit

Status
Not open for further replies.
Level 7
Joined
Apr 7, 2009
Messages
241
I need to modify the unholy blade spell from Redscores JASS spellpack, but I lack the JASS skills to do it. I need to make it so that the knockback effect on this spell cant knock units over cliffs and also I need units to always land on the ground (they get flung up in the air), sometime they land in midair and hovers for the rest of the game.
This is the different scripts that it uses:
JASS:
function Trig_UnholyBladeAttackCheck takes nothing returns boolean
    local player P = GetOwningPlayer(GetAttacker())
    return GetUnitAbilityLevel(GetAttacker(), 'A00C') > 0 and udg_KR_HitOrNo[GetPlayerId(P) + 1]
endfunction

function Trig_Unholy_Blade_Attack_Actions takes nothing returns nothing
    local unit U = GetAttacker()
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer(U)
    local integer maxsouls = 2 + (2*GetUnitAbilityLevel(U, 'A00C'))
    local real x = GetUnitX(U)
    local real y = GetUnitY(U)
    local real x1 = GetUnitX(u)
    local real y1 = GetUnitY(u) 
    local real d = Atan2(y1 - y, x1 - x)
    local real x2 = x1 + 350 * Cos(d)
    local real y2 = y1 + 350 * Sin(d)
    call QueueUnitAnimation(U, "attack slam")
    
    call CreateTextTagUnit( "Unleash! +" + I2S(R2I(20.00*udg_KR_KillCount[GetPlayerId(p) + 1])) + " Damage", U, 0.00, 10.00, 100, 100, 100, 255, 0, 0.03, 5.00, false, true)
    call DestroyEffect(udg_KR_Effect[GetPlayerId(p) + 1])
    call Jump(u, 0.50, x2, y2, 1.80, 100, "Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl")
    call UnitDamageTarget(U, u, 20.00*udg_KR_KillCount[GetPlayerId(p) + 1], true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    set udg_KR_KillCount[GetPlayerId(p) + 1] = 0
    set udg_KR_HitOrNo[GetPlayerId(p) + 1] = false
    set U = null
    set u = null
endfunction

//===========================================================================
function InitTrig_UnholyBladeAttack takes nothing returns nothing
    local integer index
    call Preload("Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl")
    set gg_trg_UnholyBladeAttack = CreateTrigger(  )
    

    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_UnholyBladeAttack, Player(index), EVENT_PLAYER_UNIT_ATTACKED, Filter(function AntiLeak))

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition( gg_trg_UnholyBladeAttack, Condition( function Trig_UnholyBladeAttackCheck ) )
    call TriggerAddAction( gg_trg_UnholyBladeAttack, function Trig_Unholy_Blade_Attack_Actions )
endfunction

JASS:
function Trig_UnholyBladeActivate_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B' 
endfunction

function Trig_UnholyBladeActivate_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local player casterowner = GetOwningPlayer(caster)
    if udg_KR_KillCount[GetPlayerId(casterowner) + 1] > 0 then
        set udg_KR_HitOrNo[GetPlayerId(casterowner) + 1] = true
        set udg_KR_Effect[GetPlayerId(casterowner) + 1] = AddSpecialEffectTarget("Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", caster, "weapon")
    endif
    set caster = null
endfunction

//===========================================================================
function InitTrig_UnholyBladeActivate takes nothing returns nothing
    set gg_trg_UnholyBladeActivate = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_UnholyBladeActivate, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_UnholyBladeActivate, Condition( function Trig_UnholyBladeActivate_Conditions ) )
    call TriggerAddAction( gg_trg_UnholyBladeActivate, function Trig_UnholyBladeActivate_Actions )
endfunction

JASS:
function Trig_UnholyBladeActivate_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B' 
endfunction

function Trig_UnholyBladeActivate_Actions takes nothing returns nothing
    local unit caster = GetSpellAbilityUnit()
    local player casterowner = GetOwningPlayer(caster)
    if udg_KR_KillCount[GetPlayerId(casterowner) + 1] > 0 then
        set udg_KR_HitOrNo[GetPlayerId(casterowner) + 1] = true
        set udg_KR_Effect[GetPlayerId(casterowner) + 1] = AddSpecialEffectTarget("Abilities\\Weapons\\ZigguratMissile\\ZigguratMissile.mdl", caster, "weapon")
    endif
    set caster = null
endfunction

//===========================================================================
function InitTrig_UnholyBladeActivate takes nothing returns nothing
    set gg_trg_UnholyBladeActivate = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_UnholyBladeActivate, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_UnholyBladeActivate, Condition( function Trig_UnholyBladeActivate_Conditions ) )
    call TriggerAddAction( gg_trg_UnholyBladeActivate, function Trig_UnholyBladeActivate_Actions )
endfunction

  • Events
    • Unit - A unit Learns a skill
  • Conditions
    • (Learned Hero Skill) Equal to The Reaper's Reap
  • Actions
    • Unit - Add The Reaper's Unleash Souls to (Triggering unit)
This is the libraries or whatever it's called
JASS:
function AntiLeak takes nothing returns boolean
return true
endfunction

library Knockback initializer Init

// *******************************************************************************
// ** **
// ** Knockback(Ex) **
// ** ————————————— **
// ** **
// ** Just a function I made for efficient knockbacking **
// ** ** Made by Silvenon
// *******************************************************************************

public struct Data
    unit u
    real d1
    real d2

    real sin
    real cos

    real r

    string s = ""
    effect e = null
endstruct

globals
    private timer Tim = CreateTimer()
    private Data array Ar
    private boolean array BoolAr
    private integer Total = 0
    private boolexpr Cond = null

    private real MAX_X
    private real MAX_Y
    private real MIN_X
    private real MIN_Y
endglobals

public function TreeFilter takes nothing returns boolean
    local integer d = GetDestructableTypeId(GetFilterDestructable())
    return d == 'ATtr' or d == 'BTtw' or d == 'KTtw' or d == 'YTft' or d == 'JTct' or d == 'YTst' or d == 'YTct' or d == 'YTwt' or d == 'JTwt' or d == 'JTwt' or d == 'FTtw' or d == 'CTtr' or d == 'ITtw' or d == 'NTtw' or d == 'OTtw' or d == 'ZTtw' or d == 'WTst' or d == 'LTlt' or d == 'GTsh' or d == 'Xtlt' or d == 'WTtw' or d == 'Attc' or d == 'BTtc' or d == 'CTtc' or d == 'ITtc' or d == 'NTtc' or d == 'ZTtc'
endfunction

private constant function Interval takes nothing returns real
    return 0.04
endfunction

private function KillTree takes nothing returns nothing
    if BoolAr[0] then
        call KillDestructable(GetEnumDestructable())
    else
        set BoolAr[1] = true
    endif
endfunction

private function Execute takes nothing returns nothing
    local Data kd
    local integer i = 0
    local real x
    local real y
    local rect r

    loop
        exitwhen i >= Total
        set kd = Ar[i]

        if kd.s != null and kd.s != null then
            set x = GetUnitX(kd.u)
            set y = GetUnitY(kd.u)

            call DestroyEffect(AddSpecialEffect(kd.s, x, y))

            set x = x + kd.d1 * kd.cos
            set y = y + kd.d1 * kd.sin
        else
            set x = GetUnitX(kd.u) + kd.d1 * kd.cos
            set y = GetUnitY(kd.u) + kd.d1 * kd.sin
        endif

        set r = Rect(x - kd.r, y - kd.r, x + kd.r, y + kd.r)
        set BoolAr[0] = kd.r != 0

        call EnumDestructablesInRect(r, Cond, function KillTree)
        call RemoveRect(r)

        set r = null

        if (x < MAX_X and y < MAX_Y and x > MIN_X and y > MIN_Y) and not BoolAr[1] then
            call SetUnitX(kd.u, x)
            call SetUnitY(kd.u, y)
        endif

        set kd.d1 = kd.d1 - kd.d2

        if kd.d1 <= 0 or (x > MAX_X or y > MAX_Y or x < MIN_X or y < MIN_Y) or BoolAr[1] then

            if kd.e != null then
                call DestroyEffect(kd.e)
            endif

            call PauseUnit(kd.u, false)

            set Ar[i] = Ar[Total - 1]
            set Total = Total - 1
            call kd.destroy()

set BoolAr[0] = false
            set BoolAr[1] = false
        endif

        set i = i + 1
    endloop

    if Total == 0 then
        call PauseTimer(Tim)
    endif
endfunction

function KnockbackEx takes unit u, real d, real a, real w, real r, integer t, string s, string p returns Data
    local Data kd = Data.create()
    local integer q = R2I(w / Interval())

    set kd.u = u
    set kd.d1 = 2 * d / (q + 1)
    set kd.d2 = kd.d1 / q

    set kd.sin = Sin(a)
    set kd.cos = Cos(a)

    set kd.r = r

    if s != "" and s != null then
        if t == 2 then
            if p != "" and p != null then
                set kd.e = AddSpecialEffectTarget(s, u, p)
            else
                set kd.e = AddSpecialEffectTarget(s, u, "chest")
            endif
        elseif t == 1 then
            set kd.s = s
        endif
    endif

    call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
call PauseUnit(u, true)

    if Total == 0 then
        call TimerStart(Tim, Interval(), true, function Execute)
    endif

    set Total = Total + 1
    set Ar[Total - 1] = kd

    return kd
endfunction

function Knockback takes unit u, real d, real a, real w returns Data
    return KnockbackEx(u, d, a, w, 0, 1, "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl", "")
endfunction

private function Init takes nothing returns nothing
    set Cond = Filter(function TreeFilter)

    set BoolAr[0] = false
    set BoolAr[1] = false

    set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea) - 64
    set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea) - 64
    set MIN_X = GetRectMinX(bj_mapInitialPlayableArea) + 64
    set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea) + 64
endfunction

endlibrary

function SetUnitXY takes unit u, real x, real y returns nothing
  local real minx = GetRectMinX ( bj_mapInitialPlayableArea )
  local real maxx = GetRectMaxX ( bj_mapInitialPlayableArea )
  local real miny = GetRectMinY ( bj_mapInitialPlayableArea )
  local real maxy = GetRectMaxY ( bj_mapInitialPlayableArea )
  if ( x < minx ) then
    call SetUnitX ( u, minx )
  elseif ( x > maxx ) then
    call SetUnitX ( u, maxx )
  else
    call SetUnitX ( u, x )
  endif
  if ( y < miny ) then
    call SetUnitY ( u, miny )
  elseif ( y > maxy ) then
    call SetUnitY ( u, maxy )
  else
    call SetUnitY ( u, y )
  endif
endfunction

library Jump initializer Init_Jump

// *******************************************************************************
// ** **
// ** Jump **
// ** ———————— **
// ** **
// ** Just a function I made for efficient jumping **
// ** **
// *******************************************************************************

//========================================//
//Credits to Shadow1500 for this function!//
//========================================//

private function JumpParabola takes real dist, real maxdist, real curve returns real
    local real t = (dist * 2) / maxdist - 1
    return (- t * t + 1) * (maxdist / curve)
endfunction

//=======================================//
//Credits to PitzerMike for this function//
//=======================================//

//===========================================================================

private function TreeKill takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

globals
    private integer DUMMY_ID = 'h005'

    private constant real Interval = 0.035
    private boolexpr Bool
    private location Loc = Location(0, 0)

    private timer Tim = CreateTimer()
    private integer Total = 0
endglobals

private function TreeFilter takes nothing returns boolean
    local destructable d = GetFilterDestructable()
    local boolean i = IsDestructableInvulnerable(d)
    local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), DUMMY_ID,GetWidgetX(d), GetWidgetY(d), 0)
    local boolean result = false
    call UnitAddAbility(u, 'Ahrl')
    if i then
        call SetDestructableInvulnerable(d, false)
    endif
    set result = IssueTargetOrder(u, "harvest", d)
    call RemoveUnit(u)
    if i then
      call SetDestructableInvulnerable(d, true)
    endif
    set u = null
    set d = null
    return result
endfunction

public struct Data
    unit u
    integer q
    real md
    real d
    real c

    real sin
    real cos
    integer i = 1

    real r
    string s

    static method create takes unit u, integer q, real x2, real y2, real c, real r, string s1, string s2 returns Data
        local Data dat = Data.allocate()

        local real x1 = GetUnitX(u)
        local real y1 = GetUnitY(u)
        local real dx = x1 - x2
        local real dy = y1 - y2
        local real a = Atan2(y2 - y1, x2 - x1)

        set dat.u = u
        set dat.q = q
        set dat.md = SquareRoot(dx * dx + dy * dy)
        set dat.d = dat.md / q
        set dat.c = c
        set dat.sin = Sin(a)
        set dat.cos = Cos(a)
        set dat.r = r
        set dat.s = s2

        if s1 != "" and s1 != null then
            call DestroyEffect(AddSpecialEffect(s1, x1, y1))
        endif

        call UnitAddAbility(u, 'Amrf')
        call UnitRemoveAbility(u, 'Amrf')
        call PauseUnit(u, true)

        return dat
    endmethod

    method onDestroy takes nothing returns nothing
        local real x
        local real y
        local rect r

        if .r != 0 then
            set x = GetUnitX(.u)
            set y = GetUnitY(.u)
            set r = Rect(x - .r, y - .r, x + .r, y + .r)
            call EnumDestructablesInRect(r, Bool, function TreeKill)
            call RemoveRect(r)

            set r = null
        endif

        if .s != "" and .s != null then
            call DestroyEffect(AddSpecialEffect(.s, x, y))
        endif

        call PauseUnit(.u, false)
    endmethod
endstruct

globals
    private Data array Ar
endglobals

private function Execute takes nothing returns nothing
    local Data dat
    local integer i = 0
    local real x
    local real y
    local location l
    local real h
    local rect r

    loop
        exitwhen i >= Total
        set dat = Ar[i]
        set x = GetUnitX(dat.u) + dat.d * dat.cos
        set y = GetUnitY(dat.u) + dat.d * dat.sin

        call MoveLocation(Loc, x, y)

        set h = JumpParabola(dat.d * dat.i, dat.md, dat.c) - GetLocationZ(Loc)

        call SetUnitX(dat.u, x)
        call SetUnitY(dat.u, y)
        call SetUnitFlyHeight(dat.u, h, 0)

        if dat.i >= dat.q then
            call dat.destroy()
            set Total = Total - 1
            set Ar[i] = Ar[Total]
        else
            set dat.i = dat.i + 1
endif

        set i = i + 1
    endloop

    if Total == 0 then
        call PauseTimer(Tim)
    endif

    set l = null
endfunction

function Jump takes unit whichUnit, real dur, real destX, real destY, real curve, real radius, string sfx1, string sfx2 returns nothing
local Data dat = Data.create(whichUnit, R2I(dur / Interval), destX, destY, curve, radius, sfx1, sfx2)

    if Total == 0 then
        call TimerStart(Tim, Interval, true, function Execute)
    endif

    set Ar[Total] = dat
    set Total = Total + 1
endfunction

//==================================================================================

function Init_Jump takes nothing returns nothing
    set Bool = Filter(function TreeFilter)
endfunction

endlibrary


function CreateTextTagUnit takes string s, unit whichUnit, real zOffset, real size, integer red, integer green, integer blue, integer transparency, real velocityA, real velocityB, real lifespan, boolean perma, boolean visible returns nothing
    local texttag LastTextTag = CreateTextTag()
    call SetTextTagText(LastTextTag, s, size * 0.023 / 10)
    call SetTextTagPosUnit(LastTextTag, whichUnit, zOffset)
    call SetTextTagColor(LastTextTag, red, green, blue, transparency)
    call SetTextTagVelocity( LastTextTag, velocityA, velocityB )
    call SetTextTagLifespan( LastTextTag, lifespan )
    call SetTextTagPermanent( LastTextTag, perma )
    call SetTextTagVisibility( LastTextTag, visible )
endfunction
 
Try modifying this part of Silvenon's code, and see if it works:
JASS:
    loop
        exitwhen i >= Total
        set dat = Ar[i]
        set x = GetUnitX(dat.u) + dat.d * dat.cos
        set y = GetUnitY(dat.u) + dat.d * dat.sin
        if GetTerrainCliffLevel(GetUnitX(dat.u),GetUnitY(dat.u))<GetTerrainCliffLevel(x,y) then
        //Add this if/then block.
            set x = GetUnitX(dat.u)
            set y = GetUnitY(dat.u)
        
        endif

        call MoveLocation(Loc, x, y)

        set h = JumpParabola(dat.d * dat.i, dat.md, dat.c) - GetLocationZ(Loc)

        call SetUnitX(dat.u, x)
        call SetUnitY(dat.u, y)
        call SetUnitFlyHeight(dat.u, h, 0)

        if dat.i >= dat.q then
            call dat.destroy()
            set Total = Total - 1
            set Ar[i] = Ar[Total]
        else
            set dat.i = dat.i + 1
        endif

        set i = i + 1
    endloop

For the hovering problem, try adding this in the bottom of the Silvenon's jump code (in function Execute):
JASS:
    if Total == 0 then
        call SetUnitFlyHeight(dat.u,0,0) //add this
        call PauseTimer(Tim)
    endif
 
Level 7
Joined
Apr 7, 2009
Messages
241
Try modifying this part of Silvenon's code, and see if it works:
JASS:
    loop
        exitwhen i >= Total
        set dat = Ar[i]
        set x = GetUnitX(dat.u) + dat.d * dat.cos
        set y = GetUnitY(dat.u) + dat.d * dat.sin
        if GetTerrainCliffLevel(GetUnitX(dat.u),GetUnitY(dat.u))<GetTerrainCliffLevel(x,y) then
        //Add this if/then block.
            set x = GetUnitX(dat.u)
            set y = GetUnitY(dat.u)
        
        endif

        call MoveLocation(Loc, x, y)

        set h = JumpParabola(dat.d * dat.i, dat.md, dat.c) - GetLocationZ(Loc)

        call SetUnitX(dat.u, x)
        call SetUnitY(dat.u, y)
        call SetUnitFlyHeight(dat.u, h, 0)

        if dat.i >= dat.q then
            call dat.destroy()
            set Total = Total - 1
            set Ar[i] = Ar[Total]
        else
            set dat.i = dat.i + 1
        endif

        set i = i + 1
    endloop

For the hovering problem, try adding this in the bottom of the Silvenon's jump code (in function Execute):
JASS:
    if Total == 0 then
        call SetUnitFlyHeight(dat.u,0,0) //add this
        call PauseTimer(Tim)
    endif

Thanks man!
+rep :thumbs_up:
 
Status
Not open for further replies.
Top