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

Magic Bolts

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
The Shade fires a rapid volley of magic bolts at the target. Each bolt deals damage based on his intelligence.

Level 1: 4 magic bolts. 1.2 damage per INT point. 500 Cast Range.
Level 2: 5 magic bolts. 1.3 damage per INT point. 600 Cast Range.
Level 3: 6 magic bolts. 1.4 damage per INT point. 700 Cast Range.
Level 4: 7 magic bolts. 1.5 damage per INT point. 800 Cast Range.

Credits to Jesus4lyf for Key Timers 2.

Requires: Key Timers 2 and Jass Newgen Pack

JASS:
scope Magic initializer init
    globals
        private constant integer DUMMY_ID = 'h000'
        private constant integer ABILITY_CODE = 'BOLT'
        private constant real ARC_PER_LEVEL = .15
        private constant real OFFSET = 20
        private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
        private constant weapontype WEAPON_TYPE = null
    endglobals
    
    private function DAMAGE takes integer lvl, unit u returns real
        return (1.1 + (lvl * .1)) * GetHeroInt(u, true)
    endfunction
    
    private function DUMMY_UNITS takes integer lvl returns real
        return 3 + (lvl * 1.)
    endfunction
    
    struct Bolts
        unit Caster
        unit Target
        unit Dummyunit
        real Disttogo
        real Disthalved
    endstruct
    
    private function MoveUnits takes nothing returns boolean
        local Bolts b = KT_GetData()
        local integer level = GetUnitAbilityLevel(b.Caster, ABILITY_CODE)
        local real damage = DAMAGE(level, b.Caster)
        local real units = DUMMY_UNITS(level)
        local real casterx = GetUnitX(b.Caster)
        local real castery = GetUnitY(b.Caster)
        local real targetx = GetUnitX(b.Target)
        local real targety = GetUnitY(b.Target)
        local real dummyx = GetUnitX(b.Dummyunit)
        local real dummyy = GetUnitY(b.Dummyunit)
        local real distx = targetx - dummyx
        local real disty = targety - dummyy
        local real distance = SquareRoot(distx * distx + disty * disty)
        local real offsetx
        local real offsety
        local real angle = GetUnitFacing(b.Dummyunit)
    if distance <= 50 then
        call UnitDamageTarget(b.Caster, b.Target, (damage / units), false, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE)
        call KillUnit(b.Dummyunit)
        call b.destroy()
        return true
    elseif b.Disttogo <= b.Disthalved then
        set angle = bj_RADTODEG * Atan2(targety - dummyy, targetx - dummyx)
        set offsetx = dummyx + OFFSET * Cos(angle * bj_DEGTORAD)
        set offsety = dummyy + OFFSET * Sin(angle * bj_DEGTORAD)
        call SetUnitX(b.Dummyunit, offsetx)
        call SetUnitY(b.Dummyunit, offsety)
        call SetUnitFacing(b.Dummyunit, angle)
    else
        set b.Disttogo = b.Disttogo - OFFSET
        set offsetx = dummyx + OFFSET * Cos(angle * bj_DEGTORAD)
        set offsety = dummyy + OFFSET * Sin(angle * bj_DEGTORAD)
        call SetUnitX(b.Dummyunit, offsetx)
        call SetUnitY(b.Dummyunit, offsety)
        call SetUnitFacing(b.Dummyunit, angle + .25)
        endif
        return false
    endfunction
    
    private function CreateStructs takes unit caster, unit target, real facing returns nothing
        local Bolts b = Bolts.create()
        local integer level = GetUnitAbilityLevel(b.Caster, ABILITY_CODE)
        local real units = DUMMY_UNITS(level)
        local real casterx = GetUnitX(caster)
        local real castery = GetUnitY(caster)
        local real targetx = GetUnitX(target)
        local real targety = GetUnitY(target)
        local real Distx = targetx - casterx
        local real Disty = targety - castery
        set b.Caster = caster
        set b.Target = target
        set b.Disttogo = SquareRoot(Distx * Distx + Disty * Disty)
        set b.Disthalved = b.Disttogo / 2
        set b.Dummyunit = CreateUnit( GetTriggerPlayer(), DUMMY_ID, casterx, castery, facing)
        call KT_Add( function MoveUnits, b, 0.03)
    endfunction

    private function OnCast takes nothing returns nothing
        local integer level = GetUnitAbilityLevel(GetTriggerUnit(), ABILITY_CODE)
        local real units = DUMMY_UNITS(level)
        local unit caster = GetTriggerUnit()
        local unit target = GetSpellTargetUnit()
        local integer i = 0
        local real angle = bj_RADTODEG * Atan2(GetUnitY(target) - GetUnitY(caster), GetUnitX(target) - GetUnitX(caster)) + 50
    if GetSpellAbilityId() == ABILITY_CODE then
        loop
            exitwhen i == units
            call CreateStructs(caster, target, (angle - 10 * i))
            set i = i + 1
        endloop
        set caster = null
        set target = null
    endif
    endfunction

    //===========================================================================
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerAddAction( t, function OnCast )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    endfunction
endscope

Keywords:
Magic, Bolts, Fire, Rapid, Key Timers, Key Timers 2, Timer, Fast, Move, Bounce
Contents

Just another Warcraft III map (Map)

Reviews
12.12 IcemanBo: For long time as NeedsFix. Rejected. 14:19, 7th Apr 2011 Bribe: I've decided, KeyTimers2 is no longer an acceptable library resource. It is way too slow, way too cumbersome. Timer32 or a simple stack-loop should be used for...

Moderator

M

Moderator

12.12
IcemanBo: For long time as NeedsFix. Rejected.

14:19, 7th Apr 2011
Bribe:

I've decided, KeyTimers2 is no longer an acceptable library resource. It is way too slow, way too cumbersome. Timer32 or a simple stack-loop should be used for this instead.

There is a lot of bj_RADTODEG, just do it all in radians except in unit-facing.
 
Level 15
Joined
Jul 6, 2009
Messages
889
I understand, you mean at the getting the angles?

Probably, I don't mean much. But this:

JASS:
        set angle = bj_RADTODEG * Atan2(targety - dummyy, targetx - dummyx)
        set offsetx = dummyx + OFFSET * Cos(angle * bj_DEGTORAD)
        set offsety = dummyy + OFFSET * Sin(angle * bj_DEGTORAD)

Why do you convert from radians to degrees, then from degrees to radians again?
 
Top