| 10-26-2007, 07:56 PM | #1 |
This bug has only occurred when testing the map online - it works fine in single player. My desired functionality is 4 regions (actually, rects) that I put on the map at a certain point. Every player has control of only one unit, max 4 players. I want each player to stand in a different one of the regions simultaneously. Got it? One unit in each region. The regions have a distinct environmental effect so they are easy to recognize. Currently, the regions are visible, spawn appropriately - no problems there. My problem is in trying to detect is a player has a unit in each of them. The behavior I get with multiple players is very odd. Here's the code: JASS:// This is the code that runs whenever a unit enters one of the regions. function Switch_Enter_Actions takes nothing returns nothing local integer i = 0 if (UnitIsHero(GetEnteringUnit()) == true) then set udg_S1_SwitchesFlipped = 0 loop if (HeroInRect(udg_S1_Region[i]) == true) then set udg_S1_SwitchesFlipped = udg_S1_SwitchesFlipped + 1 endif set i = i + 1 exitwhen i > 3 endloop if (udg_S1_SwitchesFlipped < udg_HeroCount) then call DisplayTextToPlayer(GetOwningPlayer(GetEnteringUnit()), 0., 0., "You have activated this switch. As long as you stand here, the switch will remain active.") call DisplayTextToPlayer(GetOwningPlayer(GetEnteringUnit()), 0., 0.,"(" + I2S(udg_S1_SwitchesFlipped) + " / " + I2S(udg_HeroCount) + " switches Active.)") else call DisableTrigger(gg_trg_Stage_1_Switch_Enter) call EnableTrigger(gg_trg_Stage_1_Checkpoint_Reached) call DisplayTextToForce(GetPlayersAll(), "All switches active! Make it to the portal alive and you escape!") endif endif endfunction JASS:// This is the function that might have the problem. The udg_Hero array is a // unit array that stores the unit for a particular player. It's indexed by playerid, // ie udg_Hero[0] is Player 1 - Red's unit. function HeroInRect takes rect r returns boolean local integer i = 0 loop if (IsUnitInRangeXY( udg_Hero[i], GetRectCenterX(r), GetRectCenterY(r), 250. )) then return true endif set i = i + 1 exitwhen i > 3 endloop return false endfunction JASS:// This is the function I use to create the rects. There aren't any problems here, I don't think. globals rect array udg_S1_Region integer udg_S1_SwitchesFlipped endglobals function CreateS1Rect takes integer index, real x, real y returns nothing local weathereffect e call RemoveRect(udg_S1_Region[index]) set udg_S1_Region[index] = Rect(x, y, x + 400., y - 400.) set e = AddWeatherEffect( udg_S1_Region[index], 'MEds' ) call EnableWeatherEffect( e, true ) call TriggerRegisterEnterRectSimple(gg_trg_Stage_1_Switch_Enter, udg_S1_Region[index]) set e = null endfunction The results were as follows (tested with two people). The udg_S1_SwitchesFlipped was always 1 - we always got a message that said "1/2 Switches Active". Sometime I got that message multiple times - up to 4 times, in fact. I know this is a lot to look over. Thanks for reading this far, and thanks for any ideas/suggestions. |
| 10-27-2007, 07:34 AM | #2 |
Instead of this: IsUnitInRangeXY( udg_Hero[i], GetRectCenterX(r), GetRectCenterY(r), 250. ))
Try doing this: JASS:function HeroInRect takes rect r returns boolean local integer i = 0 local real ux local real uy local real minx = GetRectMinX(r) local real maxx = GetRectMaxX(r) local real miny = GetRectMinY(r) local real maxy = GetRectMaxY(r) loop set ux = GetUnitX(udg_Hero[i]) set uy = GetUnitY(udg_Hero[i]) if ((ux > minx) and (ux < maxx) and (uy > miny) and (uy < maxy)) then return true endif set i = i + 1 exitwhen i > 3 endloop return false endfunction |
| 10-27-2007, 05:23 PM | #3 |
Small warning: the 'enters region' event may fire BEFORE a unit is actually inside the region. You may want a "is almost inside" function. |
| 10-27-2007, 06:29 PM | #4 |
Pyro - You're not exactly enabling my laziness. I know that making that function call (IsUnitInRangeXY) is slower than your method (and slightly more accurate, since you're using a square where I'm using a circle. I'll go ahead and use it though, since you took all the time to type it out for me :). Strilanc - I tested this all and it worked pretty much perfectly last night, and I came to the conclusion that you nailed the problem. My math skills were failing me - my region was a 400 x 400 box, and I was checking a circle with radius 250 from the center thinking that would give me plenty of extra space. Some simple geometry will tell you the distance from the center to a corner is ~283, which is the minimum I'd want my circle radius to be. Either way, I'll use Pyro's method but expand the bounds of the box a bit (ie minx = GetRectMinX(r) - 50, etc). Thanks to both of you. |
| 10-27-2007, 09:19 PM | #5 |
Why not just make the rects bigger in the editor? Edit: Oh, that's why. |
