HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Problem finding bug in code

09-14-2009, 02:44 AM#1
Drain Pipe
Ok so I'm trying to clean up a floating text display system that i had previously made, and to generalize it to something more a much broader use, moreso than just for damage display. What i did was I preloaded all my floating texts initially. They are all permanent, but only some will be displayed at a time and the maximum is based on players playing in game. Now I know the max 100 texttags per player although this time I'm not really focusing on partitioning slots to any particular player, which means that slots will be used as they are required, as well as multiple floating texts may be attached to the same unit, for multiple different displays of information. Any maps using this will require the 100 ft at one time limit anyways, so setting it up as that seems sort of redundant.

Anyways, Right Now I'm not bothering with anything else other then getting the darn thing to display a floating text when i use the proper creation function FillTextSlot. here's the main body of the 'system' right now. Notice a lot of bits aren't being used yet, but I'm trying to fix this up before i player around with everything else.

Collapse JASS:
scope FloatingTextSystem initializer Init

globals
integer MaxSlot
private constant real PeriodicCheck = 0.025
timer GameTimer = CreateTimer()
endglobals

struct FTData extends array
    texttag TT
    string txt
    real x0
    real y0
    real z0
    real x
    real y
    real z
    ARGB color
    real size
    real Fade
    real Life
    boolean displayed
    player P
    //A few other things that I'll get to later
endstruct

function FillTextSlot takes integer ID, string txt, real x0, real y0, real z0, real Life, real FadeTime, player P returns nothing
set FTData[ID].txt = txt
set FTData[ID].Life = Life
set FTData[ID].Fade = FadeTime
set FTData[ID].displayed = true
set FTData[ID].P = P
call SetTextTagText(FTData[ID].TT,FTData[ID].txt,z0)
call SetTextTagPos(FTData[ID].TT,x0,y0,z0)
if GetLocalPlayer() == FTData[ID].P and IsMaskedToPlayer(x0,y0,FTData[ID].P)==false and IsFoggedToPlayer(x0,y0,FTData[ID].P)==false then
    call SetTextTagVisibility(FTData[ID].TT, true)
    call DisplayTextToForce( GetPlayersAll(),"true")
else
    call SetTextTagVisibility(FTData[ID].TT, false)
    call DisplayTextToForce( GetPlayersAll(),"false")
endif

set MaxSlot = MaxSlot + 1
endfunction

private function Periodic takes nothing returns nothing
endfunction

private function Init takes nothing returns nothing
    local integer J = 0
    local integer PlayNUM = 0
    local trigger trg = CreateTrigger()

    loop
        if GetPlayerSlotState(Player(J)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(J)) == MAP_CONTROL_USER  then
            set PlayNUM = PlayNUM + 1
        else
        endif
        set J = J+1
        exitwhen J >= 11
    endloop
    
    set J = 0
    loop
        set FTData[J].TT = CreateTextTag()
        set FTData[J].txt = ""
        call SetTextTagPermanent(FTData[J].TT,true)
        call SetTextTagPos(FTData[J].TT,0,0,0)
        call ARGB[J].create(0,0,0,0)
        set J = J+1
        exitwhen J >= ((PlayNUM*100)-1)
    endloop
    
    set J = 0
        call DisplayTextToForce( GetPlayersAll(),I2S(PlayNUM))
    set PlayNUM = 0
    set MaxSlot = 0
    call TimerStart(GameTimer, PeriodicCheck, true, function Periodic)
endfunction

endscope

the following little bit is just a periodic exectutuion of my main creation function:

Collapse JASS:
function Trig_TestFT2_Actions takes nothing returns nothing
    call DisplayTextToForce( GetPlayersAll()," The current slot is " + I2S(MaxSlot))
    call FillTextSlot(MaxSlot, "yay",GetUnitX(gg_unit_Hpal_0052),GetUnitY(gg_unit_Hpal_0052),75.0, 0.5, 0.5, GetOwningPlayer(gg_unit_Hpal_0052))
    call DisplayTextToForce( GetPlayersAll()," The text ''" + FTData[MaxSlot-1].txt + "'' is in slot " + I2S(MaxSlot-1) + "!")
endfunction

//===========================================================================
function InitTrig_TestFT2 takes nothing returns nothing
    set gg_trg_TestFT2 = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_TestFT2, 5.00 )
    call TriggerAddAction( gg_trg_TestFT2, function Trig_TestFT2_Actions )
endfunction

The unit is just some randomly selected unit on my testmap. Now I've already pre-loaded all the floating texts, all I'm expecting the code to do is update the actual displayed text, moving it to the designated position, and making sure it's only visible for that player owning the unit. I also increment MaxSlot, which will be used when i loop though all my currently stored information, although I'm not there yet. The text displays are just for testing.

Anyways, if somebody could tell me why the text is not appearing i'd really appreciate it.
09-14-2009, 06:56 AM#2
TheWye
I'm guessin' you have the same problem with this guy:

http://www.wc3c.net/showthread.php?t=107499

hope that helps~
09-14-2009, 11:15 PM#3
Drain Pipe
sweet thx. That might be what's causing it...

[update] now I have another problem:

Collapse JASS:
scope FloatingTextSystem initializer Init

globals
integer MaxSlot
private constant real PeriodicCheck = 0.025
timer GameTimer = CreateTimer()
location Loc
endglobals

struct FTData extends array
    texttag TT
    string txt
    unit u
    real x0
    real y0
    real z0
    real vx
    real vy
    real vz
    real ax
    real ay
    real az
    ARGB color
    real size
    real Fade
    real FaCo
    real Life
    real cslot
    boolean displayed
    player P
    //A few other things that I'll get to later
endstruct

function FTFadePath takes integer ID, integer i returns nothing

if i == 1 then //Random Floating Direction
    set FTData[ID].vx = GetRandomReal(-100.,100.)
    set FTData[ID].vy = 0
    set FTData[ID].vz = GetRandomReal(-100.,100.)
    set FTData[ID].ax = 0
    set FTData[ID].ay = 0
    set FTData[ID].az = 0

endif

if i == 2 then// Drops down in an arc
    set FTData[ID].vx = GetRandomReal(-100.,100.)
    set FTData[ID].vy = 0
    set FTData[ID].vz = GetRandomReal(300,400.)
    set FTData[ID].ax = 0
    set FTData[ID].ay = 0
    set FTData[ID].az = GetRandomReal(-800,-400)
endif

if i == 3 then
endif
endfunction

private function GetUnitZ takes unit u returns real
return GetUnitFlyHeight(u)
endfunction


private function Periodic takes nothing returns nothing
    local integer J = 0
    loop
        if FTData[J].Life <= 0. then
            if FTData[J].Fade <= 0. then
                if MaxSlot <= 0 then
                    set MaxSlot = 0
                    call PauseTimer(GameTimer)
                else
                    set MaxSlot = MaxSlot - 1
                endif
                set FTData[J].x0 = FTData[MaxSlot].x0
                set FTData[J].y0 = FTData[MaxSlot].y0
                set FTData[J].z0 = FTData[MaxSlot].z0
                set FTData[J].vx = FTData[MaxSlot].vx
                set FTData[J].vy = FTData[MaxSlot].vy
                set FTData[J].vz = FTData[MaxSlot].vz
                set FTData[J].ax = FTData[MaxSlot].ax
                set FTData[J].ay = FTData[MaxSlot].ay
                set FTData[J].az = FTData[MaxSlot].az
                set FTData[J].u = FTData[MaxSlot].u
                set FTData[J].size = FTData[MaxSlot].size
                set FTData[J].txt = FTData[MaxSlot].txt
                set FTData[J].Life = FTData[MaxSlot].Life
                set FTData[J].Fade = FTData[MaxSlot].Fade
                set FTData[J].FaCo = FTData[MaxSlot].FaCo
                set FTData[J].size = FTData[MaxSlot].size
                set FTData[J].displayed = FTData[MaxSlot].displayed
                set FTData[J].P = FTData[MaxSlot].P
                call SetTextTagText(FTData[J].TT,FTData[J].txt,FTData[J].size*0.0023)
                call SetTextTagPos(FTData[J].TT,FTData[J].x0,FTData[J].y0,FTData[J].z0+75)
                if GetLocalPlayer() == FTData[J].P and IsMaskedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false and IsFoggedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false then
                    call SetTextTagVisibility(FTData[J].TT, true)
                else
                    call SetTextTagVisibility(FTData[J].TT, false)
                endif
                set FTData[MaxSlot].txt = ""
                call SetTextTagText(FTData[MaxSlot].TT,FTData[MaxSlot].txt,FTData[MaxSlot].size*0.0023)
                call SetTextTagPos(FTData[MaxSlot].TT,0,0,0)
                set FTData[MaxSlot].displayed = false
                call SetTextTagVisibility(FTData[MaxSlot].TT, false)
            else
                set FTData[J].Fade = FTData[J].Fade - PeriodicCheck
                call SetTextTagText(FTData[J].TT,FTData[J].txt,FTData[J].size*0.0023)
                call SetTextTagPos(FTData[J].TT,FTData[J].x0+FTData[J].vx*(FTData[J].FaCo - FTData[J].Fade)+FTData[J].ax*Pow((FTData[J].FaCo - FTData[J].Fade),2),FTData[J].y0+FTData[J].vy*(FTData[J].FaCo - FTData[J].Fade)+FTData[J].ay*Pow((FTData[J].FaCo - FTData[J].Fade),2),FTData[J].z0+FTData[J].vz*(FTData[J].FaCo - FTData[J].Fade)+FTData[J].az*Pow((FTData[J].FaCo - FTData[J].Fade),2)+75)
                if GetLocalPlayer() == FTData[J].P and IsMaskedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false and IsFoggedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false then
                    call SetTextTagVisibility(FTData[J].TT, true)
                else
                    call SetTextTagVisibility(FTData[J].TT, false)
                endif
            endif
        else
            set FTData[J].Life = FTData[J].Life - PeriodicCheck
            set FTData[J].x0 = GetUnitX(FTData[J].u)
            set FTData[J].y0 = GetUnitY(FTData[J].u)
            set FTData[J].z0 = GetUnitZ(FTData[J].u)
            call SetTextTagText(FTData[J].TT,FTData[J].txt,FTData[J].size*0.0023)
            call SetTextTagPos(FTData[J].TT,FTData[J].x0,FTData[J].y0,FTData[J].z0+75)
            if GetLocalPlayer() == FTData[J].P and IsMaskedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false and IsFoggedToPlayer(FTData[J].x0,FTData[J].y0,FTData[J].P)==false then
                call SetTextTagVisibility(FTData[J].TT, true)
            else
                call SetTextTagVisibility(FTData[J].TT, false)
            endif
        endif
        set J = J+1
        exitwhen J >= MaxSlot
    endloop
    set J = 0
endfunction

function FillTextSlot takes integer ID, integer FlightPath, string txt, real size, real Life, real FadeTime, unit u, player P returns nothing


set FTData[ID].txt = txt
set FTData[ID].Life = Life
set FTData[ID].Fade = FadeTime
set FTData[ID].FaCo = FadeTime
set FTData[ID].size = size
set FTData[ID].displayed = true
set FTData[ID].u = u
set FTData[ID].cslot = ID
set FTData[ID].P = P
set FTData[ID].x0 = GetUnitX(u)
set FTData[ID].y0 = GetUnitY(u)
set FTData[ID].z0 = GetUnitZ(u)
call FTFadePath(ID,FlightPath) // This will denote the path the texttag will travel when it begins to fade
call SetTextTagText(FTData[ID].TT,FTData[ID].txt,FTData[ID].size*0.0023)
call SetTextTagPos(FTData[ID].TT,FTData[ID].x0,FTData[ID].y0,FTData[ID].z0+75)
if GetLocalPlayer() == FTData[ID].P and IsMaskedToPlayer(FTData[ID].x0,FTData[ID].y0,FTData[ID].P)==false and IsFoggedToPlayer(FTData[ID].x0,FTData[ID].y0,FTData[ID].P)==false then
    call SetTextTagVisibility(FTData[ID].TT, true)
else
    call SetTextTagVisibility(FTData[ID].TT, false)
endif
if MaxSlot <= 0 then
    call TimerStart(GameTimer, PeriodicCheck, true, function Periodic)
endif
set MaxSlot = MaxSlot + 1
endfunction

private function Init takes nothing returns nothing
    local integer J = 0
    local integer PlayNUM = 0
    local trigger trg = CreateTrigger()

    loop
        if GetPlayerSlotState(Player(J)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(J)) == MAP_CONTROL_USER  then
            set PlayNUM = PlayNUM + 1
        else
        endif
        set J = J+1
        exitwhen J >= 11
    endloop
    
    set J = 0
    loop
        set FTData[J].TT = CreateTextTag()
        set FTData[J].txt = ""
        set FTData[J].displayed = false
        call SetTextTagPermanent(FTData[J].TT,true)
        call SetTextTagPos(FTData[J].TT,0,0,0)
        call ARGB[J].create(0,0,0,0)
        set J = J+1
        exitwhen J >= ((PlayNUM*100)-1)
    endloop
    
    set J = 0
        call DisplayTextToForce( GetPlayersAll(),"The Number of Users Currently Playing is " + I2S(PlayNUM))
    set PlayNUM = 0
    set MaxSlot = 0
 
endfunction

endscope

fixed. Check out the map, its hilarious: phase 1 complete.
Attached Files
File type: w3xMercenary Clash_Beta_v0.1.w3x (84.4 KB)
09-15-2009, 07:07 AM#4
TheWye
Hmm.. I downloaded your map and I still don't get what it is supposed to do. Is the current slot number being stuck in 29 to 31 the problem?
09-15-2009, 07:25 PM#5
Bobo_The_Kodo
You aren't indexing them properly -> right now it only works if you only remove the top one -> so when the first one dies it gets fucked up
09-16-2009, 12:57 AM#6
Drain Pipe
so how must i index them? a small example would be enough to clarify

op, nvr mind I figured it out....runs fine now...
09-16-2009, 01:23 AM#7
Bobo_The_Kodo
2 examples: (one stack, one linkedlist)

Collapse JASS:
//Simple with array ...
struct A
    
    private        integer        id
    private static thistype array stack
    private static integer        stack_num = 0
    
    static method create takes nothing returns thistype
        local thistype this = thistype.allocate()
        
        //Do create stuff here
        
        //Index'd!
        set .stack_num = .stack_num + 1
        set .stack[.stack_num] = this
        set .id = .stack_num
        
        return this
    endmethod
    
    private method onDestroy takes nothing returns nothing
        if .stack[.id] != .stack[.stack_num]
            set .stack[.stack_num].id = .id
            set .stack[.id] = .stack[.stack_num]
        endif
        set .stack_num = .stack_num - 1    
    endmethod
    
    //Looped function
    private static method update takes nothing returns nothing
        local integer i = .stack_num
        local thistype this
        loop
            exitwhen i == 0
            set this = thistype(i)
            
            //Do stuff with struct here ...
            
            
                //If destroy ...
                call .destroy()
            
            set i = i - 1
        endloop
    endmethod
    
    private static method onInit takes nothing returns nothing
        call TimerStart(CreateTimer(), 0.01, true, function thistype.update)
    endmethod
    
endstruct

//Simple with list ...
struct A

    private static List stuff
    
    static method create takes nothing returns thistype
        local thistype this = thistype.allocate()
        
        call Link.create(.stuff, integer(this))
        
        return this
    endmethod
    
    private method onDestroy takes nothing returns nothing
        call .stuff.search(integer(this)).destroy()
    endmethod
    
    //Looped function
    private static method update takes nothing returns nothing
        local Link l = .stuff.first
        local thistype this
        loop
            exitwhen integer(l) == 0
            set this = thistype(l.data)
            set l = l.next
            
            //Do stuff with struct here ...
            
                //If destroy ...
                call .destroy()
        endloop
    endmethod
    
    private static method onInit takes nothing returns nothing
        set .stuff = List.create()
        call TimerStart(CreateTimer(), 0.01, true, function thistype.update)
    endmethod
endstruct
09-16-2009, 02:06 AM#8
Drain Pipe
well, i fixed it.