1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Bomb

Discussion in 'World Editor Help Zone' started by Apostle, May 26, 2017.

  1. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    I want to create an ability that essentially causes a unit to plant a bomb with a short timer on buildings or even other units, what's the easiest way to go about this?
     
  2. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    Do you want that the effect can be dispelled?
    Do you want it in GUI?
     
  3. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    Non-dispellable
    gui meaning not in jass or vjass?
     
  4. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    Yes.
    Using JASS or vJASS you can very easily use timers to make this work.
    In GUI it's a lot more complicated because you have to store the data in hashtables or arrays to make it MUI.
    You would have to iterate through the units and use some kind of counter to dealy the explosion.

    What should happen when the bomb explodes?
    Area of effect or only damaging the target?
     
  5. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    Both would be nice
     
  6. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    I decided to do it in vJASS, because it's easier to import and easier to write.
    Code (vJASS):

    scope TimeBomb initializer Init
        globals
            //ability that is used to palce bombs (single target)
            private constant integer TRIGGER_SPELL = 'A000'
            //ability the bombed unit has to display the buff (tornado slow aura)
            private constant integer BUFF_SPELL = 'A001'
            private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
            private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_MAGIC
        endglobals
       
        private function GetBombDelay takes integer level returns real
            return 5.-1*level
        endfunction
       
        private function GetBombTargetDamage takes integer level returns real
            return 50.*level
        endfunction
       
        private function GetBombAOEDamage takes integer level returns real
            return 50.*level
        endfunction
       
        private function GetBombAOERange takes integer level returns real
            return 150.+50*level
        endfunction
       
        //Return true, if the target should be damaged by the area of effect
        private function AllowedTargets takes unit caster, unit target returns boolean
            return TRUE
        endfunction
       
        /*====================================================================
        ======================= END OF CONFIGURATION =========================
        ====================================================================*/

       
        globals
            private hashtable hash
            private group bombedUnits
        endglobals
       
        private function DeathConditions takes nothing returns boolean
            return IsUnitInGroup(GetTriggerUnit(), bombedUnits)
        endfunction
       
        private function DeathActions takes nothing returns nothing
            local unit target = GetTriggerUnit()
            call UnitRemoveAbility(target, BUFF_SPELL)
            call FlushChildHashtable(hash, GetHandleId(target))
            call GroupRemoveUnit(bombedUnits, target)
            set target = null
        endfunction
       
        private function Conditions takes nothing returns boolean
            return GetSpellAbilityId() == TRIGGER_SPELL
        endfunction

        private function Explode takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local integer h = GetHandleId(t)
            local unit caster = LoadUnitHandle(hash, h, 0)
            local unit target = LoadUnitHandle(hash, h, 1)
            local integer level = LoadInteger(hash, h, 2)
            local group g = CreateGroup()
            local unit u
            local integer bombCount
           
            if(not IsUnitInGroup(target, bombedUnits)) then
                call PauseTimer(t)
                call DestroyTimer(t)
                call DestroyGroup(g)
                set u = null
                set g = null
                set caster = null
                set target = null
                set t = null
                return
            endif
            call UnitDamageTarget(caster, target, GetBombTargetDamage(level), TRUE, FALSE, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
            call GroupEnumUnitsInRange(g, GetUnitX(target), GetUnitY(target), GetBombAOERange(level), null)
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                call GroupRemoveUnit(g, u)
                if(AllowedTargets(caster, u) )then
                    call UnitDamageTarget(caster, u, GetBombAOEDamage(level), TRUE, FALSE, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
                endif
            endloop
            call FlushChildHashtable(hash, h)
            set h = GetHandleId(target)
            set bombCount = LoadInteger(hash, h, 0)-1
            call SaveInteger(hash, h, 0, bombCount)
            if(bombCount == 0) then
                call UnitRemoveAbility(target, BUFF_SPELL)
                call FlushChildHashtable(hash, h)
                call GroupRemoveUnit(bombedUnits, target)
            endif
            call PauseTimer(t)
            call DestroyTimer(t)
            call DestroyGroup(g)
            set u = null
            set g = null
            set caster = null
            set target = null
            set t = null
        endfunction
       
        private function Actions takes nothing returns nothing
            local unit caster = GetTriggerUnit()
            local unit target = GetSpellTargetUnit()
            local integer level = GetUnitAbilityLevel(caster, TRIGGER_SPELL)
            local timer t = CreateTimer()
            local integer h = GetHandleId(t)
            call TimerStart(t, GetBombDelay(level), FALSE, function Explode)
            call SaveUnitHandle(hash, h, 0, caster)
            call SaveUnitHandle(hash, h, 1, target)
            call SaveInteger(hash, h, 2, level)
            call UnitAddAbility(target, BUFF_SPELL)
            set h = GetHandleId(target)
            call SaveInteger(hash, h, 0, LoadInteger(hash, h, 0)+1)
            call GroupAddUnit(bombedUnits, target)
            set caster = null
            set target = null
            set t = null
        endfunction

        private function Init takes nothing returns nothing
            local trigger trg = CreateTrigger(  )
            local integer i = 0
            call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_SPELL_EFFECT )
            call TriggerAddCondition( trg, Condition( function Conditions ) )
            call TriggerAddAction( trg, function Actions )
            set trg = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ( trg, EVENT_PLAYER_UNIT_DEATH )
            call TriggerAddCondition( trg, Condition( function DeathConditions ) )
            call TriggerAddAction( trg, function DeathActions )
            set hash = InitHashtable()
            set bombedUnits = CreateGroup()
            set trg = null
        endfunction

    endscope
     
     

    Attached Files:

  7. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    So basically replace the A000 with the ability used to place the bomb and A001 with the bomb's buff and it's ready to go?
     
  8. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    A000: yes
    A001: you can't directly add buffs to units, so you need to add an ability that adds the buff. Usually you use slow aura (tornado)
    You can see it in my uploaded map.

    You can also set damage, aoe, delay depending on the level.
    You will probably want to modify the function AllowedTargets, so only certain tarets are damaged (enemies, organic for example).
     
  9. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    The map does not show up in the game, is it because I'm using version 1.27b rather than the new 1.28?

    I'm hesitant to upgrade to version 1.28 because of the many bugs that I've heard of
     
  10. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    I did the map with 1.26, so that's not the problem. Do you have JNGP or WEX?
     
  11. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    Just the regular wc3 world editor

    edit: nevermind I think I got it
     
  12. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    @Jampion
    Are you supposed to have something enabled in order to properly import this into another map?

    When I copy and paste the trigger into another map and try to save it, it gives me an error that states
    "Trigger 'time bomb' has been disabled due to multiple errors." And then it proceeds to show me a list of errors.
     
  13. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    You need either JNGP or WEX in order to save maps with vJASS without getting compiler errors.
     
  14. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    Ok, thanks for letting me know
     
  15. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    I could convert it into normal JASS, if you prefer it. Normal JASS can be used in the vanilla world editor.
     
  16. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    That would be awesome
     
  17. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    In the configuration trigger you can configure some things (should be self-explanatory).
    In the targets allowed trigger you can decide whether the target should be damaged.
    In the example only enemies of the caster are damaged.
     

    Attached Files:

  18. Apostle

    Apostle

    Joined:
    Apr 14, 2017
    Messages:
    137
    Resources:
    0
    Resources:
    0
    Ok, thanks :)
     
  19. Rem

    Rem

    Joined:
    Apr 12, 2017
    Messages:
    231
    Resources:
    0
    Resources:
    0
    Can't this simply be done using one ability that has a buff plus a simple trigger.

    The ability would be cast on a building, it would display an bomb or something similar on the building, the trigger would be set up such that when the ability is cast the trigger will be set to wait a certain amount of time after which it will create an effect (an explosion) at the location of the building, damage the building as well as anything in like 200 range of the building and remove the buff on the building.
     
  20. Jampion

    Jampion

    JASS Reviewer

    Joined:
    Mar 25, 2016
    Messages:
    1,286
    Resources:
    0
    Resources:
    0
    That's pretty much what I did, but I avoided using waits.
    Also in this case Apostle wanted it to be non dispelable and there are only very few spells, that can't be dispelled and most of them have side effects.