HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Force problems

07-19-2005, 02:12 PM#1
Zoxc
Code:
function MissionPlayers takes integer m returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    return a
endfunction

This is supposed to generate a force of player where the PlayerPos[ <playernumber> ] is equal to m. But its no players in it :-/
07-19-2005, 03:14 PM#2
curi
don't you need to do like

set a = make_new_force() (whatever it's called)
07-19-2005, 04:08 PM#3
Zoxc
I forgot that :P, didn't find createforce in gui, so I just tougth you didn't have to init it.
07-19-2005, 09:47 PM#4
AFZ
Quote:
Originally Posted by Zoxc
I forgot that :P, didn't find createforce in gui, so I just tougth you didn't have to init it.

the function takes an integer, if the integer is >11, it won't add any player to the force, since the players are 0-11.
07-19-2005, 10:15 PM#5
Anitarf
And it leaks the force object, or, actually, it's handle.
07-19-2005, 10:20 PM#6
Zoxc
How to unleak it then?
07-20-2005, 05:23 AM#7
curi
it's hard to avoid the leak cause you can't very well set a to null before returning. you could use gamecache or a global instead of returning. or better yet, did you know there is already an array bj_FORCE_PLAYER

There is also a blizzard.j function named GetForceOfPlayer
07-20-2005, 08:20 AM#8
Anitarf
You can use a dummy argument because arguments don't leak for some reason:
Code:
function MissionPlayers takes integer m, force f returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    call DestroyForce(f) //this is optional, depending on what do you pass as an argument, a newly created force just for this or some global force you use elsewhere
    set f = a
    set a = null
    return f
endfunction
Or, you can use the return bug and return the handle's index (which is an integer and integers don't leak, only handles do):
Code:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function MissionPlayers takes integer m returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    set i = H2I(a)
    set a = null
    return i
    return null
endfunction
07-20-2005, 11:07 AM#9
Zoxc
Whoud this leak:

Code:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function MissionPlayers takes integer m returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    set i = H2I(a)
    set a = null
    return i
    return null
endfunction

function MissionPlayers takes integer m returns force
  return Int2Force(MissionPlayers(m))
endfunction

I don't know if 'return' leak, but its just local that leak?
07-20-2005, 12:48 PM#10
Anitarf
It's not the return that leaks, it's the local handle variables that aren't set to null at end of function that leak. If you return a local handle variable, you can't set it to null afterwards because the function stops at the return statement, so it leaks. Now, this is sort of a bug, the arguments a function takes are set to null at end of function automaticaly, only local variables aren't. That's why you can use a dummy argument so you can return a value with it without a leak.

The other solution is if you use H2I and the return bug. Wheever you return a handle pointer, the function actually returns an integer, which is the handle index of the object your pointer points to. So, the idea behind this solution is that you can just return an integer instead of a pointer and the function that recieves that integer won't notice any difference. The only problem lies in the JASS syntax checker that won't let a function return a type it's not supossed to. Luckily, the checker is stupid enough to only look at the last return statement, allowing you to return whatever you wish before that.

Your solution seems ok, just what is that third function supposed to do? the first two functions already do everything you need.
07-20-2005, 01:27 PM#11
Zoxc
I want to use it like this: Show Text for players MissionPlayers(1), so I need to return a force.
07-20-2005, 06:50 PM#12
Anitarf
Well... you do return a force. Ok, you return an integer, but the function you return it to trets it as the handle id of a force, which it is, because you got it by transforming a force to it with the H2I function. That integer is your force. The function says it returns a force, so every function that calls it will treat the integer as the id number of a force.
07-20-2005, 07:06 PM#13
Zoxc
I add this to the general section:
Code:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function MissionPlayersT takes integer m returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    set i = H2I(a)
    set a = null
    return i
    return null
endfunction

function MissionPlayers takes integer m returns force
  return Int2Force(MissionPlayersT(m))
endfunction

And want to use it in GUI like this:
Display to ( MissionPlayers(1) ) the text 'sometext'

Does this leak?
07-20-2005, 09:33 PM#14
AFZ
nvm. Ok, Why don't u use a global force variable, as globals don't leak.

let's assume that you created a global force variable named: PForce, then, you can use that in jass, just add udg_ at the begining

Code:
function MissionPlayers takes integer m returns nothing
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(udg_PForce, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
endfunction

then you will have some players in the force, and you will be able to use the force in other triggers.
07-21-2005, 09:36 AM#15
Anitarf
Quote:
Originally Posted by Zoxc
I add this to the general section:
Code:
function H2I takes handle h returns integer
    return h
    return 0
endfunction

function MissionPlayersT takes integer m returns force
    local force a
    local integer i = 1
    loop
        if udg_PlayerPos[i] == m then
            call ForceAddPlayer(a, Player(i-1))
        endif
        exitwhen i == 12
        set i = i+1
    endloop
    set i = H2I(a)
    set a = null
    return i
    return null
endfunction

function MissionPlayers takes integer m returns force
  return Int2Force(MissionPlayersT(m))
endfunction

And want to use it in GUI like this:
Display to ( MissionPlayers(1) ) the text 'sometext'

Does this leak?
What I'm trying to say is, you don't need that third function. Just do it like this:
Display to ( MissionPlayersT(1) ) the text 'sometext'

Oh, and this leaks, you should do it like this:
set tempForce = MissionPlayersT(1)
Display to tempForce the text 'sometext'
call DestroyForce( tempForce )