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

[Solved] Improving Spell.

Not open for further replies.
Level 9
Apr 7, 2010
//System Name: Map Bounds
//Created by: Mckill2009

//Description & Usage:
//- Kills any unit that has an 'Aloc' (locust) ability that goes outside the map area, avoiding map crash
//- Just paste this code in your custom text trigger

library MapBounds initializer init

    private real minX 
    private real minY
    private real maxX 
    private real maxY 

private function KillDummy takes nothing returns nothing
    local unit u
    if GetUnitAbilityLevel(GetTriggerUnit(), 'Aloc') > 0 then
        set u = GetTriggerUnit()
        call ShowUnit(u, false)
        call KillUnit(u)
    set u = null

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local region reg = CreateRegion()
    local rect map
    set maxX = GetRectMaxX(bj_mapInitialPlayableArea) 
    set maxY = GetRectMaxY(bj_mapInitialPlayableArea) 
    set minX = GetRectMinX(bj_mapInitialPlayableArea) 
    set minY = GetRectMinY(bj_mapInitialPlayableArea) 
    set map = Rect(minX, minX, maxX, maxX)
    call RegionAddRect(reg, map)
    call TriggerRegisterLeaveRegion(t, reg, null)
    call TriggerAddAction(t, function KillDummy)
    call RemoveRect(map)
    set t = null
    set reg = null
    set map = null
//Spell Name: Force Arrow
//Made by: Mckill2009

library ForceArrow needs MapBounds 

    private constant hashtable                HASH = InitHashtable() //Dont touch!
    private constant integer              SPELL_ID = 'A000' //roar
    private constant integer            MISSILE_ID = 'h001' //just change this model
    private constant real                      AOE = 250
    private constant real                 PERIODIC = 0.03125
    private constant real                    SPEED = 50
    private constant attacktype                ATK = ATTACK_TYPE_CHAOS
    private constant damagetype                DMG = DAMAGE_TYPE_NORMAL
    private constant string                    SFX = "Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl"
    private constant group                FA_GROUP = CreateGroup()
    private location LOC = Location(0,0)
    private integer CHECK = 0

private function GetDamage takes integer i returns real
    return 50 + i * 50.

private function GetDistance takes integer i returns real
    return 500 + i * 300.

private module Init
    private static method onInit takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        local trigger t2 = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t1, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t1, Condition(function thistype.go))
        call TriggerRegisterTimerEvent(t2, PERIODIC, true)
        call TriggerAddCondition(t2, Condition(function thistype.runloop))
        set t1 = null
        set t2 = null

private struct FA
    unit caster
    unit missile
    integer level
    real x
    real y
    real damage
    real angle
    real distance
    real height
    real distx
    real fixedheight
    static thistype DATA
    static method damagethem takes nothing returns boolean
        local thistype this = DATA
        local unit u = GetFilterUnit()
        if GetWidgetLife(u) > 0.405 and IsUnitEnemy(u, GetOwningPlayer(.missile)) then
            call UnitDamageTarget(.missile, u, .damage, false, false, ATK, DMG, null)
        set u = null
        return false
    static method looper takes nothing returns nothing
        local unit u = GetEnumUnit()
        local thistype this = LoadInteger(HASH, GetHandleId(u), 1)
        local integer i = 0
        local real x
        local real y
        local real x1
        local real y1
        if .distance > .distx and GetWidgetLife(.missile) > 0.405 then
            set .distx = .distx + SPEED
            set x = .x + .distx * Cos(.angle*bj_DEGTORAD)
            set y = .y + .distx * Sin(.angle*bj_DEGTORAD)
            call MoveLocation(LOC, x, y)
            call SetUnitFlyHeight(.missile, .fixedheight, 0)
            call SetUnitX(.missile, x)
            call SetUnitY(.missile, y)
            set x1 = GetUnitX(.missile)
            set y1 = GetUnitY(.missile)
            call KillUnit(.missile)
            call DestroyEffect(AddSpecialEffectTarget(SFX, .missile, "chest"))
            set DATA = this
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x1, y1, AOE, Filter(function thistype.damagethem))
            call GroupRemoveUnit(FA_GROUP, .missile)
            set CHECK = CHECK - 1
            call .destroy(this)
            call FlushChildHashtable(HASH, GetHandleId(.missile))
        set u = null
    static method create takes unit u, integer level, real x, real y returns thistype
        local thistype this = thistype.allocate()
        set .distx = 0
        set .angle = GetUnitFacing(u)
        set .distance = GetDistance(level)
        set .missile = CreateUnit(GetTriggerPlayer(), MISSILE_ID, x, y, GetUnitFacing(u))
        call MoveLocation(LOC, x, y)
        call SetUnitFlyHeight(.missile, GetUnitFlyHeight(u), 0)
        set .fixedheight = GetUnitFlyHeight(.missile) + (GetLocationZ(LOC)-50)
        set .damage = GetDamage(level)
        set .x = x
        set .y = y
        set CHECK = CHECK + 1
        call GroupAddUnit(FA_GROUP, .missile)
        call SaveInteger(HASH, GetHandleId(.missile), 1, this) 
        return this
    static method go takes nothing returns boolean
        local unit u
        local integer level
        if GetSpellAbilityId()==SPELL_ID then
            set u = GetTriggerUnit()
            set level = GetUnitAbilityLevel(u, SPELL_ID)
            call FA.create(u, level, GetUnitX(u), GetUnitY(u))
        set u = null
        return false
    static method runloop takes nothing returns boolean
        if CHECK > 0 then
            call ForGroup(FA_GROUP, function thistype.looper)
        return false
    implement Init


Force Arrow is a spell ive requested from mckill2009.
anyways. i dont understand jass.
here are somethings i want to change but i do not know how.
how do i increase the distance traveled by the projectile
how do i set the projectile height to the just some point below the casters height


Code Reviewer
Level 26
Mar 19, 2008
private function GetDistance takes integer i returns real
    return 500 + i * 300.

// egzample, write:
// return 40000.
// instead, so distance is now set to 40000. units

Edit formula in that function for changing the distance.
GetUnitFlyHeight(u)Means that missile height is set to casters heght - and script already contains that.

If you want to customize default missile height go to 'create' method and edit this line:
call SetUnitFlyHeight(.missile, GetUnitFlyHeight(u), 0)The second parameter (here it's fly height of unit u) is the one you have to change.
Last edited:
Level 9
Apr 7, 2010
thanks. i got one problem solved. (distance)

anyways. can i do this "GetUnitFlyHeight (u) and add X"?
if yes, how do i do it in jass?
"x = number"
Level 9
Apr 7, 2010
oh i see.. i will just have to learn jass by editing simple codes.

already rep+ to Spinnaker.
i cant add yet to mckill, i have to spread a little more.
Not open for further replies.