• 💀 Happy Halloween! 💀 It's time to vote for the best terrain! Check out the entries to Hive's HD Terrain Contest #2 - Vampire Folklore.❗️Poll closes on November 14, 2023. 🔗Click here to cast your vote!
  • 🏆 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!
  • 🏆 HD Level Design Contest #1 is OPEN! Contestants must create a maze with at least one entry point, and at least one exit point. The map should be made in HD mode, and should not be openable in SD. Only custom models from Hive's HD model and texture sections are allowed. The only exceptions are DNC models and omnilights. This is mainly a visual and design oriented contest, not technical. The UI and video walkthrough rules are there to give everyone an equal shot at victory by standardizing how viewers see the terrain. 🔗Click here to enter!

Binding Shot v1.3

Unleashes binding arrows at the target and nearby enemies, pulling them towards the caster.

Level 1 - 120 damage.
Level 2 - 200 damage.
Level 3 - 280 damage.
Level 4 - 360 damage.

Cast Range: 700
Target Type: Unit
Cooldown: 9 seconds

//                          BINDING SHOT v1.3                      
//                              BY Ayanami                             

//                            REQUIREMENTS                                      
// - JNGP
// - Alloc     
// - SpellEffectEvent
//   * RegisterPlayerUnitEvent
//   * Table                                                   
// - Timer32                                                                

//                           IMPLEMENTATION                                     
// 1) Copy the whole "Required Systems" Trigger folder 
// 2) Copy the trigger "Binding Shot"
// 3) Copy the ability "Binding Shot" 
// 4) Copy the unit "Binding Shot Dummy"
// 5) Go through the configuration section in "Binding Shot" trigger                            

Spell Code

library BindingShot uses Alloc, SpellEffectEvent, T32

//                           CONFIGURABLES                        

    private constant integer ABIL_ID = 'ABBS' // raw code of base ability
    private constant integer DUMMY_ID = 'dBIN' // raw code of unit "Binding Shot Dummy"
    private constant real ANIM_IMPACT = 0.5 // time taken for arrow to reach target
    private constant real ANIM_BIND = 0.5 // time taken for enemies to be pulled back
    private constant real ANIM_OFFSET = 200. // offset distance of pull location (relative to caster's location)
    private constant real ANIM_HEIGHT = 50. // height of arrow
    private constant real ANIM_LIGHT_HEIGHT = 50. // height of lightning attachment point
    private constant string ANIM_LIGHTNING = "SPLK" // lightning type
    private constant real ENUM_RADIUS = 176. // max collision size of a unit in your map.
    private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type
    private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type

// bind area relative to target
private constant function GetArea takes integer level returns real
    return 300.

// damage dealt
private constant function GetDamage takes integer level returns real
    return 80. * level + 40.

// filter for allowed targets
private constant function GetFilter takes unit u, unit caster returns boolean
    return /*
    */ not IsUnitType(u, UNIT_TYPE_DEAD) /* // target is alive
    */ and IsUnitEnemy(u, GetOwningPlayer(caster)) /* // target is an enemy of caster
    */ and not IsUnitType(u, UNIT_TYPE_STRUCTURE) // target is not a structure

//                          END CONFIGURABLES                        

    private constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
    private group G = bj_lastCreatedGroup

private struct Data extends array
    implement Alloc

    private unit u
    private unit target
    private unit dummy
    private lightning l
    private boolean b
    private real dmg
    private real dur
    private real x
    private real y
    private method destroy takes nothing returns nothing
        call RemoveUnit(this.dummy)
        call DestroyLightning(this.l)
        call this.stopPeriodic()
        call this.deallocate()
    private method periodic takes nothing returns nothing
        local real x
        local real y
        local real dx
        local real dy
        local real a
        local real dist
        local real offset
        if not IsUnitType(this.target, UNIT_TYPE_DEAD) and GetUnitTypeId(this.target) != 0 then
            set x = GetUnitX(this.dummy)
            set y = GetUnitY(this.dummy)
            if this.b then
                set dx = this.x - x
                set dy = this.y - y
                set a = Atan2(dy, dx)
                set dist = SquareRoot(dx * dx + dy * dy)
                set offset = dist / this.dur * T32_PERIOD
                call SetUnitX(this.target, GetUnitX(this.target) + offset * Cos(a))
                call SetUnitY(this.target, GetUnitY(this.target) + offset * Sin(a))
                set dx = GetUnitX(this.target) - x
                set dy = GetUnitY(this.target) - y
                set a = Atan2(dy, dx)
                set dist = SquareRoot(dx * dx + dy * dy)
                set offset = dist / this.dur * T32_PERIOD
                call SetUnitFacing(this.dummy, a * bj_RADTODEG)
            call SetUnitX(this.dummy, x + offset * Cos(a))
            call SetUnitY(this.dummy, y + offset * Sin(a))
            call MoveLightningEx(this.l, true, GetUnitX(this.u), GetUnitY(this.u), GetUnitFlyHeight(this.u) + ANIM_LIGHT_HEIGHT, x, y, ANIM_HEIGHT + ANIM_LIGHT_HEIGHT)
            set this.dur = this.dur - T32_PERIOD
            if this.dur <= 0 then
                if this.b then
                    call this.destroy()
                    set this.b = true
                    set this.dur = ANIM_BIND
                    call UnitDamageTarget(this.u, this.target, this.dmg, true, false, ATK, DMG, null)
            call this.destroy()
    implement T32x

    private static method onCast takes nothing returns boolean
        local thistype this
        local unit u = GetTriggerUnit()
        local unit target = GetSpellTargetUnit()
        local integer level = GetUnitAbilityLevel(u, ABIL_ID)
        local real a = GetUnitFacing(u) * bj_DEGTORAD
        local real x = GetUnitX(u)
        local real y = GetUnitY(u)
        local real dx
        local real dy
        call GroupEnumUnitsInRange(G, GetUnitX(target), GetUnitY(target), GetArea(level) + ENUM_RADIUS, null)
            set target = FirstOfGroup(G)
            exitwhen target == null
            call GroupRemoveUnit(G, target)
            if GetFilter(target, u) then
                set this = thistype.allocate()
                set this.u = u
                set this.target = target
                set dx = GetUnitX(target)
                set dy = GetUnitY(target)
                set this.dummy = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, x, y, bj_RADTODEG * Atan2(dy - y, dx - x))
                call SetUnitFlyHeight(this.dummy, ANIM_HEIGHT, 0)
                set this.l = AddLightningEx(ANIM_LIGHTNING, true, x, y, GetUnitFlyHeight(this.u) + ANIM_LIGHT_HEIGHT, GetUnitX(this.dummy), GetUnitY(this.dummy), ANIM_HEIGHT + ANIM_LIGHT_HEIGHT)
                set this.b = false
                set this.dmg = GetDamage(level)
                set this.dur = ANIM_IMPACT
                set this.x = x + ANIM_OFFSET * Cos(a)
                set this.y = y + ANIM_OFFSET * Sin(a)
                call this.startPeriodic()
        set u = null
        set target = null
        return false

    private static method onInit takes nothing returns nothing
        call RegisterSpellEffectEvent(ABIL_ID, function thistype.onCast)


Sevion - Alloc
Jesus4Lyf - Timer32
Bribe - SpellEffectEvent
Mr.Goblin - Binding Shot Icon


- Initial relase

- Used UNIT_TYPE_DEAD instead of UnitAlive

- Removed Damage, GroupUtils and GTrigger
- Now needs SpellEffectEvent

- Fixed a condition bug in .periodic method
- Optimized variable usage in .onCast static method

Feedback will be appreciated.

binding, shot, arrow, bind

Binding Shot v1.3 (Map)

12th Nov 2011 Bribe: Thanks for making the changes, nice and unique spell here. Approved.




12th Nov 2011
Bribe: Thanks for making the changes, nice and unique spell here.