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

Void Ray v1.4



UPDATE v1.4
- Updated to use Persistent Beam v3.2. v3.1 had a small bug.

UPDATE v1.3
- Fixed an issue with the triggered damage.

UPDATE v1.2
- Some code optimisation
- Now uses Persistent Beam v3.0

UPDATE v1.1
- rewrote system to use 2D arrays instead of a bunch of if/then/else block. Thanks for the tutorial, Bribe :)
- Updated documentation (README)

UPDATE v1.0
- Initial release


JASS:
    VOID RAY v1.4 by Spellbound
    
    This emulates the Void Ray from Starcraft 2. Evert tier increases after 3 seconds up to 2 times, and each time the beam will change and the damage will increase as well.
    After the beam has terminated, the beam will downgrade 1 tier after 5 seconds.
    
    
    
    REQUIREMENTS:
    
    Persistent Beam v3.2                        http://www.hiveworkshop.com/forums/spells-569/persistent-beam-v3-2-a-270222/
        - GUI Unit Indexer v1.2.0.2             http://www.hiveworkshop.com/forums/spells-569/gui-unit-indexer-1-2-0-2-a-197329/
        - Damage Engine v3.5.4.1                http://www.hiveworkshop.com/forums/spells-569/gui-damage-engine-v3-5-4-1-a-201016/
        - GetUnitCollisionSize for GUI v1.4     http://www.hiveworkshop.com/forums/spells-569/getunitcollisionsize-gui-v1-4-a-225448/
    
    
    
    HOW TO IMPORT:
    
    If you do not have Peristent Beam already.
    * import the dummy.mdx model (credits to Vexorian) to your map.
    * import the dummy unit from the object editor to your map.
    * Make sure that in File > Preferences > General, the box next to 'Automatically create unknown variables while pasting trigger data' is ticked.
    * Copy the Requirements folder to your map.
    * Copy the PB Variable Creator trigger in the Persistent Beam folder to your map. Feel free to delete it afterwards.
    * Copy the Persistent Beam folder to your map. Refer to PB README if you need explanations on how to setup your units.
    
    Start here if you already have Peristent Beam in your map:
    * Copy Variable Creator in the Void Ray folder to your map.
    * Copy the Void Ray folder to your map.
    * Add any units to the Void Ray Setup trigger.
    
    
    
    VARIABLES:
    
    VR_IsAVoidRay[UDex] = true // Set this to true always or else the triggers won't be able to identify the unit.
    VR_MaxLevel[UDex] = 0 // This is number of times the beam can upgraded. Tier 0 is the beam's default state.
    VR_UpgradeThreshold[UDex] = 0 // this is how many intervals must happen until the beam upgrades one level. A value of 33 is 1 second.
    VR_DowngradeThreshold[UDex] = 0 // this is how many intervals must happen until the beam lowers one level. A value of 33 is 1 second.
    VR_PercentageBonusPerLevel[UDex] = 1.00 // this is by how much the damage increases per tier. 1.00 is 100%. 1.60 is 160%, etc...
    VR_LevelString[UDex] = "" // this is your default lightning effect string, like CLPB for Chain Lightning - Primary Beam. You don't have to setup
                              // lightning effects for all levels. If you have them for 3 levels, but your VR_MaxLevel[UDex] is 5, it will use the
                              // last lightning effect as the one for the rest of the levels.
    
    ***
    VR_CurrentLevel[UDex] = 1 // DO NOT CHANGE THIS. This sets the default level to 1, which is the lowest.
    
    This system uses 2D arrays, and as such you will need to go inside the array itself to add more levels. 
    Example: Set VR_LevelString[((UDex x VR_MaxLevel[UDex]) + 3)] = CLPB // If you want to add more levels, simply copy/paste this line (in the Setup trigger),
                                                                         // go inside the trigger and chaneg +3 to +4. Keep increasing the valye and changing
                                                                         // the string name to the desired lightning effect and the system should handle the
                                                                         // switch between lightning effects as the levels increase and decrease. Make sure to
                                                                         // set VR_MaxLevel[UDex] to number of upgrades + 1. Eg, the demo Sphinx's beam will upgrade
                                                                         // twice, and so it's VR_MaxLevel[UDex] is 3.

Void Ray Setup

Void Ray Stop

Void Ray Start

Void Ray Damage

  • Void Ray Setup
    • Events
      • Game - UnitIndexEvent becomes Equal to 1.00
      • Game - UnitIndexEvent becomes Equal to 2.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • UnitIndexEvent Equal to 1.00
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of UDexUnits[UDex]) Equal to Sphinx
            • Then - Actions
              • Set VR_IsAVoidRay[UDex] = True
              • Set VR_MaxLevel[UDex] = 3
              • Set VR_UpgradeThreshold[UDex] = 99
              • Set VR_DowngradeThreshold[UDex] = 165
              • Set VR_PercentageBonusPerLevel[UDex] = 1.00
              • -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
              • -------- Setup your Levels here. If you wish to add more levels, change the + 1 at the end of the array to a higher number --------
              • Set VR_LevelString[((UDex x VR_MaxLevel[UDex]) + 1)] = SLTB
              • Set VR_LevelString[((UDex x VR_MaxLevel[UDex]) + 2)] = SLPB
              • Set VR_LevelString[((UDex x VR_MaxLevel[UDex]) + 3)] = CLPB
              • -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
              • Set VR_CurrentLevel[UDex] = 1
            • Else - Actions
        • Else - Actions
          • Set VR_IsAVoidRay[UDex] = False
          • Set VR_MaxLevel[UDex] = 0
          • Set VR_UpgradeThreshold[UDex] = 0
          • Set VR_DowngradeThreshold[UDex] = 0
          • Set VR_PercentageBonusPerLevel[UDex] = 1.00
          • For each (Integer VR_Loop) from 1 to VR_MaxLevel[UDex], do (Actions)
            • Loop - Actions
              • Set VR_LevelString[((UDex x VR_MaxLevel[UDex]) + VR_Loop)] = <Empty String>
JASS:
function Trig_Void_Ray_Stop_Actions takes nothing returns nothing
    
    local unit u = null
    local integer ID = 0
    local string beam = ""
    local boolean array b
    
    call BJDebugMsg("test")
    
    loop
        set u = FirstOfGroup(udg_VR_MainGroup)
        exitwhen u == null
        
        call GroupRemoveUnit(udg_VR_MainGroup, u)
        call GroupAddUnit(udg_VR_TempGroup, u)
            
        set ID = GetUnitUserData(u)
        set udg_VR_Interval[ID] = udg_VR_Interval[ID] + 1
        
        if udg_VR_Interval[ID] >= udg_VR_DowngradeThreshold[ID] then
            set udg_VR_Interval[ID] = 0
            set udg_VR_CurrentLevel[ID] = udg_VR_CurrentLevel[ID] - 1
            
            set beam = udg_VR_LevelString[(ID * udg_VR_MaxLevel[ID]) + udg_VR_CurrentLevel[ID]]
            if beam != null then
                set udg_BeamConfig_BeamType[ID] = beam
            endif
            
            if udg_VR_CurrentLevel[ID] <= 1 then
                set udg_VR_CurrentLevel[ID] = 1
                set b[ID] = true
            endif
        endif
        
    endloop
    
    loop
        set u = FirstOfGroup(udg_VR_TempGroup)
        exitwhen u == null
        
        set ID = GetUnitUserData(u)
        
        if not b[ID] then
            call GroupAddUnit(udg_VR_MainGroup, u)
        endif
        
        call GroupRemoveUnit(udg_VR_TempGroup, u)
    endloop
    
    if FirstOfGroup(udg_VR_MainGroup) == null then
        call DisableTrigger( GetTriggeringTrigger() )
    endif
    
endfunction

//===========================================================================
function InitTrig_Void_Ray_Stop takes nothing returns nothing
    set gg_trg_Void_Ray_Stop = CreateTrigger(  )
    call DisableTrigger( gg_trg_Void_Ray_Stop )
    //call TriggerRegisterTimerEventPeriodic( gg_trg_Void_Ray_Stop, 0.03 )
    call TriggerRegisterTimerEvent( gg_trg_Void_Ray_Stop, 0.03, true)
    call TriggerAddAction( gg_trg_Void_Ray_Stop, function Trig_Void_Ray_Stop_Actions )
endfunction
  • Void Ray Start
    • Events
      • Game - BeamEvent becomes Equal to 1.00
      • Game - BeamEvent becomes Equal to 2.50
      • Game - BeamEvent becomes Equal to 4.00
    • Conditions
    • Actions
      • Custom script: local string beam
      • Custom script: local real x1 = GetUnitX(udg_BeamEvent_Caster)
      • Custom script: local real y1 = GetUnitY(udg_BeamEvent_Caster)
      • Custom script: local real z1 = GetUnitFlyHeight(udg_BeamEvent_Caster)
      • Custom script: local real x2 = GetUnitX(udg_BeamEvent_Mover)
      • Custom script: local real y2 = GetUnitY(udg_BeamEvent_Mover)
      • Custom script: local real z2 = GetUnitFlyHeight(udg_BeamEvent_Mover)
      • Set VR_ID = (Custom value of BeamEvent_Source)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • VR_IsAVoidRay[VR_ID] Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • BeamEvent Equal to 1.00
              • (BeamEvent_Source is in VR_MainGroup) Equal to True
            • Then - Actions
              • Set VR_Interval[VR_ID] = 0
              • Unit Group - Remove BeamEvent_Source from VR_MainGroup
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • BeamEvent Equal to 2.50
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • VR_CurrentLevel[VR_ID] Less than VR_MaxLevel[VR_ID]
                    • Then - Actions
                      • Set VR_Interval[VR_ID] = (VR_Interval[VR_ID] + 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • VR_Interval[VR_ID] Greater than or equal to VR_UpgradeThreshold[VR_ID]
                        • Then - Actions
                          • Set VR_Interval[VR_ID] = 0
                          • Set VR_CurrentLevel[VR_ID] = (VR_CurrentLevel[VR_ID] + 1)
                          • Custom script: set beam = udg_VR_LevelString[(udg_VR_ID * udg_VR_MaxLevel[udg_VR_ID]) + udg_VR_CurrentLevel[udg_VR_ID]]
                          • Custom script: if beam != null then
                          • Custom script: if udg_BeamLightning[udg_VR_ID] != null then
                          • Custom script: call DestroyLightning(udg_BeamLightning[udg_VR_ID])
                          • Custom script: set udg_BeamLightning[udg_VR_ID] = null
                          • Custom script: endif
                          • Custom script: set udg_BeamLightning[udg_VR_ID] = AddLightningEx(beam, true, x1, y1, z1, x2, y2, z2)
                          • Custom script: set udg_BeamConfig_BeamType[udg_VR_ID] = beam
                          • Custom script: endif
                        • Else - Actions
                    • Else - Actions
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • BeamEvent Equal to 4.00
                    • Then - Actions
                      • Set VR_Interval[VR_ID] = 0
                      • Unit Group - Add BeamEvent_Source to VR_MainGroup
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Void Ray Stop <gen> is on) Equal to False
                        • Then - Actions
                          • Trigger - Turn on Void Ray Stop <gen>
                        • Else - Actions
                    • Else - Actions
        • Else - Actions
  • Void Ray Damage
    • Events
      • Game - DamageModifierEvent becomes Equal to 1.00
    • Conditions
      • DamageEventType Equal to DamageTypeBeam
      • IsDamageSpell Equal to False
      • VR_IsAVoidRay[(Custom value of DamageEventSource)] Equal to True
      • VR_CurrentLevel[(Custom value of DamageEventSource)] Greater than 0
    • Actions
      • Set DamageEventAmount = (DamageEventAmount x (VR_PercentageBonusPerLevel[VR_ID] x (Real(VR_CurrentLevel[VR_ID]))))
Keywords:
Beam, Void Ray, Laser, Starcraft
Contents

Void Ray v1.4 (Map)

Reviews
10:50, 14th Nov 2015 BPower: A nice demonstration of how to make use of your Persistent Beam system. Persistant Beam is already approved and the Void Ray code seems good to me.

Moderator

M

Moderator

10:50, 14th Nov 2015
BPower: A nice demonstration of how to make use of
your Persistent Beam system.
Persistant Beam is already approved and the Void Ray code seems good to me.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Instead of

JASS:
if udg_VR_CurrentTier[ID] == 1 then
                    set udg_BeamConfig_BeamType[ID] = udg_VR_Tier1[ID]
                else
                    if udg_VR_CurrentTier[ID] == 2 then
                        set udg_BeamConfig_BeamType[ID] = udg_VR_Tier2[ID]
                    endif
endif

// it is

if cond1 then
    dostuff
elseif cond2 then
    dootherstuff
//you can have unlimited elseif statements. 
endif

Also, is there no way to streamline that stuff? You have a lot of duplicate code. Maybe you should use 2D arrays instead of duplicate arrays to avoid that mess.
 
A normal array has 1 index operator (myArr[x]) while 2D arrays has 2 index operators (myArr[x][y]). Unfortunately wc3 doesn't support 2D arrays. I think there are some vJass libraries that help you to create 2D arrays.

It is possible to put units in a 2D array with a unit indexer:
unit_column[unit custom value] = 3
unit_row[unit custom value] = 5

that will put a unit in the 4th column at the 6th row. I never delt with 2D arrays without units so I haven't figred that out... yet :p

Another method is to divide an array into sections. Lets say you have an array with 42 slots. If you divide it by 7, you get 6. That will give you a 7x6 table. to access cell (3;5), write 3*X + 5 where X is the amount of columns (7) and Y is the amount of Rows (6).
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
JASS:
    set u = FirstOfGroup(udg_VR_MainGroup)
    if u == null then
        call DisableTrigger( GetTriggeringTrigger() )
    else
        set u = null
    endif

// ->

if FirstOfGroup(udg_VR_MainGroup) == null then
    call DisableTrigger( GetTriggeringTrigger() )
endif

I still recommend moving the Damage conditions in the if-block to the actual trigger conditions, because conditions run faster than actions.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
Well your damage trigger now doesn't work as VRID isn't set.

Just move the ones that need the custom value into the normal if-block, and leave the 2 that are ambiguous in the conditions block. I think you read my first post before I edited it:

Edit: Also, in the damage trigger, move the beam damage type check to the conditions and do the same with the IsDamageSpell check.
 
Last edited:
Level 19
Joined
Mar 18, 2012
Messages
1,716
With the demo setup for Void Ray, the system only works until UDex ~2970. Seems ok to me.
I someone indexes more units then thread registered to the on index trigger will not run.

if b[ID] == false then in your stop trigger could be if not b[ID] then

Nice usage of your persistent beam system.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
It's a disabled line; nothing broken. You had to enable the line that says "DmgEvUnit is a structure Equal to False" for it to no longer show red, but that was just an example of what linds of things you can disallow from being detectable for damage. So by enabling something because you thought it was broken, you actually broke somethin.

One may not like the way it looks with the red banner on the trigger, but it doesn't mean it's broken.

There are probably other lines which you enabled. All of those needed to stay disabled, otherwise not everything will work properly. I updated Damage Engine recently, so since you'll likely need to re-copy it to repair that stuff you may want to take the opportunity to get the most up-to-date version. http://www.hiveworkshop.com/forums/spells-569/gui-damage-engine-v3-6-0-1-a-201016/
 
Top