| 09-03-2009, 03:06 PM | #1 | |
So, starting with the need of searching for nearest trees for a custom lumber harvesting system, I've come up with this code. Anyway, I'm kinda sure it can be improved, so I'll leave it to your expert eyes. ![]()
JASS:library FindFuncs globals //t1-21 are all the integer ids of the trees... private constant integer t1 = 'FTtw' private constant integer t2 = 'YTft' private constant integer t3 = 'BTtw' private constant integer t4 = 'VTlt' private constant integer t5 = 'KTtw' private constant integer t6 = 'DTsh' private constant integer t7 = 'JTtw' private constant integer t8 = 'OTtw' private constant integer t9 = 'ATtr' private constant integer t10 = 'CTtr' private constant integer t11 = 'ITtw' private constant integer t12 = 'NTtw' private constant integer t13 = 'LTlt' private constant integer t14 = 'YTct' private constant integer t15 = 'ZTtw' private constant integer t16 = 'JTct' private constant integer t17 = 'WTtw' private constant integer t18 = 'YTwt' private constant integer t19 = 'WTst' private constant integer t20 = 'YTst' private constant integer t21 = 'GTsh' private integer Id = 0 private destructable Dest = null private unit Unit = null private real Dist = -1 private real unitX = 0 private real unitY = 0 private rect r = null private boolean nearest = true private boolexpr cond = null endglobals private function Trees takes nothing returns boolean local integer id = GetDestructableTypeId(GetFilterDestructable()) return id == t1 or id == t2 or id == t3 or id == t4 or id == t5 or id == t6 or id == t7 or id == t8 or id == t9 or id == t10 or id == t11 or id == t12 or id == t13 or id == t14 or id == t15 or id == t16 or id == t17 or id == t18 or id == t19 or id == t20 or id == t21 endfunction private function DestCheck takes nothing returns boolean return GetDestructableTypeId(GetFilterDestructable()) == Id endfunction private function DestSearch takes nothing returns nothing local destructable d = GetEnumDestructable() local real dist local real dx local real dy set dx = unitX - GetDestructableX(d) set dy = unitY - GetDestructableY(d) set dist = (dx * dx + dy * dy) if nearest == true then if (Dist < 0) or (dist < Dist) then set Dest = d set Dist = dist endif else if (Dist < 0) or (dist > Dist) then set Dest = d set Dist = dist endif endif endfunction private function UnitSearch takes nothing returns boolean local unit u = GetFilterUnit() local real dist local real dx local real dy set dx = unitX - GetUnitX(u) set dy = unitY - GetUnitY(u) set dist = (dx * dx + dy * dy) if Id == 0 then if nearest == true then if (Dist < 0) or (dist < Dist) then set Unit = u set Dist = dist endif else if (Dist < 0) or (dist > Dist) then set Unit = u set Dist = dist endif endif elseif (GetUnitTypeId(GetFilterUnit())) == Id then if nearest == true then if (Dist < 0) or (dist < Dist) then set Unit = u set Dist = dist endif else if (Dist < 0) or (dist > Dist) then set Unit = u set Dist = dist endif endif endif return false endfunction function FindNearestTree takes real srcX, real srcY, real range returns destructable set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = true set cond = Condition(function Trees) call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, cond, function DestSearch) call DestroyBoolExpr(cond) return Dest endfunction function FindFarthestTree takes real srcX, real srcY, real range returns destructable set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = false set cond = Condition(function Trees) call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, cond, function DestSearch) call DestroyBoolExpr(cond) return Dest endfunction function FindNearestDestOfType takes real srcX, real srcY, real range, integer id returns destructable set Id = id set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = true set cond = Condition(function DestCheck) call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, cond, function DestSearch) call DestroyBoolExpr(cond) return Dest endfunction function FindFarthestDestOfType takes real srcX, real srcY, real range, integer id returns destructable set Id = id set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = false set cond = Condition(function DestCheck) call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, cond, function DestSearch) call DestroyBoolExpr(cond) return Dest endfunction function FindNearestDest takes real srcX, real srcY, real range returns destructable set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = true call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, null, function DestSearch) return Dest endfunction function FindFarthestDest takes real srcX, real srcY, real range returns destructable set unitX = srcX set unitY = srcY set Dist = -1 set Dest = null set nearest = false call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, null, function DestSearch) return Dest endfunction function FindNearestUnitOfType takes real srcX, real srcY, real range, integer id returns unit local group g = CreateGroup() set Id = id set unitX = srcX set unitY = srcY set Dist = -1 set Unit = null set nearest = true set cond = Condition(function UnitSearch) call GroupEnumUnitsInRange(g, unitX, unitY, range, cond) call DestroyBoolExpr(cond) call DestroyGroup(g) return Unit endfunction function FindFarthestUnitOfType takes real srcX, real srcY, real range, integer id returns unit local group g = CreateGroup() set Id = id set unitX = srcX set unitY = srcY set Dist = -1 set Unit = null set nearest = false set cond = Condition(function UnitSearch) call GroupEnumUnitsInRange(g, unitX, unitY, range, cond) call DestroyBoolExpr(cond) call DestroyGroup(g) return Unit endfunction function FindNearestUnit takes real srcX, real srcY, real range returns unit local group g = CreateGroup() set Id = 0 set unitX = srcX set unitY = srcY set Dist = -1 set Unit = null set nearest = true set cond = Condition(function UnitSearch) call GroupEnumUnitsInRange(g, unitX, unitY, range, cond) call DestroyBoolExpr(cond) call DestroyGroup(g) return Unit endfunction function FindFarthestUnit takes real srcX, real srcY, real range returns unit local group g = CreateGroup() set Id = 0 set unitX = srcX set unitY = srcY set Dist = -1 set Unit = null set nearest = false set cond = Condition(function UnitSearch) call GroupEnumUnitsInRange(g, unitX, unitY, range, cond) call DestroyBoolExpr(cond) call DestroyGroup(g) return Unit endfunction endlibrary |
| 09-03-2009, 03:50 PM | #2 |
I'm pretty sure you can get rid of the squareroot usage in your functions. Instead compare all squares of distances to find the shortest one, i.e. set dist = dx*dx + dy*dy and Dist = Dist*Dist. The rationale is that if the square of one distance is less than the square of another distance, the actual distance of the first is less than the second. I also noticed that you are creating rects, enumerating, and then not destroying them, as well as constantly destroying a separate boolexpr from the one you are using. Use a global rect and use MoveRectTo or SetRect to enumerate. A global boolexpr is also recommended so you only need one. In your Trees function, set a local integer equal to the destructable Id to save some cost. You could spread the function into a column of JASS:local boolean b = first condition set b = b and second condition set b = b and third condition.... but that's just fugly with all of those tree conditions. Stick to the one line, it doesn't matter much. |
| 09-03-2009, 04:11 PM | #3 |
Thanks for the help, I'll work on it right away EDIT: Done |
| 09-03-2009, 07:17 PM | #4 |
JASS:private function Trees takes nothing returns boolean local integer id = GetDestructableTypeId(GetFilterDestructable()) return id == t1 or id == t2 or id == t3 or id == t4 or id == t5 or id == t6 or id == t7 or id == t8 or id == t9 or id == t10 or id == t11 or id == t12 or id == t13 or id == t14 or id == t15 or id == t16 or id == t17 or id == t18 or id == t19 or id == t20 or id == t21 endfunction JASS:set cond = Condition(function Trees) call SetRect(r, unitX - range, unitY - range, unitX + range, unitY + range) call EnumDestructablesInRect(r, cond, function DestSearch) call DestroyBoolExpr(cond) //Wrong. JASS:local destructable d = GetEnumDestructable() local unit u = GetFilterUnit() //You never seem to null these? |
| 09-03-2009, 07:27 PM | #5 |
1) Don't need to destroy boolexprs 2) Use grouputils 3) There is a "IsTree" cond somewhere in database using "ghoul harvest" ability to check |
| 09-03-2009, 07:54 PM | #6 |
Pitzo tree detector function: JASS:function IsDestructableTree takes destructable d returns boolean local boolean i = IsDestructableInvulnerable(d) local unit u = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), <invisible caster>,GetWidgetX(d), GetWidgetY(d), 0) local boolean result = false call UnitAddAbility(u, 'Ahrl') if i then call SetDestructableInvulnerable(d, false) endif set result = IssueTargetOrder(u, "harvest", d) call RemoveUnit(u) if i then call SetDestructableInvulnerable(d, true) endif return result endfunction |
| 09-03-2009, 08:02 PM | #7 |
Should update it to use a single dummy though |
| 09-03-2009, 08:25 PM | #8 | |
Quote:
Wait, wait... wouldn't this be slower than my obnoxiously long check? |
| 09-03-2009, 08:27 PM | #9 |
Please use the one in the database. |
| 09-03-2009, 08:31 PM | #10 |
Okie, thanks everyone, I'll remove all of my noob-ish errors soon :P |
