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

Floating text problem - Combining text to prevent screen clutter

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,564
Hello, I'm having trouble with these triggers. I want to create a system that displays floating text whenever a unit is killed, easy enough, but I want to avoid having 100 different floating texts appear when 100 units are killed at or around the same time. So if you kill 100 units with one cast of thunderclap, then the text would display +100 once instead of +1, 100 times.

I have it working for the most part, however, every so often when I kill units the text displays 0 instead of the # of units killed. Here are the triggers so you can understand what I mean:

  • Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • Set TempInteger1 = (TempInteger1 + 1)
      • Countdown Timer - Start TestTimer as a One-shot timer that will expire in 0.50 seconds
  • Text
    • Events
      • Time - TestTimer expires
    • Conditions
    • Actions
      • Floating Text - Create floating text that reads (String(TempInteger1)) at (Position of PlayerHero[1]) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
      • Set TempInteger1 = 0
So I set TempInteger1 to be equal to 0 after the timer expires, and i'm assuming this is the source of the problem. But how else would I go about resetting the "Kill Counter" (TempInteger1)? And why does it work like 90% of the time? Am I wrong on how Timers work? I was under the impression that starting a timer that's already running will reset it.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
I'd imagine something like:

You need to have a timer for each floating text, and check for nearby floating texts with less than say 0.1 second lifespan.

So basically all texts created within 0.1 seconds would be added together.

This is a more general approach which would work in the entire map, not just a hard coded solution to a spell.

Sound like a pain to make in gui
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,564
Thanks for the responses. I ended up going with something similar to this:

I index a bunch of variables so I can keep track of the unit's Energy (A resource gained for Killing units) and how long the timer should last.

  • Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • -------- TempInteger2 = Killing unit's custom value --------
      • -------- If a timer isn't currently running then start one --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Energy_Counter[TempInteger2] Equal to 0.00
        • Then - Actions
          • Set Energy_Timer[TempInteger2] = 0.50
          • Trigger - Run Uncle Timer Setup <gen> (ignoring conditions)
          • Set ut_Unit[UTInt] = TempUnit1
          • Set ut_Trigger[UTInt] = Energy Text Run <gen>
        • Else - Actions
      • -------- Store how much "Energy" is gained for the kill --------
      • Set Energy_Counter[TempInteger2] = (Energy_Counter[TempInteger2] + (Spawn_EnergyBounty[(Custom value of TempUnit2)] x Stats_EnergyGain[TempInteger2]))
And then I run this trigger every 0.01 seconds on a timer that will end after 0.50 seconds, displaying how much Energy (Kills) were gained in the last 0.50 seconds:

  • Energy Text Run
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Energy_Timer[(Custom value of ut_Unit[UTInt])] Greater than 0.00
        • Then - Actions
          • -------- Duration --------
          • Set Energy_Timer[(Custom value of ut_Unit[UTInt])] = (Energy_Timer[(Custom value of ut_Unit[UTInt])] - 0.01)
          • -------- End --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Energy_Timer[(Custom value of ut_Unit[UTInt])] Equal to 0.00
            • Then - Actions
              • Set TempPoint1 = (Position of ut_Unit[UTInt])
              • Set TempString1 = (+ + (|cff1e90ff + ((String((Integer(Energy_Counter[(Custom value of ut_Unit[UTInt])])))) + |r%)))
              • Floating Text - Create floating text that reads TempString1 at TempPoint1 with Z offset 0.00, using font size 12.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
              • Floating Text - Change (Last created floating text): Disable permanence
              • Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
              • Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
              • Floating Text - Set the velocity of (Last created floating text) to 96.00 towards 90.00 degrees
              • Custom script: call RemoveLocation (udg_TempPoint1)
              • Set Energy_Counter[(Custom value of ut_Unit[UTInt])] = 0.00
              • Set ut_isOn[UTInt] = False
            • Else - Actions
        • Else - Actions

So I just store a variable called "Energy" which the player gains for killing enemy units, and then after 0.50 seconds I display the amount of Energy gained in that time frame. This works good enough for what I was trying to achieve and only uses 1 timer which is nice for performance. I realized I didn't want to prolong the timer with every new kill, otherwise if you managed to keep killing units before the timer expired then you could prolong it forever, not what I wanted.
 
Last edited:

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
647245db424c7bf875e06eb852d54ee1.png


Code damages a target by 1 every 0.03 seconds for 5 seconds
all damage dealt within 1 second intervals are joined together instead of creating a new floating text.
This means that it will start at 1 and end at 33 before reseting

A cooler solution would be to reset texttag duration when taking damage. Which is just one in of code.

Really should make a system for this myself, hm.

Don't expect you to understand the code but hopefully you can get the overall concept of how it is done.
 
Status
Not open for further replies.
Top