• 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.

[General] Problem with Multiplayer Floating Texts

Status
Not open for further replies.
Level 5
Joined
Aug 30, 2009
Messages
114
Hello everyone, I'm having some strange issues with floating texts in multiplayer.

When I play my map alone, all floating text works just fine, but when in multiplayer, they sometimes don't show up!!!

The whole script works, but the floating text doesn't !!!

So, here is how I was creating the Floating Texts...

JASS:
local texttag te = CreateTextTag()
call SetTextTagText(te, "EXEMPLE", 0.024)
call SetTextTagPos(te, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagColor(te, 255, 155, 155, 255)
call SetTextTagVelocity(te, 0, 0.04)
call SetTextTagVisibility(te, true)
call SetTextTagFadepoint(te, 2)
call SetTextTagLifespan(te, 5)
call SetTextTagPermanent(te, false)
set te = null

But it doesn't work so then I tried this way:

JASS:
local texttag te = CreateTextTag()
call SetTextTagText(te, "EXEMPLE", 0.024)
call SetTextTagPos(te, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagColor(te, 255, 155, 155, 255)
call SetTextTagVelocity(te, 0, 0.04)
if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS)) then
    call SetTextTagVisibility(te, true)
endif
call SetTextTagFadepoint(te, 2)
call SetTextTagLifespan(te, 5)
call SetTextTagPermanent(te, false)
set te = null


... but it doesn't work neither!! Can someone tells me what in seven hells is going on????

This seems to happen only in multiplayer, with all players including me (red, host)

Thanks
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
This is probably because you are hitting the 100 texttag limit for all players. Unless you create the texttags locally you can have a maximum of 100 texttags. (texttags have a custom handle id stack ranging from 0-99).

You could create them locally for each player so that each player has 100 texttag slots.
But more then that will be impossible due to the limitations of wc3.
If you want to make sure this doesn't happen you need to make sure that previous texttags that are not in use anymore are being destroyed.
(be careful for locally created texttags, they need to be destroyed locally for the corresponding player instead of globally or else they will cause a desync.)
 
JASS:
if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS)) then
    call SetTextTagVisibility(te, true)
endif
Is really unneeded because it will always return TRUE.
It just makes no sense.
JASS:
if (IsPlayerInForce(GetLocalPlayer(), example_force_f)) then
    call SetTextTagVisibility(te, true)
endif
this can return false if you don't add some players to force.
 
Level 5
Joined
Aug 30, 2009
Messages
114
This is probably because you are hitting the 100 texttag limit for all players. Unless you create the texttags locally you can have a maximum of 100 texttags. (texttags have a custom handle id stack ranging from 0-99).

You could create them locally for each player so that each player has 100 texttag slots.
But more then that will be impossible due to the limitations of wc3.
If you want to make sure this doesn't happen you need to make sure that previous texttags that are not in use anymore are being destroyed.
(be careful for locally created texttags, they need to be destroyed locally for the corresponding player instead of globally or else they will cause a desync.)

Thanks for your help man, but I don't think that's the problem, I knew about this limit already, and I am destroying every texttag by disabling their permanence and giving lifespan, and also, this happens even earlier in game, when I haven't used any Floating Text yet, I use my skill, and the floating text sometimes appears and sometimes don't. But thanks for your help.

JASS:
if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS)) then
    call SetTextTagVisibility(te, true)
endif
Is really unneeded because it will always return TRUE.
It just makes no sense.
JASS:
if (IsPlayerInForce(GetLocalPlayer(), example_force_f)) then
    call SetTextTagVisibility(te, true)
endif
this can return false if you don't add some players to force.

I will test this, thank you... I will edit here when I'm done.
 
You don't need to test it, that's not problem, only useless code...

JASS:
local texttag te = CreateTextTag()
call SetTextTagText(te, "EXEMPLE", 0.024)
call SetTextTagPos(te, GetUnitX(u), GetUnitY(u), 0.00)
call SetTextTagColor(te, 255, 155, 155, 255)
call SetTextTagVelocity(te, 0, 0.04)
call SetTextTagVisibility(te, true)
call SetTextTagFadepoint(te, 2)
call SetTextTagLifespan(te, 5)
call SetTextTagPermanent(te, false)
set te = null
Works fine for all players.
But Local players is used for different things:
JASS:
/* Example: We hide text tag for red player like this:*/
if GetLocalPlayer() == Player(0) then
     call SetTextTagVisibility(te, false)
endif
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
What if you don't display it locally at all, but just display it globally? (like -Kobas- showed in his first post in this thread)

If this is only happening in multiplayer then the only connection that I can see is the local code.
So you're probably doing something wrong there.

Plus: why would you display a texttag locally if that would take up 1 texttag slot for all players :/?
As I said, it's way more useful to just create it locally instead of displaying locally because then it'll just
take up 1 slot for that specific player instead of all players.

Tell me: when exactly do you want to display the floating text?
Does it need to be displayed for only 1 player? Or for all players?

What are you trying to do here? Because displaying a texttag locally to all players simply doesn't make any sense at all.
Local code is used to do things locally, displaying something to all players is global so I don't see the logic here.

EDIT: on a side-note, try doing:
JASS:
call BJDebugMsg(R2S(GetUnitX(u)))
call BJDebugMsg(R2S(GetUnitY(u)))
call BJDebugMsg(I2S(GetHandleId(tt)))
Yet again, like -Kobas- mentioned, debug your code ;)
Incorrect unit positions might be the cause why "some" floating texts are not being displayed.
Or it's because you are hitting the limit. This will help you to check both.
 
Level 5
Joined
Aug 30, 2009
Messages
114
What if you don't display it locally at all, but just display it globally? (like -Kobas- showed in his first post in this thread)

If this is only happening in multiplayer then the only connection that I can see is the local code.
So you're probably doing something wrong there.

Plus: why would you display a texttag locally if that would take up 1 texttag slot for all players :/?
As I said, it's way more useful to just create it locally instead of displaying locally because then it'll just
take up 1 slot for that specific player instead of all players.

Tell me: when exactly do you want to display the floating text?
Does it need to be displayed for only 1 player? Or for all players?

What are you trying to do here? Because displaying a texttag locally to all players simply doesn't make any sense at all.
Local code is used to do things locally, displaying something to all players is global so I don't see the logic here.

EDIT: on a side-note, try doing:
JASS:
call BJDebugMsg(R2S(GetUnitX(u)))
call BJDebugMsg(R2S(GetUnitY(u)))
call BJDebugMsg(I2S(GetHandleId(tt)))
Yet again, like -Kobas- mentioned, debug your code ;)
Incorrect unit positions might be the cause why "some" floating texts are not being displayed.
Or it's because you are hitting the limit. This will help you to check both.

I don't think you have undesrtood it at all!!

I was using global, but when I got this bug, I switched to local trying to fix this bug, and yet, its not ALL floating text that are not showing up, sometimes they show!! That's the strangest part, for example, I casted my spell against an enemy, the spell is supposed to steal strength showing how much strength it has stolen, and sometimes the floating text shows, sometimes they don't, but the spell works just fine, the strength is stolen, and the enemy killed.

Here is one of my spells that are having this issue:

JASS:
scope TouchOfDeath initializer Init

private function CastConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A03S'
endfunction

private function CastActions takes nothing returns nothing
    local unit U = GetTriggerUnit()
    local unit T = GetSpellTargetUnit()
    local integer Lv = GetUnitAbilityLevel(U, 'A03S')
    local real Hp = 150 + (150 * Lv)
    local real PHp = 0.10 + (0.10 * Lv)
    local real CHp = GetUnitState(T, UNIT_STATE_LIFE)
    local real THp = GetUnitState(T, UNIT_STATE_MAX_LIFE)
    if GetUnitState(T, UNIT_STATE_LIFE) <= Hp or GetUnitState(T, UNIT_STATE_LIFE) <= (THp * PHp) then
    else
        call IssueImmediateOrder(U, "stop")
        call SimError(GetOwningPlayer(U), "Your target is not injuried enough.")
    endif    
    set U = null
    set T = null
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A03S'
endfunction

private function Actions takes nothing returns nothing
    local unit U = GetTriggerUnit()
    local unit T = GetSpellTargetUnit()
    local player P1 = GetOwningPlayer(U)
    local player P2 = GetOwningPlayer(T)
    local integer Pi1 = GetPlayerId(P1)
    local integer Pi2 = GetPlayerId(P2)
    local integer Lv = GetUnitAbilityLevel(U, 'A03S')
    local texttag Te1 = CreateTextTag()
    local texttag Te2 = CreateTextTag()
    local integer Stre = 2 * Lv
    // Ignore this BJ, it is cheking if the enemy has Linken's Sphere
    if not UnitHasItemOfTypeBJ(T, 'I000') then
        // The Floating text is here:
        call SetTextTagText(Te1, "+" + I2S(Stre) +" Str", 0.024)
        call SetTextTagPos(Te1, GetUnitX(U), GetUnitY(U), 0.00)
        call SetTextTagColor(Te1, 200, 75, 75, 255)
        call SetTextTagVelocity(Te1, 0, 0.04)
        if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS)) then
            call SetTextTagVisibility(Te2, true)
        endif
        call SetTextTagPermanent( Te1, false )
        call SetTextTagLifespan( Te1, 4.00 )
        
        call SetTextTagText(Te2, "-" + I2S(Stre) +" Str", 0.024)
        call SetTextTagPos(Te2, GetUnitX(T), GetUnitY(T), 0.00)
        call SetTextTagColor(Te2, 200, 75, 75, 255)
        call SetTextTagVelocity(Te2, 0, 0.04)
        if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS)) then
            call SetTextTagVisibility(Te2, true)
        endif
        call SetTextTagPermanent( Te2, false )
        call SetTextTagLifespan( Te2, 4.00 )
        
        // Here works just fine
        call SetHeroStr(U, GetHeroStr(U, false)+Stre, true)
        call SetHeroStr(T, GetHeroStr(T, false)-Stre, true)
        set TOfDeathStr[Pi1] = TOfDeathStr[Pi1] + Stre
        set TOfDeathStr[Pi2] = TOfDeathStr[Pi2] - Stre
        call UnitDamageTargetEx(U, T, 99999999999, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DIRECT, false)
    else
        call LinkensActivate(T)
    endif
    set P1 = null
    set P2 = null
    set Te1 = null
    set Te2 = null
    set U = null
    set T = null
endfunction

// Basic Shit ignore it:
////////////////////////////////////////////////////////////////////////////////////////////

private function LearnAct takes nothing returns nothing
    local trigger T = CreateTrigger()
    local trigger T2 = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(T, Condition(function Conditions))
    call TriggerAddAction(T, function Actions)
    call TriggerRegisterAnyUnitEventBJ(T2, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition(T2, Condition(function CastConditions))
    call TriggerAddAction(T2, function CastActions)
    set T = null
    set T2 = null
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

private function LearnCond takes nothing returns boolean
    return GetLearnedSkill() == 'A03S'
endfunction

private function Init takes nothing returns nothing
    local trigger T = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_HERO_SKILL)
    call TriggerAddCondition(T, Condition(function LearnCond))
    call TriggerAddAction(T, function LearnAct)
    set T = null
endfunction

////////////////////////////////////////////////////////////////////////////////////////////
endscope
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
I don't think you have undesrtood it at all!!

I was using global, but when I got this bug, I switched to local trying to fix this bug, and yet, its not ALL floating text that are not showing up, sometimes they show!!
Who said anything about all floating texts causing problems?
I most certainly did not :/. I said something entirely different.

So basically... You are debugging your spell using local code instead of debug messages? Right, good luck with that.

Have you even tried doing what I suggested?
Or are you just going to complaint about my incapabilities?
These debug messages will probably display more information necessary to solve your problem then local code will,
but if you don't want my help I'll just leave ;). I've got plenty of stuff to worry about anyways.

Good luck with your problem bro, I hope you'll solve it.
 
Last edited:
Level 5
Joined
Aug 30, 2009
Messages
114
Hashjie

First of all, sorry if I offended you, I really didn't meant to, I didn't said you were incapable of anything at all, I'm actually very gratefull for you guys trying to help me here, sorry if I sound arrogant (I didn't realised if I did). Respect is always above everything.

I did what you guys said about the BJDebugMsg stuff, and the msg works, it is displayed exactly when it is supposed to, but the floating text is still only showing up sometimes!!
Can you tell me if by setting SetTextTagPermanent to false destroys the text entirely so I don't hit up the texttag limit.

-Kobas- Can you recommend me a good Floating Text library?

And just for explanation, you can see that I used the spell cast event only to check if the target is above a certain % hitpoints, because if it doesn't then the order is canceled and a SimError is triggered, else the spell is started normally and the spell effect event triggers.

Thank you guys, and sorry if I sound rude again, I really didn't mean to
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
I'm sorry to have reacted so violently, I have had a pretty hard day yesterday and got easilly offended by what you said.
Either ways, doesn't this problem have something to do with:

JASS:
call SetTextTagText(Te1, "+" + I2S(Stre) +" Str", 0.024)
call SetTextTagPos(Te1, GetUnitX(U), GetUnitY(U), 0.00)
call SetTextTagColor(Te1, 200, 75, 75, 255)
call SetTextTagVelocity(Te1, 0, 0.04)
call SetTextTagVisibility(Te2, true)
call SetTextTagPermanent( Te1, false )
call SetTextTagLifespan( Te1, 4.00 )

Here you set all the properties for Te1 but you display Te2, which is not set yet.
I think that is not supposed to be done now is it ;)?

It's normal in this case that the debug messages where correct since the texttags did get created and the positions of the units where correct. So it's safe to say that this was not your issue.
(Even though it was a pretty good assumption considering your first code was correct)
The issue you currently have and why the debug messages did display correctly is that the texttag Te2 was created but is not having any properties which is why it doesn't display. This ofcourse was impossible to debug with debug messages.

Here is a floating text library that you can use: http://www.hiveworkshop.com/forums/jass-resources-412/snippet-texttag-213488/

Though, it shouldn't really change the outcome that much.
It will just prevent problems with texttag limits aforementioned.
I hope this helped a bit.
 
Last edited:
Level 5
Joined
Aug 30, 2009
Messages
114
Hey, I don't know why, but I solved the problem by creating BJTextTags, strange, but solved.

Thanks you both guys!!!

Here is how I'm creating the texttags now and it is working properly

JASS:
set Te = CreateTextTagUnitBJ( "Example", U, 0, 10, 100.00, 0.00, 0.00, 0 )
call SetTextTagVelocityBJ( Te, 64.00, 90.00 )
call SetTextTagPermanentBJ( Te, false )
call SetTextTagLifespanBJ( Te, 4.00 )
set Te = null
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Have you even tried doing what I suggested in my previous post?
You should've been abled to fix it by simply changing 1
JASS:
call SetTextTagVisibility(Te2, true)
into:
JASS:
call SetTextTagVisibility(Te1, true)
 
Level 5
Joined
Aug 30, 2009
Messages
114
yes, but that was not the problem, as you said yourself my first code was correct, and I have many floating texts that were bugged, this spell was only one of them. I don't know why but when I used the BJ Floating Text, it worked fine!!!

Funny isn't it? hueuheauheau
 
Status
Not open for further replies.
Top