• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Advanced Bouncing System v2

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: IcemanBo
An MUI system, usable by any person because of lot of variables that can be pre-set before game.
Examples:
- You can set if the projectile will bounce after hitting buildings
- if the projectile removes dead bodies
- if the projectile damages allyed units
- if the projectile bounce from allyed units

There is really lot of combinations of usable. Enjoy :)
And please give me some credits if you use, thanks :)



  • Bounce Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set p_Hashtable = (Last created hashtable)
      • -------- Other --------
      • Set p_damage = 60.00
      • Set p_attacktype = Normal
      • Set p_size = 40.00
      • Set p_speed = 22.00
      • Set p_livetime = 4.00
      • Set p_preciseleak = 2.00
      • Set p_createpointoffset = 50.00
      • Set p_allydamage = 0.00
      • -------- Bounce --------
      • Set p_bounceterrain = 1.00
      • Set p_bouncedestructibles = 1.00
      • Set p_bounceunits = 1.00
      • Set p_bouncedead = 1.00
      • Set p_bouncebuilding = 0.00
      • Set p_bounceterraintype = Lordaeron Summer - Dark Grass
      • Set p_bounceally = 1.00
      • -------- Hit --------
      • Set p_hitterrainremove = 0.00
      • Set p_hitdestructibles = 1.00
      • Set p_hitunits = 1.00
      • Set p_hitbuilding = 0.00
      • Set p_hitdead = 1.00
      • Set p_removedead = 1.00
      • Set p_hitnremove = 0.00
      • Set p_hitally = 1.00
      • Set p_hiteffect = Objects\Spawnmodels\Human\HumanBlood\BloodElfSpellThiefBlood.mdl


  • BounceAbilityCast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Bounce Ability
    • Actions
      • Set p_TriggerUnit = (Triggering unit)
      • Set p_Point = (Position of p_TriggerUnit)
      • Set p_Point2 = (Target point of ability being cast)
      • Set p_Real = ((Angle from p_Point to p_Point2) + (Random real number between (p_preciseleak x -1.00) and p_preciseleak))
      • Custom script: call RemoveLocation(udg_p_Point)
      • Custom script: call RemoveLocation(udg_p_Point2)
      • Set p_Point = (Position of p_TriggerUnit)
      • Set p_Point2 = (p_Point offset by p_createpointoffset towards p_Real degrees)
      • Unit - Create 1 projectileUnit for (Owner of p_TriggerUnit) at p_Point2 facing p_Real degrees
      • Unit - Add a p_livetime second Water Elemental expiration timer to (Last created unit)
      • Custom script: call RemoveLocation(udg_p_Point)
      • Custom script: call RemoveLocation(udg_p_Point2)
      • Hashtable - Save Handle Ofp_TriggerUnit as (Key p_owner) of (Key (Last created unit)) in p_Hashtable
      • Hashtable - Save p_Real as (Key p_direction) of (Key (Last created unit)) in p_Hashtable
      • Unit Group - Add (Last created unit) to p_functiongroup
      • Unit - Order p_TriggerUnit to Stop
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in p_functiongroup) Greater than 0
        • Then - Actions
          • Trigger - Turn on BounceFunctionGroup <gen>
        • Else - Actions


  • BounceFunctionGroup
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in p_functiongroup and do (Actions)
        • Loop - Actions
          • Set p_PickedUnit = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (p_PickedUnit is alive) Equal to True
            • Then - Actions
              • Set p_Real = (Load (Key p_direction) of (Key (Picked unit)) from p_Hashtable)
              • Set p_Point = (Position of p_PickedUnit)
              • Set p_Point2 = (p_Point offset by p_speed towards p_Real degrees)
              • Custom script: call SetUnitX(udg_p_PickedUnit, GetLocationX(udg_p_Point2))
              • Custom script: call SetUnitY(udg_p_PickedUnit, GetLocationY(udg_p_Point2))
              • Custom script: call RemoveLocation(udg_p_Point)
              • Custom script: call RemoveLocation(udg_p_Point2)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Or - Any (Conditions) are true
                    • Conditions
                      • p_hitunits Equal to 1.00
                      • p_hitdead Equal to 1.00
                      • p_bounceunits Equal to 1.00
                      • p_bouncedead Equal to 1.00
                • Then - Actions
                  • Set p_Point = (Position of p_PickedUnit)
                  • Set p_Group = (Units within p_size of p_Point matching (((Unit-type of (Matching unit)) Not equal to (Unit-type of p_PickedUnit)) and ((Matching unit) Not equal to (Load (Key p_owner) of (Key (Picked unit)) in p_Hashtable))))
                  • Custom script: call RemoveLocation(udg_p_Point)
                  • Set p_Unit = (Random unit from p_Group)
                  • Custom script: call DestroyGroup(udg_p_Group)
                  • -------- Bounce Function --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • p_Unit Not equal to No unit
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (p_Unit is alive) Equal to True
                          • And - All (Conditions) are true
                            • Conditions
                              • (p_Unit is alive) Equal to False
                              • p_bouncedead Equal to 1.00
                      • Or - Any (Conditions) are true
                        • Conditions
                          • And - All (Conditions) are true
                            • Conditions
                              • p_bounceunits Equal to 1.00
                              • (p_Unit is A structure) Equal to False
                          • And - All (Conditions) are true
                            • Conditions
                              • p_bouncebuilding Equal to 1.00
                              • (p_Unit is A structure) Equal to True
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (p_PickedUnit belongs to an enemy of (Owner of p_Unit)) Equal to True
                          • And - All (Conditions) are true
                            • Conditions
                              • p_bounceally Equal to 1.00
                              • (p_PickedUnit belongs to an ally of (Owner of p_Unit)) Equal to True
                    • Then - Actions
                      • Set p_Point = (Position of p_PickedUnit)
                      • Set p_Point2 = (Position of p_Unit2)
                      • Set p_Real = ((Angle from p_Point to p_Point2) - 180.00)
                      • Custom script: call RemoveLocation(udg_p_Point)
                      • Custom script: call RemoveLocation(udg_p_Point2)
                      • Hashtable - Save p_Real as (Key p_direction) of (Key (Picked unit)) in p_Hashtable
                    • Else - Actions
                  • -------- Hit Function --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • p_Unit Not equal to No unit
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (p_Unit is alive) Equal to True
                          • And - All (Conditions) are true
                            • Conditions
                              • (p_Unit is alive) Equal to False
                              • p_hitdead Equal to 1.00
                      • Or - Any (Conditions) are true
                        • Conditions
                          • And - All (Conditions) are true
                            • Conditions
                              • p_hitunits Equal to 1.00
                              • (p_Unit is A structure) Equal to False
                          • And - All (Conditions) are true
                            • Conditions
                              • p_hitbuilding Equal to 1.00
                              • (p_Unit is A structure) Equal to True
                      • Or - Any (Conditions) are true
                        • Conditions
                          • (p_PickedUnit belongs to an enemy of (Owner of p_Unit)) Equal to True
                          • And - All (Conditions) are true
                            • Conditions
                              • p_hitally Equal to 1.00
                              • (p_PickedUnit belongs to an ally of (Owner of p_Unit)) Equal to True
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • p_removedead Equal to 1.00
                          • (p_Unit is alive) Equal to False
                        • Then - Actions
                          • Unit - Remove p_Unit from the game
                          • Set p_Point = (Position of p_Unit)
                          • Special Effect - Create a special effect at p_Point using Objects\Spawnmodels\Human\HumanLargeDeathExplode\HumanLargeDeathExplode.mdl
                          • Special Effect - Destroy (Last created special effect)
                          • Custom script: call RemoveLocation(udg_p_Point)
                        • Else - Actions
                      • Unit - Cause p_PickedUnit to damage p_Unit, dealing p_damage damage of attack type p_attacktype and damage type Normal
                      • Special Effect - Create a special effect attached to the chest of p_Unit using p_hiteffect
                      • Special Effect - Destroy (Last created special effect)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • p_hitnremove Equal to 1.00
                        • Then - Actions
                          • Unit - Kill p_PickedUnit
                        • Else - Actions
                    • Else - Actions
                  • -------- Destructibles Function --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • p_bouncedestructibles Equal to 1.00
                          • p_hitdestructibles Equal to 1.00
                    • Then - Actions
                      • Set p_Point = (Position of p_PickedUnit)
                      • Destructible - Pick every destructible within p_size of p_Point and do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ((Picked destructible) is alive) Equal to True
                            • Then - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • p_bouncedestructibles Equal to 1.00
                                • Then - Actions
                                  • Set p_Point = (Position of p_PickedUnit)
                                  • Set p_Point2 = (Position of (Picked destructible))
                                  • Set p_Real = ((Angle from p_Point to p_Point2) - 180.00)
                                  • Custom script: call RemoveLocation(udg_p_Point)
                                  • Custom script: call RemoveLocation(udg_p_Point2)
                                  • Hashtable - Save p_Real as (Key p_direction) of (Key (Picked unit)) in p_Hashtable
                                • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • p_hitdestructibles Equal to 1.00
                                • Then - Actions
                                  • Animation - Play (Picked destructible)'s stand hit animation
                                  • Destructible - Set life of (Picked destructible) to ((Current life of (Picked destructible)) - p_damage)
                                • Else - Actions
                            • Else - Actions
                      • Custom script: call RemoveLocation(udg_p_Point)
                    • Else - Actions
                  • -------- Terrain Function --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • p_bounceterrain Equal to 1.00
                          • p_hitterrainremove Equal to 1.00
                    • Then - Actions
                      • Set p_Real = 0.00
                      • For each (Integer A) from 1 to 4, do (Actions)
                        • Loop - Actions
                          • Set p_Point = (Position of p_PickedUnit)
                          • Set p_Point2 = (p_Point offset by p_size towards p_Real degrees)
                          • Custom script: call RemoveLocation(udg_p_Point)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Terrain type at p_Point2) Equal to p_bounceterraintype
                            • Then - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • p_bounceterrain Equal to 1.00
                                • Then - Actions
                                  • Set p_Point = (Position of p_PickedUnit)
                                  • Set p_Point3 = (p_Point offset by p_size towards (Load (Key p_direction) of (Key (Picked unit)) from p_Hashtable) degrees)
                                  • Set p_Real = ((Angle from p_Point3 to p_Point2) - 180.00)
                                  • Custom script: call RemoveLocation(udg_p_Point)
                                  • Custom script: call RemoveLocation(udg_p_Point3)
                                  • Hashtable - Save p_Real as (Key p_direction) of (Key (Picked unit)) in p_Hashtable
                                • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • p_hitterrainremove Equal to 1.00
                                • Then - Actions
                                  • Unit - Kill p_PickedUnit
                                • Else - Actions
                            • Else - Actions
                          • Custom script: call RemoveLocation(udg_p_Point2)
                          • Set p_Real = (p_Real + 90.00)
                    • Else - Actions
                • Else - Actions
            • Else - Actions
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in p_Hashtable
              • Unit Group - Remove p_PickedUnit from p_functiongroup
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Number of units in p_functiongroup) Less than or equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions







Keywords:
bounce, advanced, system, datnessX, mui, basic
Contents

Advanced bouncing system v2 (Map)

Reviews
12th Dec 2015 IcemanBo: Too long as NeedsFix. Rejected. BPower 5.2.2014 For GUI spells/systems it is better to use two chars prefix p_ --> AB_ You should add a documentation to the configuration trigger, not all variables are self-explaining...

Moderator

M

Moderator

12th Dec 2015
IcemanBo: Too long as NeedsFix. Rejected.

BPower 5.2.2014
  • For GUI spells/systems it is better to use two chars prefix p_ --> AB_
  • You should add a documentation to the configuration trigger, not all variables are self-explaining.
  • You set p_Point twice to the same value in the spell cast trigger.
  • p_Unit Not equal to No unit ---> p_Unit will never be null, you don't have to make this check.
  • The damagetype should be configurable.
  • All used effects should be configurable.
  • You should check wether the destructable is a tree or not, otherwise you would also kill bridges, etc.
  • In general abilities have levels, which you should take into consideration.
  • Aslong as you only distinguish between 1 and 2 use booleans instead of reals for the condition checks.
23:07, 18th Jan 2014
BPower:
- Store TriggeringUnit and PickedUnit into variables
- Variablenames must be more specific, just Point is unacceptable, because it might mess up other triggers.
- The loop shouldn't be running, when no instance is allocated.
- Overall very inefficient coding.

However it works and I would appreciate, if you work on your resource. PM me or leave a message in the thread, if you plan to improve the code and I'll point out weak points in detail for you.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
- The periodic trigger should be turned off, if no instance of Advanced Bounce exists. In other words, turn off the trigger if p_functiongroup is empty and turn it back on if not.
- The variablenames have to be unique. Names like Real, Unit, Point are unacceptable. ---> AB_Time, AB_Temp_Loc , ... otherwise they might mess up with other triggers inside the map.
- Store PickedUnit into a variable, instead of calling GetEnumUnit() over and over again.
- In BounceAbilityCast the TriggeringUnit should be stored into a variable aswell.

Bouncing is a cool feature, but you have to put some work into your system. In its current state it will face a rejection.
You can ask for help in the forum Triggers&Skripts or maybe some keen helpers will post suggestions here.
 
Review - Advanced Bouncing System v1 by DatnessX
1.
In your cast trigger, you don't need to set Point (Position of triggering unit) and remove it two times.
Just remove it once after you don't need it anymore.

2.
If you only need these two first locations for getting angle, you can avoid this.
You can use a tan function to get angle between two points:
JASS:
Atan2(y_2 - y_1 , x_2 - x_1) * bj_RADTODEG
You should use this in both of your triggers.

3. In your periodic trigger, same as said in '1.' but now for picked unit.
Also create a new unit variabe, because you obviously overwrite "Unit". You can use Unit_2 for example, for next unit.

4.
Don't use IntegerA/B for loops, they are less efficient as custom integer would be.

5.
I see you use points only for using GetLocationX/Y, so you can use SetUnitX/Y.
SetUnitX/Y is faster yes, but using locations here can be avoided with some maths:
  • Custom script: call SetUnitY(unit, GetUnitY(unit) + offset * Sin(angle))
  • Custom script: call SetUnitX(unit, GetUnitX(unit) + offset * Cos(angle))
Offset is your speed and angle is the direction.

6.
SetUnitX/Y is faster, but doesnt check map pathing.
You could init coordinates of world bounds, and then check them later to prevent unit from getting out of map accidently.

Spell itself looked really cool in game :thumbs_up:
I think it's a cool spell, go on improving code! +rep
 
Level 10
Joined
Aug 21, 2010
Messages
316
Try this

JASS:
function AngleBetweenXY takes real x1, real y1, real x2, real y2 returns real
    return 57.29582 * Atan2( y2 - y1, x2 - x1 )  // ->  bj_RADTODEG * Atan2( y2 - y1, x2 - x1 )
endfunction


formula 1,2 = first x1,y1 then x2,y2 [makes more sense]

JASS:
set yourangle =  AngleBetweenXY( x_1, y_1, x_2, y_2 )

For Distance
JASS:
function DistanceBetweenXY takes real x1, real y1, real x2, real y2 returns real
    return SquareRoot( ( x1 - x2 ) * ( x1 - x2 ) + ( y1 - y2 ) * ( y1 - y2 ) )
endfunction

For offset
JASS:
function PolarProjectionX takes real source, real dist, real angle returns real
    local real x = source + dist * Cos(angle * 0.01745)
    return x
endfunction

JASS:
function PolarProjectionY takes real source, real dist, real angle returns real
    local real y = source + dist * Sin(angle * 0.01745)
    return y
endfunction

JASS:
Atan2(y_2 - y_1 , x_2 - x_1) * bj_RADTODEG
In this case, the formula is: 2,1

or easiest for you[because you probably GUI user]

  • Set Your_Angle = (Atan2((y_2 - y_1), (x_2 - x_1)))
 
Dummy units which are no longer in use should be removed(removed as in the function) (if you need death effects to play then you should put a short timer that'll run after it was killed before it is removed.

All effect paths should be configurable.
  • Special Effect - Create a special effect at p_Point using Objects\Spawnmodels\Human\HumanLargeDeathExplode\HumanLargeDeathExplode.mdl
This one was left out

The Spell should be able to be levelled (or at the very least, as a "system", be able to support more than exactly 1 type, really)

Conditional things like "can it remove dead bodies" and such should be boolean values, not reals. (even if there were more than either on or off, it would then need to be an integer -> variable efficiency and all that

Just a few notes
 
Top