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

Bombardment v1.4a

  • Like
Reactions: Magtheridon96
Spell Name: Bombardment v1.4a

Description:
Summons copters from the sky and bombards the target point. Bombs can also destroy trees and has a siege damage so it's useful for bombarding buildings.

|cffffcc00Level 1|r - Each bombs damages 50, bombardment lasts 10 seconds.
|cffffcc00Level 2|r - Each bombs damages 75, bombardment lasts 15 seconds.
|cffffcc00Level 3|r - Each bombs damages 100, bombardment lasts 20 seconds.
|cffffcc00Level 4|r - Each bombs damages 125, bombardment lasts 25 seconds.
|cffffcc00Level 5|r - Each bombs damages 150, bombardment lasts 30 seconds.


JASS:
/*
=====Spell Name: Bombardment v1.4a
=====Created by: Mckill2009

REQUIRES:
- JassNewGenPack by Vexorian

REQUIRED LIBRARIES:
- DestructableLib by PitzerMike (http://www.wc3c.net/showthread.php?t=103927)
- T32 by Jesus4Lyf (http://www.thehelper.net/forums/showthread.php/132538-Timer32)
- RegisterSpellEffectEvent by Bribe (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/)
- RegisterPlayerUnitEvent by Magtheridon96 (http://www.hiveworkshop.com/forums/jass-resources-412/snippet-registerplayerunitevent-203338/)

OPTIONAL LIBRARIES:
- BoundSentinel by Vexorian (http://www.wc3c.net/showthread.php?t=102576)

HOW TO USE:
- Make a new trigger and convert to custom text via EDIT >>> CONVERT CUSTOM TEXT
- Copy ALL that is written here (overwrite the existing texts in the trigger)
- Copy ALL the required libraries stated above
- Copy the Dummy unit and the custom ability OR make your own
- You MUST input or change the correct raw ID's (see below)
- To view raw ID, press CTRL+D in the object editor
*/

scope Bombardment

globals
    //NOTE: The custom ability should be 'Rain of Fire', or change it if you like
    //but the ability order should be equal to CHANNEL_ORDER_ID
    private constant integer            SPELL_ID = 'A001' //raw code (rain of fire)
    private constant integer           COPTER_ID = 'h001' //raw code
    private constant integer             BOMB_ID = 'h000' //raw code
    private constant integer    CHANNEL_ORDER_ID = 852238 //rain of fire
    private constant real             FALL_SPEED = 10. //fall speed of the bomb
    private constant real             MOVE_SPEED = 15. //copter move speed
    private constant real          COPTER_HEIGHT = 300. //copter default height at creation time
    private constant real      CREATION_INTERVAL = 1.5 //interval for copter creation
    private constant real            COPTER_LIFE = 5.0 //life of copter after bomb is released
    private constant real                    AOE = 300.//area of effect for damage
    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 rect Rct
endglobals

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

private function GetDuration takes integer i returns real
    return 5 + i * 5.
endfunction

private function UnitAlive takes unit u returns boolean
    return not IsUnitType(u, UNIT_TYPE_DEAD) 
endfunction

private interface Bomb
    unit caster
    unit copter
    real damage
    real distance
    real xSpell
    real ySpell
endinterface

//===Bombs Explode
private struct BombExplode extends Bomb
    unit bomb
    real height  
    
    static method getDestructables takes nothing returns boolean
        local destructable d = GetFilterDestructable()
        if IsDestructableTree(d) then
            call KillDestructable(d)
        endif    
        set d = null
        return false
    endmethod  
    
    method periodic takes nothing returns nothing   
        local real x
        local real y
        local unit first
        if .height > 0 then
            set .height = .height - FALL_SPEED
            call SetUnitFlyHeight(.bomb, .height, 0)
        else
            set x = GetUnitX(.bomb)
            set y = GetUnitY(.bomb)
            call DestroyEffect(AddSpecialEffect(SFX, x, y))
            call MoveRectTo(Rct, x, y)
            call EnumDestructablesInRect(Rct, function thistype.getDestructables, null)
            call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, AOE, null)
            loop
                set first = FirstOfGroup(bj_lastCreatedGroup)
                exitwhen first==null
                if UnitAlive(first) and IsUnitEnemy(first, GetOwningPlayer(.bomb)) or IsUnitType(first, UNIT_TYPE_STRUCTURE) then
                    call UnitDamageTarget(.bomb, first, .damage, false, false, ATK, DMG, null)
                endif
                call GroupRemoveUnit(bj_lastCreatedGroup, first)
            endloop
            call KillUnit(.bomb)
            call .stopPeriodic()
            call .destroy() 
        endif    
    endmethod
    
    implement T32x 
    
    static method create takes unit b, real d, real h returns thistype
        local thistype this = thistype.allocate()
        set .bomb = b
        set .damage = d
        set .height = h       
        call .startPeriodic()    
        return this
    endmethod

endstruct

//Copters Appear
private struct Copter extends Bomb
    real angle 
    integer chk
    
    method periodic takes nothing returns nothing
        local unit bomb
        if UnitAlive(.copter) then
            call SetUnitPosition(.copter, GetUnitX(.copter)+MOVE_SPEED*Cos(.angle), GetUnitY(.copter)+MOVE_SPEED*Sin(.angle))
            if .distance > 0 then
                set .distance = .distance - MOVE_SPEED
            elseif .chk==1 then
                set .chk = 0
                set bomb = CreateUnit(GetOwningPlayer(.copter), BOMB_ID, .xSpell, .ySpell, GetUnitFacing(.copter))
                call SetUnitFlyHeight(bomb, COPTER_HEIGHT, 0)
                call BombExplode.create(bomb, .damage, COPTER_HEIGHT)
                call UnitApplyTimedLife(.copter, 'BTLF', COPTER_LIFE)
            endif
        else
            call .stopPeriodic()
            call .destroy()            
        endif       
    endmethod
    
    implement T32x  
    
    static method create takes unit copter, real damage, real distance, real x, real y returns thistype
        local thistype this = thistype.allocate()
        set .copter = copter
        set .damage = damage
        set .angle = Atan2(y-GetUnitY(copter), x-GetUnitX(copter))
        set .distance = distance
        set .chk = 1
        set .xSpell = x
        set .ySpell = y
        call .startPeriodic()     
        return this
    endmethod   
endstruct

//===Cast
private struct Bombardment extends Bomb
    real xUnit
    real yUnit
    real duration
    real creationgap 
   
    method periodic takes nothing returns nothing
        local unit copter
        if .duration > 0 and GetUnitCurrentOrder(.caster)==CHANNEL_ORDER_ID and UnitAlive(.caster) then
            set .duration = .duration - T32_PERIOD
            set .creationgap = .creationgap + T32_PERIOD
            if .creationgap >= CREATION_INTERVAL then
                set .creationgap = 0
                set copter = CreateUnit(GetOwningPlayer(.caster), COPTER_ID, .xUnit, .yUnit, GetUnitFacing(.caster))
                call SetUnitFlyHeight(copter, COPTER_HEIGHT, 0)
                call Copter.create(copter, .damage, .distance, .xSpell, .ySpell)
                set copter = null
            endif
        else
            call IssueImmediateOrder(.caster, "stop")
            call .stopPeriodic()
            call .destroy()
        endif   
    endmethod
    
    implement T32x  
    
    private static method create takes nothing returns thistype
        local thistype this = thistype.allocate()
        local integer level
        set .caster = GetTriggerUnit()
        set level = GetUnitAbilityLevel(.caster, SPELL_ID)
        set .xUnit = GetUnitX(.caster)
        set .yUnit = GetUnitY(.caster)
        set .xSpell = GetSpellTargetX()
        set .ySpell = GetSpellTargetY()
        set .duration = GetDuration(level)
        set .damage = GetDamage(level)
        set .distance = SquareRoot((.xSpell-.xUnit) * (.xSpell-.xUnit) + (.ySpell-.yUnit) * (.ySpell-.yUnit)) 
        set .creationgap = CREATION_INTERVAL
        call .startPeriodic()    
        return this
    endmethod
    
    private static method onInit takes nothing returns nothing
        set Rct = Rect(-AOE, -AOE, AOE, AOE)
        call RegisterSpellEffectEvent(SPELL_ID, function thistype.create)
        call Preload(SFX)
    endmethod
endstruct

endscope



v1.4
- TimedLoop replaced by T32
- Rect changed to a global
- Added SpellEffectEvent by Bribe

v1.3a
- Code fixed to cast on every spell tnx to Ruke for pointing that out

v1.3
- Converted to vJass with libraries.
- Removed NTimer.
- Now it's channeled.
- Description changed & codes optimized.

v1.2
- Terrain deformations has been removed.
- Filtered trees.
- Allign script in the initialization part.
- Uses release timer. By baassee


Keywords:
copter, bombs, rockets, modern, warfare, battle, air, plane
Contents

Bombardment v1.4a (Map)

Reviews
18 Feb 2012 Bribe: Thanks for making the changes. Approved 3.5/5.

Moderator

M

Moderator

18 Feb 2012
Bribe: Thanks for making the changes. Approved 3.5/5.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
I'm not at my computer so I didn't test the spell.

Comments:

Should be right after Bom = Bom - 1
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
  • If - Conditions
  • BOM_In1 Equal to 0
  • Then - Actions
  • Custom script: call RemoveLocation(udg_BOM_Pt1[udg_BOM_In3Loop])
  • Custom script: call RemoveLocation(udg_BOM_Pt2[udg_BOM_In3Loop])
  • Custom script: call RemoveLocation(udg_BOM_Pt3[udg_BOM_In3Loop])
  • Set BOM_In2 = 0
  • Trigger - Turn off (This trigger)
  • Unit - Order (Triggering unit) to Move To BOM_AwayPt[2]
A unit ordered to move to a point does not necessarily move straight to the point, it can have a wiggling path to the point.

Trig 4 could possibly be eliminated by setting "does not decay" in object manager.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
Should be right after Bom = Bom - 1

you mean the clearing of leaks?...

A unit ordered to move to a point does not necessarily move straight to the point, it can have a wiggling path to the point.

the point of 'going' away is not necessarily 'going straight', as long as it 'goes away' anyway tnx for this info...

Trig 4 could possibly be eliminated by setting "does not decay" in object manager.

will it 'NOT' play its death animation? coz the purpose of trig 4 is 'not' to play its death animation, if you get what I mean :)...
 
Level 10
Joined
Apr 22, 2010
Messages
421
Just because it is a ultimate, dosent mean i cant have levels, i am trying to make a five level ultimate that is just what this spell is like, so why not just explain, why can this ability not have levels? And if it can, then how do you edit this to suit the needs of a leveling spell?
 
Level 10
Joined
Sep 19, 2011
Messages
527
JASS:
    private static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()          
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t, function thistype.create)
        call Preload(SFX)
        @set t = null@
    endmethod

You don't need to null it.

What happens if I cast another spell? You missed the conditions xD.

In "getDestructables" method, you don't null the "d" variable.

Amm... Don't you need the "destroy" method?

Nice spell :)

EDIT: Use requires/uses to know what libraries uses your spell.
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
- You don't need to null it.
Yes, but It's my feeling to do it :)...

- What happens if I cast another spell? You missed the conditions xD.
I totally missed that, haha, Im thinking that Im using RegisterSpellEffectEvent library...

- In "getDestructables" method, you don't null the "d" variable.
I'll fix that...

- Amm... Don't you need the "destroy" method?
It's already in the TimedLoop library, if it returns false, it will call .destroy()...

- Use requires/uses to know what libraries uses your spell.
It's already stated in the description above, plus I preffer to use scopes for spells & libraries for systems...



- so its one plane dropping a bomb followed by the same thing... why dont u make 1 plane total that drops a set number of bombs...
Maybe next spell, not this one ;)...
 
Level 7
Joined
Sep 2, 2011
Messages
350
I have nothing more to say, it does what it is coded to be done.

Rating: 4/5
It is MUI
Leakless
Simple yet cool
Clean triggers
Job well done, Sir


Happy Holidays
 
Level 10
Joined
Sep 19, 2011
Messages
527
That's PER STRUCT dude and so does TimedLoop, it does not Destroy a timer, just pauses
it, see the code and read it carefully, if the timer is null, it creates it but the timer is NOT
nulled anymore after the creation so ONLY 1 TIMER...

You cant implement T32 twice inside a struct, so does TimedLoop...

I know that. But T32 and CTL only uses 1 timer. This one, uses 1 timer per implement/struct, can you see the difference?
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
I see this spell is just like Bombardier's ulti (HoN).. And I love it.. Gonna check this!
Reviews and suggestions
The bombardment is too slow I think.. It's better to remove the copter (not killing it) after some seconds.
And I have a good idea for you.. Maybe you can lower the copter's flying height after he is summoned and sets his flying height higher after he lands the bomb. It makes your spell become more realistic
 
Level 29
Joined
Mar 10, 2009
Messages
5,016
The bombardment is too slow I think.. It's better to remove the copter (not killing it) after some seconds.

FALL_SPEED set to high value...

And I have a good idea for you.. Maybe you can lower the copter's flying height after he is summoned and sets his flying height higher after he lands the bomb. It makes your spell become more realistic

COPTER_HEIGHT set to lower value, I've done the increasing of flying height in past versions, but there are people who doesnt like it...
 
Top