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

Spirit of the Forest v1.5

Spirit of the Forest

Someone requested this certain spell in GUI using Hashtable with the Spirits being clickable and showing HP. Might as well share it in the spell section. Maybe someone can use it or learn from it.

Spell Info:
Has a chance to summon a spirit that will circle around this Hero when attacked. Each spirit summoned decreases all attributes of this Hero by 1. Spirits damages nearby enemy units and self within 200 AoE. Spirits cast a weaker Detonate upon death and has an HP of 300.

Level 1 - 20% chance, 30 DPS, maximum of 6 spirits
Level 2 - 40% chance, 40 DPS, maximum of 8 spirits
Level 3 - 60% chance, 50 DPS, maximum of 10 spirits

CONFIGURABLES:
- The chance to summon Spirits per Level
- Editable to be clickable / not clickable
- Damage per second of the Spirits
- AoE of the Spirit Damage
- Damage to self of the Spirits
- Attribute Effects to the Hero when a spirit is summoned (gain / loss / no effect)
- Speed of Spirit Rotation
- Spirit Radius from the Hero
- Maximum number of Spirits that can circle the hero per level
- HP of the Spirit


  • Spirit of the Forest Configurables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Spirit of the Forest Attack Type and Damage Type --------
      • Set SOTF_attackType = Spells
      • Set SOTF_damageType = Magic
      • -------- If you want the spinning spirits to be clickable and showing HP bar, set SOTF_clickable = true --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_clickable = False
      • -------- --------------------------------------------------------------------------------- --------
      • -------- Special Effect when an enemy unit is damaged by the spirit --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_damagedSpEffect = Abilities\Spells\Undead\DeathandDecay\DeathandDecayTarget.mdl
      • Set SOTF_spiritSpEffect = Abilities\Weapons\SpiritOfVengeanceMissile\SpiritOfVengeanceMissile.mdl
      • -------- --------------------------------------------------------------------------------- --------
      • -------- The Chance for the Spirit of the Forest To Active --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_chanceToActivate[1] = 20
      • Set SOTF_chanceToActivate[2] = 40
      • Set SOTF_chanceToActivate[3] = 60
      • -------- --------------------------------------------------------------------------------- --------
      • -------- The Spirit Damage to Nearby Units within certain AoE every 0.03 second --------
      • -------- Formula: SOTF_damage = 0.03 * X damage/second --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_damage[1] = 0.90
      • Set SOTF_damage[2] = 1.20
      • Set SOTF_damage[3] = 1.50
      • -------- --------------------------------------------------------------------------------- --------
      • -------- The Spirit Damage Area of Effect --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_aoe[1] = 120.00
      • Set SOTF_aoe[2] = 135.00
      • Set SOTF_aoe[3] = 150.00
      • -------- --------------------------------------------------------------------------------- --------
      • -------- The Spirit Damage to Self. Setting it to 0.3 reduces 10 hp/second. --------
      • -------- Formula: SOTF_selfDamage = 0.03 * X damage/second --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_selfDamage[1] = 0.90
      • Set SOTF_selfDamage[2] = 1.20
      • Set SOTF_selfDamage[3] = 1.50
      • -------- --------------------------------------------------------------------------------- --------
      • -------- Maximum number of spirits that can spin around the Hero --------
      • -------- Values can be from 0 to (Number of Levels in the "SOTF_AttributeEffect" Ability) --------
      • Set SOTF_maxSpirits[1] = 6
      • Set SOTF_maxSpirits[2] = 8
      • Set SOTF_maxSpirits[3] = 10
      • -------- --------------------------------------------------------------------------------- --------
      • -------- Distance of the spirits from the Hero --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_spiritDistance = 300.00
      • -------- --------------------------------------------------------------------------------- --------
      • -------- An SOTF_speed of 10.8 is equal to 1 revolution per second --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_spiritSpeed = 5.40
      • -------- --------------------------------------------------------------------------------- --------
      • -------- Spell Variables --------
      • -------- --------------------------------------------------------------------------------- --------
      • Set SOTF_buff = Spirit of the Forest
      • Set SOTF_heroAbility = Spirit of the Forest
      • Set SOTF_unitType = Spirit of the Forest Unit
      • Set SOTF_detonateAbility = SOTF Detonate
      • Set SOTF_attributeEffectAbility = SOTF Attribute Effect


REQUIREMENTS:
A Damage Detection System. In the sample map, I used
Physical Damage Detection for GUI by looking_for_help, but any DDS will do if you prefers to trigger the spell when unit is damaged instead of when attacked.



SPELL TRIGGERS:


  • OnDamage
    • Events
      • Game - PDD_damageEventTrigger becomes Equal to 1.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • PDD_damageType Equal to PDD_PHYSICAL
        • Then - Actions
          • -------- -------------------------------------- --------
          • -------- Spirit of the Forest Codes --------
          • -------- Copy these CODES to your Damage Detection System/Engine --------
          • -------- -------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (PDD_target has buff SOTF_buff) Equal to True
            • Then - Actions
              • Set SOTF_tempInteger = (Random integer number between 1 and 100)
              • Set SOTF_spiritNum = (Level of SOTF_attributeEffectAbility for PDD_target)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SOTF_tempInteger Less than or equal to SOTF_chanceToActivate[(Level of SOTF_heroAbility for PDD_target)]
                  • SOTF_spiritNum Less than SOTF_maxSpirits[(Level of SOTF_heroAbility for PDD_target)]
                • Then - Actions
                  • Set SOTF_tempInteger = (Level of SOTF_heroAbility for PDD_target)
                  • -------- --------------------------------------------------------------------------------- --------
                  • -------- Positioning of the next Spirit to summon --------
                  • -------- --------------------------------------------------------------------------------- --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • SOTF_spiritNum Equal to 0
                    • Then - Actions
                      • -------- The first spirit to spawn has a random location --------
                      • Set SOTF_tempAngle = (Random real number between 0.00 and 359.00)
                      • -------- The Level of the Ability is also used as a storage for how many spirits are currently spinning --------
                      • Unit - Add SOTF_attributeEffectAbility to PDD_target
                    • Else - Actions
                      • -------- Next spirit's location is relative to the previous spirit's location --------
                      • -------- tempReal is the polar distance between spirits --------
                      • Set SOTF_angleIncrement = (360.00 / (Real((SOTF_spiritNum + 1))))
                      • -------- Pick a spirit's current angular position to be used as a reference --------
                      • Set SOTF_tempBoolean = True
                      • Unit Group - Pick every unit in SOTF_unitGroup and do (Actions)
                        • Loop - Actions
                          • Set SOTF_caster = (Load (Key SOTF_Caster) of (Key (Picked unit)) in SOTF_hashtable)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • SOTF_caster Equal to PDD_target
                              • SOTF_tempBoolean Equal to True
                            • Then - Actions
                              • Set SOTF_tempAngle = (Load (Key SOTF_Angle) of (Key (Picked unit)) from SOTF_hashtable)
                              • -------- Reference angle is determined. Do not pick another unit again --------
                              • Set SOTF_tempBoolean = False
                            • Else - Actions
                      • -------- Move all other spirits relative to the reference --------
                      • Unit Group - Pick every unit in SOTF_unitGroup and do (Actions)
                        • Loop - Actions
                          • Set SOTF_caster = (Load (Key SOTF_Caster) of (Key (Picked unit)) in SOTF_hashtable)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • SOTF_caster Equal to PDD_target
                            • Then - Actions
                              • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Picked unit)) in SOTF_hashtable
                              • Set SOTF_tempAngle = (SOTF_tempAngle + SOTF_angleIncrement)
                            • Else - Actions
                      • -------- The Level of the Ability is also used as a storage for how many spirits are currently spinning --------
                      • Unit - Increase level of SOTF_attributeEffectAbility for PDD_target
                  • -------- --------------------------------------------------------------------------------- --------
                  • -------- ------------- Summoned Spirit Codes ---------------- --------
                  • -------- --------------------------------------------------------------------------------- --------
                  • Set SOTF_tempLoc = (Position of PDD_target)
                  • Set SOTF_tempLoc2 = (SOTF_tempLoc offset by SOTF_spiritDistance towards SOTF_tempAngle degrees)
                  • Unit - Create 1 SOTF_unitType for (Owner of PDD_target) at SOTF_tempLoc2 facing 0.00 degrees
                  • Set SOTF_tempUnit = (Last created unit)
                  • Special Effect - Create a special effect attached to the origin of SOTF_tempUnit using SOTF_spiritSpEffect
                  • Set SOTF_effect = (Last created special effect)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • SOTF_clickable Equal to False
                    • Then - Actions
                      • Custom script: call UnitAddAbility(udg_SOTF_tempUnit, 'Aloc')
                    • Else - Actions
                  • Unit - Turn collision for SOTF_tempUnit Off
                  • Hashtable - Save Handle OfSOTF_effect as (Key SOTF_effect) of (Key (Last created unit)) in SOTF_hashtable
                  • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Last created unit)) in SOTF_hashtable
                  • Hashtable - Save Handle OfPDD_target as (Key SOTF_Caster) of (Key (Last created unit)) in SOTF_hashtable
                  • Custom script: if (FirstOfGroup(udg_SOTF_unitGroup) == null) then
                  • Trigger - Turn on Spirit of the Forest Loop <gen>
                  • Custom script: endif
                  • Unit Group - Add SOTF_tempUnit to SOTF_unitGroup
                  • Custom script: call RemoveLocation(udg_SOTF_tempLoc)
                  • Custom script: call RemoveLocation(udg_SOTF_tempLoc2)
                • Else - Actions
            • Else - Actions
        • Else - Actions

  • Spirit of the Forest Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SOTF_unitGroup and do (Actions)
        • Loop - Actions
          • -------- --------------------------------------------------------------------------------- --------
          • -------- ------------- SOTF_tempUnit refers to Spirit -------------------------- --------
          • -------- --------------------------------------------------------------------------------- --------
          • Set SOTF_tempUnit = (Picked unit)
          • -------- --------------------------------------------------------------------------------- --------
          • -------- The Polar Angle of the Spirit relative to the Hero --------
          • -------- --------------------------------------------------------------------------------- --------
          • Set SOTF_tempAngle = ((Load (Key SOTF_Angle) of (Key (Picked unit)) from SOTF_hashtable) + SOTF_spiritSpeed)
          • -------- --------------------------------------------------------------------------------- --------
          • -------- SOTF_caster refers to the Hero --------
          • -------- --------------------------------------------------------------------------------- --------
          • Set SOTF_caster = (Load (Key SOTF_Caster) of (Key (Picked unit)) in SOTF_hashtable)
          • Set SOTF_tempInteger = (Level of SOTF_heroAbility for SOTF_caster)
          • Set SOTF_tempLoc = (Position of SOTF_caster)
          • Set SOTF_tempLoc2 = (SOTF_tempLoc offset by SOTF_spiritDistance towards SOTF_tempAngle degrees)
          • Unit - Move SOTF_tempUnit instantly to SOTF_tempLoc2
          • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Picked unit)) in SOTF_hashtable
          • -------- --------------------------------------------------------------------------------------------------- --------
          • -------- -------------------- Damages Nearby Enemy Units ----------------------------- --------
          • -------- --------------------------------------------------------------------------------------------------- --------
          • Set SOTF_tempGroup = (Units within SOTF_aoe[SOTF_tempInteger] of SOTF_tempLoc2)
          • Unit Group - Pick every unit in SOTF_tempGroup and do (Actions)
            • Loop - Actions
              • -------- -------------------- Damages Nearby Enemy Units ----------------------------- --------
              • Set SOTF_tempUnit = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (SOTF_tempUnit is alive) Equal to True
                  • (SOTF_tempUnit belongs to an enemy of (Owner of SOTF_caster)) Equal to True
                  • ((Unit-type of SOTF_tempUnit) is A structure) Equal to False
                • Then - Actions
                  • Unit - Cause SOTF_caster to damage SOTF_tempUnit, dealing SOTF_damage[SOTF_tempInteger] damage of attack type SOTF_attackType and damage type SOTF_damageType
                  • Special Effect - Create a special effect attached to the origin of SOTF_tempUnit using SOTF_damagedSpEffect
                  • Special Effect - Destroy (Last created special effect)
                • Else - Actions
          • Set SOTF_tempUnit = (Picked unit)
          • Custom script: call DestroyGroup(udg_SOTF_tempGroup)
          • -------- --------------------------------------------------------------------------------- --------
          • -------- -------------------- Decrease Spirit Life ----------------------------- --------
          • -------- --------------------------------------------------------------------------------- --------
          • Custom script: call SetWidgetLife(udg_SOTF_tempUnit, GetWidgetLife(udg_SOTF_tempUnit) - udg_SOTF_selfDamage[udg_SOTF_tempInteger])
          • -------- --------------------------------------------------------------------------------- --------
          • -------- Cast the weaker Detonate before dying --------
          • -------- --------------------------------------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Life of SOTF_tempUnit) Less than or equal to SOTF_selfDamage[SOTF_tempInteger]
            • Then - Actions
              • -------- Destroy the Attached Effect on the Spirit before killing it --------
              • Set SOTF_effect = (Load (Key SOTF_effect) of (Key (Picked unit)) in SOTF_hashtable)
              • Special Effect - Destroy SOTF_effect
              • -------- --------------------------------------------------------------------------------------- --------
              • Unit - Order SOTF_tempUnit to Night Elf Wisp - Detonate SOTF_tempLoc2
              • Unit Group - Remove SOTF_tempUnit from SOTF_unitGroup
              • -------- --------------------------------------------------------------------------------- --------
              • -------- Attribute Effect to the Hero. The Level of the Ability is also used as a storage for how many spirits are currently spinning --------
              • -------- --------------------------------------------------------------------------------- --------
              • Set SOTF_spiritNum = (Level of SOTF_attributeEffectAbility for SOTF_caster)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • SOTF_spiritNum Equal to 1
                • Then - Actions
                  • Unit - Remove SOTF_attributeEffectAbility from SOTF_caster
                • Else - Actions
                  • Unit - Decrease level of SOTF_attributeEffectAbility for SOTF_caster
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in SOTF_hashtable
              • -------- If SOTF_unitGroup is empty, turn off this trigger --------
              • Custom script: if (FirstOfGroup(udg_SOTF_unitGroup) == null) then
              • Trigger - Turn off Spirit of the Forest Loop <gen>
              • Custom script: endif
            • Else - Actions
          • Custom script: call RemoveLocation(udg_SOTF_tempLoc)
          • Custom script: call RemoveLocation(udg_SOTF_tempLoc2)




IMPLEMENTATION
1) Make sure you check the "Automatically create unknown variables while pasting trigger data" in File->Preferences of World Editor.
2) Copy the 1 Custom Buff named Spirit of the Forest.
3) Copy SOTF Attribute Effect, SOTF Detonate, and the Spirit of the Forest Hero Ability
4) Copy the 'Spirit of the Forest' Unit.
5) Copy the whole "Spells" Trigger folder & paste in map.
6) If you are using your own DDS, copy this part to your own DDS, otherwise copy the "Damage Library" Trigger folder.

  • -------- -------------------------------------- --------
    • -------- Spirit of the Forest Codes --------
    • -------- Copy these CODES to your Damage Detection System/Engine --------
    • -------- -------------------------------------- --------
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (PDD_target has buff SOTF_buff) Equal to True
      • Then - Actions
        • Set SOTF_tempInteger = (Random integer number between 1 and 100)
        • Set SOTF_spiritNum = (Level of SOTF_attributeEffectAbility for PDD_target)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • SOTF_tempInteger Less than or equal to SOTF_chanceToActivate[(Level of SOTF_heroAbility for PDD_target)]
            • SOTF_spiritNum Less than SOTF_maxSpirits[(Level of SOTF_heroAbility for PDD_target)]
          • Then - Actions
            • Set SOTF_tempInteger = (Level of SOTF_heroAbility for PDD_target)
            • -------- --------------------------------------------------------------------------------- --------
            • -------- Positioning of the next Spirit to summon --------
            • -------- --------------------------------------------------------------------------------- --------
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • SOTF_spiritNum Equal to 0
              • Then - Actions
                • -------- The first spirit to spawn has a random location --------
                • Set SOTF_tempAngle = (Random real number between 0.00 and 359.00)
                • -------- The Level of the Ability is also used as a storage for how many spirits are currently spinning --------
                • Unit - Add SOTF_attributeEffectAbility to PDD_target
              • Else - Actions
                • -------- Next spirit's location is relative to the previous spirit's location --------
                • -------- tempReal is the polar distance between spirits --------
                • Set SOTF_angleIncrement = (360.00 / (Real((SOTF_spiritNum + 1))))
                • -------- Pick a spirit's current angular position to be used as a reference --------
                • Set SOTF_tempBoolean = True
                • Unit Group - Pick every unit in SOTF_unitGroup and do (Actions)
                  • Loop - Actions
                    • Set SOTF_caster = (Load (Key SOTF_Caster) of (Key (Picked unit)) in SOTF_hashtable)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • SOTF_caster Equal to PDD_target
                        • SOTF_tempBoolean Equal to True
                      • Then - Actions
                        • Set SOTF_tempAngle = (Load (Key SOTF_Angle) of (Key (Picked unit)) from SOTF_hashtable)
                        • -------- Reference angle is determined. Do not pick another unit again --------
                        • Set SOTF_tempBoolean = False
                      • Else - Actions
                • -------- Move all other spirits relative to the reference --------
                • Unit Group - Pick every unit in SOTF_unitGroup and do (Actions)
                  • Loop - Actions
                    • Set SOTF_caster = (Load (Key SOTF_Caster) of (Key (Picked unit)) in SOTF_hashtable)
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • SOTF_caster Equal to PDD_target
                      • Then - Actions
                        • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Picked unit)) in SOTF_hashtable
                        • Set SOTF_tempAngle = (SOTF_tempAngle + SOTF_angleIncrement)
                      • Else - Actions
                • -------- The Level of the Ability is also used as a storage for how many spirits are currently spinning --------
                • Unit - Increase level of SOTF_attributeEffectAbility for PDD_target
            • -------- --------------------------------------------------------------------------------- --------
            • -------- ------------- Summoned Spirit Codes ---------------- --------
            • -------- --------------------------------------------------------------------------------- --------
            • Set SOTF_tempLoc = (Position of PDD_target)
            • Set SOTF_tempLoc2 = (SOTF_tempLoc offset by SOTF_spiritDistance towards SOTF_tempAngle degrees)
            • Unit - Create 1 SOTF_unitType for (Owner of PDD_target) at SOTF_tempLoc2 facing 0.00 degrees
            • Set SOTF_tempUnit = (Last created unit)
            • Special Effect - Create a special effect attached to the origin of SOTF_tempUnit using SOTF_spiritSpEffect
            • Set SOTF_effect = (Last created special effect)
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • SOTF_clickable Equal to False
              • Then - Actions
                • Custom script: call UnitAddAbility(udg_SOTF_tempUnit, 'Aloc')
              • Else - Actions
            • Unit - Turn collision for SOTF_tempUnit Off
            • Hashtable - Save Handle OfSOTF_effect as (Key SOTF_effect) of (Key (Last created unit)) in SOTF_hashtable
            • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Last created unit)) in SOTF_hashtable
            • Hashtable - Save Handle OfPDD_target as (Key SOTF_Caster) of (Key (Last created unit)) in SOTF_hashtable
            • Custom script: if (FirstOfGroup(udg_SOTF_unitGroup) == null) then
            • Trigger - Turn on Spirit of the Forest Loop <gen>
            • Custom script: endif
            • Unit Group - Add SOTF_tempUnit to SOTF_unitGroup
            • Custom script: call RemoveLocation(udg_SOTF_tempLoc)
            • Custom script: call RemoveLocation(udg_SOTF_tempLoc2)
          • Else - Actions
      • Else - Actions

7) If you are using the same Damage Detection Engine, copy the 2 abilities 'DAMAGE_TYPE_DETECTOR and SET_MAX_LIFE'.
8) Test the map

Keywords:
Spirit, circle, nature, wisp, chance, hashtable, mui, spin
Contents

Spirit of the Forest (Map)

Reviews
Spirit of the Forest v1.5 | Reviewed by BPower | 11.07.2015 Concept[/COLOR]] Wisps are circulating around the caster, damaging nearby units and themself. Their death ends in a small dentonation. Hero stats decreasment adds a unique...

Moderator

M

Moderator


Spirit of the Forest v1.5 | Reviewed by BPower | 11.07.2015

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

[COLOR="gray"

Concept[/COLOR]]
126248-albums6177-picture66521.png
Wisps are circulating around the caster,
damaging nearby units and themself.
Their death ends in a small dentonation.

Hero stats decreasment adds a unique character to the spell.
Code[/COLOR]]
126248-albums6177-picture66521.png
  • The spell is MUI, leakless and working.
Objects[/COLOR]]
126248-albums6177-picture66523.png
  • Object data appears to be ok.
Effects[/COLOR]]
126248-albums6177-picture66521.png
  • Effects are sufficient. Good job.
Rating[/COLOR]]
CONCEPTCODEOBJECTSEFFECTSRATINGSTATUS
3.5/5
3/5
4/5
4/5
3.75/5
APPROVED
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
I've seen other spells that are simpler than this. Besides, this spell is not extremely simple otherwise I would not receive it as a request in the first place.

Spells must be useful. Extremely simple, cinematic, or other spells which have no place in a game will not be accepted.

EDIT:
- Now it is a little more complicated, I made the newly summoned spirit to have equal angular distance with the other spirits, instead of just spawning at a random angular position.
- Maximum number of spirits per level also changed.
 
Last edited:
Level 13
Joined
Aug 19, 2014
Messages
1,111
Looks awesome, the way it is a passive and will create spirits that will circle around the hero is kinda cool. I'll be using this once it gets approved.
 
- Why do you want them clickable/useable and showing hp? This is untypical.
- How you came to decrease stats when a new spirit is created. I don't see much relation in the concept.
- When addind a new spirit the angles screw up. It looks unfluent.
- I don't very like you work so much with adding/removing abilities from object editor. It's better when it's triggered.
User would have much more power when in comes to configuration.
- All spell related stuff, also initialiazions should be included into spell folder.
  • -------- An SOTF_speed of 10.8 is equal to 1 revolution per second --------
  • Set SOTF_spiritSpeed = 5.40
^What is a "recolution per second"? Also note that it's the speed per interval. (0.03)
- You don't necessarily need to normalize angle. 10, for example will be same as 370.
- Don't hardcode. Put the dummy unit into a variable.
- Responses used multiple times should be stored into variables to boost performance. (LastCreatedUnit)
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
- Why do you want them clickable/useable and showing hp? This is untypical.
The original request was to make the spirits clickable to show their HP. Anyway, if you think it is better for them to be locust I can change it.

- How you came to decrease stats when a new spirit is created. I don't see much relation in the concept.
Just to add more effect. Do you want me to remove this as well?


- When addind a new spirit the angles screw up. It looks unfluent.
That is because the angular distance between spirits changes. Example, if I have 3 spirits, each is 120 degree apart to each other. When another spirit is summoned, they became 90 degree apart.


- I don't very like you work so much with adding/removing abilities from object editor. It's better when it's triggered.
User would have much more power when in comes to configuration.
Noted and I will try to improve it.

- All spell related stuff, also initialiazions should be included into spell folder.
Noted.

  • -------- An SOTF_speed of 10.8 is equal to 1 revolution per second --------
  • Set SOTF_spiritSpeed = 5.40
^What is a "recolution per second"? Also note that it's the speed per interval. (0.03)
It is how many times the spirit will revolve around the caster per second. If it is equal to 10.8, then the spirit will complete a full revolution in exactly 1 second. Yeah it does depend on the interval.

- You don't necessarily need to normalize angle. 10, for example will be same as 370.
- Don't hardcode. Put the dummy unit into a variable.
Noted.

- Responses used multiple times should be stored into variables to boost performance. (LastCreatedUnit)
Ok I will store them to a variable.
 
The original request was to make the spirits clickable to show their HP. Anyway, if you think it is better for them to be locust I can change it.
Atm user can select dummies and even (try) to cast abilities, order unit, etc. Dummies
should not show these charesteristics.
So I think yes, it should not be. But if you say it may be needed good way to have it optional though. :) (boolean = true/false)

Just to add more effect. Do you want me to remove this as well?
No, you can let it. I just wondered about the concept.

It is how many times the spirit will revolve around the caster per second.
Ah, my bad.^^ ... "Circulation" would be easier to understand for me, but you are right.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Spell Updated to v1.3

Store all abilty ids used for integer comparisons into variables.
These variables have to be setup in the configuration trigger.
This also includes the spirit of the forest buff.

Store the integer for the dummy unit into a variable and use it in your code.
Done, but I don't get the point.

Turn on the loop trigger only in case it is off. You can use the
same method for checking as you do when you turn it off. ( FirstOfGroup )
For this you have to move the GroupAddUnit function below.
Done.

Object editor based damage is not very welcome
in public spell submissions. It wouldn't be too hard to
change to triggered damage instead.
The world editor already has the ability so triggering it seems kinda redundant. Besides its not difficult to change it. Another thing is, this will increase the codes in the loop trigger that runs every 0.03 second. I have to create a new group consisting of all enemies then pick all the units within that group and decrease their life. That doesn't seems efficient compared to just using the Immolation.

ADDITIONAL EDIT:
Removed the Spell Book and used a 0,-11 coordinate for the button to be hidden
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
Done, but I don't get the point.
This way configuration is kept under one trigger. It's also a very minor speed improvement
as you replace a function call with an non-constant integer.

The world editor already has the ability so triggering it seems kinda redundant. Besides its not difficult to change it. Another thing is, this will increase the codes in the loop trigger that runs every 0.03 second. I have to create a new group consisting of all enemies then pick all the units within that group and decrease their life. That doesn't seems efficient compared to just using the Immolation.
GroupEnumUnitsInRange is quite fast. If I would have to guess, I would say Blizzard does the
same for Immolation internally. ( some way immolation also has to enumerate close units.
Btw you would be suprised how slow GUI is compared to JASS. It's literally two worlds.

Oject data isn't really good for abilities, especially when it comes to dealing damage.

Removed the Spell Book and used a 0,-11 coordinate for the button to be hidden
I read about this and I don't know if it works on every kind of engine.
I don't consider this update as a benefit at all, but also not negative.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
GroupEnumUnitsInRange is quite fast. If I would have to guess, I would say Blizzard does the
same for Immolation internally. ( some way immolation also has to enumerate close units.
Btw you would be suprised how slow GUI is compared to JASS. It's literally two worlds.

Oject data isn't really good for abilities, especially when it comes to dealing damage.
So I just have to trigger immolation and it will be approved?
You said GUI is slowed compared to Jass and I totally agree, that is why I think I should not trigger immolation coz I think Immolation is coded in Jass Script internally.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Your variable names are not consistent. Chose either a small letter
or a capital one after the SOFT_ prefix. Currently it's a wild mix.
Done. I chose small letter sucg as SOTF_attributeEffect.

Your hashtable should also have the SOFT_ prefix
Done.

Here you should used previously stored SOFT_tempUnit
  • Unit - Set level of SOTF_DPS for (Last created unit) to SOTF_tempInteger
Removed because it is no longer needed since I triggered immolation.

Object editor based damage is not very welcome
in public spell submissions. It wouldn't be too hard to
change to triggered damage instead. It's not as
expensive as you think.
Immolation is now triggered.

Added:
- Configurable DPS per level in triggers (mentioned above).
- Configurable AoE per level in triggers.
- Configurable Special Effects in triggers.
 
First, good to see that you triggered the AOE damage now.
But I still I mark some things that can be optimized:

  • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Last created unit)) in SOTF_hashtable
  • Hashtable - Save Handle OfPDD_target as (Key SOTF_Caster) of (Key (Last created unit)) in SOTF_hashtable
LastCreatedUnit -> Set SOTF_tempUnit

In your periodic trigger you can change something similar:
PickedUnit -> SOTF_tempUnit
(Don't forget the part where you clean hashtable)

OwnerOfCaster might also be stored into hashtables, as it's called on periodic event.

  • Set SOTF_tempGroup = ...
^When doing this just pick all units in range.
Then immediatly set your variable to "PickedUnit",
and then filter all units with help of "If/Then/Else multiple".
You also will gain readability of the filter.

Please make the damage and attack type configurable for user.
It's always good if these things can be changed easily, instead of having it hardcoded.

  • (Life of SOTF_tempUnit) Less than or equal to 5.00
^What if the "selfDamage" is higher than 5? Please also take care of it.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
IcemanBo said:
  • Hashtable - Save SOTF_tempAngle as (Key SOTF_Angle) of (Key (Last created unit)) in SOTF_hashtable
  • Hashtable - Save Handle OfPDD_target as (Key SOTF_Caster) of (Key (Last created unit)) in SOTF_hashtable
LastCreatedUnit -> Set SOTF_tempUnit

In your periodic trigger you can change something similar:
PickedUnit -> SOTF_tempUnit
(Don't forget the part where you clean hashtable)
I have already thought of this but I can't find how to do it. Unit variables just don't appear in the drop down menu. Do you know how?

IcemanBo said:
OwnerOfCaster might also be stored into hashtables, as it's called on periodic event.
Since you said "might", I'll assume this is optional. I just think it is slower to store them in hashtable and retrieve them than just using OwnerOfCaster.

IcemanBo said:
  • Set SOTF_tempGroup = ...
^When doing this just pick all units in range.
Then immediatly set your variable to "PickedUnit",
and then filter all units with help of "If/Then/Else multiple".
You also will gain readability of the filter.
Done, but I haven't uploaded the update yet because I still have a question in my first statement above.

IcemanBo said:
Please make the damage and attack type configurable for user.
It's always good if these things can be changed easily, instead of having it hardcoded.
Will do.

IcemanBo said:
  • (Life of SOTF_tempUnit) Less than or equal to 5.00
^What if the "selfDamage" is higher than 5? Please also take care of it.
Ok I changed it to if Life <= selfDamage.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
I have already thought of this but I can't find how to do it. Unit variables just don't appear in the drop down menu. Do you know how?
Not supported in GUI. There might be a specific type of variable, but it's not important
in your case. Just leave it as it is ( key of last created unit ).

Since you said "might", I'll assume this is optional. I just think it is slower to store them in hashtable and retrieve them than just using OwnerOfCaster.
An hashtable lookup will turn out to be faster ( just because you asked )
For this spell it doesn't matter and can be left as OwnerOfCaster.
GUI itself is such a slowpoke.
Applying changes here can be considered as micro-optimization.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
You leak an effect handle in OnDamage
No the effect gets destroyed when the wisp dies.


SOFT attribute effect in OnDamage should be added/increased via the stored variable.
will do.


I just saw that you use tempUnit and tempUnit2 in the loop trigger.
Actually you can handle everything via tempUnit. ( tempUnit2 is not required )
you mean like this
  • Set SOTF_tempGroup = (Units within SOTF_aoe[SOTF_tempInteger] of SOTF_tempLoc2)
    • Unit Group - Pick every unit in SOTF_tempGroup and do (Actions)
      • Loop - Actions
        • Set SOTF_tempUnit = (Picked unit)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (SOTF_tempUnit is alive) Equal to True
            • (SOTF_tempUnit belongs to an ally of (Owner of SOTF_caster)) Equal to True
          • Then - Actions
            • Unit - Cause SOTF_caster to damage SOTF_tempUnit, dealing SOTF_damage[SOTF_tempInteger] damage of attack type SOTF_attackType and damage type SOTF_damageType
            • Special Effect - Create a special effect attached to the origin of SOTF_tempUnit using SOTF_damagedSpEffect
            • Special Effect - Destroy (Last created special effect)
          • Else - Actions
    • Set SOTF_tempUnit = (Picked unit)
    • Custom script: call DestroyGroup(udg_SOTF_tempGroup)

Can Wisps use denotate, if they are dead?
( eventually you kill your wisps with -damage/second. )
No, that is why when their HP is less than or equal to their self damage, before the next loop runs (which will kill them), it will cast detonate. Basically, it cast detonate before it dies.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
No the effect gets destroyed when the wisp dies.
You mean blizzard checks internally every effect placed on a unit which gets removed and removes it?
I doubt this very much.

No, that is why when their HP is less than or equal to their self damage, before the next loop runs (which will kill them), it will cast detonate. Basically, it cast detonate before it dies.
I missed that. Your are right.

For the unit thingy. Yes
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
You mean blizzard checks internally every effect placed on a unit which gets removed and removes it?
I doubt this very much.


I missed that. Your are right.

For the unit thingy. Yes

Hmm, you are right
http://www.hiveworkshop.com/forums/...tached-unit-destroy-when-unit-removed-206630/
http://www.hiveworkshop.com/forums/...estroyed-when-unit-they-attached-dies-235741/
http://www.hiveworkshop.com/forums/...stroy-special-effects-made-unit-group-215398/

The effects disappearing made me assume it was removed when the unit dies.
 
Top