A "Stifling Dagger"-like spell? [Spell Request]

MasterRofl

New Member
Reaction score
8
Hey there. I just started learning JASS yesterday evening, and spent roughly 6 hours trying to duplicate a stifling dagger. However, I failed pretty hard. :thdown:

My attempt (warning your head will explode):
JASS:
scope ThrowKnife

function Actions takes nothing returns nothing
    globals
        unit TargetUnit = GetSpellTargetUnit()
        unit Caster = GetTriggerUnit()
        location CasterLocation = GetUnitLoc( GetTriggerUnit() )
        integer SlowLevel = GetUnitAbilityLevelSwapped( 'A01U', Caster )
    endglobals
    CreateUnitAtLoc( GetOwningPlayer( Caster ), 'n00N', CasterLocation, 0.00 )
    globals
        unit Knife = GetLastCreatedUnit()
    endglobals
    call EnableTrigger( KnifeMovement )
endfunction

function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A01U'
endfunction

public function InitTrig takes nothing returns nothing
    local trigger ThrowKnife = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( ThrowKnife, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( ThrowKnife, Condition( function Conditions ) )
    call TriggerAddAction( ThrowKnife, function Actions )
endfunction

endscope
JASS:
scope KnifeMovement

private function Actions takes nothing returns nothing
    local location TargetLocation = GetUnitLoc( TargetUnit )
    local location KnifeLocation = GetUnitLoc( Knife )
    SetUnitPositionLocFacingLocBJ( Knife, PolarProjectionBJ( KnifeLocation, 36, AngleBetweenPoints( KnifeLocation, TargetLocation ) ), TargetLocation )
    if ( DistanceBetweenPoints( KnifeLocation, TargetLocation ) < 36 ) then
        call SetUnitAbilityLevel( Knife, 'A026', SlowLevel )
        call IssueTargetOrder( Knife, "slow", TargetUnit )
        call KillUnit( Knife )
        call UnitDamageTargetBJ( Caster, TargetUnit, 300, ATTACK_TYPE_HERO, DAMAGE_TYPE_FIRE )
        call DisableTrigger( KnifeMovement )
    endif
endfunction

//===========================================================================
function InitTrig takes nothing returns nothing
    globals
        trigger KnifeMovement = CreateTrigger()
    endglobals
    call DisableTrigger( KnifeMovement )
    call TriggerRegisterTimerEventPeriodic( KnifeMovement, 0.03 ) 
    call TriggerAddAction( KnifeMovement, function Actions )
endfunction

endscope

So now, I'd like to see how it's done by somebody more experienced. It would be good if it was in vJASS.

Thanks! :D
 

T.s.e

Wish I was old and a little sentimental
Reaction score
133
Indeed it is, but I don't see the point. At all. By the way, that trigger is not mui.
Give me un momento and I will see what I can do :)

This uses the attachment system HSAS, you can find it at wc3campaigns.net
JASS:
library StiflingDagger initializer Init uses HSAS

globals
    private constant integer SPELLID = 'A000'
    private constant string SLOWSTRING = "slow"
    private constant integer DUMMYID = 'e000'
    private constant real SPEED = 1250. // How fast the missile flies.
endglobals

private struct Dagger
    unit u
    unit t
    unit d
    real x
    real y
    real xy
    real yx
    real speed
    real damage
endstruct

private function AngleBetweenXY takes real x, real y, real xy, real yx returns real
    return bj_RADTODEG * Atan2(y - yx, xy - x)
endfunction

private function DistanceBetweenXY takes real x, real y, real xy, real yx returns real
    local real dx = x - xy
    local real dy = y - yx
    return SquareRoot(dx * dx + dy * dy)
endfunction
//! runtextmacro HSAS_Static("d", "1288", "private")

private function Callback takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Dagger d = GetAttachedStructd(t)
    local real x
    local real y 
    local real v = d.speed / DistanceBetweenXY(d.x, d.y, d.xy, d.yx)
    set d.d = CreateUnit( GetOwningPlayer(d.u), DUMMYID, d.x, d.y, AngleBetweenXY(d.x, d.y, d.xy, d.yx))
    set x = GetUnitX(d.d)
    set y = GetUnitY(d.d)
    call SetUnitPosition(d.d, x+v, y+v)
    if DistanceBetweenXY(d.x, d.y, d.xy, d.yx) < 128. then
        call IssueTargetOrder( d.d, SLOWSTRING, d.t)
        call UnitDamageTarget(d.d, d.t, d.damage, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
        call RemoveUnit(d.d)
        call d.destroy()
    endif
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

private function Actions takes nothing returns nothing
    local Dagger d = Dagger.create()
    local timer t = CreateTimer()
    set d.x = GetUnitX(d.u)
    set d.y = GetUnitY(d.u)
    set d.xy = GetUnitX(d.t)
    set d.yx = GetUnitY(d.t)
    set d.u = GetTriggerUnit()
    set d.t = GetSpellTargetUnit()
    set d.speed = SPEED
    set d.damage = GetUnitAbilityLevel(d.u, SPELLID) * 100.
    call AttachStructd(t, d)
    call TimerStart(t, 0.03, true, function Callback)
    set t = null
endfunction


private function Conds takes nothing returns boolean
    return GetSpellAbilityId() == SPELLID
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 Conds))
    call TriggerAddAction(t, function Actions)
    set t = null
endfunction

endlibrary


It compiled nicely atleast :)

EDIT: Oh nose, I just saw an error. I set "x" and "y" to the dummy's xy coordinates, even when the dummy doesn't exist. Fixed now though.
EDITED EDITION: Everlasting timer ftl.
 
Reaction score
86
Quick Note: No, you cannot put globals in the function AS IT IS NOW. Globals are compiled and moved to the top with the rest of the globals, thus, they cannot be dynamically declared for a trigger. Meaning, don't set the globals to anything and then just set them at the beginning of the trigger.

Also, I have know Idea what a stifling dagger is o_O Which is why I can't help you. Also, a LOT of syntax errors...
 

MasterRofl

New Member
Reaction score
8
Yeah... I kind of scrapped the old one, now. >_>

Stifling Dagger is just a skill in DotA. Deals damage, and slows the target.
 

T.s.e

Wish I was old and a little sentimental
Reaction score
133
> //! runtextmacro HSAS_Static("d", "1288", "private")
What does that do?

It enables you to attach structs by using HSAS. Basically, it just creates a function in the trigger you use it.

"d" is the struct identifier.
"1288" is the array number in which the struct is stored.
"private" renders the attachment function private. "public" and "" are also usable.
 

MasterRofl

New Member
Reaction score
8
Uhh... when I test it out, the dummy unit doesn't seem to be created. Any ideas? :| (I imported HSAS)

I changed the values of SPELLID and DUMMYID to correspond to the objects in my map:
JASS:
private constant integer SPELLID = 'A01U'
private constant integer DUMMYID = 'n00N'

but that's all I changed. Is there something else that should've been changed?
 

T.s.e

Wish I was old and a little sentimental
Reaction score
133
Are you sure that is the correct value?

Edit - Does your dummy have a model file?
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top