• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[JASS] Orbital Bombardment

Status
Not open for further replies.
Here's the script:

JASS:
struct kb //knock back
    unit u
    real angle
    real speed
    real friction
endstruct
globals
    group OB_hit=CreateGroup() //to prevent multiple knockbacks.
endglobals
constant function OB_Id takes nothing returns integer
    return 'A0KU'
endfunction
constant function OB_UnitId takes nothing returns integer
    return 'hpea'
endfunction
constant function OB_TimerSpeed takes nothing returns real
    return 0.035
endfunction
constant function OB_FallSpeed takes nothing returns real
    return 1600.00*OB_TimerSpeed() // how fast the bombs fall
endfunction
constant function OB_StartEffectScale takes real level returns real
    return 4.00
endfunction
constant function OB_Height takes nothing returns real
    return 1200.00 //starting height of the bombs
endfunction
constant function OB_Radius takes real l returns real
    return 500.00 //the radius at where the bombs are dropped
endfunction
constant function OB_StartEffect takes nothing returns string
    return "Abilities\\Spells\\NightElf\\TrueshotAura\\TrueshotAura.mdl" //the effect that comes whenever the spell is cast
endfunction
constant function OB_DamageRadius takes real l returns real
    return 230.00 //radius of the bombs when they explode
endfunction
constant function OB_BombInterval takes real l returns real
    return 0.20 //interval between bombs being dropped
endfunction
constant function OB_WaveInterval takes real l returns real
    return 1.20 //interval between waves
endfunction
constant function OB_StartInterval takes real l returns real
    return 4.00 //waiting time before bombing starts
endfunction
constant function OB_Damage takes real l returns real
    return 150*l //damage from each bomb
endfunction
constant function OB_Scale takes real l returns real
    return 1.60 //size of the bombs
endfunction
constant function OB_KnockBackSpeed takes real l returns real
    return 700.00 //distance knocked back per sec
endfunction
constant function OB_KnockBackFriction takes real l returns real
    return 600.00 //knockback decreasing each second
endfunction
constant function OB_Model takes nothing returns string
    return "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" //bomb model
endfunction
constant function OB_Explosion takes nothing returns string
    return "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl"//explosion model
endfunction
constant function OB_KnockbackEffect takes nothing returns string
    return "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl" //the effect on units hit
endfunction
constant function OB_Knockback_AP takes nothing returns string
    return "origin" //attachment point for knockback effect
endfunction
//==================================================================
function ProjectX takes real x, real dist, real angle returns real
    return x+dist*Cos(angle*0.01745)
endfunction
 
function ProjectY takes real y, real dist, real angle returns real
    return y+dist*Sin(angle*0.01745)
endfunction
 
function GetAngleBetweenPoints takes real x1, real y1, real x2, real y2 returns real
    return 57.29582 * Atan2(y2-y1, x2-x1)
endfunction
function TimedWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = NewTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > 2.00) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(0.10)
            endif
        endloop
        call ReleaseTimer(t)
    endif
endfunction

function OB_Filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(),UNIT_TYPE_GROUND)
endfunction
 
function AddSpecialEffectTargetForPlayer takes string path, widget target,string ap , player p returns effect
    local string model = ""
    if ( GetLocalPlayer() == p ) then
        set model = path
    endif
    return AddSpecialEffectTarget( model, target, ap)
endfunction

function OB_KnockBackfunc takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local kb k=GetCSData(t)
    if k.speed <= 0 then
        call GroupRemoveUnit(OB_hit,k.u)
        call kb.destroy(k)
        call ReleaseTimer(t)
    else
        call DestroyEffect(AddSpecialEffectTarget(OB_KnockbackEffect(),k.u,OB_Knockback_AP()))
        call SetUnitX(k.u,ProjectX(GetUnitX(k.u),k.speed*OB_TimerSpeed(),k.angle))
        call SetUnitY(k.u,ProjectY(GetUnitY(k.u),k.speed*OB_TimerSpeed(),k.angle))
        set k.speed=k.speed-k.friction*OB_TimerSpeed()
    endif
endfunction
function OB_KnockBack takes unit u,real speed,real angle,real friction returns nothing
    local timer t=NewTimer()
    local kb k=kb.create()
    if IsUnitInGroup(u,OB_hit) == false then
        set k.u=u
        set k.speed=speed
        set k.angle=angle
        set k.friction=friction
        call SetCSData(t,k)
        call GroupAddUnit(OB_hit,u)
        call TimerStart(t,OB_TimerSpeed(),true,function OB_KnockBackfunc)
    endif
endfunction
function OB_Bombs takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local unit u=I2U(GetCSData(t))
    local group g
    local integer i=0
    local unit eu
    local integer l=GetUnitUserData(u)
    call SetUnitFlyHeight(u,GetUnitFlyHeight(u)-OB_FallSpeed(),0)
    if GetUnitFlyHeight(u) <= 1 then
        set g=CreateGroup()
        call DestroyEffect(I2Effect(GetCSData(u)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,330),ProjectY(GetUnitY(u),100,330)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,300),ProjectY(GetUnitY(u),100,300)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,240),ProjectY(GetUnitY(u),100,240)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,210),ProjectY(GetUnitY(u),100,210)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,150),ProjectY(GetUnitY(u),100,150)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,120),ProjectY(GetUnitY(u),100,120)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,60),ProjectY(GetUnitY(u),100,60)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),ProjectX(GetUnitX(u),100,30),ProjectY(GetUnitY(u),100,30)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)+100))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u),GetUnitY(u)-100))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u)+100,GetUnitY(u)))
        call DestroyEffect(AddSpecialEffect(OB_Explosion(),GetUnitX(u)-100,GetUnitY(u)))
        call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),OB_DamageRadius(0),Condition(function OB_Filter))
        loop
            set eu=FirstOfGroup(g)
            exitwhen eu==null
            if GetWidgetLife(eu) > 0.405 then
                call UnitDamageTarget(u,eu,OB_Damage(l),false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_DEMOLITION,null)
                call OB_KnockBack(eu,OB_KnockBackSpeed(l),GetAngleBetweenPoints(GetUnitX(u),GetUnitY(u),GetUnitX(eu),GetUnitY(eu)),OB_KnockBackFriction(l))
            endif
            call GroupRemoveUnit(g,eu)
        endloop
        call ReleaseTimer(t)
        call RemoveUnit(u)
        call DestroyGroup(g)
        set u=null
        set g=null
        set eu=null
    endif
endfunction

function OB_CreateBomb takes player p, integer l, real x, real y returns nothing
    local unit u
    local timer t=NewTimer()
    set u=CreateUnit(p,OB_UnitId(),GetRandomReal(x-OB_Radius(l),x+OB_Radius(l)),GetRandomReal(y-OB_Radius(l),y+OB_Radius(l)),270.00)
    call SetUnitFlyHeight(u,OB_Height(),0)
    call SetUnitScale(u,OB_Scale(l),OB_Scale(l),OB_Scale(l))
    call SetUnitTimeScale(u,0)
    call SetCSData(t,H2I(u))
    call SetCSData(u,H2I(AddSpecialEffectTarget(OB_Model(),u,"origin")))
    call SetUnitUserData(u,l)
    call SetUnitAnimationByIndex(u,0)
    call UnitAddAbility(u,'Arav')
    call UnitRemoveAbility(u,'Arav')
    call SetUnitFlyHeight(u,OB_Height(),0)
    call TimerStart(t,OB_TimerSpeed(),true,function OB_Bombs)
    set u=null
endfunction

function OB_Actions takes nothing returns nothing
    local unit cast=GetTriggerUnit()
    local integer l=GetUnitAbilityLevel(cast,OB_Id())
    local location targ=GetSpellTargetLoc()
    local real x=GetLocationX(targ)
    local real y=GetLocationY(targ)
    local effect e
    local unit u=CreateUnit(GetOwningPlayer(cast),OB_UnitId(),x,y,90)
    call SetUnitScale(u,OB_StartEffectScale(l),OB_StartEffectScale(l),OB_StartEffectScale(l))
    set e=AddSpecialEffectTargetForPlayer(OB_StartEffect(),u,"origin",GetOwningPlayer(cast))
    call SetUnitTimeScale(u,0)
    call TimedWait(OB_StartInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_WaveInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_WaveInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call TimedWait(OB_BombInterval(l))
    call OB_CreateBomb(GetOwningPlayer(cast),l,x,y)
    call DestroyEffect(e)
    call RemoveUnit(u)
    call RemoveLocation(targ)
    set targ=null
    set cast=null
    set u=null
    set e=null
endfunction

function OB_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == OB_Id()
endfunction

//===========================================================================
function InitTrig_Orbital_Bombardment takes nothing returns nothing
    set gg_trg_Orbital_Bombardment = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Orbital_Bombardment, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Orbital_Bombardment, Condition( function OB_Conditions ) )
    call TriggerAddAction( gg_trg_Orbital_Bombardment, function OB_Actions )
endfunction
 
Last edited:
I tried adding *I2R(GetHeroInt(u, true)) to it there but it gave me an error when i save the map. What should i add there to change the damage?
 
I also tried adding it to the line
call UnitDamageTarget(u,eu,OB_Damage(l)*I2R... it still doesn't seem to work. I'm only familiar with GUI atm, so can you tell me where to insert the code and which to insert?
 
Alright thanks I'll change it and test it out in a bit

Update:

Since the ability has more than 1 level I changed that line into:

local integer l=GetUnitAbilityLevel(cast,OB_Id())*GetHeroInt(cast, true)

It still doesn't seem to work though.
 
Last edited:
Status
Not open for further replies.
Back
Top