Need help doing math to find the correct "hitbox" for my triggered spell?

Level 5
Joined
Mar 16, 2014
Messages
90
Intended spell effect/tooltip: "Sloth slams his chains onto the target point dealing 650/750/850 damage in a 150 area of effect 500 distance away from himself, stunning enemies for 1 second, and knocking the target back towards Sloth. Enemies hit by the giant slam of the chains take full damage, but other enemies between Sloth and the slam take only half the damage, along with no stun or knockback. 20 second cooldown, 600 cast range."

In practice, my spell's hitbox is wildly inaccurate and often doesn't hit when it's supposed to. Here is the trigger.

Code:
Chain Crusher
    Events
        Unit - A unit Starts the effect of an ability
    Conditions
        (Ability being cast) Equal to Chain Crusher
    Actions
        Set VariableSet Sloth_Unit = (Triggering unit)
        Set VariableSet Temp_Point = (Position of Sloth_Unit)
        Set VariableSet ChainCrusherTargetOriginal = (Target point of ability being cast)
        Set VariableSet ChainCrusherTarget = (Temp_Point offset by 400.00 towards (Angle from Temp_Point to ChainCrusherTargetOriginal) degrees.)
        Custom script:   call RemoveLocation (udg_Temp_Point)
        Custom script:   call RemoveLocation (udg_ChainCrusherTargetOriginal)
        Unit - Pause Sloth_Unit
        Animation - Change Sloth_Unit's animation speed to 75.00% of its original speed
        Animation - Play Sloth_Unit's spell gold animation
        Wait 0.50 seconds
        Wait 0.50 game-time seconds
        Special Effect - Create a special effect at ChainCrusherTarget using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
        Special Effect - Destroy (Last created special effect)
        Set VariableSet Temp_Point = (Position of Sloth_Unit)
        Set VariableSet ChainCrusherGroup = (Units within 650.00 of Temp_Point matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is Mechanical) Equal to False) and ((((Owner of (Matching unit)) is an enemy of (Owne
        Custom script:   call RemoveLocation (udg_Temp_Point)
        Unit Group - Pick every unit in ChainCrusherGroup and do (Actions)
            Loop - Actions
                Set VariableSet TempLoc2 = (Position of (Picked unit))
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Cos(((Angle from TempLoc2 to Temp_Point) - (Facing of Sloth_Unit)))) Less than or equal to (Cos((180.00 - 85.00)))
                    Then - Actions
                        Set VariableSet TempLoc = (Position of (Picked unit))
                        Unit - Cause Sloth_Unit to damage (Picked unit), dealing ((275.00 + ((50.00 x (Real((Level of Chain Crusher  for Sloth_Unit)))) + 0.00)) + (0.00 + (((Real((Strength of Sloth_Unit (Include bonuses)))) x 0.15) x (Real((Custom value of Sloth_Unit)))))) damage of attack type Spells and damage type Universal
                        Special Effect - Create a special effect attached to the origin of Sloth_Unit using war3mapImported\mihawkslashhit.mdx
                        Special Effect - Destroy (Last created special effect)
                    Else - Actions
                Custom script:   call RemoveLocation(udg_TempLoc2)
        Custom script:   call DestroyGroup(udg_ChainCrusherGroup)
        Set VariableSet Temp_Group = (Units within 150.00 of ChainCrusherTarget matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is Magic Immune) Equal to False) and ((((Matching unit) is Mechanical) Equal to False) and ((((Owner of (Matching unit)) is an enemy
        Unit Group - Pick every unit in Temp_Group and do (Actions)
            Loop - Actions
                Unit - Cause Sloth_Unit to damage (Picked unit), dealing ((275.00 + ((50.00 x (Real((Level of Chain Crusher  for Sloth_Unit)))) + 0.00)) + (0.00 + (((Real((Strength of Sloth_Unit (Include bonuses)))) x 0.15) x (Real((Custom value of Sloth_Unit)))))) damage of attack type Spells and damage type Universal
                Set VariableSet Temp_Point = (Position of Sloth_Unit)
                Unit - Create 1 Dummy unit spells for (Owner of Sloth_Unit) at Temp_Point facing Default building facing degrees
                Custom script:   call RemoveLocation (udg_Temp_Point)
                Set VariableSet Temp_Unit = (Last created unit)
                Unit - Add a 1.20 second Generic expiration timer to Temp_Unit
                Unit - Add Storm Bolt (Dummy, 0.5, 0.75, 1, 1.25, 1.5, 0.03, 2) to Temp_Unit
                Unit - Set level of Storm Bolt (Dummy, 0.5, 0.75, 1, 1.25, 1.5, 0.03, 2) for Temp_Unit to 3
                Unit - Order Temp_Unit to Human Mountain King - Storm Bolt (Picked unit)
                Set VariableSet Temp_Point = (Position of Sloth_Unit)
                Set VariableSet TempLoc = (Position of (Picked unit))
                -------- CALL KNOCKBACK START --------
                Set VariableSet KnockbackCall_Unit = (Picked unit)
                Set VariableSet KnockbackCall_Dur = 0.50
                Set VariableSet KnockbackCall_Dist = (Distance between TempLoc and Temp_Point)
                Set VariableSet KnockbackCall_Angle = (Angle from TempLoc to Temp_Point)
                Custom script:   call RemoveLocation (udg_Temp_Point)
                Set VariableSet KnockbackCall_SFX = <Empty String>
                Set VariableSet KnockbackCall_DestroyTree = False
                Trigger - Run Knockback Call <gen> (ignoring conditions)
                -------- CALL KNOCKBACK END --------
                Custom script:   call RemoveLocation (udg_TempLoc)
                Custom script:   call RemoveLocation (udg_Temp_Point)
                For each (Integer A) from 1 to 12, do (Actions)
                    Loop - Actions
                        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            If - Conditions
                                (Unit-type of (Picked unit)) Equal to Stone Prison Wall 2
                            Then - Actions
                                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    If - Conditions
                                        (Picked unit) Equal to EdWallUnit[(Integer A)]
                                    Then - Actions
                                        Destructible - Remove EdWallPathingBlocker[(Integer A)]
                                    Else - Actions
                            Else - Actions
        Custom script:   call DestroyGroup(udg_Temp_Group)
        Custom script:   call RemoveLocation (udg_ChainCrusherTarget)
        Wait 0.50 game-time seconds
        Wait 0.50 seconds
        Unit - Unpause Sloth_Unit
        Animation - Reset Sloth_Unit's animation
        Animation - Change Sloth_Unit's animation speed to 100.00% of its original speed
 
Level 32
Joined
Aug 10, 2018
Messages
3,390
The Waits + Pause actions look concerning. I recommend using this to Stun the unit instead of Pausing it:
  • stun:
  • Custom script: call BlzPauseUnitEx(udg_Sloth_Unit, true)
  • unstun:
  • Custom script: call BlzPauseUnitEx(udg_Sloth_Unit, false)
Pausing has a lot of undesirable side effects like pausing buff timers as well.

Also, it's pretty hard to read the trigger like that. If you post it properly I may be able to help debug it.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 59
Joined
Jan 18, 2005
Messages
26,664
Point searches for units do not factor in unit hit boxes like native ability hazard areas do. Instead they only consider the unit's origin point. This is likely the cause of your "wildly inaccurate" hitting behaviour.

To fix this you need to search in circle that is at least the maximum collision radius bigger than the desired hazard circle and then filter the results down using the UnitInRange function. The UnitInRange function does factor in unit hit boxes allowing you to accurately recreate native ability hazard areas as long as your original set of units contains them all affected units. Unit in range might be available in GUI, and if it is it would be a boolean comparison.
 
Level 9
Joined
Feb 27, 2019
Messages
215
How come you remove Temp_Point then use Temp_Point in your If comparison?

Code:
Custom script:   call RemoveLocation (udg_Temp_Point)
        Unit Group - Pick every unit in ChainCrusherGroup and do (Actions)
            Loop - Actions
                Set VariableSet TempLoc2 = (Position of (Picked unit))
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        (Cos(((Angle from TempLoc2 to Temp_Point) - (Facing of Sloth_Unit)))) Less than or equal to (Cos((180.00 - 85.00)))
                    Then - Actions
                        Set VariableSet TempLoc = (Position of (Picked unit))
                        Unit - Cause Sloth_Unit to damage (Picked unit), dealing ((275.00 + ((50.00 x (Real((Level of Chain Crusher  for Sloth_Unit)))) + 0.00)) + (0.00 + (((Real((Strength of Sloth_Unit (Include bonuses)))) x 0.15) x (Real((Custom value of Sloth_Unit)))))) damage of attack type Spells and damage type Universal
                        Special Effect - Create a special effect attached to the origin of Sloth_Unit using war3mapImported\mihawkslashhit.mdx
                        Special Effect - Destroy (Last created special effect)
 
Top