• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Revolving Hammers v1.1 GUI

[TD] REVOLVING HAMMERS [ GUI ] [/TD]
SPELL DESCRIPTION:
full

[TD] SPELL IMAGES: [/TD]

onCast

onMid

onRevolving


full


full


full


[TD] CHANGELOGS :[/TD][TD]
v1.0 - Released
v1.1 - Updated based on KILLCIDE's review.
[/TD]
[TD] CREDITS :[/TD][TD]
Bribe ( Unit Indexer System )
Jad ( KB3D System )
[/TD]

Revolving Hammers Configuration

Cast

Loop

  • Revolving Hammers Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- --------
      • -------- declaration of external variables ( DELETE THESE EXTERNAL VARIABLES AFTER YOU IMPORT ) --------
      • Set RH_CasterX[0] = 0.00
      • Set RH_CasterY[0] = 0.00
      • Set RH_Map[0] = 0.00
      • -------- --------
      • -------- --------
      • -------- * SPELL CONFIGURATION FIELD * --------
      • -------- --------
      • -------- OBJECT EDITOR ( F6 ) --------
      • -------- --------
      • -------- The spell or ability used in the triggers. ( Import the Revolving Hammers Ability ) --------
      • Set RH_Ability = Revolving Hammers
      • -------- The dummy unit used in the triggers. ( Import the Revolving Hammers Dummy ) --------
      • Set RH_DummyType = Revolving Hammers Dummy
      • -------- --------
      • -------- SPELL DATA --------
      • -------- --------
      • -------- The maximum level of the spell or ability. --------
      • Set RH_AbilityMaxLevel = 3
      • -------- ^ Modify at your own risk: Must be equal to the number of levels of Revolving Hammers Ability. ( Default: 3 ) --------
      • -------- --------
      • -------- The string order of the spell. Must be equal to BaseOrderId of the Revolving Hammers Ability. --------
      • Set RH_ChannelOrder = thunderclap
      • -------- --------
      • -------- The event duration of the spell. Must be equal to followed through time values in the Revolving Hammers Ability. --------
      • Set RH_ChannelDuration[1] = 8.00
      • Set RH_ChannelDuration[2] = 9.00
      • Set RH_ChannelDuration[3] = 10.00
      • -------- ^ Go to Object Editor ( F6 ) to see followed through time values in the Revolving Hammers Ability. It must be EQUAL to these values. --------
      • -------- --------
      • -------- Destroy Trees? True = Yes, False = No --------
      • Set RH_DestroyTrees = True
      • -------- --------
      • -------- Enable dummy units player color? True = Yes, False = No --------
      • Set RH_DummyPlayerColor = True
      • -------- --------
      • -------- The attack and damage type of the source. --------
      • Set RH_AttackType = Spells
      • Set RH_DamageType = Normal
      • -------- --------
      • -------- The interval of the looping trigger. --------
      • Set RH_LoopInterval = 0.02
      • -------- ^ Modify at your own risk; changing the value can affect the spell performance. Recommended Value: 0.03 for a good performance , 0.02 is optional BUT can cause lags because of the number of units used in the spell loop trigger. --------
      • -------- ^ I've chosen 0.02 to support the smoothness motion of the hammers but it can decrease a little performance. --------
      • -------- --------
      • -------- HAMMERS DATA --------
      • -------- --------
      • -------- The art model used to attach in the hammer unit and trail effect. --------
      • Set RH_Effect[1] = Abilities\Spells\Human\StormBolt\StormBoltMissile.mdl
      • Set RH_EffectAttach[1] = origin
      • Set RH_Effect[8] = Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Set RH_EffectAttach[6] = chest
      • -------- ^ If you want to disable the trail effect just erase the model path in the RH_Effect[ 8 ] variable. ( <Empty String> ) --------
      • -------- --------
      • -------- The amount of the hammer units that will revolve around the caster. --------
      • Set RH_HammerCount[1] = 3
      • Set RH_HammerCount[2] = 4
      • Set RH_HammerCount[3] = 5
      • -------- ^ Modify at your own risk: Large values can cause serious lags and the value must not be 0. ( != 0 ) --------
      • -------- --------
      • -------- The size of the hammers. --------
      • Set RH_HammerSize[1] = 1.50
      • Set RH_HammerSize[2] = 1.45
      • Set RH_HammerSize[3] = 1.45
      • -------- --------
      • -------- The height of the hammers. --------
      • Set RH_HammerHeight[1] = 15.00
      • Set RH_HammerHeight[2] = 15.00
      • Set RH_HammerHeight[3] = 15.00
      • -------- --------
      • -------- An effect occurs at the attachment of the caster when releasing hammers. --------
      • Set RH_Effect[2] = Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Set RH_EffectAttach[2] = chest
      • -------- --------
      • -------- The max distance that hammers will spread. ( Area of Effect or Radius ) --------
      • Set RH_HammerSpreadDistance[1] = 400.00
      • Set RH_HammerSpreadDistance[2] = 400.00
      • Set RH_HammerSpreadDistance[3] = 400.00
      • -------- --------
      • -------- The speed of the hammers will spread. ( Distance Per Second ) --------
      • Set RH_HammerSpreadSpeed[1] = 250.00
      • Set RH_HammerSpreadSpeed[2] = 350.00
      • Set RH_HammerSpreadSpeed[3] = 450.00
      • -------- --------
      • -------- An effect occurs when the hammers are at the motion state. --------
      • Set RH_Effect[3] = Abilities\Weapons\Bolt\BoltImpact.mdl
      • Set RH_HammerMotionEffectChance = 15
      • -------- ^ It is the probability of spawning a motion effects ( looping effects ). The value must based on a percentage ( 0 - 100 ). --------
      • -------- ^ If you want to disable this motion effect then set the chance value to 0. --------
      • -------- ^ Modify at your own risk; The large maximum value is 100 do not EXCEED or it will cause problems. Recommended Value: the modified value ( 15 ). --------
      • -------- --------
      • -------- The collision radius of the hammer. --------
      • Set RH_HammerCollisionSize[1] = 75.00
      • Set RH_HammerCollisionSize[2] = 70.00
      • Set RH_HammerCollisionSize[3] = 70.00
      • -------- --------
      • -------- Rotate the hammers while revolving? True = Yes, False = No --------
      • Set RH_HammerRotate = True
      • -------- --------
      • -------- An effect occurs when the hammers starts revolving. --------
      • Set RH_Effect[4] = Abilities\Weapons\FarseerMissile\FarseerMissile.mdl
      • -------- --------
      • -------- The revolving angle speed of the hammers. These modified values are Recommended. --------
      • Set RH_HammerRevolveAngleSpeed[1] = 1.50
      • Set RH_HammerRevolveAngleSpeed[2] = 4.50
      • Set RH_HammerRevolveAngleSpeed[3] = 7.50
      • -------- --------
      • -------- An effect occurs when the hammers hit an enemy unit. --------
      • Set RH_Effect[5] = Abilities\Spells\Human\StormBolt\StormBoltMissile.mdl
      • Set RH_EffectAttach[5] = chest
      • -------- --------
      • -------- The damage of the hammer ( Source -> Caster ) when it hits an enemy unit ( Target -> Enemy Unit ). --------
      • Set RH_HammerHitDamage[1] = 100.00
      • Set RH_HammerHitDamage[2] = 150.00
      • Set RH_HammerHitDamage[3] = 200.00
      • -------- --------
      • -------- Knockback when the hammer hits enemy unit? True = Yes, False = No --------
      • Set RH_HammerHitKnockback = True
      • -------- --------
      • -------- KNOCKBACK DATA --------
      • -------- ^ Knockbacks are generated by the 'KB3D System' so make sure you implemented the required system to your map. --------
      • -------- --------
      • -------- A looping effect occurs to the enemy unit when hitted by the hammer. --------
      • Set RH_Effect[6] = Abilities\Spells\Human\FlakCannons\FlakTarget.mdl
      • -------- --------
      • -------- The range of the knockback. ( Distance ) --------
      • Set RH_KB_Range = 200.00
      • -------- The speed of the knockback. ( Distance Per Second ) --------
      • Set RH_KB_Speed = 450.00
      • -------- The acceleration of the knockback. The modified value is recommended. --------
      • Set RH_KB_Acceleration = -100.00
      • -------- --------
      • -------- Knockback enemy units nearby the caster when onCast? True = Yes, False = No --------
      • Set RH_KB_OnCast = True
      • -------- A looping effect occurs to the enemy unit when knockbacked onCast. --------
      • Set RH_Effect[7] = Abilities\Weapons\FarseerMissile\FarseerMissile.mdl
      • -------- --------
      • -------- The range of the knockback. ( Distance ) ( onCast ) --------
      • Set RH_KB_OnCastRange = 300.00
      • -------- The speed of the knockback. ( Distance Per Second ) ( onCast ) --------
      • Set RH_KB_OnCastSpeed = 800.00
      • -------- The acceleration of the knockback. The modified value is recommended. ( onCast ) --------
      • Set RH_KB_OnCastAcceleration = -100.00
      • -------- --------
      • -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------
      • -------- CODE DATA --------
      • -------- ( DON'T TOUCH THE LINES BELOW UNLESS SOME OF THEM MALFUNCTIONS ) --------
      • -------- ...................................................................................................................................... --------
      • -------- Preload Objects --------
      • -------- Abilties, Units: --------
      • Custom script: set udg_RH_Unit = CreateUnit( Player( 15 ), udg_RH_DummyType, 0, 0, 0 )
      • Custom script: call UnitAddAbility( udg_RH_Unit, udg_RH_Ability )
      • Custom script: call RemoveUnit( udg_RH_Unit )
      • -------- Effects: --------
      • Set RH_EffectCount = 8
      • For each (Integer RH_CustomInteger) from 1 to RH_EffectCount, do (Actions)
        • Loop - Actions
          • Custom script: call Preload( udg_RH_Effect[ udg_RH_CustomInteger ] )
      • -------- ...................................................................................................................................... --------
      • -------- Initialize Calculations --------
      • For each (Integer RH_CustomInteger) from 1 to RH_AbilityMaxLevel, do (Actions)
        • Loop - Actions
          • Set RH_CustomReal[RH_CustomInteger] = (360.00 / (Real(RH_HammerCount[RH_CustomInteger])))
          • Set RH_CustomReal2[RH_CustomInteger] = (RH_HammerSpreadSpeed[RH_CustomInteger] x RH_LoopInterval)
      • -------- ...................................................................................................................................... --------
      • -------- Loop Event --------
      • Trigger - Add to Revolving Hammers Loop <gen> the event (Time - Every RH_LoopInterval seconds of game time)
      • -------- ...................................................................................................................................... --------
      • -------- Tree Checker --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RH_DestroyTrees Equal to True
        • Then - Actions
          • Custom script: set udg_RH_TreeChecker = CreateUnit( Player( 15 ), udg_RH_DummyType, 0, 0, 0 )
          • Custom script: call UnitAddAbility( udg_RH_TreeChecker, 'Ahar' ) // Harvest Ability
        • Else - Actions
      • -------- ...................................................................................................................................... --------
      • -------- Motion Effect Disabler --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RH_HammerMotionEffectChance Equal to 0
        • Then - Actions
          • Set RH_HammerMotionEffectChance = -1
        • Else - Actions
      • -------- ...................................................................................................................................... --------
      • -------- declaration of initial variables --------
      • Custom script: set udg_RH_Map[ 1 ] = GetRectMinX( bj_mapInitialPlayableArea )
      • Custom script: set udg_RH_Map[ 2 ] = GetRectMaxX( bj_mapInitialPlayableArea )
      • Custom script: set udg_RH_Map[ 3 ] = GetRectMinY( bj_mapInitialPlayableArea )
      • Custom script: set udg_RH_Map[ 4 ] = GetRectMaxY( bj_mapInitialPlayableArea )
      • -------- ...................................................................................................................................... --------
      • -------- --------
      • -------- * END OF SPELL CONFIGURATION FIELD * --------
      • -------- --------
      • Custom script: endfunction
      • Custom script:
      • -------- !Essential Function! --------
      • Custom script: function RH_SafeFilter takes nothing returns boolean
      • Custom script: return true
      • Custom script: endfunction
      • -------- ^ For using/calling GroupEnumUnitsInRange func in a loop, eventually prevents leak. --------
      • Custom script: function RH_ValidateXY takes real x, real y returns boolean
      • Custom script: return x < udg_RH_Map[ 2 ] and x > udg_RH_Map[ 1 ] and y < udg_RH_Map[ 4 ] and y > udg_RH_Map[ 3 ]
      • -------- ^ For detecting if X/Y coordinates inside boundaries. --------
  • Revolving Hammers Execution
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to RH_Ability
    • Actions
      • -------- ...................................................................................................................................... --------
      • -------- onCast --------
      • -------- ...................................................................................................................................... --------
      • -------- declaration of locals --------
      • Custom script: local unit u = GetTriggerUnit( )
      • Custom script: local real casterX = GetWidgetX( u )
      • Custom script: local real casterY = GetWidgetY( u )
      • Custom script: local real spawnX
      • Custom script: local real spawnY
      • -------- --------
      • -------- [ 0 ] = temporary before the index declared --------
      • Custom script: set udg_RH_Level[ 0 ] = GetUnitAbilityLevel( u, udg_RH_Ability )
      • Custom script: set udg_RH_CasterPlayer[ 0 ] = GetOwningPlayer( u )
      • -------- --------
      • Custom script: call DestroyEffect( AddSpecialEffectTarget( udg_RH_Effect[ 2 ], u, udg_RH_EffectAttach[ 2 ] ) )
      • -------- --------
      • -------- Knockback OnCast Boolean --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RH_KB_OnCast Equal to True
        • Then - Actions
          • -------- --------
          • Custom script: call GroupEnumUnitsInRange( bj_lastCreatedGroup, casterX, casterY, udg_RH_HammerSpreadDistance[ udg_RH_Level[ 0 ] ], Condition( function RH_SafeFilter ) )
          • Custom script: loop
          • Custom script: set udg_RH_KB_Unit = FirstOfGroup( bj_lastCreatedGroup )
          • Custom script: exitwhen udg_RH_KB_Unit == null
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (RH_KB_Unit is dead) Equal to False
              • (RH_KB_Unit is A structure) Equal to False
              • (RH_KB_Unit is Magic Immune) Equal to False
              • (RH_KB_Unit is A flying unit) Equal to False
              • (RH_KB_Unit belongs to an enemy of RH_CasterPlayer[0]) Equal to True
            • Then - Actions
              • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
              • -------- KB3D SYSTEM --------
              • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
              • Set KB3D_Unit = RH_KB_Unit
              • Set KB3D_Range = RH_KB_OnCastRange
              • Set KB3D_Speed = RH_KB_OnCastSpeed
              • Custom script: set udg_KB3D_Angle = Atan2( GetWidgetY( udg_RH_KB_Unit ) - casterY, GetWidgetX( udg_RH_KB_Unit ) - casterX ) * bj_RADTODEG
              • Set KB3D_EndOnObstacle = True
              • Set KB3D_EndwhenDead = True
              • Set KB3D_Accel = RH_KB_OnCastAcceleration
              • Set KB3D_AttackType = RH_AttackType
              • Set KB3D_DamageType = RH_DamageType
              • Custom script: set udg_KB3D_Damager = u
              • Set KB3D_DestroyTree = RH_DestroyTrees
              • Set KB3D_DisableUnit = True
              • Set KB3D_Fx = RH_Effect[7]
              • Set KB3D_iKB = True
              • Set KB3D_UnpathableStop = True
              • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
              • -------- Registed All of the Settings --------
              • Custom script: call ExecuteFunc( "KB3D_Registration" )
              • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
            • Else - Actions
          • -------- --------
          • Custom script: call GroupRemoveUnit( bj_lastCreatedGroup, udg_RH_KB_Unit )
          • Custom script: endloop
          • -------- --------
        • Else - Actions
      • -------- --------
      • -------- Hammers Creation --------
      • -------- --------
      • For each (Integer RH_CustomInteger) from 1 to RH_HammerCount[RH_Level[0]], do (Actions)
        • Loop - Actions
          • -------- --------
          • Set RH_HammerSpreadAngle[0] = (RH_HammerSpreadAngle[0] + RH_CustomReal[RH_Level[0]])
          • Custom script: set spawnX = casterX + udg_RH_HammerCollisionSize[ udg_RH_Level[ 0 ] ] * Cos( udg_RH_HammerSpreadAngle[ 0 ] * bj_DEGTORAD )
          • Custom script: set spawnY = casterY + udg_RH_HammerCollisionSize[ udg_RH_Level[ 0 ] ] * Sin( udg_RH_HammerSpreadAngle[ 0 ] * bj_DEGTORAD )
          • -------- --------
          • Custom script: if RH_ValidateXY( spawnX, spawnY ) then
          • Custom script: set udg_RH_HammerUnit = CreateUnit( udg_RH_CasterPlayer[ 0 ], udg_RH_DummyType, spawnX, spawnY, udg_RH_HammerSpreadAngle[ 0 ] )
          • Custom script: set udg_RH_ID = GetUnitUserData( udg_RH_HammerUnit )
          • Custom script: set udg_RH_HammerModelHandler[ udg_RH_ID ] = AddSpecialEffectTarget( udg_RH_Effect[ 1 ], udg_RH_HammerUnit, udg_RH_EffectAttach[ 2 ] )
          • Custom script: set udg_RH_HammerTrailHandler[ udg_RH_ID ] = AddSpecialEffectTarget( udg_RH_Effect[ 8 ], udg_RH_HammerUnit, udg_RH_EffectAttach[ 6 ] )
          • Custom script: call SetUnitScale( udg_RH_HammerUnit, udg_RH_HammerSize[ udg_RH_Level[ 0 ] ], 0, 0 )
          • Custom script: call SetUnitFlyHeight( udg_RH_HammerUnit, udg_RH_HammerHeight[ udg_RH_Level[ 0 ] ], 0 )
          • -------- --------
          • -------- Player Dummy Color Boolean --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RH_DummyPlayerColor Equal to True
            • Then - Actions
              • Unit - Change color of RH_HammerUnit to (Color of RH_CasterPlayer[0])
            • Else - Actions
              • Unit - Change color of RH_HammerUnit to (Color of Neutral Passive)
          • -------- --------
          • -------- Attaching values into ID --------
          • Set RH_Caster[RH_ID] = (Triggering unit)
          • Set RH_CasterPlayer[RH_ID] = RH_CasterPlayer[0]
          • Set RH_ChannelDurationCounter[RH_ID] = 0.00
          • Set RH_HammerSpreadDistanceCounter[RH_ID] = 0.00
          • Set RH_Level[RH_ID] = RH_Level[0]
          • Set RH_HammerRevolve[RH_ID] = False
          • Set RH_HammerCustomBoolean[RH_ID] = False
          • Custom script: set udg_RH_HammerSpreadAngle[ udg_RH_ID ] = GetUnitFacing( udg_RH_HammerUnit )
          • Custom script: set udg_RH_HammerRevolveAngle[ udg_RH_ID ] = udg_RH_HammerSpreadAngle[ 0 ]
          • Custom script: set udg_RH_CasterX[ udg_RH_ID ] = casterX
          • Custom script: set udg_RH_CasterY[ udg_RH_ID ] = casterY
          • -------- --------
          • Unit Group - Add RH_HammerUnit to RH_Group
          • -------- --------
          • Custom script: endif
          • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Revolving Hammers Loop <gen> is on) Equal to False
        • Then - Actions
          • Trigger - Turn on Revolving Hammers Loop <gen>
        • Else - Actions
      • -------- --------
      • -------- nulling variables --------
      • Custom script: set u = null
      • -------- --------
  • Revolving Hammers Loop
    • Events
    • Conditions
    • Actions
      • -------- ...................................................................................................................................... --------
      • -------- onLoop --------
      • -------- ...................................................................................................................................... --------
      • Unit Group - Pick every unit in RH_Group and do (Actions)
        • Loop - Actions
          • -------- --------
          • -------- declaration of locals --------
          • Custom script: local real casterX
          • Custom script: local real casterY
          • Custom script: local real hammerX
          • Custom script: local real hammerY
          • Custom script: local real hammerSpreadMotionX
          • Custom script: local real hammerSpreadMotionY
          • Custom script: local real hammerRevolveMotionX
          • Custom script: local real hammerRevolveMotionY
          • -------- --------
          • Set RH_Unit = (Picked unit)
          • Custom script: set udg_RH_ID = GetUnitUserData( udg_RH_Unit )
          • -------- --------
          • Custom script: set hammerX = GetWidgetX( udg_RH_Unit )
          • Custom script: set hammerY = GetWidgetY( udg_RH_Unit )
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RH_DestroyTrees Equal to True
            • Then - Actions
              • -------- --------
              • Custom script: set udg_RH_CustomLocation = Location( hammerX, hammerY )
              • Destructible - Pick every destructible within RH_HammerCollisionSize[RH_Level[RH_ID]] of RH_CustomLocation and do (Actions)
                • Loop - Actions
                  • Set RH_Trees = (Picked destructible)
                  • Unit - Order RH_TreeChecker to Harvest RH_Trees
                  • -------- IsTree --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current order of RH_TreeChecker) Equal to (Order(harvest))
                    • Then - Actions
                      • Destructible - Kill RH_Trees
                    • Else - Actions
                  • Unit - Order RH_TreeChecker to Stop
              • Custom script: call RemoveLocation( udg_RH_CustomLocation )
              • -------- --------
            • Else - Actions
          • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
          • -------- Loads, Updates, Saves: ChannelDurationCounter --------
          • Set RH_ChannelDurationCounter[RH_ID] = (RH_ChannelDurationCounter[RH_ID] + RH_LoopInterval)
          • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (RH_Caster[RH_ID] is dead) Equal to True
                  • (Current order of RH_Caster[RH_ID]) Not equal to (Order(RH_ChannelOrder))
                  • RH_ChannelDurationCounter[RH_ID] Greater than or equal to RH_ChannelDuration[RH_Level[RH_ID]]
            • Then - Actions
              • -------- --------
              • Custom script: if GetUnitCurrentOrder( udg_RH_Caster[ udg_RH_ID ] ) == 851973 and IssueImmediateOrder( udg_RH_Caster[ udg_RH_ID ], "stop" ) then
              • Custom script: endif
              • -------- --------
              • Special Effect - Destroy RH_HammerModelHandler[RH_ID]
              • Special Effect - Destroy RH_HammerTrailHandler[RH_ID]
              • Unit - Kill RH_Unit
              • Unit Group - Remove RH_Unit from RH_Group
              • -------- --------
            • Else - Actions
              • -------- --------
              • -------- Hammers Motion Phases --------
              • -------- --------
              • Custom script: if GetRandomInt( 0, 100 ) <= udg_RH_HammerMotionEffectChance then
              • Custom script: call DestroyEffect( AddSpecialEffect( udg_RH_Effect[ 3 ], hammerX, hammerY ) )
              • Custom script: endif
              • -------- --------
              • Custom script: set casterX = GetWidgetX( udg_RH_Caster[ udg_RH_ID ] )
              • Custom script: set casterY = GetWidgetY( udg_RH_Caster[ udg_RH_ID ] )
              • -------- --------
              • -------- Prevents Odd Channeling --------
              • Custom script: if udg_RH_CasterX[ udg_RH_ID ] != casterX and udg_RH_CasterY[ udg_RH_ID ] != casterY then
              • Custom script: call IssueImmediateOrder( udg_RH_Caster[ udg_RH_ID ], "stop" )
              • Custom script: endif
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • RH_HammerRevolve[RH_ID] Equal to False
                  • RH_HammerSpreadDistanceCounter[RH_ID] Less than or equal to RH_HammerSpreadDistance[RH_Level[RH_ID]]
                • Then - Actions
                  • -------- --------
                  • -------- Hammers Spread Motion --------
                  • -------- --------
                  • Custom script: set hammerSpreadMotionX = casterX + udg_RH_HammerSpreadDistanceCounter[ udg_RH_ID ] * Cos( udg_RH_HammerSpreadAngle[ udg_RH_ID ] * bj_DEGTORAD )
                  • Custom script: set hammerSpreadMotionY = casterY + udg_RH_HammerSpreadDistanceCounter[ udg_RH_ID ] * Sin( udg_RH_HammerSpreadAngle[ udg_RH_ID ] * bj_DEGTORAD )
                  • -------- --------
                  • Custom script: if RH_ValidateXY( hammerSpreadMotionX, hammerSpreadMotionY ) then
                  • Custom script: call SetUnitX( udg_RH_Unit, hammerSpreadMotionX )
                  • Custom script: call SetUnitY( udg_RH_Unit, hammerSpreadMotionY )
                  • Custom script: endif
                  • -------- --------
                  • Custom script: call SetUnitFacing( udg_RH_Unit, udg_RH_HammerSpreadAngle[ udg_RH_ID ] )
                  • -------- --------
                  • -------- Loads, Updates, Saves: HammerSpreadDistanceCounter --------
                  • Set RH_HammerSpreadDistanceCounter[RH_ID] = (RH_HammerSpreadDistanceCounter[RH_ID] + RH_CustomReal2[RH_Level[RH_ID]])
                  • -------- --------
                • Else - Actions
                  • -------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • RH_HammerSpreadDistanceCounter[RH_ID] Greater than or equal to RH_HammerSpreadDistance[RH_Level[RH_ID]]
                    • Then - Actions
                      • -------- --------
                      • Set RH_HammerRevolve[RH_ID] = True
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • RH_HammerRevolve[RH_ID] Equal to True
                        • Then - Actions
                          • -------- --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • RH_HammerCustomBoolean[RH_ID] Equal to False
                            • Then - Actions
                              • Custom script: call DestroyEffect( AddSpecialEffectTarget( udg_RH_Effect[ 4 ], udg_RH_Unit, udg_RH_EffectAttach[ 1 ] ) )
                              • Set RH_HammerCustomBoolean[RH_ID] = True
                            • Else - Actions
                          • -------- --------
                          • -------- Hammers Revolve Motion --------
                          • -------- --------
                          • -------- Loads, Updates, Saves: HammerRevolveAngle --------
                          • Set RH_HammerRevolveAngle[RH_ID] = (RH_HammerRevolveAngle[RH_ID] + RH_HammerRevolveAngleSpeed[RH_Level[RH_ID]])
                          • -------- --------
                          • Custom script: set hammerRevolveMotionX = casterX + udg_RH_HammerSpreadDistanceCounter[ udg_RH_ID ] * Cos( udg_RH_HammerRevolveAngle[ udg_RH_ID ] * bj_DEGTORAD )
                          • Custom script: set hammerRevolveMotionY = casterY + udg_RH_HammerSpreadDistanceCounter[ udg_RH_ID ] * Sin( udg_RH_HammerRevolveAngle[ udg_RH_ID ] * bj_DEGTORAD )
                          • -------- --------
                          • Custom script: if RH_ValidateXY( hammerRevolveMotionX, hammerRevolveMotionY ) then
                          • Custom script: call SetUnitX( udg_RH_Unit, hammerRevolveMotionX )
                          • Custom script: call SetUnitY( udg_RH_Unit, hammerRevolveMotionY )
                          • Custom script: endif
                          • -------- --------
                          • -------- Hammers Rotation --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • RH_HammerRotate Equal to True
                            • Then - Actions
                              • Set RH_HammerSpreadAngle[RH_ID] = (RH_HammerSpreadAngle[RH_ID] + 180.00)
                              • Custom script: call SetUnitFacing( udg_RH_Unit, udg_RH_HammerSpreadAngle[ udg_RH_ID ] * bj_DEGTORAD )
                            • Else - Actions
                          • -------- --------
                          • Custom script: call GroupEnumUnitsInRange( bj_lastCreatedGroup, hammerX, hammerY, udg_RH_HammerCollisionSize[ udg_RH_Level[ udg_RH_ID ] ], Condition( function RH_SafeFilter ) )
                          • Custom script: loop
                          • Custom script: set udg_RH_KB_Unit = FirstOfGroup( bj_lastCreatedGroup )
                          • Custom script: exitwhen udg_RH_KB_Unit == null
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (RH_KB_Unit is dead) Equal to False
                              • (RH_KB_Unit is A structure) Equal to False
                              • (RH_KB_Unit is Magic Immune) Equal to False
                              • (RH_KB_Unit is A flying unit) Equal to False
                              • (RH_KB_Unit belongs to an enemy of RH_CasterPlayer[RH_ID]) Equal to True
                            • Then - Actions
                              • -------- --------
                              • Custom script: call DestroyEffect( AddSpecialEffectTarget( udg_RH_Effect[ 5 ], udg_RH_KB_Unit, udg_RH_EffectAttach[ 5 ] ) )
                              • Unit - Cause RH_Caster[RH_ID] to damage RH_KB_Unit, dealing RH_HammerHitDamage[RH_Level[RH_ID]] damage of attack type RH_AttackType and damage type RH_DamageType
                              • -------- --------
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • RH_HammerHitKnockback Equal to True
                                • Then - Actions
                                  • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
                                  • -------- KB3D SYSTEM --------
                                  • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
                                  • Set KB3D_Unit = RH_KB_Unit
                                  • Set KB3D_Range = RH_KB_Range
                                  • Set KB3D_Speed = RH_KB_Speed
                                  • Custom script: set udg_KB3D_Angle = Atan2( GetWidgetY( udg_RH_KB_Unit ) - hammerY, GetWidgetX( udg_RH_KB_Unit ) - hammerX ) * bj_RADTODEG
                                  • Set KB3D_EndOnObstacle = True
                                  • Set KB3D_EndwhenDead = True
                                  • Set KB3D_Accel = RH_KB_Acceleration
                                  • Set KB3D_AttackType = RH_AttackType
                                  • Set KB3D_DamageType = RH_DamageType
                                  • Set KB3D_Damager = RH_Caster[RH_ID]
                                  • Set KB3D_DestroyTree = RH_KB_DestroyTrees
                                  • Set KB3D_DisableUnit = True
                                  • Set KB3D_Fx = RH_Effect[6]
                                  • Set KB3D_iKB = True
                                  • Set KB3D_UnpathableStop = True
                                  • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
                                  • -------- Registed All of the Settings --------
                                  • Custom script: call ExecuteFunc( "KB3D_Registration" )
                                  • -------- ---------------------------------------------------------------------------------------------------------------------------------------- --------
                                • Else - Actions
                              • -------- --------
                              • Special Effect - Destroy RH_HammerModelHandler[RH_ID]
                              • Special Effect - Destroy RH_HammerTrailHandler[RH_ID]
                              • Unit - Kill RH_Unit
                              • Unit Group - Remove RH_Unit from RH_Group
                              • -------- --------
                            • Else - Actions
                          • -------- --------
                          • Custom script: call GroupRemoveUnit( bj_lastCreatedGroup, udg_RH_KB_Unit )
                          • Custom script: endloop
                          • -------- --------
                        • Else - Actions
                      • -------- --------
                    • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Number of units in RH_Group) Equal to 0
            • Then - Actions
              • Trigger - Turn off (This trigger)
            • Else - Actions
          • -------- --------

" Greetings Hivers ^^, I'm jakeZinc and I want to continue coding GUI spells for now on since I've abandoned this profile account ( 2-3 years ago ) but suddenly a powerful system motivates me to return in the hive. I'm expecting that my spell code right now have issues ( if there is ) because I'm still gaining what I've lost experience in spell coding even the WorldEditor itself. I'm glad to see the huge changes here in hiveworkshop. Currently, I want to make bunch of spells using Unit Indexer System ( Bribe ) and KB3D System ( Jad ) in the future. So I'd consider this as my 1st Spell using different method, using Unit Indexer System is like a fusion type of Indexing and Hashtable styles of method. Thanks."
Contents

Revolving Hammers v1.1 GUI (Map)

Reviews
KILLCIDE
Code looks good except one thing: only check to turn off the trigger when you deindex. There is no point in doing so after every iteration. Anyway, like all your other spells, it has a descriptive configuration trigger, a decent spell concept, and...
Level 37
Joined
Jul 22, 2015
Messages
3,485
Awesome spell! There are some issues though:
  • Please keep map demo stuff in their own folder (TreeRevival)
  • TreeRevival was not letting me launch the map because of an "unexpected: elseif"
  • I would move the RH_ChannelOrder to the top of the list with RH_Ability and RH_DummyType. Not sure what it is doing so far down the configuration :p
  • When you are preloading, why have users input the strings manually when you can just directly refer to their variables?
  • I find the 0.02 loop interval to have very little visual improvement from 0.03
  • I'm not familar with Jad's KB system, but is KB3D_LoopDamage the damage interval? If so, it's currently hardcoded
  • Instead of having to recalculate 360. / RH_HammerCount[RH_Level] for every unit on cast, you can calculate it in map init and then just RH_SpreadAngle + SpawnAngle[AbilityLevel][
  • RH_HammerModel should have an attachment point configurable as well
  • The "prevent unit stacking" If/Then/Else looks pretty useless. How can a newly created unit already be in the group?
  • Why do you have two conditions to check if it is time to turn on the loop? You only need one of the other
  • You don't have to check to see if RH_Tree is dead before killing it. I believe the harvester unit will still have the stop order when ordered to harvest a dead tree
  • From the looks of it, Cos and Sin can be stored on cast instead of having to recalculate every loop iteration
  • call DestroyEffect( AddSpecialEffectTarget( udg_RH_HammerStartRevolveEffect, udg_RH_Unit, "origin" ) ) should have an attachment point configurable! Some effects look weird when applied to origin, so you should give users the freedom to choose where it goes
  • Do you intend for the caster to be able to channel multiple instances of this spell? It also appears that the caster immediately begins rechanneling the spell even after they are stunned (I've had this problem before)
  • This spell creates a lot of dummy units! I recommend you take a look at DummyRecycler to help with performance
You use way more Jass than you do GUI. It made your trigger pretty unreadable since Custom script doesn't have any indentation or colored syntax. Why did you chose to make this spell in GUI...? The spell is extremely promising, but for now it will be set to Awaiting Update.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
^
- Yep it is intended to cast multiple times.

It also appears that the caster immediately begins rechanneling the spell even after they are stunned (I've had this problem before)
I don't know what is the problem on rechanneling the spell but It is just occuring when you casted it multiple times when the channeling is still running which is weird. I've checked and tested some channeling spells in the spell section and the problem is also appearing in them. Is there any fix or solution to this? or the channeling ability itself is the issue?
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
I've checked and tested some channeling spells in the spell section and the problem is also appearing in them. Is there any fix or solution to this? or the channeling ability itself is the issue?
The way I fixed it was checking if the caster is stunned, then ordering them to stop, right before deindex begins. This is how I did it in JASS:
JASS:
if (caster is dead) or (current order != channel order) then

    if (current order == 851973) then
        // order caster to stop
    endif

    // deindex start
endif
851973 is the "stunned" order id. Stunned units will always continue whatever order they were doing before the stun (you can confirm this by ordering a unit to walk to a point, and then stunning them in the middle of it). We obviously don't want this effect with spells, so ordering the caster to "stop" when they are stunned will prevent the caster from rechanneling the spell.

I believe just using the string "stunned" will work properly in GUI. Also, I think there is a condition statement that checks if a unit is actually stunned instead of checking for the current order.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Awesome spell! There are some issues though:
  • Please keep map demo stuff in their own folder (TreeRevival)
  • TreeRevival was not letting me launch the map because of an "unexpected: elseif"
  • I would move the RH_ChannelOrder to the top of the list with RH_Ability and RH_DummyType. Not sure what it is doing so far down the configuration :p
  • When you are preloading, why have users input the strings manually when you can just directly refer to their variables?
  • I find the 0.02 loop interval to have very little visual improvement from 0.03
  • I'm not familar with Jad's KB system, but is KB3D_LoopDamage the damage interval? If so, it's currently hardcoded
  • Instead of having to recalculate 360. / RH_HammerCount[RH_Level] for every unit on cast, you can calculate it in map init and then just RH_SpreadAngle + SpawnAngle[AbilityLevel][
  • RH_HammerModel should have an attachment point configurable as well
  • The "prevent unit stacking" If/Then/Else looks pretty useless. How can a newly created unit already be in the group?
  • Why do you have two conditions to check if it is time to turn on the loop? You only need one of the other
  • You don't have to check to see if RH_Tree is dead before killing it. I believe the harvester unit will still have the stop order when ordered to harvest a dead tree
  • From the looks of it, Cos and Sin can be stored on cast instead of having to recalculate every loop iteration
  • call DestroyEffect( AddSpecialEffectTarget( udg_RH_HammerStartRevolveEffect, udg_RH_Unit, "origin" ) ) should have an attachment point configurable! Some effects look weird when applied to origin, so you should give users the freedom to choose where it goes
  • Do you intend for the caster to be able to channel multiple instances of this spell? It also appears that the caster immediately begins rechanneling the spell even after they are stunned (I've had this problem before)
  • This spell creates a lot of dummy units! I recommend you take a look at DummyRecycler to help with performance
You use way more Jass than you do GUI. It made your trigger pretty unreadable since Custom script doesn't have any indentation or colored syntax. Why did you chose to make this spell in GUI...? The spell is extremely promising, but for now it will be set to Awaiting Update.

^ Updated to v1.1

* Removed unused systems on the demo map.
* SPELL DATA section moved from the top of the configuration field.
* Preloads now the string effect variables instead of manually touching the preload custom script lines.
* Removed the kb loop damage. ( It is not intended to damage on kbed units )
* Added initialization calculations. ( Prevents recalculating issues )
* Attachment points are now configurable.
* Added a trail effect to the hammers.
* the prevent unit stacking if block is now removed lol didn't notice that it is useless xD.
* Now only uses 1 checking group to turn off the looping trigger.
* Removes the checking of dead trees condition.
* The caster nows stops rechanneling the spell when stunned.
* All effects variable are now merged into 1 effect array variable.
* Now the hammers prevent to go outside the playable area or the map.
* Added a safe filtering function, ( removes null boolexpr leaks in 1.24version below ) ( leakless )
* Added a playable area boundaries function.
* Removed some useless configuration values.
* Added a note that the hammers amount cannot be 0.
* Added a configuration of ability's max level.
* Added a dummy hammers player configuration boolean. ( Hammer units now supports player colors )
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Code looks good except one thing: only check to turn off the trigger when you deindex. There is no point in doing so after every iteration.

Anyway, like all your other spells, it has a descriptive configuration trigger, a decent spell concept, and great effects.

Approved with a 5/5 rating.

P.S - Please just code the whole thing in JASS if you are going to use that much :D it makes it really hard to read without the colored syntax and no indentation.
 
Level 4
Joined
Dec 30, 2019
Messages
55
Nice spell, but is it possible to leave hammers after hit? As i see hammers are collapsing after hitting target and i want to disable it. Didnt find that feature in config.
Would it be correct if i remove that lines in loop script?

Code:
Special Effect - Destroy RH_HammerModelHandler[RH_ID]
Special Effect - Destroy RH_HammerTrailHandler[RH_ID]
Unit - Kill RH_Unit
Unit Group - Remove RH_Unit from RH_Group
 
Last edited:
Top