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

Local text tags

Status
Not open for further replies.
Level 12
Joined
May 22, 2015
Messages
1,051
I read (somewhere at some point) that it is possible to use GetLocalPlayer() to go above the texttag (floating text) cap of 100.

I am thinking of experimenting with displaying all damage dealt (and maybe taken) for each player, but it would be limited to only what damage they deal and what damage their units take - creating the text for all players and only displaying them to the right players might work, but I can see it hitting the 100 floating text cap very easily if there is a decent amount of players.

In order to use GetLocalPlayer() with the text tags, I basically just put the entire creation of the text tag inside the GetLocalPlayer() block, right? Is that all there is to it?

Something like:
JASS:
if (p == GetLocalPlayer()) then
    set myTextTag = CreateTextTag()
    ... // Set the position, the text, velocity, size, etc.
    set myTextTag = null
endif
 
Level 7
Joined
Nov 19, 2015
Messages
283
I also want to know if this works. Would you be able to upload all of the final code when if you get it working?
 
Level 12
Joined
May 22, 2015
Messages
1,051
I also want to know if this works. Would you be able to upload all of the final code when if you get it working?

Just the floating text code or my whole damage system? lol

My damage detection system is made by me for my own map (mostly just for fun, really). I can't guarantee it doesn't have bugs, and it has some excess stuff for myself (though I'm sure I could strip it out to make it more simple and clean). I'd rather only do all of that on request, though.
 
Level 7
Joined
Nov 19, 2015
Messages
283
Just the floating text part would be cool. I'm not very familiar implementing GetLocalPlayer() and kinda scared to use it without supervision. An example of how you did it would be great to follow. Although, would still need to see if this works.

Have you tried testing it or just waiting for answers?
 
Check the Hp & Mana bar system in my signature for a system that does this. I make it so they are not visible to a player unless the unit is visible. Otherwise they are always visible. For future reference in case my signature changes, the map Ultimate Micro Melee also contains the system.

The visibility section looks like this:
  • Visibility Loop
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to HP_int, do (Actions)
        • Loop - Actions
          • -------- Checks for signs of Life --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (HP_Unit[(Integer A)] is alive) Equal to True
              • HP_Unit[(Integer A)] Not equal to No unit
            • Then - Actions
              • -------- --------------------------------------------------------------- --------
              • -------- ! These next loops are set for 2 players ---- change the varible if you add more players ! ! ! --------
              • -------- --------------------------------------------------------------- --------
              • Set NumberofPlayers = 2
              • -------- --------------------------------------------------------------- --------
              • For each (Integer B) from 1 to NumberofPlayers, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (HP_Unit[(Integer A)] is visible to (Player((Integer B)))) Equal to True
                      • (HP_Unit[(Integer A)] is hidden) Equal to False
                      • ManaBars_On[(Player number of (Player((Integer B))))] Equal to True
                    • Then - Actions
                      • -------- Shows bars for units that are visible to a player --------
                      • Set Mana_PlayerB = (Player((Integer B)))
                      • Set Mana_PlayerGroup = (Player group(Mana_PlayerB))
                      • Floating Text - Show HP_Text[(Integer A)] for Mana_PlayerGroup
                      • Custom script: call DestroyForce(udg_Mana_PlayerGroup)
                    • Else - Actions
                      • -------- Hides bars for units that are not visible to a player --------
                      • Set Mana_PlayerB = (Player((Integer B)))
                      • Set Mana_PlayerGroup = (Player group(Mana_PlayerB))
                      • Floating Text - Hide HP_Text[(Integer A)] for Mana_PlayerGroup
                      • Custom script: call DestroyForce(udg_Mana_PlayerGroup)
            • Else - Actions
Looking at it now, I guess I didn't use getlocalplayer(). I remember considering it and possibly having it crash. I recommend trying it, but my way works for some purposes. Now if you are trying to reduce the number of floating text in existence in a particular game by only creating them when they are visible and destroying them once they are not, that is a little different but it might work. Hope this help.
 
Level 12
Joined
May 22, 2015
Messages
1,051
I've used GetLocalPlayer for other things, just not the full creation of the floating text. I have only set it up so that it only shows for certain players (also did that with unit transparency to hide certain dummies from certain players). I'll probably test it out, but I can't really confirm if it is safe or not until I play with people online or something.

Not something I can quickly test and I am generally not very knowledgeable with it, so advice from more experienced people is probably the best way to go about it.
 
Level 7
Joined
Nov 19, 2015
Messages
283
If you have the JNGP you can test it multiplayer by yourself. Using the multiplayer emulation. I used that before to test my GetLocalPlayer() transparent units.
 
Level 12
Joined
May 22, 2015
Messages
1,051
I actually stopped using JNGP haha (TBH I didn't know what I was doing with it in the first place). I stopped because it did some things that bugged me. I could probably do much more with it now, but I'll do that another time. Just using default editor with regular JASS at the moment.

Anyway, this is what I am using right now (though it will need tweaks for sure):
JASS:
    if (udg_owner[udg_DI] == GetLocalPlayer()) then
        set x = GetUnitX(udg_victim[udg_DI])
        set y = GetUnitY(udg_victim[udg_DI])

        set tt = CreateTextTag()
        call SetTextTagText(tt, I2S(R2I(udg_damage[udg_DI])), TextTagSize2Height(10))

        if (udg_crit[udg_DI]) then
            call SetTextTagColor(tt, 150, 0, 0, 255)
        elseif (udg_hit[udg_DI]) then
            call SetTextTagColor(tt, 255, 255, 255, 255)
        elseif (udg_magic[udg_DI]) then
            call SetTextTagColor(tt, 100, 0, 100, 255)
        else
            call SetTextTagColor(tt, 255, 50, 0, 255)
        endif

        call SetTextTagPos(tt, x - 20, y, 25)
        call SetTextTagVelocity(tt, 0, TextTagSpeed2Velocity(60))
        call SetTextTagPermanent(tt, false)
        call SetTextTagFadepoint(tt, 2)
        call SetTextTagLifespan(tt, 3)
        set tt = null
    endif

I haven't tested it with multiplayer yet. Seems to work, otherwise, though the colours are kind of bleh and if lots of damage events happen within a short time, it looks really bad lol - all the numbers stacking up on each other.

I'll have to think of a way to display them better. I am currently thinking that some kind of queue could be built and it would just unload through the queue at a decently fast rate - I could potentially even add logic later to draw the floating text in ways that they won't overlap so it can draw them more quickly.

EDIT:
Anyway, this makes my question more clear. Is the JASS above 100% safe in multiplayer or will I run into problems?
 
Just to clear things up:
  • Creating and modifying texttags within a GetLocalPlayer() block is safe. Since texttag does not extend agent, the Wc3 client won't attempt to keep them in sync.
  • The 100 limit is only for the number of texttags you can have concurrently existing. i.e. You can create thousands of texttags throughout the course of your map, you just need to make sure you destroy them or give them lifespans so you'll stay below the 100 simultaneous limit.
  • Creating texttags for players allows you to have 100 texttags per player. You can mix and match. For example, if you have 50 texttags that are only created for player 1, and 50 texttags created for everyone else (and assume all these texttags are currently active), then you've hit your limit.

To answer your question, yes your code is safe. A tip for the road: in general, try to do as little things as necessary within GetLocalPlayer() blocks. Even if it is safe to do so, there are common pitfalls that can be really difficult to debug later. For example, in your case I would move the set x = ... ; set y = ... part outside of the block (put it before the if GetLocalPlayer()... statement). If you tried to access x and y outside the local block immediately after that, those values would be different for udg_owner than everyone else (which may or may not cause problems depending on what you do with the data).
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The 100 texttag limit only counts rendering texttags iirc.
So if you create 1200 texttags but hide them all and unhide the first 100 for player 1, the second 100 for player 2, the third 100 for player 3, etc, then you have hit all limits but there is nothing wrong.

I think it is a good habit to have texttags created for all players simply because of not having to update texttags for players individually.
Only showing them to the players that actually want to see them would then be done in local blocks.
 
The 100 texttag limit only counts rendering texttags iirc.
So if you create 1200 texttags but hide them all and unhide the first 100 for player 1, the second 100 for player 2, the third 100 for player 3, etc, then you have hit all limits but there is nothing wrong.

I think it is a good habit to have texttags created for all players simply because of not having to update texttags for players individually.
Only showing them to the players that actually want to see them would then be done in local blocks.

The issue isn't with rendering them on screen--the issue has to do with the handle ID. Blizzard only reserved 100 handle ID slots for texttags (0 to 99). If you have 100 texttags actively using up those ID's, then the next texttag will use slot 0 (and you'll lose reference to the old texttag that was in that slot--I don't remember whether it is destroyed or not).

In this case, you should prefer creating locally vs. hiding locally.
 
Status
Not open for further replies.
Top