1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. 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
  3. 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
  4. Travel to distant realms and encounter scenes unknown to the common folk. The Greatest of Adventures is upon us with the 8th Cinematic Contest. Join in on a fun ride.
    Dismiss Notice
  5. The 18th Icon Contest is ON! Choose any ingame unit and give him/her Hero abilities. Good luck to all.
    Dismiss Notice
  6. Contestants are to create a scene set in the Stone Age. Come and see what you can come up with. We wish you the best of luck!
    Dismiss Notice
  7. Colour outside the lines! Techtree Contest #13 is a go. The contest is optionally paired.
    Dismiss Notice
  8. Greetings cerebrates, our Swarm needs new spawners that will have numerous children. Join the HIVE's 31st Modeling Contest - Spawners and Spawned! The contest is optionally paired.
    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.

Triggered Incinerate v1.2

Submitted by AGD
This bundle is marked as approved. It works and satisfies the submission rules.
Credits:
- Bribe [Damage Engine]

You can use this spell as an alternative to the FireLord's Incinerate spell.
Many of us including myself have encountered problems when editing or making duplicate out of this spell and for this reason I made this.
With this simple system, you can have as many incinerate-like spells in your map as you want, all with different rawcodes and stats.

Read the readme for importing instructions.

Triggered Incinerate v1.2

Configuration Section
  • Incinerate SpellsList
    • Events
    • Conditions
    • Actions
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- |||||||||||||||||||||||||||||||||||||||| INCINERATE SPELLS LIST |||||||||||||||||||||||||||||||||||||||| --------
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- --------
      • -------- If you want to add a slot for an incinerate spell, copy one of these --------
      • -------- spell blocks and paste it next to the last block. Then you can freely --------
      • -------- configure the stats of the spell. --------
      • -------- --------
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- ||||| Incinerate Spell 1 ||||| --------
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- --------
      • -------- [ Activation spell ] --------
      • Set TI_Spell = Incinerate
      • -------- [ Determines if spells can trigger incinerate ] --------
      • Set TI_AllowSpellAsTrigger = False
      • -------- [ Damage increase per attack ] --------
      • Set TI_DamageStackBase = 8.00
      • Set TI_DamageStackPerLevel = 2.00
      • -------- [ Duration of the stack damage ] --------
      • Set TI_DurBase = 8.00
      • Set TI_DurPerLevel = 0.00
      • -------- [ Limit of the damage stacking (Value of 0 means no stacking limit) ] --------
      • Set TI_DCapBase = 500.00
      • Set TI_DCapPerLevel = 0.00
      • -------- [ Full damage area/radius of the explosion ] --------
      • Set TI_EXAOEBase = 150.00
      • Set TI_EXAOEPerLevel = 0.00
      • -------- [ Small damage area/radius of the explosion ] --------
      • Set TI_EXSmallAOEBase = 250.00
      • Set TI_EXSmallAOEPerLevel = 0.00
      • -------- [ Explosion's small damage factor ] --------
      • Set TI_EXSmallDamageFactorBase = 0.60
      • Set TI_EXSmallDamageFactorPerLevel = 0.00
      • -------- [ Attack type of the spell ] --------
      • Set TI_AttackType = Hero
      • -------- [ Damage type of the spell ] --------
      • Set TI_DamageType = Magic
      • -------- [ Damage stacking SFX model ] --------
      • Set TI_EffectModel1 = Abilities\Spells\Other\Incinerate\IncinerateBuff.mdl
      • -------- [ Explosion SFX model ] --------
      • Set TI_EffectModel2 = Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
      • -------- [ Damage stacking SFX attachment point ] --------
      • Set TI_EffectAttachment = chest
      • -------- [ The following determines the type of units allowed as the spell's target ] --------
      • Set TI_Structures = False
      • Set TI_Mechanicals = False
      • Set TI_MagicImmune = False
      • Set TI_Allies = True
      • Set TI_Illusions = True
      • -------- [ It's possible that this script was compiled first before TI_InitSpellIndex in which case normal function call won't work. ] --------
      • -------- [ Therefore we use ExecuteFunc. ] --------
      • Custom script: call ExecuteFunc( "TI_InitSpellIndex" )
      • -------- --------
      • -------- --------
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- ||||| Incinerate Spell 2 ||||| --------
      • -------- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||| --------
      • -------- --------
      • -------- [ Activation spell ] --------
      • Set TI_Spell = Fury Swipe
      • -------- [ Determines if spells can trigger incinerate ] --------
      • Set TI_AllowSpellAsTrigger = False
      • -------- [ Damage increase per attack ] --------
      • Set TI_DamageStackBase = 10.00
      • Set TI_DamageStackPerLevel = 5.00
      • -------- [ Duration of the stack damage ] --------
      • Set TI_DurBase = 8.00
      • Set TI_DurPerLevel = 0.00
      • -------- [ Limit of the damage stacking (Value of 0 means no stacking limit) ] --------
      • Set TI_DCapBase = 0.00
      • Set TI_DCapPerLevel = 0.00
      • -------- [ Full damage area/radius of the explosion ] --------
      • Set TI_EXAOEBase = 0.00
      • Set TI_EXAOEPerLevel = 0.00
      • -------- [ Small damage area/radius of the explosion ] --------
      • Set TI_EXSmallAOEBase = 0.00
      • Set TI_EXSmallAOEPerLevel = 0.00
      • -------- [ Explosion's small damage factor ] --------
      • Set TI_EXSmallDamageFactorBase = 0.00
      • Set TI_EXSmallDamageFactorPerLevel = 0.00
      • -------- [ Attack type of the spell ] --------
      • Set TI_AttackType = Hero
      • -------- [ Damage type of the spell ] --------
      • Set TI_DamageType = Normal
      • -------- [ Damage stacking SFX model ] --------
      • Set TI_EffectModel1 = Abilities\Spells\NightElf\BattleRoar\RoarTarget.mdl
      • -------- [ Explosion SFX model ] --------
      • Set TI_EffectModel2 = Objects\Spawnmodels\Undead\UndeadBlood\UndeadBloodNecromancer.mdl
      • -------- [ Damage stacking SFX attachment point ] --------
      • Set TI_EffectAttachment = overhead
      • -------- [ The following determines the type of units allowed as the spell's target ] --------
      • Set TI_Structures = False
      • Set TI_Mechanicals = False
      • Set TI_MagicImmune = True
      • Set TI_Allies = True
      • Set TI_Illusions = True
      • -------- [ It's possible that this script was compiled first before TI_InitSpellIndex in which case normal function call won't work. ] --------
      • -------- [ Therefore we use ExecuteFunc. ] --------
      • Custom script: call ExecuteFunc( "TI_InitSpellIndex" )
      • -------- --------
      • -------- --------


Main Section
Code (vJASS):

///////////////////////////////////////////////////////////////////////////////////////////////////////
//===================================================================================================//
//============================= ***    ****   ***   ****   *   *  **** ==============================//
//============================= *  *   *     *   *  *   *  ** **  *    ==============================//
//============================= ***    ***   *****  *   *  * * *  ***  ==============================//
//============================= *  *   *     *   *  *   *  *   *  *    ==============================//
//============================= *   *  ****  *   *  ****   *   *  **** ==============================//
//===================================================================================================//
///////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                   //
// *****************************                                                                     //
// * Triggered Incinerate v1.2 *                                                                     //
// *          by: AGD          *                                                                     //
// *****************************                                                                     //
//                                                                                                   //
// Credits:                                                                                          //
// - Bribe ( Damage Engine )                                                                         //
//                                                                                                   //
//                                                                                                   //
// How to Import:                                                                                    //
// - Copy the all the custom abilities                                                               //
// - Copy the "Damage Engine by Bribe" trigger category                                              //
// - Copy the "Triggered Incinerate by AGD" trigger category                                         //
//                                                                                                   //
// But first, check "automatically create unknown variables while pasting trigger data" so that the  //
// "TI Variable Creator" will create the necessary variables in your map.                            //
//                                                                                                   //
//                                                                                                   //
// Spell Summary:                                                                                    //
//                                                                                                   //
// The spell's effect is passive. It activates everytime the unit deals damage to its target. This   //
// spell causes the unit to deal increasing damage (additionally) per attack. The damage stacking    //
// has a duration after which if the target takes no damage from a unit with incinerate spell, it    //
// will be reset back to zero. Upon the target unit's death, it will explode and deal damage equal   //
// to the damage stacked to a certain AOE.                                                           //
//                                                                                                   //
//                                                                                                   //
// Spell Info (Please Read):                                                                         //
//                                                                                                   //
// For those who don't know yet, the Incinerate spell of Fire Lord which was made by Blizzard is     //
// actually buggy if you're not using the original spell ( i.e. if you're using a custom ability     //
// based on that spell ). In this case, even if you change the stats of the custom spell, the stats  //
// of the original spell will persist and it's almost impossible or atleast difficult to make        //
// many incinerate spells with different stats and sometimes you will be forced to use triggers to   //
// do this.                                                                                          //
//                                                                                                   //
// For this reason I made this spell hoping that this will help you with your difficulties regarding //
// the buggy Incinerate. In this spell, you can make as many incinerate spells as you like, all with //
// different stats and spellIDs. The spell's effects is also not limited by the unit's weapon type   //
// which, unlike Blizzard's Incinerate, will only work with missile attacks. And lastly, one         //
// POSSIBLE advantage of this sytem is that it works together with other buff placers and orb        //
// effects.                                                                                          //
//                                                                                                   //
// Please share your feedback and suggestions about this spell at Hive Workshop or you can PM AGD    //
// at Hive. Please also report bugs and glitches if you found some.                                  //
//                                                                                                   //
//                                                                                                   //
// Note: If you use this resource in your map, please don't forget to give credits to AGD. And if    //
//       you're having problem regarding how to import or in configuring the spell, you can PM him   //
//       or post your comment at Hive Workshop.                                                      //
//                                                                                                   //
//                                                                                                   //
///////////////////////////////////////////////////////////////////////////////////////////////////////
//===================================================================================================//
//===================================================================================================//
//===================================================================================================//
///////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////
// This function indexes the spell's stats listed //
// in the Incinerate spells list one by one       //
////////////////////////////////////////////////////
function TI_InitSpellIndex takes nothing returns nothing

    local integer i = udg_TI_SpellIndex + 1

    set udg_TI_SpellID[i] = udg_TI_Spell
    set udg_TI_SpellAsTrigger[i] = udg_TI_AllowSpellAsTrigger
    set udg_TI_DPABase[i] = udg_TI_DamageStackBase
    set udg_TI_DPAPerLevel[i] = udg_TI_DamageStackPerLevel
    set udg_TI_DurationBase[i] = udg_TI_DurBase
    set udg_TI_DurationPerLevel[i] = udg_TI_DurPerLevel
    set udg_TI_DamageCapBase[i] = udg_TI_DCapBase
    set udg_TI_DamageCapPerLevel[i] = udg_TI_DCapPerLevel
    set udg_TI_ExplodeAOEBase[i] = udg_TI_EXAOEBase
    set udg_TI_ExplodeAOEPerLevel[i] = udg_TI_EXAOEPerLevel
    set udg_TI_ExplodeSmallDAOEBase[i] = udg_TI_EXSmallAOEBase
    set udg_TI_ExplodeSmallDAOEPerLev[i] = udg_TI_EXSmallAOEPerLevel
    set udg_TI_ExplodeSmallDFactorBase[i] = udg_TI_EXSmallDamageFactorBase
    set udg_TI_ExplodeSmallDFactorPerLev[i] = udg_TI_EXSmallDamageFactorPerLevel
    set udg_TI_AT[i] = udg_TI_AttackType
    set udg_TI_DT[i] = udg_TI_DamageType
    set udg_TI_SFXModel1[i] = udg_TI_EffectModel1
    set udg_TI_SFXModel2[i] = udg_TI_EffectModel2
    set udg_TI_AttachPoint[i] = udg_TI_EffectAttachment
    set udg_TI_IsUnitStructure[i] = udg_TI_Structures
    set udg_TI_IsUnitMechanical[i] = udg_TI_Mechanicals
    set udg_TI_IsUnitMagicImmune[i] = udg_TI_MagicImmune
    set udg_TI_IsUnitAlly[i] = udg_TI_Allies
    set udg_TI_IsUnitIllusion[i] = udg_TI_Illusions

    set udg_TI_SpellIndex = i

endfunction


/////////////////////////////////////////////////////
// This function filters unwanted units from being //
// affected by the spell                           //
/////////////////////////////////////////////////////
function TI_TargetFilter takes unit target, player p, integer i returns boolean
    return ( ( not IsUnitType( target, UNIT_TYPE_STRUCTURE ) ) or udg_TI_IsUnitStructure[i] ) and ( ( not IsUnitType( target, UNIT_TYPE_MECHANICAL ) ) or udg_TI_IsUnitMechanical[i] ) and ( ( not IsUnitType( target, UNIT_TYPE_MAGIC_IMMUNE ) ) or udg_TI_IsUnitMagicImmune[i] ) and ( IsUnitEnemy( target, p ) or udg_TI_IsUnitAlly[i] ) and ( ( not IsUnitIllusion( target ) ) or udg_TI_IsUnitIllusion[i] )
endfunction


/////////////////////////////////////////////////////
// This function debuffs the target unit when not  //
// damaged for a certain duration                  //
/////////////////////////////////////////////////////
function TI_Debuff takes nothing returns nothing

    local timer t           = GetExpiredTimer()
    local integer timerkey  = GetHandleId( t )
    local integer i         = LoadInteger( udg_TI_Hash, timerkey, 0 )
    local unit u            = LoadUnitHandle( udg_TI_Hash, timerkey, 1 )
    local integer key       = GetHandleId( u )
    local string I          = I2S( i )

    call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
    call DestroyTimer( t )
    call SaveBoolean( udg_TI_Hash, key, i, false )
    call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), 0 )
    call FlushChildHashtable( udg_TI_Hash, timerkey )

    set t = null
    set u = null
    set I = null

endfunction


//////////////////////////////////////////////////////
// This function triggers the dead unit's explosion //
//////////////////////////////////////////////////////
function TI_Incinerate takes nothing returns boolean

    local unit dying        = GetTriggerUnit()
    local integer key       = GetHandleId( dying )
    local real x            = GetUnitX( dying )
    local real y            = GetUnitY( dying )
    local integer i         = 0
    local unit target
    local player p
    local real dx
    local real dy
    local real damage
    local real smalldfactor
    local unit buffplacer
    local string I

    loop

        set i = i + 1
        set I = I2S( i )

        if LoadBoolean( udg_TI_Hash, key, i ) then

            set damage = LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) )
            set smalldfactor = LoadReal( udg_TI_Hash, key, StringHash( "SmallDFactor" + I ) )
            set buffplacer = LoadUnitHandle( udg_TI_Hash, key, StringHash( "BuffPlacer" + I ) )
            set p = GetOwningPlayer( buffplacer )
            call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), 0 )
            call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
            call DestroyEffect( AddSpecialEffect( udg_TI_SFXModel2[i], x, y ) )
            call GroupEnumUnitsInRange( udg_TI_TempGroup, x, y, LoadReal( udg_TI_Hash, key, StringHash( "SmallDAOE" + I ) ), null )

            loop

                set target = FirstOfGroup( udg_TI_TempGroup )
                exitwhen target == null
                call GroupRemoveUnit( udg_TI_TempGroup, target )
                set dx = GetUnitX( target ) - x
                set dy = GetUnitY( target ) - y

                if ( target != buffplacer ) and TI_TargetFilter( target, p, i ) then

                    if SquareRoot( dx*dx + dy*dy ) > LoadReal( udg_TI_Hash, key, StringHash( "AOE" + I ) ) then

                        call UnitDamageTarget( buffplacer, target, damage*smalldfactor, true, false, udg_TI_AT[i], udg_TI_DT[i], null )

                    else

                        call UnitDamageTarget( buffplacer, target, damage, true, false, udg_TI_AT[i], udg_TI_DT[i], null )

                    endif

                endif

            endloop

        endif

        exitwhen i == udg_TI_SpellIndex

    endloop

    call FlushChildHashtable( udg_TI_Hash, key )

    set dying = null
    set buffplacer = null
    set p = null
    set I = null

    return false

endfunction


///////////////////////////////////////////////////////////
// This function checks if the level of incinerate spell //
// for the damage source is greater than zero in order   //
// run the main actions of the spell.                    //
///////////////////////////////////////////////////////////
function TI_MainAction takes nothing returns boolean

    local trigger trig   = GetTriggeringTrigger()
    local integer key    = GetHandleId( udg_DamageEventTarget )
    local integer i      = 0
    local integer level
    local integer timerkey
    local real dcap
    local string I

    loop

        set i = i + 1
        set level = GetUnitAbilityLevel( udg_DamageEventSource, udg_TI_SpellID[i] )

        if level > 0 then

            if not udg_IsDamageSpell or udg_TI_SpellAsTrigger[i] then

                set I = I2S( i )
                set dcap = udg_TI_DamageCapBase[i] + udg_TI_DamageCapPerLevel[i]*level

                if TI_TargetFilter( udg_DamageEventTarget, GetOwningPlayer( udg_DamageEventSource ), i ) then

                    call DestroyEffect( LoadEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ) ) )
                    call SaveEffectHandle( udg_TI_Hash, key, StringHash( "SFX" + I ), AddSpecialEffectTarget( udg_TI_SFXModel1[i], udg_DamageEventTarget, udg_TI_AttachPoint[i] ) )
                    call DestroyTimer( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ) )
                    call SaveTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ), CreateTimer() )
                    set timerkey = GetHandleId( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ) )
                    call SaveUnitHandle( udg_TI_Hash, timerkey, 1, udg_DamageEventTarget )
                    call SaveUnitHandle( udg_TI_Hash, key, StringHash( "BuffPlacer" + I ), udg_DamageEventSource )
                    call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ) + udg_TI_DPABase[i] + udg_TI_DPAPerLevel[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "AOE" + I ), udg_TI_ExplodeAOEBase[i] + udg_TI_ExplodeAOEPerLevel[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "SmallDAOE" + I ), udg_TI_ExplodeSmallDAOEBase[i] + udg_TI_ExplodeSmallDAOEPerLev[i]*level )
                    call SaveReal( udg_TI_Hash, key, StringHash( "SmallDFactor" + I  ), udg_TI_ExplodeSmallDFactorBase[i] + udg_TI_ExplodeSmallDFactorPerLev[i]*level )
                    call SaveInteger( udg_TI_Hash, timerkey, 0, i )
                    call SaveBoolean( udg_TI_Hash, key, i, true )

                    if dcap != 0 then

                        if LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ) > dcap then

                            call SaveReal( udg_TI_Hash, key, StringHash( "Damage" + I ), dcap )

                        endif

                    endif

                    call DisableTrigger( trig )
                    call UnitDamageTarget( udg_DamageEventSource, udg_DamageEventTarget, udg_DamageEventAmount + LoadReal( udg_TI_Hash, key, StringHash( "Damage" + I ) ), true, false, udg_TI_AT[i], udg_TI_DT[i], null )
                    call EnableTrigger( trig )
                    set udg_DamageEventAmount = 0
                    call TimerStart( LoadTimerHandle( udg_TI_Hash, key, StringHash( "Timer" + I ) ), udg_TI_DurationBase[i] + udg_TI_DurationPerLevel[i]*level, false, function TI_Debuff )

                endif

            endif

        endif

        exitwhen i == udg_TI_SpellIndex

    endloop

    set trig = null
    set I = null

    return false

endfunction


/////////////////////////////
// Initialization function //
/////////////////////////////
function InitTrig_Triggered_Incinerate takes nothing returns nothing

    local trigger t1  = CreateTrigger()
    local trigger t2  = CreateTrigger()
    set udg_TI_Hash   = InitHashtable()

    call TriggerRegisterAnyUnitEventBJ( t1, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( t1, Filter( function TI_Incinerate ) )
    call TriggerRegisterVariableEvent( t2, "udg_DamageEvent", EQUAL, 1 )
    call TriggerAddCondition( t2, Filter( function TI_MainAction ) )
    call ExecuteFunc( "Trig_Incinerate_SpellsList_Actions" )

endfunction


//////////////////////
//******************//
//** End of Spell **//
//******************//
//////////////////////
 



Changelogs

v1.0
- First Upload
v1.1
- Multiple incinerates of different rawcodes now doesn't stack damage with each other on
a single unit but instead, they stack their OWN damage( or incinerates of the same rawcode )
on that same unit.
- Removed the dummy units, the attacker is now the one to damage the targets instead of
the dummy
- Removed the AddEvent function, now uses a damage detection system instead
- Added a debug option
- Combined the triggeractions with triggerconditions
- Removed the TI_AbilLevel function for ability level check but instead, uses a simplier way
- Replaced the global indexes at the configuration with a local integer for neatness
- Fixed some lapses in the previous spell such as:
* Damage stacked not removed from the hero after dying and being revived
* incineration of once affected units when they die even after the incinerate timer expires
- Replaced the local groups with a single global group
- Other changes
v1.1b
- Moved the TI_SpellsList to a different section and also converted is from jass
to a GUI friendly configuration section
- Moved the debug section to a separate trigger
- Renamed a variable with a misleading name. Changed the name from killer => buffplacer
- Other very minor changes
v1.2
- Replaced GDD by Bribe's Damage Engine
- You can now configure whether spells( this extends to all damage of attack type normal) can trigger incinerate or not
- Combined the full damage explosion and small damage explosion group into one loop
- Made a separate function for filtering target units
- Minor changes



Keywords:
Incinerate, Fury Swipe, Damage Stacking, Simple
Contents

Triggered Incinerate v1.2 (Map)

Reviews
KILLCIDE
Ugh yes. The code is much shorter :D Here are a few suggestions: You should maybe switch all the global variables to some type of default incinerate just in case users forget to use one of the variables before they call the function. If they do...
  1. Aether

    Aether

    Joined:
    Dec 31, 2015
    Messages:
    120
    Resources:
    0
    Resources:
    0
    There's nothing in the code in the description. :O
     
  2. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Ah, my bad.
    Now updated.
     
    Last edited: Jun 6, 2016
  3. Emm-A-

    Emm-A-

    Joined:
    Jul 1, 2008
    Messages:
    1,313
    Resources:
    0
    Resources:
    0
    Hey AGD, why are you using
    Code (vJASS):
    StringHash()
    instead of integer numbers? For readability?
     
  4. Kyrbi0

    Kyrbi0

    Joined:
    Jul 29, 2008
    Messages:
    7,786
    Resources:
    1
    Models:
    1
    Resources:
    1
    This is pretty nifty. CURSE YOU BLIZZARD HARDCODING!
     
  5. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Cool idea, especially for a passive ability like Incinerate that has a lot of hardcoded values. However, I see this functioning way more as a system rather than multiple abilities. I also wonder how many different types of Incinerates people would actually want in their maps. Anyway, here are some issues I would like for you to tackle:
    • It's not necessary to null the local triggers in the InitTrig function
    • The way you index abilities are horrendous. Instead of copy-pasting all the variables inside one function, why not have a function that will do it for you? You set some values to some temp global variables, and then call the function that will index + transfer all the temp global variables to the indexed variables. This will dramatically reduce the size of function TI_Config
    • Instead of making your own "DDS", please just use any of the reliable DDS in the spell section
    • TI_SpellCheck & MainAction can be combined into one function
    • In TI_SpellCheck, replace
      return true
      to
      exitwhen true
      . Even if the ability is found, the loop will still continue to run with your current setup
    • The dummy unit's ID is currently hardcoded
    • It's not necessary to convert level to a real when you calculate things like duration & damage
    • I would move the filters to a function somewhere near the top of the code so users can easily configure it
    • In MainAction, why is the dummy only removed if unit u passes the filters?
    • In MainAction, you should only declare the locals like level nand duration, and then store things into them if the unit passes the filter
    • Why SaveStringBJ over SavStr?
    • Personally, I think the damage and death event functions should only register events if there is an instance of the debuff
    • You can get rid of the locals fulldamagegroup & smalldamage group by just using a single recycled global group
    • Why is a dummy unit dealing damage to the units instead of the actual caster?

    Could you also add an ingame screenshot instead of the spell's code? For now, I will set the spell's status to Awaiting Update.
     
  6. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Yes

    It is because if the actual caster will be the one to deal damage, it will trigger another incinerate, and thus creating an unending loop. But if it is the dummy, it will not because it has no incinerate ability.
     
    Last edited by a moderator: Jun 13, 2016
  7. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Could you not add an extra condition to your "DDS" to make sure that the target source is not already affected by Incinerate? Or can other incinerates stack on each other?
     
  8. IcemanBo

    IcemanBo

    Joined:
    Sep 6, 2013
    Messages:
    6,156
    Resources:
    22
    Maps:
    3
    Spells:
    11
    Template:
    1
    Tutorials:
    4
    JASS:
    3
    Resources:
    22
    The
    'n000'
    unit type in code should not be hardcoded, as Killcide mentioned.

    The StringHash function is not very compared to usage of constants. It's not required to evaluate it again and again.
    It would be more performant to use variables for the usage.

    Directly give the user access to define attacktype, damagetype, weapntype, instead of defining the index. No need to convert them each call.

    Really follow Killcide's suggestion and use a DDS system. Some systems are made for good reasons, and are not easy to do perfectly from scratch.
     
  9. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Yes I'll include it in the update.

    The source is not affected by the incinerate but the target unit. And yes, other incinerates can stack damage on each other ( additionally ).
    I'm not sure if I understood your first question here correctly.
     
  10. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    I'm aware. However, that was not what I was suggesting. I really dislike the fact that the caster of the spell does not get appropriate credit for the kills. Since the dummy unit is dealing damage, the dummy unit will get credit. If you're afraid of an infinite loop, why not just disable the trigger before the you deal the triggered damage and then turn it back on afterwards?
     
  11. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Resource updated.
    I still need to use StringHashes because I used the concatenated string with the spell index as the parent key.
     
    Last edited: Oct 25, 2016
  12. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    It seems you ignored some of my important suggestions.
    • The brute copy-paste setup you have for TI_SpellsList can be avoided by using temp global variables that a user can setup and then simply calling a function that will index all the variables for them is better than having every single incinerate spell under one function
    • It would be better to keep the unit filters in TI_MainAction in a seperate function near the top of the code so that users can easily configure it to their liking instead of having to look for it in the code
    • Out of curiousity, why does the unit that deals the killing blow not get damaged by the AoE?
    • My same suggestion for the filters in TI_MainAction go for TI_Incinerate
    • I personally think all the debug messages you have in the code are not needed and just make the code look like a mess. Since you are using hashtables, you can have the debug in some seperate code/trigger and easily look up who is dealing what damage with what spell, right?
    I would really like for you to do the first suggestion and maybe the one about the debug messages. This will dramatically reduce the length of your code. I will set this resource back to Awaiting Update.
     
  13. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    If I understood correctly, that would mean that they can only setup one set of stats that is the same for all incinerates.

    I think these lines in the configurations does it already, no?
    Code (vJASS):

       //** Determines if the following type of units are allowed as target **//

       // Structures
       set udg_TI_IsUnitStructure[i] = false

       // Mechanical
       set udg_TI_IsUnitMechanical[i] = false

       // Magic Immune
       set udg_TI_IsUnitMagicImmune[i] = false

       // Allies
       set udg_TI_IsUnitAlly[i] = true

       // Illusions
       set udg_TI_IsUnitIllusion[i] = true


    Okay I will do it

    I missed this one, I'll fix it
     
  14. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    No? What makes you think that?

    • Set SaveAbility = Incinerate v1
    • Set SaveBaseDamage = 100
    • Set SaveBaseDamagePerLevel = 50
    • Set SaveSFXExplosion = Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
    • Custom script: call TI_SpellsList()
    • -------- --------
    • Set SaveAbility = Incinerate v2
    • Set SaveBaseDamage = 50
    • Set SaveBaseDamagePerLevel = 100
    • Set SaveSFXExplosion = Objects\Spawnmodels\Undead\UndeadBlood\UndeadBloodNecromancer.mdl
    • Custom script: call TI_SpellsList()


    Code (vJASS):

    function TI_SpellsList takes nothing returns nothing
        set udg_Ability[udg_Index] = udg_SaveAbility
        set udg_BaseDamage[udg_Index] = udg_SaveBaseDamage
        set udg_BaseDamagePerLevel[udg_Index] = udg_SaveBaseDamagePerLevel
        set udg_SFXExplosion[udg_Index] = udg_SaveSFXExplosion
        set udg_Index = udg_Index + 1
    endfunction
     


    You can even add a "safety" by having default Incinerate that will switch all the global variables to their default values.

    Ahh yes :p my mistake. I would still do it for readability though.
     
  15. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    But users still need to do the same copy - paste if they want to add more slot for the spell right?
     
  16. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Yes, but at least they wont be under one insanely long function in the main code.
     
  17. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Alright i'll do it, i guess it would also be better for this spell to be more GUI friendly.
     
  18. AGD

    AGD

    Joined:
    Mar 29, 2016
    Messages:
    396
    Resources:
    13
    Spells:
    7
    Tutorials:
    1
    JASS:
    5
    Resources:
    13
    Now updated

    Done

    The unit named killer there is not actually the killing unit but the one that places the incinerate buff on the dying unit so it should not take damage from the explosion it caused.
    However I already changed the variable name from killer => buffplacer to make it clear.

    Done

    BTW, I also added the credits which I forgot to put previously.
     
  19. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,495
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    Ugh yes. The code is much shorter :D Here are a few suggestions:
    • You should maybe switch all the global variables to some type of default incinerate just in case users forget to use one of the variables before they call the function. If they do forget, the global variable will be storing the most recent incinerate they made. You could have users configure the default incinerate in some seperate function or a bunch of constant functions
    • I fail to see the purpose of this
      call ExecuteFunc( "Trig_Incinerate_SpellsList_Actions" )

    • You don't have to post your debug trigger in your description :p
    My only gripe with the code is how you keep the actual filters in the code ! It makes the code all wide and ugly. I still stand by my previous suggestion to you before by just calling the function directly like so:
    Code (vJASS):

    function Filters takes unit u, player p returns boolean
        return (not IsUnitType(u, UNIT_TYPE_STRUCTURE) and (not IsUnitType(u,UNIT_TYPE_MECHANICAL) and (IsUnitEnemy(u, p)
    endfunction

    //=======================================================
    function SomeFunction takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local player p = GetTriggerPlayer()

        if Filters(u, p) then
            // do stuff
        endif
     


    Other than that, the code looks fine to me. The submission overall isn't something gamebreaking, nor is it original :p I still question how many versions of Incinerate people will actually have in their map, but someone is bound to find this useful. Approved with a rating of 3/5.