[vJASS] Atomic Bomb v3.1.0.1

This bundle is marked as approved. It works and satisfies the submission rules.
The documentation explains everything you need to know.

JASS:
/*************************************
*
*   AtomicBomb
*   v3.1.0.1
*   By Magtheridon96
*
*   - Creates a bombing plane behind the caster
*     that will drop an atomic bomb dealing damage
*     to enemy units in an area of effect. Deals
*     bonus damage to closer units.
*
*   Requires:
*   ---------
*
*       - CTL by Nestharus
*           - hiveworkshop.com/forums/jass-resources-412/snippet-constant-timer-loop-32-a-201381/
*       - SpellEffectEvent by Bribe
*           - hiveworkshop.com/forums/jass-resources-412/snippet-spelleffectevent-187193/
*       - Particle by Nestharus
*           - hiveworkshop.com/forums/submissions-414/snippet-needs-work-particle-206279/
*
*       Optional:
*       ---------
*
*           - TimerUtils by Vexorian (This also caters to my version of TimerUtils in the Hive Jass section Graveyard)
*               - wc3c.net/showthread.php?t=101322
*
*   Importing:
*   ----------
*
*       - Copy this code to a new trigger.
*       - Make sure you have all the requirements implemented too.
*       - Go the object editor and copy/paste the objects to your map (1 ability, 2 dummy units).
*       - There is also an object called Particle that you need which is part of the Particle library.
*       - Import the special effect and dummy.mdl to your map.
*       - Configure the data in the globals to your liking.
*       - Done!
*
*   Credits:
*   --------
*
*       - WILL THE ALMIGHTY (Explosion Effect)
*       - Bribe (SpellEffectEvent, Table)
*       - Nestharus (CTL, Particle)
*       - Vexorian (TimerUtils)
*
*************************************/
library AtomicBomb requires CTL, SpellEffectEvent, Particle, optional TimerUtils
    
    // Configuration
    globals
        // The ability raw code
        private constant integer ABIL_CODE = 'A000'
        // The plane dummy unit raw code
        private constant integer PLANE_CODE = 'h003'
        // The bomb dummy unit raw code
        private constant integer BOMB_CODE = 'h001'
        // Explosion Effect
        private constant string EXPLOSION_EFFECT = "war3mapImported\\NuclearExplosion.mdx"
        // The effect that is created when the plane is created.
        private constant string PLANE_IN_EFFECT = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
        // The effect that is created when the plane is destroyed.
        private constant string PLANE_OUT_EFFECT = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
        // How much time should we wait before destroying the explosion effect?
        private constant real DESTROY_EXPLOSION_AFTER = 15.
        // How much time should we wait before destroying the effect created when the plane is created?
        private constant real DESTROY_IN_EFFECT_PARTICLE_AFTER = 1.4
        // How much time should we wait before destroying the effect created when the plane is destroyed?
        private constant real DESTROY_OUT_EFFECT_PARTICLE_AFTER = 1.4
        // Bomb and Plane height
        private constant real BOMB_HEIGHT = 700.
        // Bomb Drop Speed Base (It will accelerate starting from this base-speed)
        private constant real BOMB_DROP_SPEED = 1.
        // Bomb Drop Acceleration
        private constant real BOMB_DROP_ACCEL = 1.
        // The dummy owning player
        private constant player DUMMY_OWNER = Player(13)
        // Destroy trees around the explosion?
        private constant boolean DESTROY_TREES = true
        // The offset from the point from the target point for plane creation
        private constant real PLANE_DISTANCE = 800.
        // How long does the plane stay after it drops the bomb?
        private constant real PLANE_AFTER_DROP = 2.
        // Attack type
        private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
        // Damage type
        private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
        // The largest collision a unit has in your map
        private constant real MAX_COLLISION = 197.
    endglobals
    // End Configuration
    
    // The speed of the plane per 1/32th of a second
    private function GetPlaneSpeedFactor takes integer level returns real
        return 9.
    endfunction
    
    // The damage dealed to each unit
    private function GetDamage takes integer level returns real
        return 150 + level * 75.
    endfunction
    
    // The damage radius
    private function GetDamageRadius takes integer level returns real
        return 275 + level * 75.
    endfunction
    
    // How close do units have to be for the spell to deal bonus damage?
    private function GetBonusDamageRadius takes integer level returns real
        return 125 + level * 50.
    endfunction
    
    // I want the spell to deal double the damage to units closer than the bonus damage radius.
    private function GetBonusDamageFactor takes integer level returns real
        return 1.3
    endfunction
    
    // This function will filter out some targets (Allied, dead, magic immune and structures)
    private function TargetFilter takes player owner, unit caster, unit target returns boolean
        return IsUnitEnemy(target, owner) and not (IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) or IsUnitType(target, UNIT_TYPE_STRUCTURE) or IsUnitType(target, UNIT_TYPE_DEAD) or GetUnitTypeId(target) == 0)
    endfunction
    
    private struct Spell extends array
        private static group enumGroup = CreateGroup()
        
        private static unit array caster
        private static unit array plane
        private static unit array bomb
        private static real array xDis
        private static real array yDis
        private static real array planeX
        private static real array planeY
        private static real array dropX
        private static real array dropY
        private static real array damage
        private static real array radius
        private static real array bonusDamage
        private static real array bonusRadius
        private static real array speed
        private static real array height
        private static integer array counter
        private static integer array level
        private static boolean array dropped
        private static boolean array exploded
        private static player array owner
        
        static if DESTROY_TREES then
            private static rect treeRect = null
            private static unit treeDetector = null
            private static real treesRadius = 0
            private static real treesX = 0
            private static real treesY = 0
            private static method isTree takes destructable d returns boolean
                return IssueTargetOrderById(treeDetector, 852018, d) and IssueImmediateOrderById(treeDetector, 851972)
            endmethod
            private static method destroyTree takes nothing returns nothing
                local destructable d = GetEnumDestructable()
                local real x = GetWidgetX(d) - treesX
                local real y = GetWidgetY(d) - treesY
                // If the destructable is a tree and it is in the circle, kill it
                if x*x+y*y <= treesRadius and isTree(d) then
                    call KillDestructable(d)
                endif
                set d = null
            endmethod
        endif
        
        // You don't need a Table or a hashtable if you have TimerUtils
        static if not LIBRARY_TimerUtils then
            private static Table timerData
        endif
        
        // I want to murder this function
        private static method destroyParticle takes nothing returns nothing
            static if LIBRARY_TimerUtilsEx then
                call Particle(ReleaseTimer(GetExpiredTimer())).destroy()
            elseif LIBRARY_TimerUtils then
                call Particle(GetTimerData(GetExpiredTimer())).destroy()
                call ReleaseTimer(GetExpiredTimer())
            else
                call Particle(timerData[GetHandleId(GetExpiredTimer())]).destroy()
                call DestroyTimer(GetExpiredTimer())
            endif
        endmethod
        
        implement CTL
            local timer t
            local unit u
            local real x
            local real y
        implement CTLExpire
            // Set the planeX and planeY coordinates
            set planeX[this] = planeX[this] + xDis[this]
            set planeY[this] = planeY[this] + yDis[this]
            
            // Moving the plane out of the map bounds would crash the game, so we should make sure the coordinates are sound.
            if planeX[this] <= WorldBounds.maxX or planeX[this] >= WorldBounds.minX or planeY[this] <= WorldBounds.maxY or planeY[this] >= WorldBounds.minY then
                // Move the plane
                call SetUnitX(plane[this], planeX[this])
                call SetUnitY(plane[this], planeY[this])
            endif
            
            // If the bomb has been dropped
            if dropped[this] then
                // If the bomb exploded
                if exploded[this] then
                    
                    // Counter-based checking
                    set counter[this] = counter[this] - 1
                    if counter[this] == 0 then
                    
                        // Destroy the current instance of the spell
                        call this.destroy()
                        
                        // Remove the plane
                        call RemoveUnit(plane[this])
                        
                        // Timer Utils is optional :3
                        // This is a pretty ugly way of creating a special effect with a Z-coordinate.
                        static if LIBRARY_TimerUtils then
                            call TimerStart(NewTimerEx(Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_OUT_EFFECT, 0)), DESTROY_OUT_EFFECT_PARTICLE_AFTER, false, function thistype.destroyParticle)
                        else
                            set t = CreateTimer()
                            set timerData[GetHandleId(t)] = Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_OUT_EFFECT, 0)
                            call TimerStart(t, DESTROY_OUT_EFFECT_PARTICLE_AFTER, false, function thistype.destroyParticle)
                            set t = null
                        endif
                        
                        // Null variables
                        set caster[this] = null
                        set plane[this] = null
                        set bomb[this] = null
                        set owner[this] = null
                    endif
                else
                    // If the height of the bomb is close to 0
                    if height[this] <= 5 then
                        
                        // Destroy the bomb and create the explosion
                        call RemoveUnit(bomb[this])
                        
                        static if LIBRARY_TimerUtils then
                            call TimerStart(NewTimerEx(Particle.createEx(Player(13), dropX[this], dropY[this], 0, 0, 0, 1, 255, 255, 255, 255, EXPLOSION_EFFECT, 0)), DESTROY_EXPLOSION_AFTER, false, function thistype.destroyParticle)
                        else
                            set t = CreateTimer()
                            set timerData[GetHandleId(t)] = Particle.createEx(Player(13), dropX[this], dropY[this], 0, 0, 0, 1, 255, 255, 255, 255, EXPLOSION_EFFECT, 0)
                            call TimerStart(t, DESTROY_EXPLOSION_AFTER, false, function thistype.destroyParticle)
                            set t = null
                        endif
                        
                        // Loop through all units in the area
                        call GroupEnumUnitsInRange(enumGroup, dropX[this], dropY[this], radius[this] + MAX_COLLISION, null)
                        loop
                            set u = FirstOfGroup(enumGroup)
                            exitwhen u == null
                            call GroupRemoveUnit(enumGroup, u)
                            
                            // Check if the target unit passes the filter and make sure he's in the blast radius.
                            if TargetFilter(owner[this], caster[this], u) and IsUnitInRangeXY(u, dropX[this], dropY[this], radius[this]) then
                                
                                set x = GetUnitX(u) - dropX[this]
                                set y = GetUnitY(u) - dropY[this]
                                
                                // If the unit is closer than the bonusRange
                                if x*x+y*y <= bonusRadius[this] then
                                    // We deal the bonus damage
                                    call UnitDamageTarget(caster[this], u, bonusDamage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                                else
                                    // Else, we deal the normal damage
                                    call UnitDamageTarget(caster[this], u, damage[this], false, false, ATTACK_TYPE, DAMAGE_TYPE, null)
                                endif
                            endif
                        endloop
                        
                        static if DESTROY_TREES then
                            call SetRect(treeRect, dropX[this] - radius[this], dropY[this] - radius[this], dropX[this] + radius[this], dropY[this] + radius[this])
                            
                            // Cache tree destroy data
                            set treesRadius = radius[this]*radius[this]
                            set treesX = dropX[this]
                            set treesY = dropY[this]
                            
                            // Enumerate through all destructables in the rect
                            call EnumDestructablesInRect(treeRect, null, function thistype.destroyTree)
                        endif
                        
                        // The counter is now going to be used to determine
                        // the number of iterations before the spell ends.
                        set counter[this] = R2I(PLANE_AFTER_DROP * 32)
                        set exploded[this] = true
                    else
                        // Decrease the bomb's height a bit
                        set height[this] = height[this] - speed[this]
                        call SetUnitFlyHeight(bomb[this], height[this], 0)
                        
                        // Accelerate drop speed
                        set speed[this] = speed[this] + BOMB_DROP_ACCEL
                    endif
                endif
            else
                // Decrease the counter by 1
                set counter[this] = counter[this] - 1
                // When the counter is 0, the plane has reached it's destination.
                if counter[this] == 0 then
                    // Store the dropX and dropY coordinates
                    set dropX[this] = planeX[this]
                    set dropY[this] = planeY[this]
                    
                    // Create the bomb under the plane
                    set bomb[this] = CreateUnit(DUMMY_OWNER, BOMB_CODE, dropX[this], dropY[this], 0)
                    
                    // Set the bomb's height
                    call UnitAddAbility(bomb[this], 'Amrf')
                    call UnitRemoveAbility(bomb[this], 'Amrf')
                    call SetUnitFlyHeight(bomb[this], BOMB_HEIGHT, 0)
                    
                    // We have dropped the bomb
                    set dropped[this] = true
                    
                    // Set the bomb height and the bomb drop speed
                    set height[this] = BOMB_HEIGHT
                    set speed[this] = BOMB_DROP_SPEED
                endif
            endif
        implement CTLNull
            set u = null
        implement CTLEnd
        
        private static method run takes nothing returns nothing
            local thistype this = create()
            local real x = GetSpellTargetX()
            local real y = GetSpellTargetY()
            local real a
            local real s
            local real cos
            local real sin
            local timer t
            
            // Set the caster and the owner and the level of the ability
            set caster[this] = GetTriggerUnit()
            set owner[this] = GetTriggerPlayer()
            set level[this] = GetUnitAbilityLevel(caster[this], ABIL_CODE)
            
            // Cache angle data
            set a = Atan2(y - GetUnitY(caster[this]), x - GetUnitX(caster[this]))
            set cos = Cos(a)
            set sin = Sin(a)
            
            // Set the plane coordinates
            set planeX[this] = x - PLANE_DISTANCE * cos
            set planeY[this] = y - PLANE_DISTANCE * sin
            
            // Create the plane
            set plane[this] = CreateUnit(DUMMY_OWNER, PLANE_CODE, planeX[this], planeY[this], a * bj_RADTODEG)
            
            // Set the speed and x/yOffsets per timeout
            set s = GetPlaneSpeedFactor(level[this])
            set xDis[this] = cos * s
            set yDis[this] = sin * s
            
            // We haven't dropped or exploded the bomb
            set dropped[this] = false
            set exploded[this] = false
            
            // Number of iterations before the bomb drops
            set counter[this] = R2I(PLANE_DISTANCE / s)
            
            // Set the plane's height
            call UnitAddAbility(plane[this], 'Amrf')
            call UnitRemoveAbility(plane[this], 'Amrf')
            call SetUnitFlyHeight(plane[this], BOMB_HEIGHT, 0)
            
            // TimerUtils is optional
            // This is an ugly way of creating a special effect with Z
            static if LIBRARY_TimerUtils then
                call TimerStart(NewTimerEx(Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_IN_EFFECT, 0)), DESTROY_IN_EFFECT_PARTICLE_AFTER, false, function thistype.destroyParticle)
            else
                set t = CreateTimer()
                set timerData[GetHandleId(t)] = Particle.createEx(Player(13), planeX[this], planeY[this], BOMB_HEIGHT, 0, 0, 1, 255, 255, 255, 255, PLANE_IN_EFFECT, 0)
                call TimerStart(t, DESTROY_IN_EFFECT_PARTICLE_AFTER, false, function thistype.destroyParticle)
                set t = null
            endif
            
            // Set the damage and the radius
            set damage[this] = GetDamage(level[this])
            set radius[this] = GetDamageRadius(level[this])
            
            // Set the bonus damage and the bonus radius
            set a = GetBonusDamageRadius(level[this])
            set bonusRadius[this] = a*a
            set bonusDamage[this] = GetBonusDamageFactor(level[this])*damage[this]
        endmethod
        
        private static method onInit takes nothing returns nothing
            // Register the spell to SpellEffectEvent
            call RegisterSpellEffectEvent(ABIL_CODE, function thistype.run)
            
            static if DESTROY_TREES then
                set treeDetector = CreateUnit(Player(15), 'hfoo', 0, 0, 0)
                call UnitAddAbility(treeDetector, 'Ahrl')
                call UnitAddAbility(treeDetector, 'Aloc')
                call ShowUnit(treeDetector, false)
                set treeRect = Rect(0,0,0,0)
            endif
            
            // If you don't have TimerUtils, you need a Table
            static if not LIBRARY_TimerUtils then
                set timerData = Table.create()
            endif
        endmethod
    endstruct
endlibrary

Finally, after more than a year, I've updated this spell and it works perfectly :)
It used to be in GUI, but I finally had the time to rewrite and fix it.

Oh, and the testmap is a must-see ;)
I made it so that it's like a demonstration :D
Just type 'start', then sit back and watch the show 8)

Keywords:
Bomb, Bomber, Nuke, Nuclear, Explosion, Magtheridon96, Explode, Atom, Atomic, Naruto, DotA, Kamehameha, Omnislash, Meathook, Meat hook.
Contents

new map (Map)

Reviews
6 April 2012 Bribe: This is a very good example of well-written, readable code, and since it works flawlessly from what I can tell from my tests, I will go for approving this.

Moderator

M

Moderator

6 April 2012
Bribe: This is a very good example of well-written, readable code, and since it works flawlessly from what I can tell from my tests, I will go for approving this.
 
  • Custom script: call RemoveLocation ( udg_AtomicBomb_Target_Point[udg_AtomicBomb_Index] )
I fixed it. :ogre_haosis: :goblin_yeah:

I hope there aren't anymore leaks.

Oh and btw i forgot to write a Changelog ( even though it's almost nothing )

The full trigger is below:

  • Atomic Bomb
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Atomic Bomb
    • Actions
      • Set AtomicBomb_Index = (AtomicBomb_Index + 1)
      • Set AtomicBomb_Caster[AtomicBomb_Index] = (Casting unit)
      • Set AtomicBomb_Level[AtomicBomb_Index] = (Level of Atomic Bomb for AtomicBomb_Caster[AtomicBomb_Index])
      • Set AtomicBomb_Damage[AtomicBomb_Index] = (100 + (AtomicBomb_Level[AtomicBomb_Index] x 125))
      • Set AtomicBomb_Target_Point[AtomicBomb_Index] = (Target point of ability being cast)
      • Unit - Create 1 Dummy (rocket) for (Owner of AtomicBomb_Caster[AtomicBomb_Index]) at AtomicBomb_Target_Point[AtomicBomb_Index] facing Default building facing degrees
      • Set AtomicBomb_Dummy[AtomicBomb_Index] = (Last created unit)
      • Unit - Add a 1.00 second Generic expiration timer to AtomicBomb_Dummy[AtomicBomb_Index]
      • Animation - Change AtomicBomb_Dummy[AtomicBomb_Index] flying height to 0.00 at 800.00
      • Custom script: call RemoveUnit ( udg_AtomicBomb_Dummy[udg_AtomicBomb_Index] )
      • Unit - Create 1 Atomic Bomb Dummy for (Owner of AtomicBomb_Caster[AtomicBomb_Index]) at AtomicBomb_Target_Point[AtomicBomb_Index] facing Default building facing degrees
      • Set AtomicBomb_Group[AtomicBomb_Index] = (Units within 1200.00 of AtomicBomb_Target_Point[AtomicBomb_Index])
      • Unit Group - Pick every unit in AtomicBomb_Group[AtomicBomb_Index] and do (Actions)
        • Loop - Actions
          • Unit - Cause AtomicBomb_Caster[AtomicBomb_Index] to damage (Picked unit), dealing (Real(AtomicBomb_Damage[AtomicBomb_Index])) damage of attack type Chaos and damage type Normal
          • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Environment\UndeadBuildingFire\UndeadLargeBuildingFire2.mdl
          • Special Effect - Destroy (Last created special effect)
      • Custom script: call DestroyGroup ( udg_AtomicBomb_Group[udg_AtomicBomb_Index] )
      • Custom script: call RemoveLocation ( udg_AtomicBomb_Target_Point[udg_AtomicBomb_Index] )
If you find any more problems or have any advice on how I can improve the spell, please notify me as soon as possible.
 
Last edited:
First, dont multi post... next don't advertise...

and its pretty big for a simple spell, does it have custom models? if yes, then remove them...

and there's no use using the index since its just an instant spell...

I only used the index just in case 2 heroes used the same spell at the same time - very rare, but just to stay on the safe side ;)
 
Level 8
Joined
Jun 30, 2010
Messages
259
Nice eyecandy, but, very simple, and, the spell effects could be improved, as if a bomb is dropped form the sky as a visual effect and when it reaches the ground, it detonates. It could be improved further by letting a plane or helicopter drop the bomb.
Also, you have a poor description.
The model is a bit useless, and it seems to bug when it is used in shallow water (look at the water that is yellow).
 
i'll improve everything on friday cuz im kind of busy right now (homework, tests, all that shit). But keep giving me feedback cuz this spell does need a little bit of improvement.
i'll add more special effects, make it destroy trees and destructibles, and the plane drop thing sounds good. On the weekend i'll upload v1.3. Till then, keep giving me feedback.
 
Level 8
Joined
Jun 30, 2010
Messages
259
and maybe try to do an in-game screenie of the spell in action, coz it looks like it was from WE...

not to say that the index you used is bad (coz you just add 1 every time, once you reach 8140, ur doomed...)

Well, since you can see the starting pos in the screenshot, I am almost certain it is from WE.
And as said, the index is useless, unless you add all the things you hav epromised, cause a delayed spell would require an indexing system or hashtables.
 
Level 37
Joined
Mar 6, 2006
Messages
9,242
Object editor:
*Give the ability a bit of follow through time (about a second or two) so it plays the caster's animation.
*Enable Targeting image in Options for the ability
*Set the AoE
*The dummies have sight radius of 1. Why not 0?

Trigger editor:
*Do the real conversion of the damage outside the unit group loop.
*What is the first dummy supposed to do? You remove it instantly so it doesn't show at all.
*You could add a trigger that actually shows the bomb flying to the targeted point. Now the spell is too simple.
*The damage could be distance dependant, since atomic bomb explosion on ground level causes the most overpressure at close range and less at further away.
*Rather than using a variable fot the group, do this, it's faster:
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit Units within 1200.00 of AtomicBomb_Target_Point and do (Actions)
    • Loop - Actions
 
ok thanks for the advice guys. i'm going to change the spell almost completely. I'll make a B2 bomber come and drop the bomb, and then it will detonate. And as you said Maker, i'll change the damage to range-dependent. :) i'm so glad u guys are there to help me improve. i've learned a lot about writing spells, fixing leaks, indexing, recycling indexes, and many other stuff - All thanks to you :D




--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GUYS!!! I rewrote the spell!
Check it out. It's much better now!!
Hope you like it! :D
 
Last edited:
Level 8
Joined
Jun 30, 2010
Messages
259
Your new verison is not MUI.
If the spell is cast twice in a row, the first plane stops moving, without dropping the bomb.
Also, you still have a cooldown on your spell. Remove it, since you get no cooldown by pressing ESC anyway, so it is useless.
The new effects is fine, allthought I do not like the way the bomb is travelling. It is travelling at full speed at start. Make the speed increase over-time.
And, the chopper would look better if it would come down from the clouds and then go back up after the bomb is dropped. Also, increase the bomb falling height.

Fixes needed:
-Make it MUI
-Update your spell targeting.
-Remove the ESC trigger and simply set the HP and Mana regen to 1000 and set ability cooldown to 0.

I think that is all, for now.
Hope this helps!
 
Look LaserDude, i've been trying to fix the spell using hashtables, but for some reason, when i use the spell and wait till it finishes, i use it again, then the plane comes, but it doesn't drop the bomb! Can you tell me what's wrong? I'll post the triggers:

Main


  • Atomic Bomb
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Atomic bomb
    • Actions
      • -------- ------------ --------
      • -------- Variables and Hashtable (ORDER IS IMPORTANT) --------
      • -------- ------------ --------
      • Hashtable - Save Handle Of(Casting unit) as 0 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Caster = (Load 0 of (Key (Triggering unit)) in Hashtable)
      • -------- ------------ --------
      • Hashtable - Save (Level of Atomic bomb for AtomicBomb_Caster) as 1 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Level = (Load 1 of (Key (Triggering unit)) from Hashtable)
      • -------- ------------ --------
      • Hashtable - Save Handle Of(Target point of ability being cast) as 2 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Target_Point = (Load 2 of (Key (Triggering unit)) in Hashtable)
      • -------- ------------ --------
      • Hashtable - Save 0 as 3 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Counter = (Load 3 of (Key (Triggering unit)) from Hashtable)
      • -------- ------------ --------
      • Set AtomicBomb_Counter_Max = 63
      • -------- ------------ --------
      • Hashtable - Save Handle Of(AtomicBomb_Target_Point offset by 612.00 towards 180.00 degrees) as 4 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Spawn_Point = (Load 4 of (Key (Triggering unit)) in Hashtable)
      • -------- ------------ --------
      • Hashtable - Save False as 12 of (Key (Triggering unit)) in Hashtable
      • Set STOP_COUNTER = (Load 12 of (Key (Triggering unit)) from Hashtable)
      • -------- ------------ --------
      • -------- Create B2 --------
      • -------- ------------ --------
      • Unit - Create 1 B2 Bomber for (Owner of AtomicBomb_Caster) at AtomicBomb_Spawn_Point facing 0.00 degrees
      • Hashtable - Save Handle Of(Last created unit) as 5 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_B2 = (Load 5 of (Key (Triggering unit)) in Hashtable)
      • Unit - Add a 10.00 second Generic expiration timer to AtomicBomb_B2
      • -------- ------------ --------
      • -------- Turning On Other Triggers --------
      • -------- ------------ --------
      • Trigger - Turn on Atomic Bomb Move B2 <gen>
      • Trigger - Turn on Atomic Bomb Final Effect <gen>
      • Trigger - Turn on Atomic Bomb END <gen>


Move Loop

  • Atomic Bomb Move B2
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Load 3 of (Key (Triggering unit)) from Hashtable) Equal to AtomicBomb_Counter_Max
        • Then - Actions
          • Unit - Create 1 Atomic Bomb (dummy) for (Owner of AtomicBomb_Caster) at AtomicBomb_Target_Point facing Default building facing degrees
          • Hashtable - Save Handle Of(Last created unit) as 6 of (Key (Triggering unit)) in Hashtable
          • Set AtomicBomb_Dummy = (Load 6 of (Key (Triggering unit)) in Hashtable)
          • Unit - Add a 2.00 second Generic expiration timer to AtomicBomb_Dummy
          • Animation - Change AtomicBomb_Dummy flying height to 0.00 at 400.00
          • Hashtable - Save True as 12 of (Key (Triggering unit)) in Hashtable
          • Set STOP_COUNTER = (Load 12 of (Key (Triggering unit)) from Hashtable)
        • Else - Actions
      • Hashtable - Save Handle Of(Position of AtomicBomb_B2) as 7 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_B2_Current_Position = (Load 7 of (Key (Triggering unit)) in Hashtable)
      • Hashtable - Save Handle Of(AtomicBomb_B2_Current_Position offset by 9.00 towards 0.00 degrees) as 8 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_B2_Move_Position = (Load 8 of (Key (Triggering unit)) in Hashtable)
      • Unit - Move AtomicBomb_B2 instantly to AtomicBomb_B2_Move_Position
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Load 12 of (Key (Triggering unit)) from Hashtable) Equal to False
        • Then - Actions
          • Hashtable - Save ((Load 3 of (Key (Triggering unit)) from Hashtable) + 1) as 3 of (Key (Triggering unit)) in Hashtable
        • Else - Actions
          • Hashtable - Save 0 as 3 of (Key (Triggering unit)) in Hashtable
      • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Current_Position )
      • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Move_Position )


Damage and Effects


  • Atomic Bomb Final Effect
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to Atomic Bomb (dummy)
    • Actions
      • Unit - Create 1 Atomic Bomb (dummy2) for (Owner of AtomicBomb_Caster) at AtomicBomb_Target_Point facing Default building facing degrees
      • Hashtable - Save Handle Of(Last created unit) as 6 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Dummy = (Load 6 of (Key (Triggering unit)) in Hashtable)
      • Unit - Add a 8.00 second Generic expiration timer to AtomicBomb_Dummy
      • Hashtable - Save Handle Of(Units within 200.00 of AtomicBomb_Target_Point matching (((Owner of AtomicBomb_Caster) is an enemy of (Owner of (Matching unit))) Equal to True)) as 9 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Group_200 = (Load 9 of (Key (Triggering unit)) in Hashtable)
      • Hashtable - Save Handle Of(Units within 600.00 of AtomicBomb_Target_Point matching (((Owner of AtomicBomb_Caster) is an enemy of (Owner of (Matching unit))) Equal to True)) as 10 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Group_600 = (Load 10 of (Key (Triggering unit)) in Hashtable)
      • Hashtable - Save Handle Of(Units within 1200.00 of AtomicBomb_Target_Point matching (((Owner of AtomicBomb_Caster) is an enemy of (Owner of (Matching unit))) Equal to True)) as 11 of (Key (Triggering unit)) in Hashtable
      • Set AtomicBomb_Group_1200 = (Load 11 of (Key (Triggering unit)) in Hashtable)
      • Unit Group - Pick every unit in AtomicBomb_Group_200 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
      • Unit Group - Pick every unit in AtomicBomb_Group_600 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
      • Unit Group - Pick every unit in AtomicBomb_Group_1200 and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Caster to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
      • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in Hashtable


END SPELL

  • Atomic Bomb END
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to B2 Bomber
    • Actions
      • Trigger - Turn off Atomic Bomb Move B2 <gen>
      • Trigger - Turn off Atomic Bomb Final Effect <gen>
      • Trigger - Turn off (This trigger)
      • Custom script: call RemoveLocation ( udg_AtomicBomb_Spawn_Point )
      • Custom script: call RemoveLocation ( udg_AtomicBomb_Target_Point )
      • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Current_Position )
      • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Move_Position )
      • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_200 )
      • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_600 )
      • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_1200 )


Please help me. I can't find the cause of this problem! Please help!
 
ok guys, im going to release the final patch for this spell as soon as i fix a small bug, but i'm going to need your help.
The spell is 100% MUI
It can run up to 36 times without bugging.
You can change this value simply with one integer variation.
I made it 36 because i used some "integer A" loop actions.
Try to keep the number below 50. You don't need to recycle the index when it's 8191. 50 is enough especially in my case.
Anyways, the bug i'm having problems with is the appearance of the bomb suspended in the air a few seconds after the spell finishes casting completely.
Here are the triggers:


  • Atomic Bomb
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Atomic bomb
    • Actions
      • Set AtomicBomb_Index_Max = 36
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AtomicBomb_Index Greater than or equal to AtomicBomb_Index_Max
        • Then - Actions
          • Set AtomicBomb_Index = 0
        • Else - Actions
      • Set AtomicBomb_Index = (AtomicBomb_Index + 1)
      • -------- ------------ --------
      • -------- Variable Declarations (ORDER IS IMPORTANT) --------
      • -------- ------------ --------
      • Set AtomicBomb_Caster[AtomicBomb_Index] = (Casting unit)
      • Set AtomicBomb_Target_Point[AtomicBomb_Index] = (Target point of ability being cast)
      • Set AtomicBomb_Counter[AtomicBomb_Index] = 0
      • Set AtomicBomb_Counter_Max = 66
      • -------- ------------ --------
      • -------- Create B2 --------
      • -------- ------------ --------
      • Set AtomicBomb_Spawn_Point[AtomicBomb_Index] = (AtomicBomb_Target_Point[AtomicBomb_Index] offset by 612.00 towards 180.00 degrees)
      • Unit - Create 1 B2 Bomber for Player 1 (Red) at AtomicBomb_Spawn_Point[AtomicBomb_Index] facing 0.00 degrees
      • Custom script: call RemoveLocation ( udg_AtomicBomb_Spawn_Point[udg_AtomicBomb_Index] )
      • Set AtomicBomb_B2_Temp[AtomicBomb_Index] = (Last created unit)
      • Unit - Add a 10.00 second Generic expiration timer to AtomicBomb_B2_Temp[AtomicBomb_Index]
      • Unit Group - Add AtomicBomb_B2_Temp[AtomicBomb_Index] to AtomicBomb_B2_Group
      • -------- ------------ --------
      • -------- Turning On Other Triggers --------
      • -------- ------------ --------
      • Trigger - Turn on Atomic Bomb Move B2 <gen>
      • Trigger - Turn on Atomic Bomb Final Effect <gen>
      • Trigger - Turn on Atomic Bomb END <gen>
  • Atomic Bomb Move B2
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to AtomicBomb_Index_Max, do (Actions)
        • Loop - Actions
          • Set AtomicBomb_B2_Current_Position[(Integer A)] = (Position of AtomicBomb_B2_Temp[(Integer A)])
          • Set AtomicBomb_B2_Move_Position[(Integer A)] = (AtomicBomb_B2_Current_Position[(Integer A)] offset by 9.00 towards 0.00 degrees)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Counter[(Integer A)] Equal to AtomicBomb_Counter_Max
            • Then - Actions
              • Unit - Create 1 Atomic Bomb (dummy) for Neutral Passive at AtomicBomb_Target_Point[(Integer A)] facing Default building facing degrees
              • Set AtomicBomb_Dummy_Temp = (Last created unit)
              • Set AtomicBomb_Handle1 = (Last created unit)
              • Hashtable - Save Handle OfAtomicBomb_Caster[(Integer A)] as 0 of (Key AtomicBomb_Handle1) in AtomicBomb_Hashtable
              • Unit - Add a 1.00 second Generic expiration timer to AtomicBomb_Dummy_Temp
              • Animation - Change AtomicBomb_Dummy_Temp flying height to 0.00 at 800.00
              • Set int = (Integer A)
              • Custom script: call RemoveLocation ( udg_AtomicBomb_Target_Point[udg_int] )
              • Set AtomicBomb_Counter[(Integer A)] = -1000000000
            • Else - Actions
      • For each (Integer A) from 1 to AtomicBomb_Index_Max, do (Actions)
        • Loop - Actions
          • Unit - Move AtomicBomb_B2_Temp[(Integer A)] instantly to AtomicBomb_B2_Move_Position[(Integer A)]
          • Set AtomicBomb_Counter[(Integer A)] = (AtomicBomb_Counter[(Integer A)] + 1)
          • Set int = (Integer A)
          • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Current_Position[udg_int] )
          • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Move_Position[udg_int] )
  • Atomic Bomb Final Effect
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to Atomic Bomb (dummy)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • AtomicBomb_SFX_index Greater than or equal to AtomicBomb_Index_Max
        • Then - Actions
          • Set AtomicBomb_Index = 0
        • Else - Actions
      • Set AtomicBomb_SFX_index = (AtomicBomb_SFX_index + 1)
      • Set AtomicBomb_Bomb = (Dying unit)
      • Set AtomicBomb_Effect_Loc = (Position of AtomicBomb_Bomb)
      • Special Effect - Create a special effect at AtomicBomb_Effect_Loc using war3mapImported\NuclearExplosion.mdx
      • Set AtomicBomb_SFX[AtomicBomb_SFX_index] = (Last created special effect)
      • Set AtomicBomb_Damager = (Load 0 of (Key AtomicBomb_Handle1) in AtomicBomb_Hashtable)
      • Set AtomicBomb_Level[AtomicBomb_Index] = (Level of Atomic bomb for AtomicBomb_Damager)
      • Set AtomicBomb_Group_200[AtomicBomb_Index] = (Units within 200.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager) is an enemy of (Owner of (Matching unit))) Equal to True))
      • Set AtomicBomb_Group_600[AtomicBomb_Index] = (Units within 600.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager) is an enemy of (Owner of (Matching unit))) Equal to True))
      • Set AtomicBomb_Group_1200[AtomicBomb_Index] = (Units within 1200.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager) is an enemy of (Owner of (Matching unit))) Equal to True))
      • Custom script: call RemoveLocation ( udg_AtomicBomb_Effect_Loc )
      • Unit Group - Pick every unit in AtomicBomb_Group_200[AtomicBomb_Index] and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level[AtomicBomb_Index] Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level[AtomicBomb_Index] Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level[AtomicBomb_Index] Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
      • Unit Group - Pick every unit in AtomicBomb_Group_600[AtomicBomb_Index] and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level[AtomicBomb_Index] Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level[AtomicBomb_Index] Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level[AtomicBomb_Index] Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
      • Unit Group - Pick every unit in AtomicBomb_Group_1200[AtomicBomb_Index] and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AtomicBomb_Level[AtomicBomb_Index] Equal to 1
            • Then - Actions
              • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 75.00 damage of attack type Chaos and damage type Normal
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AtomicBomb_Level[AtomicBomb_Index] Equal to 2
                • Then - Actions
                  • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 116.67 damage of attack type Chaos and damage type Normal
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AtomicBomb_Level[AtomicBomb_Index] Equal to 3
                    • Then - Actions
                      • Unit - Cause AtomicBomb_Damager to damage (Picked unit), dealing 158.33 damage of attack type Chaos and damage type Normal
                    • Else - Actions
  • Atomic Bomb END
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Dying unit)) Equal to B2 Bomber
    • Actions
      • For each (Integer A) from 1 to AtomicBomb_Index_Max, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AtomicBomb_B2_Group is empty) Equal to True
            • Then - Actions
              • Trigger - Turn off Atomic Bomb Move B2 <gen>
              • Trigger - Turn off Atomic Bomb Final Effect <gen>
              • Trigger - Turn off (This trigger)
              • Set int = (Integer A)
              • Custom script: call RemoveLocation ( udg_AtomicBomb_Spawn_Point[udg_int] )
              • Custom script: call RemoveLocation ( udg_AtomicBomb_Target_Point[udg_int] )
              • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Current_Position[udg_int] )
              • Custom script: call RemoveLocation ( udg_AtomicBomb_B2_Move_Position[udg_int] )
              • Custom script: call RemoveLocation ( udg_AtomicBomb_Effect_Loc )
              • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_200[udg_int] )
              • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_600[udg_int] )
              • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_1200[udg_int] )
              • Custom script: call DestroyGroup ( udg_AtomicBomb_B2_Group )
              • Custom script: call DestroyGroup ( udg_AtomicBomb_Dummy_Group )
              • Hashtable - Clear all child hashtables of child (Key AtomicBomb_Handle1) in AtomicBomb_Hashtable
              • Special Effect - Destroy AtomicBomb_SFX[(Integer A)]
            • Else - Actions


Please help me with this bug! I've been working really hard on fixing this spell. I'm not giving up now.

PS. This bug does not interfere with the functionality of this spell. It functions perfectly!

And another thing, i'm adding a "Destroy Destructibles" option after i fix this bug. Thanks for giving me the idea ;)

I guarentee you're going to love the spell in the end. :thumbs_up:

Satisfaction not guarenteed. :ogre_icwydt::xxd:
 
Level 37
Joined
Mar 6, 2006
Messages
9,242
Anyways, the bug i'm having problems with is the appearance of the bomb suspended in the air a few seconds after the spell finishes casting completely.

Make the dummies have shorter expiration time and/or set the dummies to Can't raise , does not decay.

Additionally, why are you mixing hashtables and indexing. Use one or the other, not both.

You're looping through instances that have already ended, use a boolean to prevent that.

You could use an equation for the damage: 33.33 + 41.67 * abil_level.
 
i'll take ur advice. except for the hashtable/indexing mix. I did that because i cant store integers with indexes easily, and with hashtables, i was having a VERY big leak/bug problem. So i mixed both for it to be perfectly MUI. Since it doesn't affect functionality, i don't think it matters that much. Plus, if i change it to Completely indexed or completely hashtable stored, it'll take me another week to work out the MUI.

Oh and adding a boolean to prevent looping just complicate things :/ srry
Plus, it doesn't bug.

The damage formula is good though. => Decreased file size :)

Thanks for helping i'm checking if ur advice worked.

testing........

IT WORKS!! Thanks man! +rep
ur becoming like one of my favorite users. Maker = User of the Year 2010

Seriously i did 70 consecutive tests of the spell and each one executed PERFECTLY!!

The only bug that can occur will occur if the person uses the spell exactly 30,000,000 times (LITERALLY). I'm not kidding.

I'm uploading the new spell right now.

thanks again Maker :D
 
Level 8
Joined
Jun 30, 2010
Messages
259
i'll take ur advice. except for the hashtable/indexing mix. I did that because i cant store integers with indexes easily, and with hashtables, i was having a VERY big leak/bug problem. So i mixed both for it to be perfectly MUI. Since it doesn't affect functionality, i don't think it matters that much. Plus, if i change it to Completely indexed or completely hashtable stored, it'll take me another week to work out the MUI.

Oh and adding a boolean to prevent looping just complicate things :/ srry
Plus, it doesn't bug.

The damage formula is good though. => Decreased file size :)

Thanks for helping i'm checking if ur advice worked.

testing........

IT WORKS!! Thanks man! +rep
ur becoming like one of my favorite users. Maker = User of the Year 2010

Seriously i did 70 consecutive tests of the spell and each one executed PERFECTLY!!

The only bug that can occur will occur if the person uses the spell exactly 30,000,000 times (LITERALLY). I'm not kidding.

I'm uploading the new spell right now.

thanks again Maker :D

Creating it completely Hashtables should not be hard.
Just replace all your indexes with saves in hashtables...
For example:
  • Set AtomicBomb_Target_Point[AtomicBomb_Index] = (Target point of ability being cast)
Create the unit before you save the point. In fact, don't save the point at all. Use this isntead:
  • Hashtable - Save handle of (Target point of ability being cast) as (Key(Target)) of (Key(Last Created Unit)) in Hashtables
Then use that point.
Using hashtables would also reduce your triggers to about half of its current size.
 
ok ok guys. I'm converting to Hashtables if i CAN. I'm sort of new to hashtables, so i might not be able to update, but i'll try. Till next week :)

Oh and one more thing. Laserdude, when you refer to (Key(Target)), r u implying that i have to create Handle variables?

plz try to answer ASAP


Oh and one more unrelated thing, i was thinking of creating a Trigger Diagnostic System (TDS). It gives you execution time, number of executions, variable variations, and many other stuff. This helps users find the problems with their triggers so that they can fix them immediately. They have to make conclusions by themselves when given the data that the system will produce. This would be a very big help when attempting to fix bugs especially for the variable variations. I plan to start on it as soon as i'm done with this atomic bomb spell. :)
 
Level 8
Joined
Jun 30, 2010
Messages
259
ok ok guys. I'm converting to Hashtables if i CAN. I'm sort of new to hashtables, so i might not be able to update, but i'll try. Till next week :)

Oh and one more thing. Laserdude, when you refer to (Key(Target)), r u implying that i have to create Handle variables?

plz try to answer ASAP


Oh and one more unrelated thing, i was thinking of creating a Trigger Diagnostic System (TDS). It gives you execution time, number of executions, variable variations, and many other stuff. This helps users find the problems with their triggers so that they can fix them immediately. They have to make conclusions by themselves when given the data that the system will produce. This would be a very big help when attempting to fix bugs especially for the variable variations. I plan to start on it as soon as i'm done with this atomic bomb spell. :)

The first selection when you save hashtable data is what you want to save. The second should be a String. The third should be a Handle. The forth should be the Hashtable you want to save the data to. In most cases, you only need one Hashtable.

One more thing. Why do you post in this thread about what you are going to do? Isn't that counted as advertisement?
However, I am uncertain of what you mean by that, but, that is off-topic.

I've sent a whole description of how Hashtables work before in a thread and in a PM, give me a VM should you want this message.
 
UPDATE: Must i make a new version with hashtables?
My current one is MUI, and it works almost perfectly!
And besides, using hashtables might decrease the length of my code, but not the width ;)
It may lead to short triggers, but it can also lead to looooooooong lines.
I think 55 KB is good enough. So this is my final version, and i'm ready for it to be either rejected :( or approved :)
 
Level 8
Joined
Jun 30, 2010
Messages
259
UPDATE: Must i make a new version with hashtables?
My current one is MUI, and it works almost perfectly!
And besides, using hashtables might decrease the length of my code, but not the width ;)
It may lead to short triggers, but it can also lead to looooooooong lines.
I think 55 KB is good enough. So this is my final version, and i'm ready for it to be either rejected :( or approved :)

Either you gotta make it fully Hashtables, or fully Index, since people do not appreciate when you are using both. This is because you are adding useless stuff which takes place and makes the spell harder to understand.
Else it will be rejected, I am sure of it.
Sorry for saying this, but, I've been where you are and let me tell you, it takes time.
 
Level 8
Joined
Jun 30, 2010
Messages
259
Tested.
It works.
Good job.
Leaks: 1.
  • Custom script: call RemoveLocation ( udg_AtomicBomb_Effect_Loc )
You should remove this in the trigger you are setting it in, or make it an array. As far as I know, using your method causes it to leak.

Review:
Triggers - 4/5 - Very Good triggers, but you could've looped the damage and slightly changed some of the triggers.
Effects and sound - 4/5 - Very Good effects, but the bomb looks a bit strange since it spins when it falls, and the sound when it hits the ground is awful.
MUI - 5/5 - It works and it is MUI.
Idea - 3/5 - The idea for an atomic bomb is somewhat new and exciting, but area of effect spells has been made too many times before.
Misc. - 3/5 - Your import description is good and is step by step, that is good.
-You could've added a level description for the spell tooltip.
-You did not credit the creator of the atomic bomb model!


Total: 19/25 - Very Good, althought you should add the credits for the model to your map and to the thread A.S.A.P.
 
FINALLY! I'm about to finish with this thing! I'll give credit like u said ( which i never really do in detail since i can't remember all the names ) and i'll fix that leak. And the bomb is supposed to spin when it falls btw cuz it makes it look unstable, but i'll fix that by setting animation speed to 0.
And about the score, u'd give me a 4/5 right? (not a 3.8 lol)
I'll upload v2.3 asap.

-----------------------------

Ok. i'm done. So..... When does this spell get judged for approval/rejection. I've been confused about that from the start :S
 
Last edited:
Level 22
Joined
Nov 14, 2008
Messages
3,256
Quick Review.

-
  • Set AtomicBomb_Index_Max = 200
Should be in a seperate trigger running at Map Init.

-The indexing method is awful, sorry to mention it.

-
  • Set AtomicBomb_Caster[AtomicBomb_Index] = (Casting unit)
Should be Triggering Unit.

-I'm not a great fan of the Integer A usage but yeah whatever.

-Why are there 2 seperate loops in the loop trigger? Merge those together.

-
  • (Unit-type of (Dying unit)) Equal to Atomic Bomb (dummy)
Should be Triggering Unit

  • Set AtomicBomb_Bomb = (Dying unit)
Same as above.

-
  • Set AtomicBomb_Damage = ((Integer(33.33)) + ((Integer(41.67)) x AtomicBomb_Level[AtomicBomb_Index2]))
Why are you calling Integer? Why isn't it a real variable?

-The unit groups which you use when you damage doesn't have to be arrayed and you could jsut use one and destroy it after each damage loop.

-Last time I checked, the damage of the spell is pretty relevant to store into a variable to make it easier for the user.

-
  • (Unit-type of (Dying unit)) Equal to B2 Bomber
Triggering Unit.

-Is this really MUI? You turn off the end trigger which will be off if two instances are running, casted 0.5 second after the first.

-
  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_100[udg_int] )
  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_200[udg_int] )
  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_400[udg_int] )
Removed in the damage trigger, why remove them again?
 
ok.

I'll update the spell again. I guess i forgot to change the integer A loops :p

Anyways, this spell is MUI. I casted it over 130 times in a row in 20 seconds and it didn't bug.

My indexing system, may not be the best, but it is functional, so i'm okay with it.

And about those unit group remove actions in the "END" trigger, yeah, i wanted to remove ALL leaks just in case something were to go wrong. They won't really make a difference (<60 bytes) :p (I'll rethink it)

And one more thing, i'm arraying the unit group variables because of an MUI issue i had in versions 2.0-2.2. (I'll rethink arraying them)

This spell will be updated ASAP (Literally).

EDIT: UPDATED :D
 
Last edited:

Bribe

Code Moderator
Level 44
Joined
Sep 26, 2009
Messages
8,960
  • Custom script: call DestroyTrigger (GetTriggeringTrigger())
Don't bother, destroying GUI triggers can cause handle-stack corruption so actually this is worse than just leaving it alone.

  • Unit - Add a 8.00 second Generic expiration timer to AtomicBomb_B2_Temp[AtomicBomb_Index]
Maybe the 8.00 seconds should be configurable?

  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_100[udg_AtomicBomb_Index2] )
  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_200[udg_AtomicBomb_Index2] )
  • Custom script: call DestroyGroup ( udg_AtomicBomb_Group_400[udg_AtomicBomb_Index2] )
You use those on top of setting the groups to temporary variables and you also use bj_wantDestroyGroup. I have a better idea, delete all those set groupx things and do:

  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 100.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager[AtomicBomb_Index2]) is an enemy of (Owner of (Matching unit))) Equal to True)) and do (Actions)
    • Loop - Actions
      • Unit - Cause AtomicBomb_Damager[AtomicBomb_Index2] to damage (Picked unit), dealing (AtomicBomb_Damage / 3.00) damage of attack type Chaos and damage type Normal
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 200.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager[AtomicBomb_Index2]) is an enemy of (Owner of (Matching unit))) Equal to True)) and do (Actions)
    • Loop - Actions
      • Unit - Cause AtomicBomb_Damager[AtomicBomb_Index2] to damage (Picked unit), dealing (AtomicBomb_Damage / 3.00) damage of attack type Chaos and damage type Normal
  • Custom script: set bj_wantDestroyGroup = true
  • Unit Group - Pick every unit in (Units within 400.00 of AtomicBomb_Effect_Loc matching (((Owner of AtomicBomb_Damager[AtomicBomb_Index2]) is an enemy of (Owner of (Matching unit))) Equal to True)) and do (Actions)
    • Loop - Actions
      • Unit - Cause AtomicBomb_Damager[AtomicBomb_Index2] to damage (Picked unit), dealing (AtomicBomb_Damage / 3.00) damage of attack type Chaos and damage type Normal
 
Level 10
Joined
Apr 25, 2009
Messages
296
Boom!

This spell seems leakless, fluent. I'd suggest adding a knockback/radiation effects to make it more visually complex. Also, I'd like to see the bomber come in from different directions, as now it only seems to come in at 0 degrees.

Other than that the spell is fluent and has good potential for space-themed maps.
 
Thanks Archangel :D
If you think about it, this spell would look so cool in a cinematic.
WWIII !!! :ogre_haosis:

That would be soooooo awesome!
The bombs dropping at different intervals and decimating the area, and the background music would be like:

(In the attatchment) :ogre_hurrhurr:

Am i breaking the rules by posting this? :ogre_datass:
If yes, plz inform me Before Reporting ;) :ogre_frown:
 

Attachments

  • PlayMusicTheme1.mp3
    1.4 MB · Views: 65
Top