• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[System] Rectwraps

Level 8
Joined
Oct 3, 2008
Messages
367
JASS:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~ Rectwraps ~~ By Azlier ~~ 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
endlibrary
library Rectwraps requires rectwrap
endlibrary
library RectWrap requires rectwrap
endlibrary
library RectWraps requires rectwrap
endlibrary

library rectwrap

globals
    private rectwrap TrigRec = 0
endglobals

//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
    endstruct

private function interface IterateFilter takes real x, real y returns nothing

struct 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 = GetRectMinY(.theRect)
        set .maxXR = GetRectMaxX(.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 = GetRectMinY(.theRect)
        set .maxXR = GetRectMaxX(.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.minXR = .minXR
        set new.minYR = .minYR
        set new.maxXR = .maxXR
        set new.maxYR = .maxYR
        set new.cenXR = .cenXR
        set new.cenYR = .cenYR
        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 .minXR = GetRectMinX(.theRect)
        set .minYR = GetRectMinY(.theRect)
        set .maxXR = GetRectMaxX(.theRect)
        set .maxYR = GetRectMaxY(.theRect)
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
        set .cenYR = .minYR + (.maxYR - .minYR) / 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 .minXR = GetRectMinX(.theRect)
        set .minYR = GetRectMinY(.theRect)
        set .maxXR = GetRectMaxX(.theRect)
        set .maxYR = GetRectMaxY(.theRect)
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
        set .cenYR = .minYR + (.maxYR - .minYR) / 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 .old == 0 or 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 >= .minXR and x <= .maxXR and y >= .minYR and y <= .maxYR")
    //! 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)
    endmethod
   
endstruct

endlibrary
 

Attachments

  • Rectwraps.w3m
    28.8 KB · Views: 274
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
Since Azlier doesn't seems to care about tell it, for those which already use it (doesn't seems so :grin:, 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.
 
Level 8
Joined
Oct 3, 2008
Messages
367
well, for one, you cant easily attach to native regions without some hashtable tomfoolery. this uses a method faster than hashtables and does it cleanly behind the scenes, on top of recycling its handles during normal operation making it easy to use in cases where you require dynamic rect/region usage without fear of memory leaks

as for making your own, i guess you can say that about any script, cant you?

its a combination wrapper that encompasses both rects and regions. the only cases where i wouldnt recommend it are where you need to do things with rects alone (such as destructable enumeration) and in cases where you need irregularly shaped (ie non-rectangular) regions

also contains some methods for changing terrain, pathing, and such. also lets you iterate through it on your own terms
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
I still don't get it :/
To influence the oder of how your code gets compiled by the JassHelper.
You need it if you want to provide 100% backwards compability for an deprecated resource sharing the same API.
I don't see an advantage in it for rectwrap, just a fingerprint of azlier.

Of course you can now do --> library xy uses rectwarp, Rectwrap, RectWrap, RectWraps
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Shall I ask the purpose of this :
JASS:
library Rectwrap requires rectwrap
endlibrary
library Rectwraps requires rectwrap
endlibrary
library RectWrap requires rectwrap
endlibrary
library RectWraps requires rectwrap
endlibrary
I still don't get it :/

so... what is this? :p

I think in some conditions we may ask something here..
 
Can I use this to check if all points in a rectwrap are blighted? I'm making some sort of teleporting building spell that can be interrupted if the destination's blight is removed, so .iterateThrough sounds really useful for that. However, I don't really understand how to use IterateFunc func.

Help

EDIT: So Wareditor helped me out with it, though I would say the instructions for .iterateThrough could use a little demo in the OP. Filters are not exactly simple and people not well-versed in code would have a hard time figuring it out.
 
Last edited:
Level 26
Joined
Mar 19, 2008
Messages
3,140
Those function-objects filters could be replaced by precidates (delegate based structs). Would make them elegant while still being arbitrary.

Unfortunately, azlier never updated his lib. Generates plenty of unnecessary methods (after compilation there are even more of them), wraps Event lib within its code (which is not really allowed, you should specify requirements instead) and more.

Overall, my Rects is rectwraps after heavy lifting + contains some useful rect-based functions taken from typical UI oriented dialects, like intersect method.
Maybe, just maybe, iterate method could be added. Though that sounds more like a plugin, rather than part of core library. On the other hand, I might be wrong, and such method should be added.
 
Last edited:
Top