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

Apus v.1.5

This is my first spell uploaded here :)

Description:
Summons Big Apus pet to fight for your hero. You can't control him, he can't attack :D
Apus follow your hero whenever you move.
Once you are attacked or you attack someone, attacked/attacking unit is added to Apus Targets.
Having the Targets causes Apus to charge into them, slowly increasing his movement speed.
If any unit in Apus Targets come too close to Apus, he stomps Target unit dealing up to 25/37/50 damage depending on Apus current movement speed and stuns target for 0.25 seconds.
Every 3 seconds Apus cast Nova at every unit in Apus Targets dealing 25/50/75 damage and slowing movement speed for 2 seconds.
Every 11/10/9 seconds Apus cast FlameStrike in 3/4/5 directions dealing 50/100/150 damage to units from Apus Targets which are in range.
Apus last 70/80/90 seconds.

  • Apus Config
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Ability Type --------
      • Set A_Spell = Apus
      • -------- Distance required to remove target from Apus Targets --------
      • Set A_Area[1] = 1500.00
      • Set A_Area[2] = 2000.00
      • Set A_Area[3] = 2500.00
      • -------- Damage of Ice --------
      • Set A_Dmg[1] = 25.00
      • Set A_Dmg[2] = 50.00
      • Set A_Dmg[3] = 75.00
      • -------- Cooldown Damage of Ice (In Seconds) --------
      • Set A_Cooldown[1] = 3.00
      • Set A_Cooldown[2] = 3.00
      • Set A_Cooldown[3] = 3.00
      • -------- Ice Effect --------
      • Set A_IceEffectString = Abilities\Spells\Undead\FrostNova\FrostNovaTarget.mdl
      • -------- Ice Attack Type --------
      • Set A_FreezeAttackType = Spells
      • -------- Ice Damage Type --------
      • Set A_FreezeDamageType = Cold
      • -------- Stomp Damage --------
      • Set A_Dmg2[1] = 25.00
      • Set A_Dmg2[2] = 37.00
      • Set A_Dmg2[3] = 50.00
      • -------- Distance required to be damaged by Stomp --------
      • Set A_Area2[1] = 100.00
      • Set A_Area2[2] = 100.00
      • Set A_Area2[3] = 100.00
      • -------- Stomp Effect --------
      • Set A_StompEffectString = Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
      • -------- Stomp Attack Type --------
      • Set A_StompAttackType = Spells
      • -------- Stomp Damage Type --------
      • Set A_StompDamageType = Universal
      • -------- FlameStrike Damage --------
      • Set A_Dmg3[1] = 50.00
      • Set A_Dmg3[2] = 100.00
      • Set A_Dmg3[3] = 150.00
      • -------- Area of FlameStrike effect --------
      • Set A_Area3[1] = 200.00
      • Set A_Area3[2] = 200.00
      • Set A_Area3[3] = 200.00
      • -------- FlameStrike Effect --------
      • Set A_FlameStrikeEffectString = Abilities\Spells\Other\Incinerate\FireLordDeathExplode.mdl
      • -------- FlameStrike Attack Type --------
      • Set A_FlameStrikeAttackType = Spells
      • -------- FlameStrike Damage Type --------
      • Set A_FlameStrikeDamageType = Fire
      • -------- MaxDist3 defines how many FlameStrikes are gonna be created, calculation MaxDist3/Area3 = 5/6/7 --------
      • Set A_MaxDist3[1] = 800.00
      • Set A_MaxDist3[2] = 1000.00
      • Set A_MaxDist3[3] = 1200.00
      • -------- In how many directions FlameStrike will be created --------
      • Set A_Directions3[1] = 3
      • Set A_Directions3[2] = 4
      • Set A_Directions3[3] = 5
      • -------- Cooldown FlameStrike (In Seconds) --------
      • Set A_Cooldown2[1] = 11.00
      • Set A_Cooldown2[2] = 10.00
      • Set A_Cooldown2[3] = 9.00
      • -------- Does Apus require any time limit? --------
      • Set A_Limit = True
      • -------- If True, then how long he last? (In Seconds) --------
      • Set A_Last[1] = 70.00
      • Set A_Last[2] = 80.00
      • Set A_Last[3] = 90.00
      • -------- Distance between Hero and Apus creation point --------
      • Set A_SpawnArea[1] = 300.00
      • Set A_SpawnArea[2] = 300.00
      • Set A_SpawnArea[3] = 300.00
      • -------- Apus speed while he is calm and following his hero --------
      • Set A_ApusSpeed[1] = 300.00
      • Set A_ApusSpeed[2] = 300.00
      • Set A_ApusSpeed[3] = 300.00
      • -------- Set Apus size per level --------
      • Set A_ApusSize[1] = 200.00
      • Set A_ApusSize[2] = 250.00
      • Set A_ApusSize[3] = 300.00
      • -------- Set Apus color per level. It's a percentage value of 255 RGB coloring --------
      • Set A_ApusColor[1] = 100.00
      • Set A_ApusColor[2] = 66.00
      • Set A_ApusColor[3] = 33.00
      • -------- Unit type of Dummy which cast Stun and Slow --------
      • Set A_DummyType = Apus Stun/Freeze Dummy
      • -------- Increase Apus animation speed (percentage) --------
      • Set A_AnimSpeed = 300.00
      • -------- Unit type Apus --------
      • Set A_UnitType = Apus
      • -------- This variable determines changing speed and maximum range of Apus charge --------
      • Set A_Velocity = 20.00
      • -------- Animation set by index number for red shadow casting FlameStrike. --------
      • Set A_ShadowIndexAnim = 8
      • -------- Do you want Apus to destroy trees on collision and while casting FlameStrike? --------
      • Set A_DestTreesBool = True
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_DestTreesBool Equal to True
        • Then - Actions
          • Set A_TempPoint = (Random point in (Playable map area))
          • Unit - Create 1 Peasant for Neutral Passive at A_TempPoint facing Default building facing degrees
          • Set A_Peasant = (Last created unit)
          • Unit - Hide A_Peasant
          • Custom script: call RemoveLocation(udg_A_TempPoint)
        • Else - Actions
      • -------- If TRUE then Apus destroy trees in range: --------
      • Set A_DestTreesRange[1] = 200.00
      • Set A_DestTreesRange[2] = 200.00
      • Set A_DestTreesRange[3] = 200.00
      • -------- Loop Time of Loop Trigger --------
      • Set A_LoopTime = 0.05
      • Trigger - Add to Apus Loop <gen> the event (Time - Every A_LoopTime seconds of game time)
      • -------- Loop Time of Movement and Stomp Trigger --------
      • Set A_LoopTime2 = 0.03
      • Trigger - Add to Apus Movement and Stomp <gen> the event (Time - Every A_LoopTime2 seconds of game time)
      • -------- Loop Time of FlameStrike Trigger --------
      • Set A_LoopTime3 = 0.20
      • Trigger - Add to Apus FlameStrike <gen> the event (Time - Every A_LoopTime3 seconds of game time)
  • Apus Cast
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to A_Spell
    • Actions
      • Set A_Index = (A_Index + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on Apus Loop <gen>
          • Trigger - Turn on Apus Attack <gen>
        • Else - Actions
      • Set A_Caster[A_Index] = (Triggering unit)
      • Set A_Level[A_Index] = (Level of A_Spell for A_Caster[A_Index])
      • Set A_CooldownR[A_Index] = A_Cooldown[A_Level[A_Index]]
      • Set A_Cooldown2R[A_Index] = A_Cooldown2[A_Level[A_Index]]
      • Custom script: if udg_A_Group[udg_A_Index] == null then
      • Custom script: set udg_A_Group[udg_A_Index] = CreateGroup()
      • Custom script: endif
      • Set A_TempPoint = (Position of A_Caster[A_Index])
      • Set A_TempPoint2 = (A_TempPoint offset by A_SpawnArea[A_Level[A_Index]] towards (Facing of A_Caster[A_Index]) degrees)
      • Unit - Create 1 A_UnitType for (Owner of A_Caster[A_Index]) at A_TempPoint2 facing (Facing of A_Caster[A_Index]) degrees
      • Set A_Apus[A_Index] = (Last created unit)
      • Animation - Change A_Apus[A_Index]'s size to (A_ApusSize[A_Level[A_Index]]%, A_ApusSize[A_Level[A_Index]]%, A_ApusSize[A_Level[A_Index]]%) of its original size
      • Animation - Change A_Apus[A_Index]'s vertex coloring to (A_ApusColor[A_Level[A_Index]]%, A_ApusColor[A_Level[A_Index]]%, A_ApusColor[A_Level[A_Index]]%) with 0.00% transparency
      • Unit - Create 1 A_DummyType for (Owner of A_Caster[A_Index]) at A_TempPoint2 facing Default building facing degrees
      • Set A_Dummy[A_Index] = (Last created unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_Limit Equal to True
        • Then - Actions
          • Unit - Add a A_Last[A_Level[A_Index]] second Generic expiration timer to A_Apus[A_Index]
          • Set A_Last2[A_Index] = A_Last[A_Level[A_Index]]
        • Else - Actions
      • Custom script: call RemoveLocation(udg_A_TempPoint)
      • Custom script: call RemoveLocation(udg_A_TempPoint2)
      • Set A_MaxDist3_2[A_Index] = A_MaxDist3[A_Level[A_Index]]
      • Set A_ApusAcc[A_Index] = 0.00
      • Set A_ApusXVelo[A_Index] = 0.00
      • Set A_ApusYVelo[A_Index] = 0.00
      • Set A_ExecCount[A_Index] = 0.00
  • Apus Loop
    • Events
    • Conditions
    • Actions
      • For each (Integer A_LoopIndex) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • Set A_Last2[A_LoopIndex] = (A_Last2[A_LoopIndex] - A_LoopTime)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (A_ApusShadow[A_LoopIndex] is dead) Equal to True
              • Or - Any (Conditions) are true
                • Conditions
                  • (A_Caster[A_LoopIndex] is dead) Equal to True
                  • And - All (Conditions) are true
                    • Conditions
                      • A_Last2[A_LoopIndex] Greater than or equal to 0.01
                      • A_Last2[A_LoopIndex] Less than or equal to (0.02 + A_LoopTime)
            • Then - Actions
              • Custom script: call DestroyGroup(udg_A_Group[udg_A_LoopIndex])
              • Custom script: call RemoveLocation(udg_A_FreezePos[udg_A_LoopIndex])
              • Unit - Kill A_Apus[A_LoopIndex]
              • Unit - Kill A_Dummy[A_LoopIndex]
              • Set A_ApusAcc[A_LoopIndex] = A_ApusAcc[A_Index]
              • Set A_ApusXVelo[A_LoopIndex] = A_ApusXVelo[A_Index]
              • Set A_ApusYVelo[A_LoopIndex] = A_ApusYVelo[A_Index]
              • Set A_Cooldown2R[A_LoopIndex] = A_Cooldown2R[A_Index]
              • Set A_CooldownR[A_LoopIndex] = A_CooldownR[A_Index]
              • Set A_TargetUnit[A_LoopIndex] = A_TargetUnit[A_Index]
              • Set A_Group[A_LoopIndex] = A_Group[A_Index]
              • Set A_Caster[A_LoopIndex] = A_Caster[A_Index]
              • Set A_Apus[A_LoopIndex] = A_Apus[A_Index]
              • Set A_MaxDist3_2[A_LoopIndex] = A_MaxDist3_2[A_Index]
              • Set A_FreezePos[A_LoopIndex] = A_FreezePos[A_Index]
              • Set A_ExecCount[A_LoopIndex] = A_ExecCount[A_Index]
              • Set A_Level[A_LoopIndex] = A_Level[A_Index]
              • Set A_Dummy[A_LoopIndex] = A_Dummy[A_Index]
              • Set A_ApusShadow[A_LoopIndex] = A_ApusShadow[A_Index]
              • Set A_TargetUnit[A_Index] = No unit
              • Set A_Caster[A_Index] = No unit
              • Set A_Apus[A_Index] = No unit
              • Set A_Dummy[A_Index] = No unit
              • Set A_ApusShadow[A_Index] = No unit
              • Custom script: set udg_A_Group[udg_A_Index] = null
              • Set A_LoopIndex = (A_LoopIndex - 1)
              • Set A_Index = (A_Index - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                  • Trigger - Turn off Apus Movement and Stomp <gen>
                  • Trigger - Turn off Apus Attack <gen>
                  • Trigger - Turn off Apus FlameStrike <gen>
                • Else - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (A_Group[A_LoopIndex] is empty) Equal to True
                • Then - Actions
                  • Animation - Change A_Apus[A_LoopIndex]'s animation speed to 100.00% of its original speed
                  • Animation - Change A_Apus[A_LoopIndex]'s vertex coloring to (A_ApusColor[A_Level[A_LoopIndex]]%, A_ApusColor[A_Level[A_LoopIndex]]%, A_ApusColor[A_Level[A_LoopIndex]]%) with 0.00% transparency
                  • Set A_TargetUnit[A_LoopIndex] = No unit
                  • Set A_ExecCount[A_LoopIndex] = 0.00
                  • Set A_ApusAcc[A_LoopIndex] = 0.00
                  • Set A_ApusXVelo[A_LoopIndex] = 0.00
                  • Set A_ApusYVelo[A_LoopIndex] = 0.00
                  • Set A_TempPoint = (Position of A_Caster[A_LoopIndex])
                  • Set A_TempPoint3 = (Position of A_Apus[A_LoopIndex])
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Distance between A_TempPoint3 and A_TempPoint) Less than or equal to A_SpawnArea[A_Level[A_LoopIndex]]
                    • Then - Actions
                      • Animation - Queue A_Apus[A_LoopIndex]'s stand animation
                    • Else - Actions
                      • Animation - Play A_Apus[A_LoopIndex]'s walk animation
                      • Set A_TempPoint2 = (A_TempPoint offset by (A_SpawnArea[A_Level[A_LoopIndex]] - 10.00) towards ((Facing of A_Caster[A_LoopIndex]) + 180.00) degrees)
                      • Set A_TempPoint4 = (A_TempPoint3 offset by (A_ApusSpeed[A_Level[A_LoopIndex]] x A_LoopTime) towards (Angle from A_TempPoint3 to A_TempPoint2) degrees)
                      • Unit - Move A_Apus[A_LoopIndex] instantly to A_TempPoint4
                      • Unit - Make A_Apus[A_LoopIndex] face A_TempPoint2 over 0.50 seconds
                      • Custom script: call RemoveLocation(udg_A_TempPoint2)
                      • Custom script: call RemoveLocation(udg_A_TempPoint4)
                  • Custom script: call RemoveLocation(udg_A_TempPoint)
                  • Custom script: call RemoveLocation(udg_A_TempPoint3)
                • Else - Actions
                  • Animation - Change A_Apus[A_LoopIndex]'s animation speed to A_AnimSpeed% of its original speed
                  • Set A_Cooldown2R[A_LoopIndex] = (A_Cooldown2R[A_LoopIndex] - A_LoopTime)
                  • Set A_CooldownR[A_LoopIndex] = (A_CooldownR[A_LoopIndex] - A_LoopTime)
                  • Set A_TempPoint = (Position of A_Caster[A_LoopIndex])
                  • Animation - Change A_Apus[A_LoopIndex]'s vertex coloring to ((A_ApusColor[A_Level[A_LoopIndex]] x (A_CooldownR[A_LoopIndex] / A_Cooldown[A_Level[A_LoopIndex]]))%, (A_ApusColor[A_Level[A_LoopIndex]] x (A_CooldownR[A_LoopIndex] / A_Cooldown[A_Level[A_LoopIndex]]))%, A_ApusColor[A_Level[A_LoopIndex]]%) with 0.00% transparency
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (A_TargetUnit[A_LoopIndex] is dead) Equal to True
                    • Then - Actions
                      • Set A_TargetUnit[A_LoopIndex] = (Random unit from A_Group[A_LoopIndex])
                    • Else - Actions
                  • Unit Group - Pick every unit in A_Group[A_LoopIndex] and do (Actions)
                    • Loop - Actions
                      • Set A_TempUnit = (Picked unit)
                      • Set A_TempPoint2 = (Position of A_TempUnit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • Or - Any (Conditions) are true
                            • Conditions
                              • (Distance between A_TempPoint and A_TempPoint2) Greater than or equal to A_Area[A_Level[A_LoopIndex]]
                              • (A_TempUnit is dead) Equal to True
                        • Then - Actions
                          • Unit Group - Remove A_TempUnit from A_Group[A_LoopIndex]
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • A_CooldownR[A_LoopIndex] Less than or equal to 0.00
                            • Then - Actions
                              • Special Effect - Create a special effect at A_TempPoint2 using A_IceEffectString
                              • Special Effect - Destroy (Last created special effect)
                              • Unit - Cause A_Apus[A_LoopIndex] to damage A_TempUnit, dealing A_Dmg[A_Level[A_LoopIndex]] damage of attack type A_FreezeAttackType and damage type A_FreezeDamageType
                              • Unit - Order A_Dummy[A_LoopIndex] to Human Sorceress - Slow A_TempUnit
                              • Animation - Play A_Apus[A_LoopIndex]'s walk animation
                            • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_CooldownR[A_LoopIndex] Less than or equal to 0.00
                    • Then - Actions
                      • Set A_CooldownR[A_LoopIndex] = A_Cooldown[A_Level[A_LoopIndex]]
                      • Set A_TargetUnit[A_LoopIndex] = (Random unit from A_Group[A_LoopIndex])
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Apus Movement and Stomp <gen> is on) Equal to False
                        • Then - Actions
                          • Trigger - Turn on Apus Movement and Stomp <gen>
                        • Else - Actions
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_Cooldown2R[A_LoopIndex] Less than or equal to 0.00
                    • Then - Actions
                      • Set A_Cooldown2R[A_LoopIndex] = A_Cooldown2[A_Level[A_LoopIndex]]
                      • Set A_MaxDist3_2[A_LoopIndex] = 0.00
                      • Set A_FreezePos[A_LoopIndex] = (Position of A_Apus[A_LoopIndex])
                      • Unit - Create 1 A_UnitType for (Owner of A_Caster[A_LoopIndex]) at A_FreezePos[A_LoopIndex] facing (Facing of A_Apus[A_LoopIndex]) degrees
                      • Set A_ApusShadow[A_LoopIndex] = (Last created unit)
                      • Custom script: call SetUnitAnimationByIndex(udg_A_ApusShadow[udg_A_LoopIndex], udg_A_ShadowIndexAnim)
                      • Animation - Change A_ApusShadow[A_LoopIndex]'s size to ((A_ApusSize[A_Level[A_LoopIndex]] x 1.50)%, (A_ApusSize[A_Level[A_LoopIndex]] x 1.50)%, (A_ApusSize[A_Level[A_LoopIndex]] x 1.50)%) of its original size
                      • Animation - Change A_ApusShadow[A_LoopIndex]'s vertex coloring to (100.00%, 0.00%, 0.00%) with 50.00% transparency
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Apus FlameStrike <gen> is on) Equal to False
                        • Then - Actions
                          • Trigger - Turn on Apus FlameStrike <gen>
                        • Else - Actions
                    • Else - Actions
                  • Custom script: call RemoveLocation(udg_A_TempPoint2)
                  • Custom script: call RemoveLocation(udg_A_TempPoint)
  • Apus Movement and Stomp
    • Events
    • Conditions
    • Actions
      • For each (Integer A_LoopIndex) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • A_TargetUnit[A_LoopIndex] Not equal to No unit
            • Then - Actions
              • Set A_ExecCount[A_LoopIndex] = (A_ExecCount[A_LoopIndex] + 0.01)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_ExecCount[A_LoopIndex] Greater than or equal to 0.20
                • Then - Actions
                  • Set A_ApusAcc[A_LoopIndex] = (A_ApusAcc[A_LoopIndex] + 0.01)
                  • Set A_ExecCount[A_LoopIndex] = 0.00
                • Else - Actions
              • Set A_TempPoint = (Position of A_Apus[A_LoopIndex])
              • Set A_TempPoint2 = (Position of A_TargetUnit[A_LoopIndex])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (X of A_TempPoint) Less than (X of A_TempPoint2)
                • Then - Actions
                  • Set A_ApusXVelo[A_LoopIndex] = (A_ApusXVelo[A_LoopIndex] + A_ApusAcc[A_LoopIndex])
                • Else - Actions
                  • Set A_ApusXVelo[A_LoopIndex] = (A_ApusXVelo[A_LoopIndex] - A_ApusAcc[A_LoopIndex])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Y of A_TempPoint) Less than (Y of A_TempPoint2)
                • Then - Actions
                  • Set A_ApusYVelo[A_LoopIndex] = (A_ApusYVelo[A_LoopIndex] + A_ApusAcc[A_LoopIndex])
                • Else - Actions
                  • Set A_ApusYVelo[A_LoopIndex] = (A_ApusYVelo[A_LoopIndex] - A_ApusAcc[A_LoopIndex])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • (Abs(A_ApusXVelo[A_LoopIndex])) Greater than A_Velocity
                      • (Abs(A_ApusYVelo[A_LoopIndex])) Greater than A_Velocity
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_ApusXVelo[A_LoopIndex] Greater than A_Velocity
                    • Then - Actions
                      • Set A_ApusXVelo[A_LoopIndex] = A_Velocity
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • A_ApusXVelo[A_LoopIndex] Less than (0.00 - A_Velocity)
                        • Then - Actions
                          • Set A_ApusXVelo[A_LoopIndex] = (0.00 - A_Velocity)
                        • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_ApusYVelo[A_LoopIndex] Greater than A_Velocity
                    • Then - Actions
                      • Set A_ApusYVelo[A_LoopIndex] = A_Velocity
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • A_ApusYVelo[A_LoopIndex] Less than (0.00 - A_Velocity)
                        • Then - Actions
                          • Set A_ApusYVelo[A_LoopIndex] = (0.00 - A_Velocity)
                        • Else - Actions
                • Else - Actions
              • Set A_TempPoint3 = (A_TempPoint offset by (A_ApusXVelo[A_LoopIndex], A_ApusYVelo[A_LoopIndex]))
              • Unit - Move A_Apus[A_LoopIndex] instantly to A_TempPoint3, facing (Angle from A_TempPoint to A_TempPoint2) degrees
              • Custom script: call RemoveLocation(udg_A_TempPoint)
              • Custom script: call RemoveLocation(udg_A_TempPoint2)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_DestTreesBool Equal to True
                • Then - Actions
                  • Destructible - Pick every destructible within A_DestTreesRange[A_Level[A_LoopIndex]] of A_TempPoint3 and do (Actions)
                    • Loop - Actions
                      • Set A_TempDest = (Picked destructible)
                      • Unit - Order A_Peasant to Harvest A_TempDest
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Current order of A_Peasant) Equal to (Order(harvest))
                        • Then - Actions
                          • Destructible - Kill A_TempDest
                        • Else - Actions
                      • Unit - Order A_Peasant to Stop
                • Else - Actions
              • Unit Group - Pick every unit in A_Group[A_LoopIndex] and do (Actions)
                • Loop - Actions
                  • Set A_TempUnit = (Picked unit)
                  • Set A_TempPoint = (Position of A_TempUnit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Distance between A_TempPoint and A_TempPoint3) Less than or equal to A_Area2[A_Level[A_LoopIndex]]
                      • (A_TempUnit is alive) Equal to True
                    • Then - Actions
                      • Special Effect - Create a special effect attached to the foot of A_TempUnit using A_StompEffectString
                      • Special Effect - Destroy (Last created special effect)
                      • Unit - Cause A_Apus[A_LoopIndex] to damage A_TempUnit, dealing (A_LoopTime2 x (A_Dmg2[A_Level[A_LoopIndex]] x (Square root(((A_ApusXVelo[A_LoopIndex] x A_ApusXVelo[A_LoopIndex]) + (A_ApusYVelo[A_LoopIndex] x A_ApusYVelo[A_LoopIndex])))))) damage of attack type A_StompAttackType and damage type A_StompDamageType
                      • Unit - Order A_Dummy[A_LoopIndex] to Human Mountain King - Storm Bolt A_TempUnit
                    • Else - Actions
                  • Custom script: call RemoveLocation(udg_A_TempPoint)
              • Custom script: call RemoveLocation(udg_A_TempPoint3)
            • Else - Actions
  • Apus Attack
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • Set A_TempUnit = (Attacked unit)
      • Set A_TempUnit2 = (Attacking unit)
      • For each (Integer A_LoopIndex) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • A_TempUnit Equal to A_Caster[A_LoopIndex]
              • (A_TempUnit2 is in A_Group[A_LoopIndex]) Equal to False
            • Then - Actions
              • Unit Group - Add A_TempUnit2 to A_Group[A_LoopIndex]
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_TempUnit2 Equal to A_Caster[A_LoopIndex]
                  • (A_TempUnit is in A_Group[A_LoopIndex]) Equal to False
                • Then - Actions
                  • Unit Group - Add A_TempUnit to A_Group[A_LoopIndex]
                • Else - Actions
  • Apus FlameStrike
    • Events
    • Conditions
    • Actions
      • For each (Integer A_LoopIndex) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • A_MaxDist3_2[A_LoopIndex] Greater than or equal to A_MaxDist3[A_Level[A_LoopIndex]]
            • Then - Actions
              • Custom script: call RemoveLocation(udg_A_FreezePos[udg_A_LoopIndex])
              • Unit - Remove A_ApusShadow[A_LoopIndex] from the game
              • Set A_ApusShadow[A_LoopIndex] = No unit
            • Else - Actions
              • Set A_MaxDist3_2[A_LoopIndex] = (A_MaxDist3_2[A_LoopIndex] + A_Area3[A_Level[A_LoopIndex]])
              • For each (Integer A_TempC) from 1 to A_Directions3[A_Level[A_LoopIndex]], do (Actions)
                • Loop - Actions
                  • Set A_TempPoint2 = (A_FreezePos[A_LoopIndex] offset by A_MaxDist3_2[A_LoopIndex] towards (((Real(A_TempC)) x (360.00 / (Real(A_Directions3[A_Level[A_LoopIndex]])))) - (360.00 / (2.00 x (Real(A_Directions3[A_Level[A_LoopIndex]]))))) degrees)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_DestTreesBool Equal to True
                    • Then - Actions
                      • Destructible - Pick every destructible within A_DestTreesRange[A_Level[A_LoopIndex]] of A_TempPoint2 and do (Actions)
                        • Loop - Actions
                          • Set A_TempDest = (Picked destructible)
                          • Unit - Order A_Peasant to Harvest A_TempDest
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Current order of A_Peasant) Equal to (Order(harvest))
                            • Then - Actions
                              • Destructible - Kill A_TempDest
                            • Else - Actions
                          • Unit - Order A_Peasant to Stop
                    • Else - Actions
                  • Special Effect - Create a special effect at A_TempPoint2 using A_FlameStrikeEffectString
                  • Special Effect - Destroy (Last created special effect)
                  • Set A_TempGroup = (Units within A_Area3[A_Level[A_LoopIndex]] of A_TempPoint2 matching (((Matching unit) is in A_Group[A_LoopIndex]) Equal to True))
                  • Unit Group - Pick every unit in A_TempGroup and do (Actions)
                    • Loop - Actions
                      • Set A_TempUnit = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (A_TempUnit is alive) Equal to True
                        • Then - Actions
                          • Unit - Cause A_Apus[A_LoopIndex] to damage A_TempUnit, dealing A_Dmg3[A_Level[A_LoopIndex]] damage of attack type A_FlameStrikeAttackType and damage type A_FlameStrikeDamageType
                        • Else - Actions
                  • Custom script: call DestroyGroup(udg_A_TempGroup)
                  • Custom script: call RemoveLocation(udg_A_TempPoint2)

1.0: Initial realise
1.1:
Changed "Casting unit" into "Triggering unit"
Added Attack and Damage types into configurable variables.
Added Dummy Unit type into configurable variable.
Changed Index variables into variables without arrays
Improved Apus movement
Now there is only 1 Apus Unit type, it's size and color can be configured via Config trigger
Now there is only 1 dummy which cast Slow and Stun per instance instead of creating 1 unit per target
Changed Stomp effect attachment from Apus to target unit. Apus size increasing do not affect its size, no lag possibilities
Some code optimalization.
1.2:
Apus is now able to destroy trees. It's configurable.
More code optimalization :)
1.3:
Removed imports from test map.
Fixed some code.
1.4:
Small fix.
1.5:
Added prefixes to variable names.
Shadow animation index is configurable.


How to import:
- Make sure to enable "Automatically create unknown variables while pasting trigger data" on the General tab of your World Editor Preferences.
- Copy all abilities and units from Object Editor and paste it into yours.
- Copy the whole Apus folder and paste in onto your Trigger Editor.
- Make sure to configure everything in the Apus Config Trigger.


Give credits if you use it anywhere.

Suggestions:
Ultimate Explosion Model made by WILL THE ALMIGHTY as a FlameStrike effect
TaurenDruidCat model made by AhhFreshWeeD as Apus model

Keywords:
apus, fire, ice, flame, pet, stomp, freeze, frozen, stun, slow
Contents

Apus v.1.5 (Map)

Reviews
IcemanBo: Approved IcemanBo: http://www.hiveworkshop.com/forums/spells-569/apus-v-1-3-a-259771/index2.html#post2654713 IcemanBo: http://www.hiveworkshop.com/forums/spells-569/apus-v-1-2-a-259771/#post2639396 IcemanBo...
  • Set A_Group[Index[1]] = (Random 0 units from (Units in (Playable map area)))
^Use custom script and CreateGroup() over this.

The unit's movement looks very unnatural. It should be improved.
It sticks to the hero like a bubble gum, it looks really weird. The following behaviour should be more intuitive.
You should let a tolerance distance for example.
The movement animations looks not smooth.

When the Apus uses spells he should make some animation, that indicates it for example.
At the moment the spell just occurs, but you can't clearly notice that the source is the Apus.

Don't make the Max/Current index variables be an array. It gets unreadable.

Use the normal function in GUI to check if a unit is dead.

Check to turn off loops should be done onDeindex.

A tooltip is needed. Add a decent description.

Reals don't need to be nulled.

It would be cool if the different Apus would have diffent scale/colour for example for each level, so you can differ them.

  • ((Execution count of (This trigger)) mod 20) Equal to 0
^I'm sure you can find a smarter way to solve this.

The idea of such a helper creep is good. But it needs some work to do, for example the weird movement.

Needs Fix
 
Last edited:
Level 3
Joined
Nov 11, 2014
Messages
14
Wow I didn't expect to receive any feedback after all this time :D Thanks for that.
Have you got any idea how to copy triggers translated? I'm using Polish version of world editor and I have to translate every GUI action into english. That makes my update really long.

Don't make the Max/Current index variables be an array. It gets unreadable.

Reals don't need to be nulled.

I made them an arrays because I'm making all spells using only 2 Index variables: Index and Loop Index. Every spell has its own array index in index so i don't have to create new variables for indexes.
If I don't null them, when all instances of spell are finished, then new instance has those reals copied from previous instance. Apus created in new instance might have higher movement speed than expected.
 
Change this:
  • Custom script: set udg_A_Group[udg_A_Index] = CreateGroup()
into this ->
  • Custom script: if udg_A_Group[udg_A_Index] == null then
  • Custom script: set udg_A_Group[udg_A_Index] = CreateGroup()
  • Custom script: endif
to prevent leak.

For deindex in loop, just check "caster[index] is dead == ture Or time < 0". Will be enough. And first check won't be needed then if caster is dead.

Remove Apus onDeindex, or set it's death type to "can't raise, won't decay" in object editor.

onDeindex you forgot about the dummy.
onDeindex you forgot all the spell variable arrays. (flame strike variables, stomp)
onDeindex you have to null all units and the group of MaxIndex.

When Apus is close caster you keep forcing to play the stand animation:
  • Animation - Play A_Apus[A_LoopIndex]'s stand animation
This makes the stand look a bit unnatural. (at least I think so :D)
You could try following instead, it might look smoother:
  • Animation - Queue A_Apus[A_LoopIndex]'s stand animation

  • Set TempPoint4 = (TempPoint3 offset by (300.00 x A_LoopTime) towards (Angle from TempPoint3 to TempPoint2) degrees)
^Why do you makke the offset depend on the looptime?

onAttack "AttackedUnit" and "AttackingUnit" should be stored into temp variables.

Instead of using modulo, you always could reset the counter? Not?

You should try with looptime 0.03 instead of 0.02. It's the recommended time for movement systems.

Needs Fix


Edit:


If you have to translate each single trigger into english, you don't have to bother to keep the code up to date until approval.
It will be ok for me to check the triggers in map. So it saves you some work. :)
But once it gets approved, there should be the newest code in description.

If you accept this, then please at least mark that the triggers in description are not up to date.
 
Level 3
Joined
Nov 11, 2014
Messages
14
When Apus is close caster you keep forcing to play the stand animation:
  • Animation - Play A_Apus[A_LoopIndex]'s stand animation
This makes the stand look a bit unnatural. (at least I think so :D)
You could try following instead, it might look smoother:
  • Animation - Queue A_Apus[A_LoopIndex]'s stand animation

That's a good idea :) Unfortunately it doesn't work for walk animation, becauce in forcing him to walk the same way.

  • Set TempPoint4 = (TempPoint3 offset by (300.00 x A_LoopTime) towards (Angle from TempPoint3 to TempPoint2) degrees)
^Why do you makke the offset depend on the looptime?
It's easier to see his real movement speed per second. He move 300.00 x 0.05 per 0.05 seconds, so 300 units per second.


Edit:


If you have to translate each single trigger into english, you don't have to bother to keep the code up to date until approval.
It will be ok for me to check the triggers in map. So it saves you some work. :)
But once it gets approved, there should be the newest code in description.

If you accept this, then please at least mark that the triggers in description are not up to date.

Thank you for that, that is making things easier :)

Edit:
Updated.
Thank you for your feedback :)
 
Last edited:
Don't use default peasant as dummy unit. Create a new dummy unit. (You can't ensure user didn't modify the default one.)

Immediatly deindex if caster is dead.
Currently "ApusShadow" must be dead, too. In my understanding this is not wanted, or am I wrong?
If caster is dead, and "ApusShadow" alive, you still want to do further operations?

onDeindex you null now all units and the group. But you use the wrong index.
You have to null the variable[maxIndex] not variable[currentIndex] after you copied the data. Otherwise it doesn't make sense.

Are these imports really needed? It's always better to have as less imports as possible, or none at all.
If you think you can, then you should make them optional. (you still can recommend them here on hive in your description)

Needs Fix
 
Level 3
Joined
Nov 11, 2014
Messages
14
I found a bug, when ApusShadow is alive and Apus timer expires. Instance is finished but ApusShadow is still alive, not removed. That's just to prevent that bug. Even if caster is dead, spell will last up to 1.4 more seconds before ApusShadow die. Then he dies and instance is finished. Look that ApusShadow not equal to Apus. ApusShadow is the red one while casting FlameStrike.
 
Hm, have you changed something with the movement behaviour? It does seem to have problems with followting the hero.
It prefers to fight enemies now, instead of staying close next to caster.

When you change the unit's size only the first only the first argument matters. You can let the others "0": SetSize(size, 0, 0)

In demo map my FPS tempory decreased to ~15 when fighting. Is it only me who has problems/lags with it?

Edit: The tooltip seems too long and is not well structured. You should try to keep only the most important.
 
Last edited:
Level 3
Joined
Nov 11, 2014
Messages
14
I havent noticed and problems with following the hero. Apus now do not go directly towards caster position, it goes to position behind caster. It looks more smooth now. Same as activating, deactivating movement happens while caster is too far from Apus.

I had no FPS drop like you. It was about 60 whole the time.

Have you downloaded the latest version I uploaded?
 
^Yes.
_________

  • In main loop don't do any further operations if you deindex.
    You get this done by putting the other block into the "Else - Actions" part. (since deindex is in "Then - Actions" part)
    Else you do the actions twice for one instance. Though it is possible.
  • Also in main loop, in your damage part. Only damage, slow, and create the effect above a target if it's not dead and is in range.
    Currently you filter these kind of units and remove them from group, but still do named operations to it.
  • I see your point with casting FlameStrike. So you have to find a solution.
    Hm, but definitly ignore further operations that belong to caster or damaging nearby units if caster is dead.
    Still you may wait until the shadow unit finished his spell if you want, until you completly deindex.
    Better way would to make them more independant from each other, but it would take much more restructering.
 
Level 3
Joined
Nov 11, 2014
Messages
14
Updated. Applied your suggestions.

^Yes.
_________

I see your point with casting FlameStrike. So you have to find a solution.
Hm, but definitly ignore further operations that belong to caster or damaging nearby units if caster is dead.
Still you may wait until the shadow unit finished his spell if you want, until you completly deindex.
Better way would to make them more independant from each other, but it would take much more restructering.

Sorry, what solution am I looking for? Is it a bad idea to deindex when Shadow is dead?
 
Is it a bad idea to deindex when Shadow is dead?
No, it's good and correct.

  • Custom script: call SetUnitAnimationByIndex(udg_A_ApusShadow[udg_A_LoopIndex], 8)
^Could you put the integer "8" into a variable? If user changes the unit type, he might need change the index as well.

I saw for example "peasant" variable without any prefix. It's tiny work, but please also use the same prefix for all your variables that you need.
 
Level 3
Joined
Nov 11, 2014
Messages
14
Thank you both :) I'm so excited

Test map has a tooltip how to import. Added the same tooltip in the first post.
Description is a little shorter. In my opinion these information are the most important so the user knows how this spell works :)
 
Top