• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Spell] Dash

Status
Not open for further replies.
Level 2
Joined
Oct 8, 2018
Messages
7
Ability(Warden - Blink $.png ) that rejects an opponent from thecentre.

(my english is super bad)
 
Level 45
Joined
Feb 27, 2007
Messages
5,578
Here's a relatively simple JASS implementation of what I think you want. Use the Warden to blink around and knock back the murlocs to the south. This uses [System] Knockback3D, IsDestructableTree, and TerrainPathability. Copy over the 4 triggers into your map and change the SPELL_ID variable in the Dash trigger to match the rawcode of your blink spell (which you can see by pressing ctrl+D in the object editor window).

JASS:
library DashSpell initializer init requires Knockback3D
globals
    private constant integer SPELL_ID = 'AEbl'
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_MAGIC
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
    private constant weapontype WEAPON_TYPE = WEAPON_TYPE_WHOKNOWS
  
    // The Art - Caster field of Blink allows you to play an effect on the targeted location when the unit appears there
    // The knockback dust sliding effect can be changed/removed in the Knockback3D library itself, where it's called FRICTION_MODEL
    // There are many other configurables for the knockback in the Knockback3D library, such as bouncing, destroying trees, friction, etc.
  
    private keyword LEVEL
endglobals

// you can use the LEVEL global variable here to refer to the spell's level on-cast
private constant function KnockbackRadius takes nothing returns real
    return 200.00 + 100.00*LEVEL
endfunction

private constant function KnockbackDamage takes nothing returns real
    return 20.00*LEVEL
endfunction

// not really a distance, this is sort of wonky because of how Knockback3D works
// you may need to try different values to get what you want, or change the frction value in KB3D
private constant function KnockbackStrength takes nothing returns real
    return 1000.00
endfunction

// probably don't want it to go up but hey maybe you do; this is in radians, not degrees
private constant function KnockbackVerticalAngle takes nothing returns real
    return 0.00
endfunction

// LEVEL is still valid here if you want to use it
private function KnockbackIsValidTarget takes unit TargetUnit, unit CastingUnit, player CasterOwner returns boolean
    return     IsUnitEnemy(TargetUnit, CasterOwner)          /* check if enemy
    */ and     GetWidgetLife(TargetUnit) > 0.405             /* check if alive
    */ and not IsUnitType(TargetUnit, UNIT_TYPE_STRUCTURE)   /* check if not a structure
    */ and not IsUnitType(TargetUnit, UNIT_TYPE_MAGIC_IMMUNE)/* check if not spell-immune
    */ and     GetUnitAbilityLevel(TargetUnit, 'Avul') == 0  /* check if not invulnerable
    */
endfunction



globals
    public trigger SpellTrig
    private timer DelayTimer
    private group SearchGroup
    private unit Caster
    private player CastOwner
    private integer LEVEL
    private boolexpr KBFilter
endglobals

private function CastCheck takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function KBTargeting takes nothing returns boolean
    return KnockbackIsValidTarget(GetFilterUnit(), Caster, CastOwner)
endfunction
  

private function OnCastDelayed takes nothing returns nothing
    local real cx = GetUnitX(Caster)
    local real cy = GetUnitY(Caster)
    local unit u
    local real ux
    local real uy
  
    call GroupEnumUnitsInRange(SearchGroup, cx, cy, KnockbackRadius(), KBFilter)
    loop
        set u = FirstOfGroup(SearchGroup)
        exitwhen u == null
        call GroupRemoveUnit(SearchGroup, u)
      
        set ux = GetUnitX(u)
        set uy = GetUnitY(u)
        call UnitDamageTarget(Caster, u, KnockbackDamage(), false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
        call Knockback3D.add(u, KnockbackStrength(), Atan2(uy-cy, ux-cx), KnockbackVerticalAngle())
    endloop
endfunction


private function OnCast takes nothing returns nothing
    set Caster = GetTriggerUnit()
    set CastOwner = GetOwningPlayer(Caster)
    set LEVEL = GetUnitAbilityLevel(Caster, SPELL_ID)
      
    call TimerStart(DelayTimer, 0.00, false, function OnCastDelayed)
    // necessary because the unit is still at its initial location when the blink 'happens'
    // and blink has a special cast paradigm that allows you to target as far away as you can see
    // but only blinks the maximum distance toward that point, thus checking the spell's target
    // point does not work properly
endfunction


private function init takes nothing returns nothing
    set DelayTimer = CreateTimer()
    set SearchGroup = CreateGroup()
    set KBFilter = Filter(function KBTargeting)
  
    set SpellTrig = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(SpellTrig, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(SpellTrig, Condition(function CastCheck))
    call TriggerAddAction(SpellTrig, function OnCast)
endfunction
endlibrary
 

Attachments

  • Dash Spell.w3x
    38.4 KB · Views: 73
Status
Not open for further replies.
Top