|
|
|
|
JASS Functions Approved JASS functions will be located here.
Remember to submit your own resources to the submission forum. |
 |
06-11-2009, 08:46 PM
|
#1 (permalink)
|
|
Blasphemy!
Join Date: Oct 2008
Posts: 161
|
[vJass] Rectwraps
The combination of rects and regions into one body, in a nice vJassy way.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//~~ Rectwraps ~~ By Azlier ~~ Version 4.0~~ Documentation ripped off from Jesus4Lyf ~~//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//// What is Rectwraps?// - Rectwraps are essentially vJass replacements for the native rects and regions.// - They can be attached to safely, which has certain uses.// - Rectwraps recycles anything it creates.//// =Pros=// - Easy to use, once you learn the basic methods.// - Possibly faster than even native rects and regions.// - Fast, safe region attachment.// - No H2I/GetHandleId. Backwards compatability through patch 1.23 and 1.24.//// =Cons=// - Uses TriggerExecCount to store data. If over 1000 rectwraps are created at one time,// there may be a short lag spike.// - Only 8191 rectwraps can exist at one time with the default settings.//// Variables:// These coordinate variables can be both read and set. Reading them is much, much faster than setting them.// They are faster than their GetRect**** counterparts.//// .minX// The x coordinate of the rectwrap's left side.//// .maxX// The x coordinate of the rectwrap's right side.//// .minY// The y coordinate of the rectwrap's bottom side.//// .maxY// The x coordinate of the rectwrap's top side.//// .cenX// The x coordinate of the rectwrap's center.//// .cenY// The y coordinate of the rectwrap's center.//// This integer variable is really there just for fun. Do not use it in any public resource.// .userData//// Methods:// ~ Event responses// GetTriggeringRectwrap takes nothing returns rectwrap// This returns the entered/exited rectwrap when you enter/exit one.//// rectwrap.getTriggering() takes nothing returns rectwrap// Same as above, but in static method form.//// ~ Static// .wrap takes rect which returns rectwrap// Wraps a rect for use as a rectwrap. Purely for gg_rct rects.//// .create takes real x1, real y1, real x2, real y2 returns rectwrap// Creates a rectwrap from the given coordinates.//// .createFromPoint takes real x, real y, real width, real height returns rectwrap// Creates a rectwrap at a point with a set width and height.// ~ Non-static// .registerEnter takes trigger which returns trigger// Rigs a trigger to fire when the rectwrap is entered.// Also returns the given trigger so that you can use that weird one-line// coding style... if you really want to.//// .registerExit takes trigger which returns trigger// Same as above, but when the rectwrap is exited.//// .registerEnterCode takes code c returns trigger// Like .registerEnter, but takes a code. Returns the trigger the code was registered to.// THE CODE MUST RETURN A BOOLEAN.//// .registerExitCode takes code c returns trigger// ...Must I really explain?//// .destroy takes nothing returns nothing// Cleans the rectwrap's members. Recycles all handle members.//// .setTo takes real x1, real y1, real x2, real y2 returns nothing// Shifts a rectwrap's dimensions to the given values.//// .moveTo takes real x, real y returns nothing// Simply moves a rectwrap to the given coordinates without altering dimensions.//// .copy takes nothing returns rectwrap// Copies a rectwrap completely, right down to the user data. Probably not much use, but it's there...//// .replaceTerrain takes integer oldTerrain, integer terrain// Swaps all terrain of type oldTerrain for type terrain. Credits to Romek for this method.//// .setPathing takes pathingtype path, boolean on returns nothing// Sets the pathingtype for a rectwrap on or off.//// .iterateThrough takes IterateFunc func, real dist returns nothing.// Separates the rectwrap into distxdist cells and iterates through them, calling func with// that cell's center x and y as arguments.//// .groupEnum takes group g, boolexpr filter returns nothing// GroupEnumUnitsInRect without the rect.//// .createWeather takes integer id returns weathereffect// AddWeatherEffect without the rect.//// .addFog takes player p, fogstate f, boolean b1, boolean b2 returns fogmodifier// CreateFogModifierRect without the rect.//// .enumDestructables takes boolexpr filter, code enum returns nothing// EnumDestructablesInRect without the rect.//// .enumItems takes boolexpr filter, code enum returns nothing// EnumItemsInRect without the rect.//// .setBlight takes player p, boolean b returns nothing// SetBlight without the rect.//// .setDoodadAnimation takes integer i, string s, boolean b returns nothing// SetDoodadAnimationRect without the rect.//// .setFogState takes player p, fogstate f, boolean b returns nothing// SetFogStateRect without the rect.//// .coordsInRect takes real x, real y returns boolean// Returns whether the given coordinates are within the rect or not.////// Thanks:// - Jesus4Lyf: For his Event struct and TriggerExecCount attachment method.//// - Troll Brain: For discovering a grave bug.//// - Romek: For letting me duplicate his ReplaceTerrain script.//// - Darkfeet (Darthfett): For giving me the idea.//// - Skrarnaks: Spotting ANOTHER grave bug////// How to import:// - Create a trigger named Rectwraps.// - Convert it to custom text and replace all the trigger text with this.////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//Hack libraries to allow CamelCase library requirement.//Yes, even I wanted to be able to do that.library Rectwrap requires rectwrap endlibrarylibrary Rectwraps requires rectwrap endlibrarylibrary RectWrap requires rectwrap endlibrarylibrary RectWraps requires rectwrap endlibrarylibrary rectwrap globals private rectwrap TrigRec = 0endglobals//This is to simulate an event response.constant function GetTriggeringRectwrap takes nothing returns rectwrap return TrigRec endfunction //Jesus4Lyf's Event private struct Event private trigger trig private Event next static method create takes nothing returns Event local Event this=Event.allocate () set this.next= 0 return this endmethod private static Event current private static trigger t method fire takes nothing returns nothing local Event curr // this = last. loop set curr= this.next exitwhen curr== 0 set .t=curr.trig if IsTriggerEnabled (.t ) then set .current=curr if TriggerEvaluate (.t ) then call TriggerExecute (.t ) endif set this=curr else call EnableTrigger (.t ) // Was trigger destroyed? if IsTriggerEnabled (.t ) then call DisableTrigger (.t ) set this=curr else // If trigger destroyed... set .current.trig= null set this.next=curr.next call curr.destroy () endif endif endloop endmethod method register takes trigger t returns nothing local Event new=Event.allocate () set new.next= this.next set new.trig=t set this.next=new endmethod method chainDestroy takes nothing returns nothing loop call this.destroy () set this= this.next exitwhen this== 0 set this.trig= null endloop endmethod endstructprivate function interface IterateFilter takes real x, real y returns nothingstruct rectwrap //This was privatized because I don't want you touching it. Satisfied? private rect theRect private region reg private real minXR private real maxXR private real minYR private real maxYR private real cenXR private real cenYR //If you ever find yourself needing more of this, don't add more variables. //Use the struct directly as an index in an array. integer userData = 0 static constant method getTriggering takes nothing returns thistype return TrigRec endmethod //*********************** //* Rectwrap properties * //*********************** //! textmacro Rectwrap__Property takes NAME, CODE method operator $NAME$ takes nothing returns real return . $NAME$R endmethod method operator $NAME$= takes real r returns nothing call RegionClearRect (.reg, .theRect ) call SetRect (.theRect, $CODE$) call RegionAddRect (.reg, .theRect ) set .minXR = GetRectMinX (.theRect ) set .minYR = GetRectMaxX (.theRect ) set .maxXR = GetRectMinY (.theRect ) set .maxYR = GetRectMaxY (.theRect ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 endmethod //! endtextmacro //! runtextmacro Rectwrap__Property("minX", "r, .minYR, .maxXR, .maxYR") //! runtextmacro Rectwrap__Property("maxX", ".minXR, .minYR, r, .maxYR") //! runtextmacro Rectwrap__Property("minY", ".minXR, r, .maxXR, .maxYR") //! runtextmacro Rectwrap__Property("maxY", ".minXR, .minYR, .maxXR, r") method operator cenX takes nothing returns real return .cenXR endmethod method operator cenY takes nothing returns real return .cenYR endmethod //.cenX=, .cenY=. What a hack! method operator cenX= takes real r returns nothing call RegionClearRect (.reg, .theRect ) call MoveRectTo (.theRect, r, .cenY ) call RegionAddRect (.reg, .theRect ) set .minXR = GetRectMinX (.theRect ) set .minYR = GetRectMaxX (.theRect ) set .maxXR = GetRectMinY (.theRect ) set .maxYR = GetRectMaxY (.theRect ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 endmethod method operator cenY= takes real r returns nothing call RegionClearRect (.reg, .theRect ) call MoveRectTo (.theRect, .cenXR, r ) call RegionAddRect (.reg, .theRect ) set .minXR = GetRectMinX (.theRect ) set .minYR = GetRectMaxX (.theRect ) set .maxXR = GetRectMinY (.theRect ) set .maxYR = GetRectMaxY (.theRect ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 endmethod //**************************** //* Various rectish methods. * //**************************** //Wrap an existing rect. Purely for gg_rct_ rects. static method wrap takes rect which returns thistype local thistype this = thistype.allocate () set .minXR = GetRectMinX (which ) set .minYR = GetRectMinY (which ) set .maxXR = GetRectMaxX (which ) set .maxYR = GetRectMaxY (which ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 if .theRect == null then set .theRect = Rect (.minXR, .minYR, .maxXR, .maxYR ) set .reg = CreateRegion () call RegionAddRect (.reg, .theRect ) else call RegionClearRect (.reg, .theRect ) call SetRect (.theRect, .minXR, .minYR, .maxXR, .maxYR ) call RegionAddRect (.reg, .theRect ) endif return this endmethod //Creates a rectwrap out of nowhere. Uses recycled rects to minimize waste. static method create takes real x1, real y1, real x2, real y2 returns thistype local thistype this = thistype.allocate () if .theRect == null then set .theRect = Rect (x1, y1, x2, y2 ) set .reg = CreateRegion () call RegionAddRect (.reg, .theRect ) else call RegionClearRect (.reg, .theRect ) call SetRect (.theRect, x1, y1, x2, y2 ) call RegionAddRect (.reg, .theRect ) endif set .minXR = GetRectMinX (.theRect ) set .minYR = GetRectMaxX (.theRect ) set .maxXR = GetRectMinY (.theRect ) set .maxYR = GetRectMaxY (.theRect ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 return this endmethod //Creates a rectwrap from a point, using given width and height. static method createFromPoint takes real x, real y, real width, real height returns thistype local thistype this = thistype.allocate () set width = width / 2 set height = height / 2 if .theRect == null then set .theRect = Rect (x - width, y - height, x + width, y + height ) set .reg = CreateRegion () call RegionAddRect (.reg, .theRect ) else call RegionClearRect (.reg, .theRect ) call SetRect (.theRect, x - width, y - height, x + width, y + height ) call RegionAddRect (.reg, .theRect ) endif set .minXR = GetRectMinX (.theRect ) set .minYR = GetRectMaxX (.theRect ) set .maxXR = GetRectMinY (.theRect ) set .maxYR = GetRectMaxY (.theRect ) set .cenXR = .minXR + (.maxXR - .minXR ) / 2 set .cenYR = .minYR + (.maxYR - .minYR ) / 2 return this endmethod //Copies a rectwrap. Hey, someone might actually use this. Someday. method copy takes nothing returns thistype local thistype new = thistype.allocate () if new.theRect == null then set new.theRect = Rect (.minX, .minY, .maxX, .maxY ) set .reg = CreateRegion () call RegionAddRect (.reg, .theRect ) else call RegionClearRect (.reg, .theRect ) call SetRect (new.theRect, .minX, .minY, .maxX, .maxY ) call RegionAddRect (.reg, .theRect ) endif set new.minX = .minX set new.minY = .minY set new.maxX = .maxX set new.maxY = .maxY set new.cenX = .cenX set new.cenY = .cenY set new.userData = .userData return new endmethod //Sets a rectwrap to an area, changing dimensions. method setTo takes real x1, real y1, real x2, real y2 returns nothing call RegionClearRect (.reg, .theRect ) call SetRect (.theRect, x1, y1, x2, y2 ) call RegionAddRect (.reg, .theRect ) set .minX = GetRectMinX (.theRect ) set .minY = GetRectMinY (.theRect ) set .maxX = GetRectMaxX (.theRect ) set .maxY = GetRectMaxY (.theRect ) set .cenX = .minX + (.maxX - .minX ) / 2 set .cenY = .minY + (.maxY - .minY ) / 2 endmethod //Moves a rectwrap, without changing dimensions. method moveTo takes real x, real y returns nothing call RegionClearRect (.reg, .theRect ) call MoveRectTo (.theRect, x, y ) call RegionAddRect (.reg, .theRect ) set .minX = GetRectMinX (.theRect ) set .minY = GetRectMinY (.theRect ) set .maxX = GetRectMaxX (.theRect ) set .maxY = GetRectMaxY (.theRect ) set .cenX = .minX + (.maxX - .minX ) / 2 set .cenY = .minY + (.maxY - .minY ) / 2 endmethod //Iteration methods (credits to Romek for the original ReplaceTerrain) //These three variables are to be shared with the other iteration methods. private static real curX private static real curY private static thistype tempRW private static integer old private static integer new private static method ReplaceTerrainB takes nothing returns nothing loop if GetTerrainType (.curX, .curY ) == .old then call SetTerrainType (.curX, .curY, .new, - 1, 1, 1) endif set .curX = .curX + 128 exitwhen .curX > .tempRW.maxX endloop endmethod private static method ReplaceTerrainA takes nothing returns nothing loop set .curX = .tempRW.minX + 64 call ReplaceTerrainB.execute () set .curY = .curY + 128 exitwhen .curY > .tempRW.maxY endloop endmethod method replaceTerrain takes integer oldTerrain, integer terrain returns nothing set .old = oldTerrain set .new = terrain set .curX = .minX + 64 set .curY = .minY + 64 //Magic numbers for the win. set .tempRW = this call ReplaceTerrainA.execute () endmethod //SetPathing methods private static pathingtype path private static boolean pathOn private static method SetPathingB takes nothing returns nothing loop call SetTerrainPathable (.curX, .curY, .path, .pathOn ) set .curX = .curX + 32 exitwhen .curX > .tempRW.maxX endloop endmethod private static method SetPathingA takes nothing returns nothing loop set .curX = .tempRW.minX + 16 call SetPathingB.execute () set .curY = .curY + 32 exitwhen .curY > .tempRW.maxY endloop endmethod method setPathing takes pathingtype path, boolean on returns nothing set .path = path set .pathOn = on set .curX = .minX + 16 set .curY = .minY + 16 //Magic numbers for the win. set .tempRW = this call SetPathingA.execute () endmethod //Iteration methods private static real iterateDist private static IterateFilter iterateFunc private static method IterateThroughB takes nothing returns nothing loop call iterateFunc.execute (.curX, .curY ) set .curX = .curX + .tempRW.iterateDist exitwhen .curX > .tempRW.maxX endloop endmethod private static method IterateThroughA takes nothing returns nothing loop set .curX = .tempRW.minX + .tempRW.iterateDist / 2 call IterateThroughB.execute () set .curY = .curY + .tempRW.iterateDist exitwhen .curY > .tempRW.maxY endloop endmethod method iterateThrough takes IterateFilter func, real dist returns nothing set .iterateFunc = func set .iterateDist = dist set .curX = .minX + dist / 2 set .curY = .minY + dist / 2 set .tempRW = this call IterateThroughA.execute () endmethod //! textmacro Rectwraps__wrapperMethod takes NAME, ARGS, RETURNS, CODE method $NAME$ takes $ARGS$ returns $RETURNS$ $CODE$ endmethod //! endtextmacro //BJlike, shorter to type wrapper methods. //! runtextmacro Rectwraps__wrapperMethod("groupEnum", "group g, boolexpr b", "nothing", "call GroupEnumUnitsInRect(g, .theRect, b)") //! runtextmacro Rectwraps__wrapperMethod("createWeather", "integer i", "weathereffect", "return AddWeatherEffect(.theRect, i)") //! runtextmacro Rectwraps__wrapperMethod("addFog", "player p, fogstate f, boolean b1, boolean b2", "fogmodifier", "return CreateFogModifierRect(p, f, .theRect, b1, b2)") //! runtextmacro Rectwraps__wrapperMethod("enumDestructables","boolexpr filter, code enum","nothing","call EnumDestructablesInRect(.theRect, filter, enum)") //! runtextmacro Rectwraps__wrapperMethod("enumItems","boolexpr filter, code enum","nothing","call EnumItemsInRect(.theRect, filter, enum)") //! runtextmacro Rectwraps__wrapperMethod("setBlight","player p, boolean b","nothing","call SetBlightRect(p, .theRect, b)") //! runtextmacro Rectwraps__wrapperMethod("setDoodadAnimation","integer i, string s, boolean b","nothing","call SetDoodadAnimationRect(.theRect, i, s, b)") //! runtextmacro Rectwraps__wrapperMethod("setFogState","player p, fogstate f, boolean b","nothing","call SetFogStateRect(p, f, .theRect, b)") //! runtextmacro Rectwraps__wrapperMethod("coordsInRect","real x, real y","boolean","return x >= .minX and x <= .maxX and y >= .minY and y <= .maxY") //! runtextmacro Rectwraps__wrapperMethod("isPointOn","real x, real y","boolean","return IsPointInRegion(.reg, x, y)") //! runtextmacro Rectwraps__wrapperMethod("isUnitOn","unit u","boolean","return IsUnitInRegion(.reg, u)") //*************************************************** //* Onto the nasty stuff (regions, triggers, etc.). * //*************************************************** private Event EnEv private Event ExEv private trigger EnTrig private trigger ExTrig private static boolexpr OnEnter private static boolexpr OnExit //The function fired when a unit enters the rectwrap. private static method OnEnterFunc takes nothing returns boolean set TrigRec = GetTriggerExecCount (GetTriggeringTrigger ()) call TrigRec.EnEv.fire () set TrigRec = 0 return false endmethod //Same as above, but when the unit leaves. private static method OnExitFunc takes nothing returns boolean set TrigRec = GetTriggerExecCount (GetTriggeringTrigger ()) call TrigRec.ExEv.fire () set TrigRec = 0 return false endmethod private static method SetTrigData takes trigger t, integer i returns nothing loop exitwhen i == 0 call TriggerExecute (t ) set i = i - 1 endloop endmethod //Readies a trigger to fire when the rectwrap is entered. method registerEnter takes trigger whichTrigger returns trigger if .EnEv == 0 then set .EnEv = Event.create () endif if .EnTrig == null then set .EnTrig = CreateTrigger () call thistype.SetTrigData.execute (.EnTrig, this) call TriggerRegisterEnterRegion (.EnTrig, .reg, null) call TriggerAddCondition (.EnTrig, .OnEnter ) elseif not IsTriggerEnabled (.EnTrig ) then call EnableTrigger (.EnTrig ) endif call .EnEv.register (whichTrigger ) return whichTrigger endmethod //Does the same as above, but for when a unit leaves. method registerExit takes trigger whichTrigger returns trigger if .ExEv == 0 then set .ExEv = Event.create () endif if .ExTrig == null then set .ExTrig = CreateTrigger () call thistype.SetTrigData.execute (.ExTrig, this) call TriggerRegisterLeaveRegion (.ExTrig, .reg, null) call TriggerAddCondition (.ExTrig, .OnExit ) elseif not IsTriggerEnabled (.ExTrig ) then call EnableTrigger (.ExTrig ) endif call .ExEv.register (whichTrigger ) return whichTrigger endmethod //registerCode methods. They return the trigger in case the user wants to destroy it. private static trigger tempTrig method registerEnterCode takes code c returns trigger set .tempTrig = CreateTrigger () call TriggerAddCondition (.registerEnter (.tempTrig ), Condition (c )) return .tempTrig endmethod method registerExitCode takes code c returns trigger set .tempTrig = CreateTrigger () call TriggerAddCondition (.registerExit (.tempTrig ), Condition (c )) return .tempTrig endmethod //Now, we clean everything up in the event that the rectwrap is destroyed. method onDestroy takes nothing returns nothing if .EnEv != 0 then call .EnEv.chainDestroy () set .EnEv = 0 endif if .ExEv != 0 then call .ExEv.chainDestroy () set .ExEv = 0 endif if .EnTrig != null then call DisableTrigger (.EnTrig ) endif if .ExTrig != null then call DisableTrigger (.ExTrig ) endif //The rects, regions, and triggers are not destroyed. //They are recycled. endmethod //************************* //* Struct initialization * //************************* private static method onInit takes nothing returns nothing set .OnEnter = Filter (function thistype.OnEnterFunc ) set .OnExit = Filter (function thistype.OnExitFunc ) endmethodendstructendlibrary
There's also a method called iterateThrough that is not as easy to use as the others. What iterateThrough does is separate a rectwrap into a grid of cells of the given size, "dist". It then moves through every cell and calls the given function with that cell's center x and y as arguments. This is a very powerful tool.
Please refrain from supplying iterateThrough with arguments less than 8 or 16 or so. Smaller numbers mean more cells, which means more calculations.
Example:
function DoSomething takes real x, real y returns nothing call CreateItem ('I000', x, y ) //Or something. //This will move through a grid of 32x32 cells in the rectwrap, creating an item in the center of each.endfunctionfunction StartIterate takes nothing returns nothing call MyRectwrap.iterateThrough (DoSomething, 32)endfunction
Last edited by azlier; 01-16-2010 at 03:20 AM.
|
|
|
09-03-2009, 04:59 PM
|
#2 (permalink)
|
|
Blasphemy!
Join Date: Oct 2008
Posts: 161
|
'Twould truly be a shame to let this rot in the submission forum. This is the most useful thing I ever wrote.
Suggestions? Anything? I can't think of much more to add.
|
|
|
09-04-2009, 12:08 AM
|
#3 (permalink)
|
|
OOP freak.
Join Date: Feb 2006
Posts: 751
|
Ok, looks good. Your test map is kinda outdated but w/e.
|
|
|
09-04-2009, 01:48 AM
|
#4 (permalink)
|
|
Blasphemy!
Join Date: Oct 2008
Posts: 161
|
Thank you! I will update the test map as soon as I am able. Which is this weekend.
EDIT: Done. This testmap actually shows some of their true power.
Last edited by azlier; 09-04-2009 at 11:54 PM.
|
|
|
09-05-2009, 02:10 PM
|
#5 (permalink)
|
|
BBoy Silv
Join Date: Nov 2006
Posts: 1,192
|
Nice! This is really useful, thanks a lot! :D
|
|
|
09-05-2009, 04:24 PM
|
#6 (permalink)
|
|
User
Join Date: Jul 2007
Posts: 427
|
One of the best systems ever written ^_^
+rep
|
|
|
09-06-2009, 12:48 PM
|
#7 (permalink)
|
|
BBoy Silv
Join Date: Nov 2006
Posts: 1,192
|
Maybe add a createCenter method? Which would a rectwrap from the center point.
static method createCenter takes real centerX, real centerY, real width, real height returns rectwrap
|
|
|
09-09-2009, 03:18 PM
|
#8 (permalink)
|
|
Blasphemy!
Join Date: Oct 2008
Posts: 161
|
Sounds like a good idea. I can't believe someone actually thought of something to add.
It'll be done in... 1.5 weeks.
EDIT: Done.
Last edited by azlier; 09-19-2009 at 01:34 AM.
|
|
|
11-01-2009, 07:06 PM
|
#9 (permalink)
|
|
Anozer jasser
Join Date: Apr 2008
Posts: 244
|
Since Azlier doesn't seems to care about tell it, for those which already use it (doesn't seems so  , or at least they never change the rect or destroy an instance of a rectwrap), a major bug was fixed.
Copy/paste the new code.
|
|
|
01-16-2010, 03:21 AM
|
#10 (permalink)
|
|
Blasphemy!
Join Date: Oct 2008
Posts: 161
|
Updated, with the replaceTerrain, setPathing, and iterateThrough methods fixed.
Also with a better description of iterateThrough.
|
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
|
|
|
|