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

Juggernaut Blast Ability

Status
Not open for further replies.
I'm looking for an ability that simulates the attached WC3 Juggernaut model firing all of it's cannons at once (5 in the front, 5 in the back). It needs to create an explosion for each cannon at a uniform radius around the Juggernaut, instant cast, that correctly aligns the explosions with the cannons. So what won't work is an ability that just creates 10 points, the explosions need to line up no matter what angle the Juggernaut faces. The explosions should also be scaled so that the size matches the cannon that fired.
 

Attachments

  • 34f34t.png
    34f34t.png
    2.3 MB · Views: 165
watermelon_1234 was kind enough to provide exactly what I wanted.

JASS:
//==========================================================================================
// Bombardment v1.00 by watermelon_1234
//******************************************************************************************
// Libraries required: (Libraries with * are optional)
//  - GroupUtils
//  - SpellEvent
//  - xemissile
//##########################################################################################
// Importing:
//  1. Copy the ability, Bombardment
//  2. Implement the required libraries
//  3. Copy this trigger
//  4. Configure the spell
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Notes:
//  - Configuration can be pretty messy. I suggest configuring each cannon's settings
//    separately and testing a lot to make sure nothing is off.
//  - The directions I refer to are all from the perspective of a person standing at the
//    front of the ship.
//==========================================================================================

scope Bombardment initializer Init

//==========================================================================================
//                              CONSTANTS
//==========================================================================================    
    globals
    
//------------------------------------------------------------------------------------------
//      General spell settings
//------------------------------------------------------------------------------------------        
        
        private constant integer    SPELL_ID = 'A004'                   // Raw id of the Bombardment ability
        
        private constant attacktype ATK_TYPE = ATTACK_TYPE_CHAOS        // Attack type
        private constant damagetype DMG_TYPE = DAMAGE_TYPE_UNIVERSAL    // Damage type
        private constant weapontype WPN_TYPE = null                     // Weapon type

//------------------------------------------------------------------------------------------
//      General cannonball settings
//------------------------------------------------------------------------------------------        
        
        private constant string CANNONBALL_SFX          = "war3mapImported\\SuperpultProjectile.mdl" // Path of the cannonball sfx
        private constant real   CANNONBALL_LAND_HEIGHT  = 0.            // Height at which the cannonball lands

//------------------------------------------------------------------------------------------
//      Big cannon settings
//------------------------------------------------------------------------------------------        
        
        private constant real BIG_CANNON_SCALE          = 1.75  // Scaling of the cannonball   
        private constant real BIG_CANNON_AOE            = 250.  // AoE of the cannonball's damage
        private constant real BIG_CANNON_HEIGHT         = 75.   // Initial height of the cannonball       
        private constant real BIG_CANNON_HORI_OFFSET    = -10   // Horizontal offset from the ship's coordinates
        private constant real BIG_CANNON_VERT_OFFSET    = 145.  // Vertical offset from the ship's coordinates       
        private constant real BIG_CANNON_ARC            = 0.04  // Arc of missile
        
//------------------------------------------------------------------------------------------
//      Medium cannon settings
//------------------------------------------------------------------------------------------  
        
        private constant real MED_CANNON_SCALE          = 1.25      // Scaling of the cannonball                  
        private constant real MED_CANNON_AOE            = 175.      // AoE of the cannonball's damage
        private constant real MED_CANNON_HEIGHT         = 75.       // Initial height of the cannonball
        private constant real MED_CANNON_HORI_OFFSET    = 30        // Horizontal offset from the ship's coordinates
        private constant real MED_CANNON_VERT_OFFSET    = 125.      // Vertical offset from the ship's coordinates
        private constant real MED_CANNON_FIX_OFFSET     = 35.       // Offset correction since the juggernaut isn't symmetrically divided at its coordinates       
        private constant real MED_ANG_OFFSET            = bj_PI/10  // The angle at which the cannonballs are shot at
        private constant real MED_CANNON_ARC            = 0.08      // Arc of missile
        
//------------------------------------------------------------------------------------------
//      Small cannon settings
//------------------------------------------------------------------------------------------ 

        private constant real SMA_CANNON_SCALE          = .75   // Scaling of the cannonball   
        private constant real SMA_CANNON_AOE            = 125.  // AoE of the cannonball's damage
        private constant real SMA_CANNON_HEIGHT         = 115.  // Initial height of the cannonball
        private constant real SMA_CANNON_HORI_OFFSET    = 10.   // Horizontal offset from the ship's coordinates
        private constant real SMA_CANNON_VERT_OFFSET    = 65.   // Vertical offset from the ship's coordinates
        private constant real SMA_CANNON_FIX_OFFSET     = 25.   // Offset correction since the juggernaut isn't symmetrically divided at its coordinates
        private constant real SMA_CANNON_ARC            = 0.1   // Arc of missile
    endglobals
    
//==========================================================================================
//                              OTHER CONFIGURATION
//==========================================================================================
    
    // Units that will be damaged by the spell
    private function AffectedTargets takes unit target, player owner returns boolean
        return not IsUnitType(target, UNIT_TYPE_DEAD) and /*
            */ IsUnitEnemy(target, owner) and /*
            */ not IsUnitType(target, UNIT_TYPE_FLYING)
    endfunction
    
    // Speed of cannonball from big cannon
    private constant function BigCannonSpeed takes integer lvl returns real
        return 650.
    endfunction
    
    // Distance travelled of the cannonball shot from big cannon
    private constant function BigCannonDistance takes integer lvl returns real
        return 400.
    endfunction
    
    // Damage dealt by the big cannonball
    private constant function BigCannonDamage takes integer lvl returns real
        return 100.
    endfunction
    
    // Speed of cannonball from medium cannon
    private constant function MediumCannonSpeed takes integer lvl returns real
        return 850.
    endfunction
    
    // Distance travelled of the cannonball shot from medium cannon
    private constant function MediumCannonDistance takes integer lvl returns real
        return 500.
    endfunction
    
    // Damage dealt by the medium cannonball
    private constant function MediumCannonDamage takes integer lvl returns real
        return 65.
    endfunction
    
    // Speed of cannonball from small cannon
    private constant function SmallCannonSpeed takes integer lvl returns real
        return 1150.
    endfunction
    
    // Distance travelled of the cannonball shot from small cannon
    private constant function SmallCannonDistance takes integer lvl returns real
        return 600.
    endfunction
    
    // Damage dealt by the small cannonball
    private constant function SmallCannonDamage takes integer lvl returns real
        return 30.
    endfunction
    
//==========================================================================================
//                              END OF CONFIGURATION
//==========================================================================================

    private struct missile extends xemissile
        unit cast
        integer lvl
        integer s // Used to decide the scale of the cannon ball
        
        method onHit takes nothing returns nothing
            local real area
            local real dmg   
            
            local unit u
            
            // Big cannon
            if .s == 0 then
                set area = BIG_CANNON_AOE
                set dmg = BigCannonDamage(.lvl)
            // Medium cannon
            elseif .s == 1 then
                set area = MED_CANNON_AOE
                set dmg = MediumCannonDamage(.lvl)
            // Small cannon
            else
                set area = SMA_CANNON_AOE
                set dmg = SmallCannonDamage(.lvl)
            endif
            
            call GroupEnumUnitsInArea(ENUM_GROUP, .x, .y, area, null)
            loop
                set u = FirstOfGroup(ENUM_GROUP)
                exitwhen u == null
                call GroupRemoveUnit(ENUM_GROUP, u)
                
                if AffectedTargets(u, GetOwningPlayer(.cast)) then
                    call UnitDamageTarget(.cast, u, dmg, false, true, ATK_TYPE, DMG_TYPE, WPN_TYPE)
                endif
            endloop
        endmethod
        
        static method create takes unit c, integer lvl, real x, real y, real tx, real ty, integer s returns thistype
            local real height
            local real scale
            local real speed
            local real arc
            local thistype this 
            
            // Big cannon
            if s == 0 then
                set height = BIG_CANNON_HEIGHT
                set scale = BIG_CANNON_SCALE
                set speed = BigCannonSpeed(lvl)
                set arc = BIG_CANNON_ARC
                
            // Medium cannon
            elseif s == 1 then
                set height = MED_CANNON_HEIGHT
                set scale = MED_CANNON_SCALE
                set speed = MediumCannonSpeed(lvl)
                set arc = MED_CANNON_ARC
                
            // Small cannon
            else
                set height = SMA_CANNON_HEIGHT
                set scale = SMA_CANNON_SCALE
                set speed = SmallCannonSpeed(lvl)
                set arc = SMA_CANNON_ARC
            endif
            
            set this = thistype.allocate(x, y, height, tx, ty, CANNONBALL_LAND_HEIGHT)
            
            set .cast = c
            set .lvl = lvl
            set .s = s
            
            set .fxpath = CANNONBALL_SFX
            set .scale = scale
            
            call .launch(speed, arc)
            
            return this
        endmethod
    endstruct
    
    private function SpellActions takes nothing returns nothing    
        local integer lvl = GetUnitAbilityLevel(SpellEvent.CastingUnit, SPELL_ID)
        local real faceAng = GetUnitFacing(SpellEvent.CastingUnit) * bj_DEGTORAD
        local real cx = GetUnitX(SpellEvent.CastingUnit)
        local real cy = GetUnitY(SpellEvent.CastingUnit)
        
        local real cos = Cos(faceAng)
        local real sin = Sin(faceAng)
        
        local real x
        local real y
        local real dist
        local real ang
        
        local integer i = -1
        
        // Loops are done in a certain pattern as to create missiles for the front and back
        
       // Big cannons
        set dist = BigCannonDistance(lvl)
        // Front & Back
        loop
            exitwhen i == 3
            
            set x = cx + i * cos * BIG_CANNON_VERT_OFFSET - i * sin * BIG_CANNON_HORI_OFFSET
            set y = cy + i * sin * BIG_CANNON_VERT_OFFSET + i * cos * BIG_CANNON_HORI_OFFSET
            call missile.create(SpellEvent.CastingUnit, lvl, x, y, x + i * dist * cos, y + i * dist * sin, 0)
            
            set i = i + 2
        endloop
        
        set i = -1
       
       // Medium cannons
        set dist = MediumCannonDistance(lvl)
        
        // Front Left and Back Right
        set ang = faceAng + MED_ANG_OFFSET
        loop
            exitwhen i == 3            
            
            set x = cx + i*cos * MED_CANNON_VERT_OFFSET - i * sin * MED_CANNON_HORI_OFFSET
            set y = cy + i*sin * MED_CANNON_VERT_OFFSET + i * cos * MED_CANNON_HORI_OFFSET
            call missile.create(SpellEvent.CastingUnit, lvl, x, y, x + i*dist * Cos(ang), y + i*dist * Sin(ang), 1)
            
            set i = i + 2
        endloop
        
        set i = -1
        
        // Front Right and Back Left
        set ang = faceAng - MED_ANG_OFFSET  
        loop
            exitwhen i == 3
            
            set x = cx + i*cos * MED_CANNON_VERT_OFFSET + i * sin * (MED_CANNON_HORI_OFFSET + MED_CANNON_FIX_OFFSET)
            set y = cy + i*sin * MED_CANNON_VERT_OFFSET - i * cos * MED_CANNON_HORI_OFFSET
            call missile.create(SpellEvent.CastingUnit, lvl, x, y, x + i*dist * Cos(ang), y + i*dist * Sin(ang), 1)
            
            set i = i + 2
        endloop

        
        set i = -1
        
       // Small cannons
        set dist = SmallCannonDistance(lvl)
        // Front Left and Back Right        
        loop
            exitwhen i == 3
            
                set x = cx + i * cos * SMA_CANNON_VERT_OFFSET - i * sin * SMA_CANNON_HORI_OFFSET
                set y = cy + i * sin * SMA_CANNON_VERT_OFFSET + i * cos * SMA_CANNON_HORI_OFFSET
                call missile.create(SpellEvent.CastingUnit, lvl, x, y, x + i * dist * cos, y + i * dist * sin, 2)            
            set i = i + 2
        endloop
        
        set i = -1
        
        // Front Right & Back Left
        loop
            exitwhen i == 3
            
            set x = cx + i * cos * SMA_CANNON_VERT_OFFSET + i * sin * (SMA_CANNON_HORI_OFFSET + SMA_CANNON_FIX_OFFSET)
            set y = cy + i * sin * SMA_CANNON_VERT_OFFSET - i * cos * SMA_CANNON_HORI_OFFSET
            call missile.create(SpellEvent.CastingUnit, lvl, x, y, x + i * dist * cos, y + i * dist * sin, 2)
            
            set i = i + 2
        endloop
    endfunction
    
    private function Init takes nothing returns nothing
        call RegisterSpellEffectResponse(SPELL_ID, SpellActions)
    endfunction
    
endscope
 
Last edited:
Status
Not open for further replies.
Top