• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

How To Make Riot Bar

Status
Not open for further replies.
Level 3
Joined
Feb 13, 2020
Messages
24
Now I want to make every human race player has a status bar of happyness. every 10 sec It's gonna decay as 1, while every kill of certain units It'll raise to 5 etc etc. when that happyness bar below to %70 3 random units riot etc etc %50 6 random units riot every 20 min and so on... I can make few things on that system but I think I'll need help to detecting and showing the bar by game. Any Ideas how to do it?
 
Now I want to make every human race player has a status bar of happyness. every 10 sec It's gonna decay as 1, while every kill of certain units It'll raise to 5 etc etc. when that happyness bar below to %70 3 random units riot etc etc %50 6 random units riot every 20 min and so on... I can make few things on that system but I think I'll need help to detecting and showing the bar by game. Any Ideas how to do it?
One easy way of having a bar is to have several dots in a floating text and shift where the color is. Say it's green and gray and each dot represents 4% or something, you'll have 25 dots. Should look decent.

I have a charge-up attack using this way of indicating current level and it lookes like this:
1626099239689.png

I do this by having a string with the "max amount of dots" like this (|c<color>.........................), with a color-indicator at the start, substring to the "correct level", put a the next color indicator (in this example a "color-reset" |r) with as many dots, then substring to correct length.

JASS:
function RiotText takes integer currentPercent returns string
    local string indicatorDots = "........................."
    local integer percentToDots = currentPercent / 4
    local string indicatorText = "|c003C14DC" + SubString(indicatorDots, 0, percentToDots + 1) + "|r"
    return indicatorText + SubString(indicatorDots, percentToDots, StringLength(indicatorDots))
endfunction

Do you get the idea?

The "currentPecent" parameter is basically number between 0-100, we calculate number of colored dots from it ("percentToDots").
We first set the "indicatorText" to the total number of dots, add color and "pick out" number of blue dots, then add "remaining" number of dots to the "indicatorText"

Call it from a GUI-trigger

  • Custom script: set udg_temp_string = RiotText(udg_percentInteger)
  • Floating Text - Change text of riot_floating_texts[(Player number of (Triggering player))] to temp_string using font size 9.00
You'll need to setup the riot_cloating_texts before doing this (create them, set their position etc.), and have a string-variable called "temp_string".
I index these with player number of Triggering player, but that should probably be something else...
 
Level 3
Joined
Feb 13, 2020
Messages
24
well... ya know... I don't know jass yet haven't learned it but I got the idea. the problem is that bar doesn't have to be near units or something fancy. All I need a right top of selection where It'll show the percentage of total morale of race. might be bar too but It's totally optional. like I said the real point of that is understandable by player. ya know something like human campaing in reign of chaos/heartglen where It was showing the time limit of game? yea something like that but Instead It'll show just 100/100 thing. hope I clearly explained myself.
 
Level 12
Joined
May 16, 2020
Messages
660
@ThompZon Would you mind adding an example code for using this system in a timer please?

I want to use your suggestions to add some indicators to channeled spells that have a trigger running "every 0.03 seconds", but have troubles understanding how your code above works.
([Solved] - Parabola in GUI (don't know how to adjust X and Y of Point))

  • Blaze Loop
    • Events
      • Time - AA_Timer expires
    • Conditions
    • Actions
      • For each (Integer AA_Integer) from 1 to AA_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet AA_Counter[AA_Integer] = (AA_Counter[AA_Integer] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Counter[AA_Integer] Less than AA_CounterMax[AA_Integer]
              • (AA_Counter[AA_Integer] mod 2) Equal to 0
            • Then - Actions
              • Set VariableSet AA_PointTemp = (AA_PointTarget[AA_Integer] offset by (Random real number between 0.00 and 200.00) towards (Random angle) degrees.)
              • -------- --------
              • -------- BASE SETTINGS --------
              • Set VariableSet AA_Index2 = (AA_Index2 + 1)
              • Set VariableSet AA_Angle[AA_Index2] = (Radians((Angle from AA_PointOrigin[AA_Integer] to AA_PointTemp)))
              • Set VariableSet AA_Speed[AA_Index2] = 25.00
              • Set VariableSet AA_DistanceReached[AA_Index2] = 0.00
              • Set VariableSet AA_DistanceMax[AA_Index2] = (Distance between AA_PointOrigin[AA_Integer] and AA_PointTemp)
              • -------- HEIGHT --------
              • Set VariableSet AA_HeigthAdjustor[AA_Index2] = (Random real number between 0.10 and 0.30)
              • Set VariableSet AA_HeightReal[AA_Index2] = (AA_DistanceMax[AA_Index2] x AA_HeigthAdjustor[AA_Index2])
              • Set VariableSet AA_HeightDegree[AA_Index2] = 0.00
              • -------- --------
              • -------- X and Y AXIS --------
              • Special Effect - Create a special effect at AA_PointOrigin[AA_Integer] using Abilities\Weapons\FireBallMissile\FireBallMissile.mdl
              • Set VariableSet AA_SFX[AA_Index2] = (Last created special effect)
              • Special Effect - Set Yaw of AA_SFX[AA_Index2] to: (AA_Angle[AA_Index2] x (Pi / 180.00))
              • -------- --------
              • Set VariableSet AA_Adjustor = (Random real number between -15.00 and 15.00)
              • Set VariableSet AA_cX[AA_Index2] = (X of AA_PointOrigin[AA_Integer])
              • Set VariableSet AA_cY[AA_Index2] = (Y of AA_PointOrigin[AA_Integer])
              • Set VariableSet AA_prevX[AA_Index2] = AA_cX[AA_Index2]
              • Set VariableSet AA_prevY[AA_Index2] = AA_cY[AA_Index2]
              • Custom script: set udg_AA_curve[udg_AA_Index2] = Tan(udg_AA_Adjustor * bj_DEGTORAD) * udg_AA_DistanceMax[udg_AA_Index2]
              • -------- --------
              • Custom script: call RemoveLocation(udg_AA_PointTemp)
            • Else - Actions
          • -------- --------
          • For each (Integer AA_Integer2) from 1 to AA_Index2, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_DistanceReached[AA_Integer2] Less than AA_DistanceMax[AA_Integer2]
                • Then - Actions
                  • Set VariableSet AA_DistanceReached[AA_Integer2] = (AA_DistanceReached[AA_Integer2] + AA_Speed[AA_Integer2])
                  • -------- --------
                  • -------- HEIGHT --------
                  • Set VariableSet AA_HeightDegree[AA_Integer2] = (AA_HeightDegree[AA_Integer2] + (180.00 / (AA_DistanceMax[AA_Integer2] / AA_Speed[AA_Integer2])))
                  • Set VariableSet AA_HeightReached[AA_Integer2] = ((Sin(AA_HeightDegree[AA_Integer2])) x AA_HeightReal[AA_Integer2])
                  • -------- --------
                  • -------- X and Y AXIS --------
                  • Custom script: set udg_AA_cX[udg_AA_Integer2] = udg_AA_prevX[udg_AA_Integer2] + udg_AA_Speed[udg_AA_Integer2] * Cos(udg_AA_Angle[udg_AA_Integer2])
                  • Custom script: set udg_AA_cY[udg_AA_Integer2] = udg_AA_prevY[udg_AA_Integer2] + udg_AA_Speed[udg_AA_Integer2] * Sin(udg_AA_Angle[udg_AA_Integer2])
                  • Set VariableSet AA_prevX[AA_Integer2] = AA_cX[AA_Integer2]
                  • Set VariableSet AA_prevY[AA_Integer2] = AA_cY[AA_Integer2]
                  • Custom script: set udg_AA_curveOffset = 4 * udg_AA_curve[udg_AA_Integer2] * udg_AA_DistanceReached[udg_AA_Integer2] * (udg_AA_DistanceMax[udg_AA_Integer2]-udg_AA_DistanceReached[udg_AA_Integer2]) / (udg_AA_DistanceMax[udg_AA_Integer2] * udg_AA_DistanceMax[udg_AA_Integer2])
                  • Custom script: set udg_AA_cX[udg_AA_Integer2] = udg_AA_cX[udg_AA_Integer2] + udg_AA_curveOffset * Cos(udg_AA_Angle[udg_AA_Integer2] + bj_PI / 2.0)
                  • Custom script: set udg_AA_cY[udg_AA_Integer2] = udg_AA_cY[udg_AA_Integer2] + udg_AA_curveOffset * Sin(udg_AA_Angle[udg_AA_Integer2] + bj_PI / 2.0)
                  • Custom script: set udg_AA_cYaw = udg_AA_Angle[udg_AA_Integer2] + Atan(-((4 * udg_AA_curve[udg_AA_Integer2]) * (2 * udg_AA_DistanceReached[udg_AA_Integer2] - udg_AA_DistanceMax[udg_AA_Integer2])) / (udg_AA_DistanceMax[udg_AA_Integer2] * udg_AA_DistanceMax[udg_AA_Integer2]))
                  • -------- --------
                  • Special Effect - Set Position of AA_SFX[AA_Integer2] to x: AA_cX[AA_Integer2], y: AA_cY[AA_Integer2], z: AA_HeightReached[AA_Integer2]
                  • Special Effect - Set Orientation of AA_SFX[AA_Integer2] to yaw: AA_cYaw, pitch: 0.00, roll: 0.00
                • Else - Actions
                  • Special Effect - Destroy AA_SFX[AA_Integer2]
                  • Set VariableSet AA_PointTemp = (AA_PointOrigin[AA_Integer] offset by AA_DistanceMax[AA_Integer2] towards (Degrees(AA_Angle[AA_Integer2])) degrees.)
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within 100.00 of AA_PointTemp.) and do (Actions)
                    • Loop - Actions
                      • Set VariableSet AA_Unit = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (AA_Unit is alive) Equal to True
                          • (AA_Unit is A structure) Equal to False
                          • (AA_Unit belongs to an enemy of (Owner of AA_Caster[AA_Integer]).) Equal to True
                        • Then - Actions
                          • Unit - Cause AA_Caster[AA_Integer] to damage AA_Unit, dealing AA_Damage[AA_Integer] damage of attack type Spells and damage type Magic
                        • Else - Actions
                  • Custom script: call RemoveLocation(udg_AA_PointTemp)
                  • -------- --------
                  • Set VariableSet AA_Angle[AA_Integer2] = AA_Angle[AA_Index2]
                  • Set VariableSet AA_Speed[AA_Integer2] = AA_Speed[AA_Index2]
                  • Set VariableSet AA_DistanceReached[AA_Integer2] = AA_DistanceReached[AA_Index2]
                  • Set VariableSet AA_DistanceMax[AA_Integer2] = AA_DistanceMax[AA_Index2]
                  • Set VariableSet AA_HeigthAdjustor[AA_Integer2] = AA_HeigthAdjustor[AA_Index2]
                  • Set VariableSet AA_HeightReal[AA_Integer2] = AA_HeightReal[AA_Index2]
                  • Set VariableSet AA_HeightDegree[AA_Integer2] = AA_HeightDegree[AA_Index2]
                  • Set VariableSet AA_SFX[AA_Integer2] = AA_SFX[AA_Index2]
                  • Set VariableSet AA_cX[AA_Integer2] = AA_cX[AA_Index2]
                  • Set VariableSet AA_cY[AA_Integer2] = AA_cY[AA_Index2]
                  • Set VariableSet AA_prevX[AA_Integer2] = AA_prevX[AA_Index2]
                  • Set VariableSet AA_prevY[AA_Integer2] = AA_prevY[AA_Index2]
                  • Set VariableSet AA_curve[AA_Integer2] = AA_curve[AA_Index2]
                  • -------- --------
                  • Set VariableSet AA_Index2 = (AA_Index2 - 1)
                  • Set VariableSet AA_Integer2 = (AA_Integer2 - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AA_Index2 Equal to 0
                    • Then - Actions
                      • -------- TBD? --------
                    • Else - Actions
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Counter[AA_Integer] Greater than or equal to AA_CounterMax[AA_Integer]
              • AA_Index2 Equal to 0
            • Then - Actions
              • Custom script: call RemoveLocation(udg_AA_PointOrigin[udg_AA_Integer])
              • Custom script: call RemoveLocation(udg_AA_PointTarget[udg_AA_Integer])
              • -------- --------
              • Set VariableSet AA_Caster[AA_Integer] = AA_Caster[AA_Index]
              • Set VariableSet AA_Counter[AA_Integer] = AA_Counter[AA_Index]
              • Set VariableSet AA_CounterMax[AA_Integer] = AA_CounterMax[AA_Index]
              • Set VariableSet AA_PointOrigin[AA_Integer] = AA_PointOrigin[AA_Index]
              • Set VariableSet AA_PointTarget[AA_Integer] = AA_PointTarget[AA_Index]
              • Set VariableSet AA_Damage[AA_Integer] = AA_Damage[AA_Index]
              • -------- --------
              • Set VariableSet AA_Index = (AA_Index - 1)
              • Set VariableSet AA_Integer = (AA_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_Index Equal to 0
                • Then - Actions
                  • Game - Display to (All players) the text: OFF
                  • Countdown Timer - Pause AA_Timer
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
 
@ThompZon Would you mind adding an example code for using this system in a timer please?

I want to use your suggestions to add some indicators to channeled spells that have a trigger running "every 0.03 seconds", but have troubles understanding how your code above works.
([Solved] - Parabola in GUI (don't know how to adjust X and Y of Point))

  • Blaze Loop
    • Events
      • Time - AA_Timer expires
    • Conditions
    • Actions
      • For each (Integer AA_Integer) from 1 to AA_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet AA_Counter[AA_Integer] = (AA_Counter[AA_Integer] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Counter[AA_Integer] Less than AA_CounterMax[AA_Integer]
              • (AA_Counter[AA_Integer] mod 2) Equal to 0
            • Then - Actions
              • Set VariableSet AA_PointTemp = (AA_PointTarget[AA_Integer] offset by (Random real number between 0.00 and 200.00) towards (Random angle) degrees.)
              • -------- --------
              • -------- BASE SETTINGS --------
              • Set VariableSet AA_Index2 = (AA_Index2 + 1)
              • Set VariableSet AA_Angle[AA_Index2] = (Radians((Angle from AA_PointOrigin[AA_Integer] to AA_PointTemp)))
              • Set VariableSet AA_Speed[AA_Index2] = 25.00
              • Set VariableSet AA_DistanceReached[AA_Index2] = 0.00
              • Set VariableSet AA_DistanceMax[AA_Index2] = (Distance between AA_PointOrigin[AA_Integer] and AA_PointTemp)
              • -------- HEIGHT --------
              • Set VariableSet AA_HeigthAdjustor[AA_Index2] = (Random real number between 0.10 and 0.30)
              • Set VariableSet AA_HeightReal[AA_Index2] = (AA_DistanceMax[AA_Index2] x AA_HeigthAdjustor[AA_Index2])
              • Set VariableSet AA_HeightDegree[AA_Index2] = 0.00
              • -------- --------
              • -------- X and Y AXIS --------
              • Special Effect - Create a special effect at AA_PointOrigin[AA_Integer] using Abilities\Weapons\FireBallMissile\FireBallMissile.mdl
              • Set VariableSet AA_SFX[AA_Index2] = (Last created special effect)
              • Special Effect - Set Yaw of AA_SFX[AA_Index2] to: (AA_Angle[AA_Index2] x (Pi / 180.00))
              • -------- --------
              • Set VariableSet AA_Adjustor = (Random real number between -15.00 and 15.00)
              • Set VariableSet AA_cX[AA_Index2] = (X of AA_PointOrigin[AA_Integer])
              • Set VariableSet AA_cY[AA_Index2] = (Y of AA_PointOrigin[AA_Integer])
              • Set VariableSet AA_prevX[AA_Index2] = AA_cX[AA_Index2]
              • Set VariableSet AA_prevY[AA_Index2] = AA_cY[AA_Index2]
              • Custom script: set udg_AA_curve[udg_AA_Index2] = Tan(udg_AA_Adjustor * bj_DEGTORAD) * udg_AA_DistanceMax[udg_AA_Index2]
              • -------- --------
              • Custom script: call RemoveLocation(udg_AA_PointTemp)
            • Else - Actions
          • -------- --------
          • For each (Integer AA_Integer2) from 1 to AA_Index2, do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_DistanceReached[AA_Integer2] Less than AA_DistanceMax[AA_Integer2]
                • Then - Actions
                  • Set VariableSet AA_DistanceReached[AA_Integer2] = (AA_DistanceReached[AA_Integer2] + AA_Speed[AA_Integer2])
                  • -------- --------
                  • -------- HEIGHT --------
                  • Set VariableSet AA_HeightDegree[AA_Integer2] = (AA_HeightDegree[AA_Integer2] + (180.00 / (AA_DistanceMax[AA_Integer2] / AA_Speed[AA_Integer2])))
                  • Set VariableSet AA_HeightReached[AA_Integer2] = ((Sin(AA_HeightDegree[AA_Integer2])) x AA_HeightReal[AA_Integer2])
                  • -------- --------
                  • -------- X and Y AXIS --------
                  • Custom script: set udg_AA_cX[udg_AA_Integer2] = udg_AA_prevX[udg_AA_Integer2] + udg_AA_Speed[udg_AA_Integer2] * Cos(udg_AA_Angle[udg_AA_Integer2])
                  • Custom script: set udg_AA_cY[udg_AA_Integer2] = udg_AA_prevY[udg_AA_Integer2] + udg_AA_Speed[udg_AA_Integer2] * Sin(udg_AA_Angle[udg_AA_Integer2])
                  • Set VariableSet AA_prevX[AA_Integer2] = AA_cX[AA_Integer2]
                  • Set VariableSet AA_prevY[AA_Integer2] = AA_cY[AA_Integer2]
                  • Custom script: set udg_AA_curveOffset = 4 * udg_AA_curve[udg_AA_Integer2] * udg_AA_DistanceReached[udg_AA_Integer2] * (udg_AA_DistanceMax[udg_AA_Integer2]-udg_AA_DistanceReached[udg_AA_Integer2]) / (udg_AA_DistanceMax[udg_AA_Integer2] * udg_AA_DistanceMax[udg_AA_Integer2])
                  • Custom script: set udg_AA_cX[udg_AA_Integer2] = udg_AA_cX[udg_AA_Integer2] + udg_AA_curveOffset * Cos(udg_AA_Angle[udg_AA_Integer2] + bj_PI / 2.0)
                  • Custom script: set udg_AA_cY[udg_AA_Integer2] = udg_AA_cY[udg_AA_Integer2] + udg_AA_curveOffset * Sin(udg_AA_Angle[udg_AA_Integer2] + bj_PI / 2.0)
                  • Custom script: set udg_AA_cYaw = udg_AA_Angle[udg_AA_Integer2] + Atan(-((4 * udg_AA_curve[udg_AA_Integer2]) * (2 * udg_AA_DistanceReached[udg_AA_Integer2] - udg_AA_DistanceMax[udg_AA_Integer2])) / (udg_AA_DistanceMax[udg_AA_Integer2] * udg_AA_DistanceMax[udg_AA_Integer2]))
                  • -------- --------
                  • Special Effect - Set Position of AA_SFX[AA_Integer2] to x: AA_cX[AA_Integer2], y: AA_cY[AA_Integer2], z: AA_HeightReached[AA_Integer2]
                  • Special Effect - Set Orientation of AA_SFX[AA_Integer2] to yaw: AA_cYaw, pitch: 0.00, roll: 0.00
                • Else - Actions
                  • Special Effect - Destroy AA_SFX[AA_Integer2]
                  • Set VariableSet AA_PointTemp = (AA_PointOrigin[AA_Integer] offset by AA_DistanceMax[AA_Integer2] towards (Degrees(AA_Angle[AA_Integer2])) degrees.)
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within 100.00 of AA_PointTemp.) and do (Actions)
                    • Loop - Actions
                      • Set VariableSet AA_Unit = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (AA_Unit is alive) Equal to True
                          • (AA_Unit is A structure) Equal to False
                          • (AA_Unit belongs to an enemy of (Owner of AA_Caster[AA_Integer]).) Equal to True
                        • Then - Actions
                          • Unit - Cause AA_Caster[AA_Integer] to damage AA_Unit, dealing AA_Damage[AA_Integer] damage of attack type Spells and damage type Magic
                        • Else - Actions
                  • Custom script: call RemoveLocation(udg_AA_PointTemp)
                  • -------- --------
                  • Set VariableSet AA_Angle[AA_Integer2] = AA_Angle[AA_Index2]
                  • Set VariableSet AA_Speed[AA_Integer2] = AA_Speed[AA_Index2]
                  • Set VariableSet AA_DistanceReached[AA_Integer2] = AA_DistanceReached[AA_Index2]
                  • Set VariableSet AA_DistanceMax[AA_Integer2] = AA_DistanceMax[AA_Index2]
                  • Set VariableSet AA_HeigthAdjustor[AA_Integer2] = AA_HeigthAdjustor[AA_Index2]
                  • Set VariableSet AA_HeightReal[AA_Integer2] = AA_HeightReal[AA_Index2]
                  • Set VariableSet AA_HeightDegree[AA_Integer2] = AA_HeightDegree[AA_Index2]
                  • Set VariableSet AA_SFX[AA_Integer2] = AA_SFX[AA_Index2]
                  • Set VariableSet AA_cX[AA_Integer2] = AA_cX[AA_Index2]
                  • Set VariableSet AA_cY[AA_Integer2] = AA_cY[AA_Index2]
                  • Set VariableSet AA_prevX[AA_Integer2] = AA_prevX[AA_Index2]
                  • Set VariableSet AA_prevY[AA_Integer2] = AA_prevY[AA_Index2]
                  • Set VariableSet AA_curve[AA_Integer2] = AA_curve[AA_Index2]
                  • -------- --------
                  • Set VariableSet AA_Index2 = (AA_Index2 - 1)
                  • Set VariableSet AA_Integer2 = (AA_Integer2 - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • AA_Index2 Equal to 0
                    • Then - Actions
                      • -------- TBD? --------
                    • Else - Actions
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • AA_Counter[AA_Integer] Greater than or equal to AA_CounterMax[AA_Integer]
              • AA_Index2 Equal to 0
            • Then - Actions
              • Custom script: call RemoveLocation(udg_AA_PointOrigin[udg_AA_Integer])
              • Custom script: call RemoveLocation(udg_AA_PointTarget[udg_AA_Integer])
              • -------- --------
              • Set VariableSet AA_Caster[AA_Integer] = AA_Caster[AA_Index]
              • Set VariableSet AA_Counter[AA_Integer] = AA_Counter[AA_Index]
              • Set VariableSet AA_CounterMax[AA_Integer] = AA_CounterMax[AA_Index]
              • Set VariableSet AA_PointOrigin[AA_Integer] = AA_PointOrigin[AA_Index]
              • Set VariableSet AA_PointTarget[AA_Integer] = AA_PointTarget[AA_Index]
              • Set VariableSet AA_Damage[AA_Integer] = AA_Damage[AA_Index]
              • -------- --------
              • Set VariableSet AA_Index = (AA_Index - 1)
              • Set VariableSet AA_Integer = (AA_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • AA_Index Equal to 0
                • Then - Actions
                  • Game - Display to (All players) the text: OFF
                  • Countdown Timer - Pause AA_Timer
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
I changed it to fit his use-case better, but for simplicity, I use "how I use it" for this example.
First I have a trigger somewhere (above the "actual trigger") with this util function:
JASS:
//Max dots must be less than 25, or increase number of dots in "indicatorDots" variable to have a higher max.
function ChargeString takes integer currentDots, integer maxDots returns string
    local string indicatorDots = "........................."
    local string indicatorText = "|c003C14DC" + SubString(indicatorDots, 0, currentDots + 1) + "|r"
    return SubString(indicatorText + SubString(indicatorDots, currentDots, StringLength(indicatorDots)), 0, 13 + maxDots) //12 chars for color-code + reset, then + 1, because index thingies...
endfunction

What it does is make first "currentDots" the hard-coded color, then "reset color" and have additional dots up to maxDots. The "|c003C14DC" is just a color and can be changed to your favorite color.

Then use it to charge up, and update a floating text, you need an integer variable that you need to keep track of "current charge" and the floatingtext.
I use a hashtable in this example.

Setup a floating text and save it.
Note that (Key ChargeUpFloatingText) is String hash.
  • TextSetup
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Custom script: set udg_temp_string = ChargeString(0, 20)
      • Floating Text - Create floating text that reads temp_string above (Triggering unit) with Z offset 70.00, using font size 9.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Hashtable - Save Handle Of(Last created floating text) as (Key (Triggering unit)) of (Key ChargeUpFloatingText) in heroes_hash
      • Hashtable - Save 0 as (Key (Triggering unit)) of (Key ChargeUp Value) in heroes_hash
      • Trigger - Turn on TextTick <gen>
Then update it in the "tick" trigger. Update the "charge counter", update the floating text.
Note that I don't have a way of keeping track of the unit with this minimal example, but otherwise MUI (each unit can have one).
  • TextTick
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • Set temp_unit = Bounty Hunter 0158 <gen>
      • Custom script: set udg_temp_integer1 = GetHandleId(udg_temp_unit)
      • Set temp_floating_text = (Load temp_integer1 of (Key ChargeUpFloatingText) in heroes_hashIf the label is not found, this function returns NULL.)
      • Set temp_integer2 = (Load temp_integer1 of (Key ChargeUp Value) from heroes_hash) + 1
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • temp_integer2 Less than 20
        • Then - Actions
          • Hashtable - Save temp_integer2 as temp_integer1 of (Key ChargeUp Value) in heroes_hash
          • Custom script: set udg_temp_string = ChargeString(udg_temp_integer2, 20)
        • Else - Actions
          • Hashtable - Save 0 as temp_integer1 of (Key ChargeUp Value) in heroes_hash
          • Custom script: set udg_temp_string = ChargeString(0, 20)
      • Floating Text - Change text of temp_floating_text to temp_string using font size 9.00
Also note that this example does not keep tracks of what the unit is doing, updates the floating-text-position if unit moves and it "cycles" back to 0 upon reaching the max (20).

Of course, you want to have events if channeling stops, a way of destroying the floating text, etc.

This is my "low-tech bar-system" :p

Was this example good?

Edit: Attached test map (saved with version 1.31.1)
 

Attachments

  • LowTechBar.w3x
    18.2 KB · Views: 9
Last edited:
Level 12
Joined
May 16, 2020
Messages
660
Thank you a lot!

Did a lot of experimentation to see what "style" I like the best, and I think some very small font with high refresh rate looks quite good (but had to increase the dot amount for 5 sec to 84). Also, I changed the hashtable to a dynamic indexing method, since I'm more comfortable with that.

1629059093014.png


But a question: Is there a way that I can only show the channel text to the caster?

JASS:
//Max dots must be less than 33, or increase number of dots in "indicatorDots" variable to have a higher max.
function ChargeString takes integer currentDots, integer maxDots returns string
    local string indicatorDots = "...................................................................................."
    local string indicatorText = "|c00d9ab57" + SubString(indicatorDots, 0, currentDots + 1) + "|r" + SubString(indicatorDots, currentDots, StringLength(indicatorDots))
    return SubString(indicatorText, 0, 13 + maxDots) //12 chars for color-code + reset, then + 1, because index thingies...
endfunction

  • Text Setup Dyn
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set VariableSet A_Index = (A_Index + 1)
      • Set VariableSet A_Caster[A_Index] = (Triggering unit)
      • Set VariableSet A_Point[1] = (Position of A_Caster[A_Index])
      • Set VariableSet A_Point[2] = (A_Point[1] offset by 90.00 towards 180.00 degrees.)
      • Set VariableSet A_Counter[A_Index] = 0
      • -------- 5 sec channel --------
      • Set VariableSet A_Counter_Max[A_Index] = 83
      • Set VariableSet A_Mod[A_Index] = 0
      • -------- --------
      • Custom script: set udg_temp_string = ChargeString(0, udg_A_Counter_Max[udg_A_Index])
      • -------- --------
      • Floating Text - Create floating text that reads temp_string at A_Point[2] with Z offset 95.00, using font size 4.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Set VariableSet A_Text[A_Index] = (Last created floating text)
      • -------- --------
      • Custom script: call RemoveLocation(udg_A_Point[1])
      • Custom script: call RemoveLocation(udg_A_Point[2])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start A_Timer as a Repeating timer that will expire in 0.03 seconds
          • Trigger - Turn on Text Tick Dyn <gen>
        • Else - Actions
  • Text Tick Dyn
    • Events
      • Time - A_Timer expires
    • Conditions
    • Actions
      • For each (Integer A_Integer) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet A_Point[1] = (Position of A_Caster[A_Integer])
          • Set VariableSet A_Point[2] = (A_Point[1] offset by 90.00 towards 180.00 degrees.)
          • Floating Text - Change the position of A_Text[A_Integer] to A_Point[2] with Z offset 95.00
          • Custom script: call RemoveLocation(udg_A_Point[1])
          • Custom script: call RemoveLocation(udg_A_Point[2])
          • -------- --------
          • Set VariableSet A_Mod[A_Integer] = (A_Mod[A_Integer] + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (A_Mod[A_Integer] mod 2) Equal to 0
            • Then - Actions
              • Set VariableSet A_Counter[A_Integer] = (A_Counter[A_Integer] + 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_Counter[A_Integer] Less than or equal to A_Counter_Max[A_Integer]
                • Then - Actions
                  • Custom script: set udg_temp_string = ChargeString(udg_A_Counter[udg_A_Integer], udg_A_Counter_Max[udg_A_Integer])
                  • Floating Text - Change text of A_Text[A_Integer] to temp_string using font size 4.00
                • Else - Actions
                  • Floating Text - Destroy A_Text[A_Integer]
                  • -------- --------
                  • Set VariableSet A_Caster[A_Integer] = A_Caster[A_Index]
                  • Set VariableSet A_Counter[A_Integer] = A_Counter[A_Index]
                  • Set VariableSet A_Counter_Max[A_Integer] = A_Counter_Max[A_Index]
                  • Set VariableSet A_Mod[A_Integer] = A_Mod[A_Index]
                  • Set VariableSet A_Text[A_Integer] = A_Text[A_Index]
                  • -------- --------
                  • Set VariableSet A_Index = (A_Index - 1)
                  • Set VariableSet A_Integer = (A_Integer - 1)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • A_Index Equal to 0
                    • Then - Actions
                      • Game - Display to (All players) the text: OFF
                      • Countdown Timer - Pause A_Timer
                      • Trigger - Turn off (This trigger)
                    • Else - Actions
            • Else - Actions
 

Attachments

  • LowTechBar v2.w3x
    19.2 KB · Views: 9
Level 12
Joined
May 16, 2020
Messages
660
There's a function for showing/hiding floating text. Hide the text then Show it to the desired player.

Thanks Uncle, can you please check the below trigger to check if that is correct? (the 2nd one)

@ThompZon I adjusted the trigger again a bit, and I think now it looks even better than before:

1629122870082.png


The bar is now always the same size (150 blocks), but the speed at which it fills can be adjusted based on the channel time.

Java:
//Max dots must be less than 151, or increase number of dots in "indicatorDots" variable to have a higher max.
function ChargeString takes integer currentDots, integer maxDots returns string
    local string indicatorDots = "lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll"
    local string indicatorText = "|c00d9ab57" + SubString(indicatorDots, 0, currentDots + 1) + "|r" + SubString(indicatorDots, currentDots, StringLength(indicatorDots))
    return SubString(indicatorText, 0, 13 + maxDots) //12 chars for color-code + reset, then + 1, because index thingies...
endfunction

  • Text Setup Dyn
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set VariableSet A_Index = (A_Index + 1)
      • Set VariableSet A_Caster[A_Index] = (Triggering unit)
      • Set VariableSet A_Point[1] = (Position of A_Caster[A_Index])
      • Set VariableSet A_Point[2] = (A_Point[1] offset by 87.00 towards 180.00 degrees.)
      • Set VariableSet A_Counter[A_Index] = 0.00
      • -------- --------
      • -------- SELECT THE CHANNEL TIME, E.G 2 = 2 SECONDS --------
      • Set VariableSet A_ChannelTick[A_Index] = ((150.00 / 2.00) x 0.03)
      • -------- --------
      • Custom script: set udg_temp_string = ChargeString(0, 150)
      • -------- --------
      • Floating Text - Create floating text that reads temp_string at A_Point[2] with Z offset 95.00, using font size 2.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Set VariableSet A_Text[A_Index] = (Last created floating text)
      • Floating Text - Hide A_Text[A_Index] for (All players)
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Floating Text - Show A_Text[A_Index] for (All players matching ((Matching player) Equal to (Owner of A_Caster[A_Index])).)
      • Custom script: endif
      • -------- --------
      • Custom script: call RemoveLocation(udg_A_Point[1])
      • Custom script: call RemoveLocation(udg_A_Point[2])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start A_Timer as a Repeating timer that will expire in 0.03 seconds
          • Trigger - Turn on Text Tick Dyn <gen>
        • Else - Actions
  • Text Tick Dyn
    • Events
      • Time - A_Timer expires
    • Conditions
    • Actions
      • For each (Integer A_Integer) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet A_Point[1] = (Position of A_Caster[A_Integer])
          • Set VariableSet A_Point[2] = (A_Point[1] offset by 87.00 towards 180.00 degrees.)
          • Floating Text - Change the position of A_Text[A_Integer] to A_Point[2] with Z offset 95.00
          • Custom script: call RemoveLocation(udg_A_Point[1])
          • Custom script: call RemoveLocation(udg_A_Point[2])
          • -------- --------
          • Set VariableSet A_Counter[A_Integer] = (A_Counter[A_Integer] + A_ChannelTick[A_Integer])
          • Set VariableSet A_CounterInteger = (Integer(A_Counter[A_Integer]))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • A_CounterInteger Less than or equal to 150
            • Then - Actions
              • Custom script: set udg_temp_string = ChargeString(udg_A_CounterInteger, 150)
              • Floating Text - Change text of A_Text[A_Integer] to temp_string using font size 2.00
            • Else - Actions
              • Floating Text - Destroy A_Text[A_Integer]
              • -------- --------
              • Set VariableSet A_Caster[A_Integer] = A_Caster[A_Index]
              • Set VariableSet A_Counter[A_Integer] = A_Counter[A_Index]
              • Set VariableSet A_ChannelTick[A_Integer] = A_ChannelTick[A_Index]
              • Set VariableSet A_Text[A_Integer] = A_Text[A_Index]
              • -------- --------
              • Set VariableSet A_Index = (A_Index - 1)
              • Set VariableSet A_Integer = (A_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_Index Equal to 0
                • Then - Actions
                  • Game - Display to (All players) the text: OFF
                  • Countdown Timer - Pause A_Timer
                  • Trigger - Turn off (This trigger)
                • Else - Actions
 

Attachments

  • LowTechBar v3.w3x
    20.2 KB · Views: 11

Uncle

Warcraft Moderator
Level 65
Joined
Aug 10, 2018
Messages
6,705
You don't need to check for Local Players. You can Hide/Show floating text for a specific player.

Delete this:
  • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
  • Custom script: endif

And simplify it to this:
  • Floating Text - Show (Last created floating text) for (Player group((Triggering player)))
^ Note that this leaks a Player Group.

Also, you may get some floating point error issues since you're increasing a real (A_Counter). It's value may get rounded down. You can use an Integer to count up the number of Ticks needed to get around this issue.

One last unimportant thing, you don't need to Turn Off/Turn On the trigger since it uses a Timer which can be Paused. That's only necessary for Periodic Interval Events since they don't turn off otherwise.

Everything else looks fine.
 
Last edited:
Thanks Uncle, can you please check the below trigger to check if that is correct? (the 2nd one)

@ThompZon I adjusted the trigger again a bit, and I think now it looks even better than before:

View attachment 385247

The bar is now always the same size (150 blocks), but the speed at which it fills can be adjusted based on the channel time.

Java:
//Max dots must be less than 151, or increase number of dots in "indicatorDots" variable to have a higher max.
function ChargeString takes integer currentDots, integer maxDots returns string
    local string indicatorDots = "lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll"
    local string indicatorText = "|c00d9ab57" + SubString(indicatorDots, 0, currentDots + 1) + "|r" + SubString(indicatorDots, currentDots, StringLength(indicatorDots))
    return SubString(indicatorText, 0, 13 + maxDots) //12 chars for color-code + reset, then + 1, because index thingies...
endfunction

  • Text Setup Dyn
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set VariableSet A_Index = (A_Index + 1)
      • Set VariableSet A_Caster[A_Index] = (Triggering unit)
      • Set VariableSet A_Point[1] = (Position of A_Caster[A_Index])
      • Set VariableSet A_Point[2] = (A_Point[1] offset by 87.00 towards 180.00 degrees.)
      • Set VariableSet A_Counter[A_Index] = 0.00
      • -------- --------
      • -------- SELECT THE CHANNEL TIME, E.G 2 = 2 SECONDS --------
      • Set VariableSet A_ChannelTick[A_Index] = ((150.00 / 2.00) x 0.03)
      • -------- --------
      • Custom script: set udg_temp_string = ChargeString(0, 150)
      • -------- --------
      • Floating Text - Create floating text that reads temp_string at A_Point[2] with Z offset 95.00, using font size 2.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Set VariableSet A_Text[A_Index] = (Last created floating text)
      • Floating Text - Hide A_Text[A_Index] for (All players)
      • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
      • Floating Text - Show A_Text[A_Index] for (All players matching ((Matching player) Equal to (Owner of A_Caster[A_Index])).)
      • Custom script: endif
      • -------- --------
      • Custom script: call RemoveLocation(udg_A_Point[1])
      • Custom script: call RemoveLocation(udg_A_Point[2])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • A_Index Equal to 1
        • Then - Actions
          • Countdown Timer - Start A_Timer as a Repeating timer that will expire in 0.03 seconds
          • Trigger - Turn on Text Tick Dyn <gen>
        • Else - Actions
  • Text Tick Dyn
    • Events
      • Time - A_Timer expires
    • Conditions
    • Actions
      • For each (Integer A_Integer) from 1 to A_Index, do (Actions)
        • Loop - Actions
          • Set VariableSet A_Point[1] = (Position of A_Caster[A_Integer])
          • Set VariableSet A_Point[2] = (A_Point[1] offset by 87.00 towards 180.00 degrees.)
          • Floating Text - Change the position of A_Text[A_Integer] to A_Point[2] with Z offset 95.00
          • Custom script: call RemoveLocation(udg_A_Point[1])
          • Custom script: call RemoveLocation(udg_A_Point[2])
          • -------- --------
          • Set VariableSet A_Counter[A_Integer] = (A_Counter[A_Integer] + A_ChannelTick[A_Integer])
          • Set VariableSet A_CounterInteger = (Integer(A_Counter[A_Integer]))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • A_CounterInteger Less than or equal to 150
            • Then - Actions
              • Custom script: set udg_temp_string = ChargeString(udg_A_CounterInteger, 150)
              • Floating Text - Change text of A_Text[A_Integer] to temp_string using font size 2.00
            • Else - Actions
              • Floating Text - Destroy A_Text[A_Integer]
              • -------- --------
              • Set VariableSet A_Caster[A_Integer] = A_Caster[A_Index]
              • Set VariableSet A_Counter[A_Integer] = A_Counter[A_Index]
              • Set VariableSet A_ChannelTick[A_Integer] = A_ChannelTick[A_Index]
              • Set VariableSet A_Text[A_Integer] = A_Text[A_Index]
              • -------- --------
              • Set VariableSet A_Index = (A_Index - 1)
              • Set VariableSet A_Integer = (A_Integer - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • A_Index Equal to 0
                • Then - Actions
                  • Game - Display to (All players) the text: OFF
                  • Countdown Timer - Pause A_Timer
                  • Trigger - Turn off (This trigger)
                • Else - Actions
Cool. Looks good.
For a channeling bar, this looks better than dots for sure!
If you have an arcade-style charging up attack, dots might look better than "l" for that case :p
 
Level 12
Joined
May 16, 2020
Messages
660
You don't need to check for Local Players. You can Hide/Show floating text for a specific player.

Delete this:
  • Custom script: if GetLocalPlayer() == GetTriggerPlayer() then
  • Custom script: endif

And simplify it to this:
  • Floating Text - Show (Last created floating text) for (Player group((Triggering player)))
^ Note that this leaks a Player Group.

Like this?

  • Floating Text - Create floating text that reads Channel_String at Channel_Point[2] with Z offset 95.00, using font size 2.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
  • Set VariableSet Bl_Text[Bl_Index] = (Last created floating text)
  • Floating Text - Hide Bl_Text[Bl_Index] for (All players)
  • Set VariableSet Global_PlayerGroup = (Player group((Triggering player)))
  • Floating Text - Show Bl_Text[Bl_Index] for Global_PlayerGroup
  • Custom script: call DestroyForce(udg_Global_PlayerGroup)

Also, you may get some floating point error issues since you're increasing a real (A_Counter). It's value may get rounded down. You can use an Integer to count up the number of Ticks needed to get around this issue.

My thinking was: I have 150 "blocks to fill" in for example 2 seconds (2 second channel time). Since my timer works on a 0.03 interval, I need to fill the block by 2.25 units per interval, for it to be full in 2 seconds.

with integer numbers (which I understood can only be whole numbers), I cannot do this calculation. Or did you have a different solution?
 

Uncle

Warcraft Moderator
Level 65
Joined
Aug 10, 2018
Messages
6,705
That looks correct.

The floating point thing is more of an issue when you need precision like: If DurationVariable Equal to 5.00 then do stuff...

In your case it's fine, I just wanted to mention it so that you're aware in the future when working with Reals like this.

But what people usually do to account for the floating point error is add a very small amount to their calculation like for example:
Set RealDuration = RealDuration + 0.03
Set IntDuration = Int(RealDuration + 0.001)

So when RealDuration is converted to an Integer it's also increased by 0.001 beforehand. This way if it was at a value like 0.99999 when it was supposed to be 1.0, it will be bumped up to a value that's equal to or slightly greater than 1.0 and as a result the conversion rounding will be correct. The floating point error is always an extremely small lack of precision that results in the value being slightly smaller.
 
Last edited:
Status
Not open for further replies.
Top