| 11-01-2009, 01:20 PM | #1 |
Hello. I'm making a map in which I have a strategic point in the middle. To caputre it you have to have the more units than anyone else close to it. Since I'm a fan of modularity I decided to make a function that retrived which player has the most units in a radius of a point. This is how it looks like: JASS:library PersonalLibrary globals private integer array Count endglobals private function Increase takes nothing returns nothing set Count[GetPlayerId(GetOwningPlayer(GetEnumUnit()))] = Count[GetPlayerId(GetOwningPlayer(GetEnumUnit()))] + 1 endfunction function GetPlayerWithMostUnitsInRange takes real x, real y, real radius, boolexpr filter returns player local group g = CreateGroup() local integer i = 0 local integer temp_count local player p = Player(0) call GroupEnumUnitsInRange( g, x, y, radius, filter ) call ForGroup( g, function Increase ) set temp_count = Count[0] loop exitwhen i > 11 if Count[i] > temp_count then set temp_count = Count[i] set p = Player(i) endif set i = i + 1 exitwhen i > 11 endloop set i = 0 loop exitwhen i > 11 set Count[i] = 0 set i = i + 1 exitwhen i > 11 endloop call DestroyGroup(g) set g = null return p endfunction endlibrary Right now, it works without bugs but it has an obvious flaw: If two players (or more) have an equal amount of units close to the point, the player with the smallest number will be returned (if player 1 has three units and player 2 also does, player 1 will be returned). To solve this dispute I'd like to return Neutral Passive if two or more players have equal amount of units. Problem is I don't know how. I tried some if's but it always returns Neutral Passive Help? |
| 11-01-2009, 02:22 PM | #2 |
JASS:library GetPlayerWithMostUnitsInRange globals private integer array Count private group g = CreateGroup() endglobals private function Increase takes nothing returns nothing local integer i=GetPlayerId(GetOwningPlayer(GetEnumUnit())) set Count[i] = Count[i] + 1 endfunction function GetPlayerWithMostUnitsInRange takes real x, real y, real radius, boolexpr filter returns player local integer i = 0 local integer tempCount = 0 local player tempPlayer call GroupEnumUnitsInRange( g, x, y, radius, filter ) call ForGroup( g, function Increase ) loop if Count[i]>tempCount then set tempCount = Count[i] set tempPlayer = Player(i) elseif Count[i]==tempCount then set tempPlayer = Player(15) endif set Count[i] = 0 set i = i + 1 exitwhen i > 11 endloop return tempPlayer endfunction endlibrary |
| 11-01-2009, 02:41 PM | #3 |
Strange. I just tried the same thing but it always returned neutral passive no matter what. And I mean exactly the same thing. Thanks, I guess :/ |
| 11-02-2009, 05:31 PM | #4 |
Yes, Anitarf's code looks strange somehow... The way I would do it is to keep the best and the second-best player. Then if both have the same amount of units, return Neutral passive. JASS:
function GetPlayerWithMostUnitsInRange takes real x, real y, real radius, boolexpr filter returns player
local integer i = 0
local integer tempCount1 = -1 //to force it to work
local integer tempCount2 = -1
local player tempPlayer1 = Player(15)
local player tempPlayer2 = Player(15)
call GroupEnumUnitsInRange( g, x, y, radius, filter )
call ForGroup( g, function Increase )
loop
if Count[i]>tempCount1 then
set tempCount2 = tempCount1
set tempPlayer2 = tempPlayer1
set tempCount1 = Count[i]
set tempPlayer1 = Player(i)
elseif Count[i]>tempCount2 then
set tempPlayer2 = Player(15)
set tempCount2 = Count[i]
endif
set Count[i] = 0
set i = i + 1
exitwhen i > 11
endloop
if(tempCount2 == tempCount2) then
return Player(15)
endif
return tempPlayer
endfunction
|
| 11-02-2009, 05:42 PM | #5 |
Haven't tested, but should work JASS:library GetPlayerWithMostUnitsInRange globals private integer array Count endglobals private function Increase takes nothing returns nothing local integer i=GetPlayerId(GetOwningPlayer(GetEnumUnit())) set Count[i] = Count[i] + 1 endfunction function GetLeadingPlayerRange takes real x, real y, real r, boolexpr filter returns player local integer i = 0 local player p = Player(PLAYER_NEUTRAL_PASSIVE) local player w = null local group g = null local integer s = 0 loop exitwhen i >= 15 set Count[i] = 0 set g = CreateGroup() call GroupEnumUnitsInRange(g, x, y, r, filter) call ForGroup(g, function Increase) call DestroyGroup(g) set g = null if Count[i] > s then set w = Player(i) set s = Count[i] elseif w != p then set w = p set i = 14 endif set i = i + 1 endloop return w endfunction endlibrary |
| 11-02-2009, 05:49 PM | #6 | |
Quote:
Edit: Anachron, that's just depressing. |
| 11-02-2009, 05:54 PM | #7 |
don't use DestroyGroup. I now think Anitarf's should work really well. Hmnn, are you sure you really did try it and always returned Neutral Passive? |
| 11-02-2009, 06:02 PM | #8 | |
Quote:
|
| 11-02-2009, 08:29 PM | #9 |
No I used an elseif, and it looked exactly the same (ok not 'exactly' since my tempPlayer was named p and my tempCount was called temp_count, but those are just names). But the problem may have been in my code which uses the module. However I noticed that if two players on the same team have equal units, no one captures the point, which is kind of stupid since capturing the point is beneficial to the whole team. I havn't worked on solving it yet (no time). I'll just double-post here if I need help with it (do hope moderators approve of this liberty) |
| 11-02-2009, 08:50 PM | #10 |
elseif Count[i]==tempCount and IsPlayerEnemy(tempPlayer, Player(i)) then
This way, if two players on the same team are tied, the one with the lower player id wins. |
