| 03-27-2007, 06:03 PM | #1 |
I want to make it so when the hero enters a region creeps are spawned within the area (Like you enter a swamp and they are created there). I'd like it so creep A patrols to points 1,2,3 while creep B patrols points 4,5,6,7. Right now I'm making the map use different regions, like swamp, destroyed town, forest for the areas where the creeps patrol. If I could make it so if a creep enters a region in this Region Variable Array I think I could figure it out, but I can't ![]() |
| 03-28-2007, 05:24 AM | #2 |
Well, here's a JASS solution that I whipped up, though I don't know if it'll work. Detect your unit entering the region, create the units to patrol, add them to a group, pick a number of circuits, and run this function: JASS:function GroupPatrol4Rects takes group Group, rect Patrol1, rect Patrol2, rect Patrol3, rect Patrol4, integer Circuits returns nothing local group g = Group local group g2 local unit u local rect array PatrolRect local region array PatrolRegion local boolean In = false local boolean In2 = false local integer i local integer Target = 1 local integer CircuitNumber = 1 local integer TargetTotal = 4 local location l = GetRectCenter(Patrol1) local real x = GetLocationX(l) local real y = GetLocationY(l) call RemoveLocation(l) set PatrolRect[1] = Patrol1 set PatrolRect[2] = Patrol2 set PatrolRect[3] = Patrol3 set PatrolRect[4] = Patrol4 loop set i = i+1 exitwhen i > 4 set PatrolRegion[i] = CreateRegion() if PatrolRect[i] == null then set TargetTotal = TargetTotal-1 else call RegionAddRect(PatrolRegion[i], PatrolRect[i]) endif endloop set g2 = g loop set u = FirstOfGroup(g2) exitwhen u == null call IssuePointOrder(u, "attack", x, y) if IssuePointOrder(u, "attack", x, y) == false then call GroupRemoveUnit(g, u) endif call GroupRemoveUnit(g2, u) endloop call DestroyGroup(g2) loop if Circuits == 0 then exitwhen (CountUnitsInGroup(g) == 0) else exitwhen (CountUnitsInGroup(g) == 0) or (CircuitNumber > Circuits) endif loop exitwhen Target > TargetTotal loop exitwhen In2 set g2 = g set l = GetRectCenter(PatrolRect[Target+1]) set x = GetLocationX(l) set y = GetLocationY(l) call RemoveLocation(l) loop set u = FirstOfGroup(g2) exitwhen u == null or In if GetUnitCurrentOrder(u) != 851983 then call IssuePointOrder(u, "attack", x, y) endif set In = IsUnitInRegion(PatrolRegion[Target], u) call GroupRemoveUnit(g2, u) endloop call DestroyGroup(g2) if In then set In = false set g2 = g set l = GetRectCenter(PatrolRect[Target+1]) set x = GetLocationX(l) set y = GetLocationY(l) call RemoveLocation(l) loop set u = FirstOfGroup(g2) exitwhen u == null call IssuePointOrder(u, "attack", x, y) call GroupRemoveUnit(g2, u) endloop call DestroyGroup(g2) set In2 = true endif call PolledWait(0.25) endloop set In2 = false set Target = Target+1 endloop set Target = 1 set CircuitNumber = CircuitNumber+1 endloop set i = 0 loop set i = i+1 exitwhen i > 4 call RemoveRegion(PatrolRegion[i]) set PatrolRect[i] = null set PatrolRegion[i] = null endloop call DestroyGroup(g) set g = null set g2 = null set u = null set l = null endfunction |
| 03-28-2007, 03:53 PM | #3 |
I'm just begining to learn jass so if you could go in more depth about what's what that would help alot. |
| 03-29-2007, 03:25 AM | #4 |
Sure, I can do that. I also tested this, and it doesn't work. Once I get it working, I'll put comments in and upload the working version. |
| 03-29-2007, 05:22 AM | #5 |
Ok, so everything works fine except for the line(s) hilighted in red. I could use someone's advice for why it's not detecting that the unit is in the region. JASS:function GroupPatrol4Rects takes group Group, rect Patrol1, rect Patrol2, rect Patrol3, rect Patrol4, integer Circuits returns nothing local group g = Group local group g2 local unit u local rect array PatrolRect local region array PatrolRegion local boolean In = false local boolean In2 = false local integer i = 0 local integer Target = 0 local integer CircuitNumber = 0 local integer TargetTotal = 4 local location l = GetRectCenter(Patrol1) local real x = GetLocationX(l) local real y = GetLocationY(l) call BJDebugMsg("Something Happened") call RemoveLocation(l) set PatrolRect[1] = Patrol1 set PatrolRect[2] = Patrol2 set PatrolRect[3] = Patrol3 set PatrolRect[4] = Patrol4 loop set i = i+1 exitwhen i > 4 set PatrolRegion[i] = CreateRegion() if PatrolRect[i] == null then set TargetTotal = TargetTotal-1 else call RegionAddRect(PatrolRegion[i], PatrolRect[i]) endif endloop call BJDebugMsg("TargetTotal: " + I2S(TargetTotal)) set g2 = g loop set u = FirstOfGroup(g2) exitwhen u == null if IssuePointOrder(u, "attack", x, y) == false then call GroupRemoveUnit(g, u) call BJDebugMsg("Removed") endif call GroupRemoveUnit(g2, u) endloop call DestroyGroup(g2) call GroupPointOrder(g, "attack", x, y) loop set CircuitNumber = CircuitNumber+1 call BJDebugMsg("CircuitNumber = " + I2S(CircuitNumber)) exitwhen CircuitNumber > Circuits //if Circuits == 0 then // exitwhen (CountUnitsInGroup(g) == 0) //else // exitwhen (CountUnitsInGroup(g) == 0) or (CircuitNumber > Circuits) //endif loop set Target = Target+1 call BJDebugMsg("Target = " + I2S(Target)) exitwhen Target > TargetTotal loop exitwhen In2 set g2 = g set l = GetRectCenter(PatrolRect[Target+1]) set x = GetLocationX(l) set y = GetLocationY(l) call RemoveLocation(l) loop set u = FirstOfGroup(g2) exitwhen u == null or In if GetUnitCurrentOrder(u) != 851983 then call IssuePointOrder(u, "attack", x, y) call BJDebugMsg("Backup Attack Order'd") endif set In = IsUnitInRegion(PatrolRegion[Target], u) if In then call BJDebugMsg("In region: yes") else call BJDebugMsg("In region: no") endif call GroupRemoveUnit(g2, u) endloop call DestroyGroup(g2) if In then call BJDebugMsg("In == true") set In = false set l = GetRectCenter(PatrolRect[Target+1]) set x = GetLocationX(l) set y = GetLocationY(l) call RemoveLocation(l) call GroupPointOrder(g, "attack", x, y) set In2 = true endif call PolledWait(0.25) call BJDebugMsg("Target loop loop'd") endloop call BJDebugMsg("Target loop exited") set In2 = false endloop set Target = 1 endloop set i = 0 loop set i = i+1 exitwhen i > 4 call RemoveRegion(PatrolRegion[i]) set PatrolRect[i] = null set PatrolRegion[i] = null endloop call DestroyGroup(g) set g = null set g2 = null set u = null set l = null call BJDebugMsg("Ended") endfunction Additionally, this should work for any number of regions as long as you change a few integers in the code, and/or put "null" as one of the rects. Would that actually work, the way I've set it up? Lastly, there's this giant commented-out if statement: JASS://if Circuits == 0 then // exitwhen (CountUnitsInGroup(g) == 0) //else // exitwhen (CountUnitsInGroup(g) == 0) or (CircuitNumber > Circuits) //endif I was attempting to get it to exit when the group was empty, but for some reason the CountUnitsInGroup(g) == 0 part was making it instantly exit. Why? |
| 03-29-2007, 06:19 AM | #6 |
Just exit when FirstOfGroup(group) == null. Also, you already destroyed the group you're trying to count the units in. Group -> g -> g2 -> loop through group -> destroy g2 |
| 03-30-2007, 01:24 AM | #7 |
As wyrmlord has said, it seems you are destroying the unit group before it's being used in the attack order loop that checks regions. (think of it in handles) You're setting g2 to equal g, which is equal to the Group argument. They all point to the same group. Destroying it once means it should be destroyed for all, I believe. You'd probably want to do: JASS:local g2 = CreateGroup() //... call GroupAddGroup(g2, g) //(or just GroupAddGroup(g, Group)) Also, are regions really necessary here? There exists the JASS function "RectContainsUnit" function that returns a boolean. JASS:function RectContainsCoords takes rect r, real x, real y returns boolean return (GetRectMinX(r) <= x) and (x <= GetRectMaxX(r)) and (GetRectMinY(r) <= y) and (y <= GetRectMaxY(r)) endfunction function RectContainsUnit takes rect r, unit whichUnit returns boolean return RectContainsCoords(r, GetUnitX(whichUnit), GetUnitY(whichUnit)) endfunction Plus there are these two natives: JASS:native GetRectCenterX takes rect whichRect returns real native GetRectCenterY takes rect whichRect returns real |
| 03-30-2007, 01:41 AM | #8 |
Yes! Thank you Krysho. I was looking for a "unit in rect" native, but nothing showed up on the ClanWENW website search. Oh well. Are groups just funky like that in that if you set one to another and then destroy the second one, it will remove the first? Do other variables do this? I've never noticed that before, but I suppose it could be happening. Thanks to both of you for your help! Rep'd! BattleBotv8.2, I should be completed soon. |
| 03-30-2007, 01:50 AM | #9 |
Since handles are just references to the real handle data, you'd be copying the reference to the new variable, not the actual data. Therefore, both variables will be pointing to the same data. If you were to destroy the group on one of the variables, it'd still be pointing to the destroyed group until you null the variable or change its value. However, the second variable would also be pointing to a destroyed group. Pretty sure it's the same for most things, and it is, in fact, the idea I use behind clean-up in one of my maps: Trigger: ![]() Set temploc = RawPoint![]() Set RawPoint = (RawPoint offset by (YardsLength x 5.00) towards 90.00 degrees)![]() Custom script: call RemoveLocation(udg_temploc)Though I could've just saved the X and Y coordinates of the region and destroyed it without reusing it. Suffice to say I'd have done a lot of things differently now in my map that I started over two years ago. JASS:set l = GetRectCenter(PatrolRect[Target+1]) set x = GetLocationX(l) set y = GetLocationY(l) call RemoveLocation(l) JASS:set x = GetRectCenterX(PatrolRect[Target+1]) set y = GetRectCenterY(PatrolRect[Target+1]) Just since you didn't mention considering that part (two functions versus four). |
