[System] Rectwraps

Scripts

14 years
edited 8 years
Code (jass) Select
1
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2
//~~ Rectwraps ~~ By Azlier ~~ Documentation ripped off from Jesus4Lyf ~~
3
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
//
5
//  What is Rectwraps?
6
//         - Rectwraps are essentially vJass replacements for the native rects and regions.
7
//         - They can be attached to safely, which has certain uses.
8
//         - Rectwraps recycles anything it creates.
9
//
10
//    =Pros=
11
//         - Easy to use, once you learn the basic methods.
12
//         - Possibly faster than even native rects and regions.
13
//         - Fast, safe region attachment.
14
//         - No H2I/GetHandleId. Backwards compatability through patch 1.23 and 1.24.
15
//
16
//    =Cons=
17
//         - Uses TriggerExecCount to store data. If over 1000 rectwraps are created at one time,
18
//           there may be a short lag spike.
19
//         - Only 8191 rectwraps can exist at one time with the default settings.
20
//
21
//    Variables:
22
//      These coordinate variables can be both read and set. Reading them is much, much faster than setting them.
23
//      They are faster than their GetRect**** counterparts.
24
//
25
//         .minX
26
//          The x coordinate of the rectwrap's left side.
27
//
28
//         .maxX
29
//          The x coordinate of the rectwrap's right side.
30
//
31
//         .minY
32
//          The y coordinate of the rectwrap's bottom side.
33
//
34
//         .maxY
35
//          The x coordinate of the rectwrap's top side.
36
//
37
//         .cenX
38
//          The x coordinate of the rectwrap's center.
39
//
40
//         .cenY
41
//          The y coordinate of the rectwrap's center.
42
//
43
//      This integer variable is really there just for fun. Do not use it in any public resource.
44
//         .userData
45
//
46
//    Methods:
47
//         ~ Event responses
48
//             GetTriggeringRectwrap takes nothing returns rectwrap
49
//               This returns the entered/exited rectwrap when you enter/exit one.
50
//
51
//             rectwrap.getTriggering() takes nothing returns rectwrap
52
//               Same as above, but in static method form.
53
//
54
//         ~ Static
55
//             .wrap takes rect which returns rectwrap
56
//               Wraps a rect for use as a rectwrap. Purely for gg_rct rects.
57
//
58
//             .create takes real x1, real y1, real x2, real y2 returns rectwrap
59
//               Creates a rectwrap from the given coordinates.
60
//
61
//             .createFromPoint takes real x, real y, real width, real height returns rectwrap
62
//               Creates a rectwrap at a point with a set width and height.
63
//         ~ Non-static
64
//            .registerEnter takes trigger which returns trigger
65
//              Rigs a trigger to fire when the rectwrap is entered.
66
//              Also returns the given trigger so that you can use that weird one-line
67
//              coding style... if you really want to.
68
//
69
//            .registerExit takes trigger which returns trigger
70
//              Same as above, but when the rectwrap is exited.
71
//
72
//            .registerEnterCode takes code c returns trigger
73
//              Like .registerEnter, but takes a code. Returns the trigger the code was registered to.
74
//              THE CODE MUST RETURN A BOOLEAN.
75
//
76
//            .registerExitCode takes code c returns trigger
77
//              ...Must I really explain?
78
//
79
//            .destroy takes nothing returns nothing
80
//              Cleans the rectwrap's members. Recycles all handle members.
81
//
82
//            .setTo takes real x1, real y1, real x2, real y2 returns nothing
83
//              Shifts a rectwrap's dimensions to the given values.
84
//
85
//            .moveTo takes real x, real y returns nothing
86
//              Simply moves a rectwrap to the given coordinates without altering dimensions.
87
//
88
//            .copy takes nothing returns rectwrap
89
//              Copies a rectwrap completely, right down to the user data. Probably not much use, but it's there...
90
//
91
//            .replaceTerrain takes integer oldTerrain, integer terrain
92
//              Swaps all terrain of type oldTerrain for type terrain. Credits to Romek for this method.
93
//
94
//            .setPathing takes pathingtype path, boolean on returns nothing
95
//              Sets the pathingtype for a rectwrap on or off.
96
//
97
//            .iterateThrough takes IterateFunc func, real dist returns nothing.
98
//              Separates the rectwrap into distxdist cells and iterates through them, calling func with
99
//              that cell's center x and y as arguments.
100
//
101
//            .groupEnum takes group g, boolexpr filter returns nothing
102
//              GroupEnumUnitsInRect without the rect.
103
//
104
//            .createWeather takes integer id returns weathereffect
105
//              AddWeatherEffect without the rect.
106
//
107
//            .addFog takes player p, fogstate f, boolean b1, boolean b2 returns fogmodifier
108
//              CreateFogModifierRect without the rect.
109
//
110
//            .enumDestructables takes boolexpr filter, code enum returns nothing
111
//              EnumDestructablesInRect without the rect.
112
//
113
//            .enumItems takes boolexpr filter, code enum returns nothing
114
//              EnumItemsInRect without the rect.
115
//
116
//            .setBlight takes player p, boolean b returns nothing
117
//              SetBlight without the rect.
118
//
119
//            .setDoodadAnimation takes integer i, string s, boolean b returns nothing
120
//              SetDoodadAnimationRect without the rect.
121
//
122
//            .setFogState takes player p, fogstate f, boolean b returns nothing
123
//              SetFogStateRect without the rect.
124
//
125
//            .coordsInRect takes real x, real y returns boolean
126
//              Returns whether the given coordinates are within the rect or not.
127
//
128
//
129
//  Thanks:
130
//         - Jesus4Lyf: For his Event struct and TriggerExecCount attachment method.
131
//
132
//         - Troll Brain: For discovering a grave bug.
133
//
134
//         - Romek: For letting me duplicate his ReplaceTerrain script.
135
//
136
//         - Darkfeet (Darthfett): For giving me the idea.
137
//
138
//         - Skrarnaks: Spotting ANOTHER grave bug
139
//
140
//
141
//  How to import:
142
//         - Create a trigger named Rectwraps.
143
//         - Convert it to custom text and replace all the trigger text with this.
144
//
145
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
146
147
//Hack libraries to allow CamelCase library requirement.
148
//Yes, even I wanted to be able to do that.
149
library Rectwrap requires rectwrap
150
endlibrary
151
library Rectwraps requires rectwrap
152
endlibrary
153
library RectWrap requires rectwrap
154
endlibrary
155
library RectWraps requires rectwrap
156
endlibrary
157
158
library rectwrap
159
160
globals
161
    private rectwrap TrigRec = 0
162
endglobals
163
164
//This is to simulate an event response.
165
constant function GetTriggeringRectwrap takes nothing returns rectwrap
166
    return TrigRec
167
endfunction
168
  
169
    //Jesus4Lyf's Event
170
    private struct Event
171
        private trigger trig
172
        private Event next
173
        static method create takes nothing returns Event
174
            local Event this=Event.allocate()
175
            set this.next=0
176
            return this
177
        endmethod
178
        private static Event current
179
        private static trigger t
180
        method fire takes nothing returns nothing
181
            local Event curr
182
            // this = last.
183
            loop
184
                set curr=this.next
185
                exitwhen curr==0
186
                set .t=curr.trig
187
                if IsTriggerEnabled(.t) then
188
                    set .current=curr
189
                    if TriggerEvaluate(.t) then
190
                        call TriggerExecute(.t)
191
                    endif
192
                    set this=curr
193
                else
194
                    call EnableTrigger(.t) // Was trigger destroyed?
195
                    if IsTriggerEnabled(.t) then
196
                        call DisableTrigger(.t)
197
                        set this=curr
198
                    else // If trigger destroyed...
199
                        set .current.trig=null
200
                        set this.next=curr.next
201
                        call curr.destroy()
202
                    endif
203
                endif
204
            endloop
205
        endmethod
206
        method register takes trigger t returns nothing
207
            local Event new=Event.allocate()
208
            set new.next=this.next
209
            set new.trig=t
210
            set this.next=new
211
        endmethod
212
        method chainDestroy takes nothing returns nothing
213
            loop
214
                call this.destroy()
215
                set this=this.next
216
                exitwhen this==0
217
                set this.trig=null
218
            endloop
219
        endmethod
220
    endstruct
221
222
private function interface IterateFilter takes real x, real y returns nothing
223
224
struct rectwrap
225
  
226
    //This was privatized because I don't want you touching it. Satisfied?
227
    private rect theRect
228
    private region reg
229
  
230
    private real minXR
231
    private real maxXR
232
    private real minYR
233
    private real maxYR
234
    private real cenXR
235
    private real cenYR
236
  
237
    //If you ever find yourself needing more of this, don't add more variables.
238
    //Use the struct directly as an index in an array.
239
    integer userData = 0
240
  
241
    static constant method getTriggering takes nothing returns thistype
242
        return TrigRec
243
    endmethod
244
  
245
    //***********************
246
    //* Rectwrap properties *
247
    //***********************
248
    //! textmacro Rectwrap__Property takes NAME, CODE
249
    method operator $NAME$ takes nothing returns real
250
        return .$NAME$R
251
    endmethod
252
  
253
    method operator $NAME$= takes real r returns nothing
254
        call RegionClearRect(.reg, .theRect)
255
        call SetRect(.theRect, $CODE$)
256
        call RegionAddRect(.reg, .theRect)
257
        set .minXR = GetRectMinX(.theRect)
258
        set .minYR = GetRectMaxX(.theRect)
259
        set .maxXR = GetRectMinY(.theRect)
260
        set .maxYR = GetRectMaxY(.theRect)
261
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
262
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
263
    endmethod
264
    //! endtextmacro
265
  
266
    //! runtextmacro Rectwrap__Property("minX", "r, .minYR, .maxXR, .maxYR")
267
    //! runtextmacro Rectwrap__Property("maxX", ".minXR, .minYR, r, .maxYR")
268
    //! runtextmacro Rectwrap__Property("minY", ".minXR, r, .maxXR, .maxYR")
269
    //! runtextmacro Rectwrap__Property("maxY", ".minXR, .minYR, .maxXR, r")
270
  
271
    method operator cenX takes nothing returns real
272
        return .cenXR
273
    endmethod
274
  
275
    method operator cenY takes nothing returns real
276
        return .cenYR
277
    endmethod
278
  
279
    //.cenX=, .cenY=. What a hack!
280
    method operator cenX= takes real r returns nothing
281
        call RegionClearRect(.reg, .theRect)
282
        call MoveRectTo(.theRect, r, .cenY)
283
        call RegionAddRect(.reg, .theRect)
284
        set .minXR = GetRectMinX(.theRect)
285
        set .minYR = GetRectMaxX(.theRect)
286
        set .maxXR = GetRectMinY(.theRect)
287
        set .maxYR = GetRectMaxY(.theRect)
288
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
289
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
290
    endmethod
291
  
292
    method operator cenY= takes real r returns nothing
293
        call RegionClearRect(.reg, .theRect)
294
        call MoveRectTo(.theRect, .cenXR, r)
295
        call RegionAddRect(.reg, .theRect)
296
        set .minXR = GetRectMinX(.theRect)
297
        set .minYR = GetRectMaxX(.theRect)
298
        set .maxXR = GetRectMinY(.theRect)
299
        set .maxYR = GetRectMaxY(.theRect)
300
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
301
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
302
    endmethod
303
  
304
    //****************************
305
    //* Various rectish methods. *
306
    //****************************
307
  
308
    //Wrap an existing rect. Purely for gg_rct_ rects.
309
    static method wrap takes rect which returns thistype
310
        local thistype this = thistype.allocate()
311
        set .minXR = GetRectMinX(which)
312
        set .minYR = GetRectMinY(which)
313
        set .maxXR = GetRectMaxX(which)
314
        set .maxYR = GetRectMaxY(which)
315
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
316
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
317
        if .theRect == null then
318
            set .theRect = Rect(.minXR, .minYR, .maxXR, .maxYR)
319
            set .reg = CreateRegion()
320
            call RegionAddRect(.reg, .theRect)
321
        else
322
            call RegionClearRect(.reg, .theRect)
323
            call SetRect(.theRect, .minXR, .minYR, .maxXR, .maxYR)
324
            call RegionAddRect(.reg, .theRect)
325
        endif
326
        return this
327
    endmethod
328
  
329
    //Creates a rectwrap out of nowhere. Uses recycled rects to minimize waste.
330
    static method create takes real x1, real y1, real x2, real y2 returns thistype
331
        local thistype this = thistype.allocate()
332
        if .theRect == null then
333
            set .theRect = Rect(x1, y1, x2, y2)
334
            set .reg = CreateRegion()
335
            call RegionAddRect(.reg, .theRect)
336
        else
337
            call RegionClearRect(.reg, .theRect)
338
            call SetRect(.theRect, x1, y1, x2, y2)
339
            call RegionAddRect(.reg, .theRect)
340
        endif
341
        set .minXR = GetRectMinX(.theRect)
342
        set .minYR = GetRectMinY(.theRect)
343
        set .maxXR = GetRectMaxX(.theRect)
344
        set .maxYR = GetRectMaxY(.theRect)
345
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
346
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
347
        return this
348
    endmethod
349
  
350
    //Creates a rectwrap from a point, using given width and height.
351
    static method createFromPoint takes real x, real y, real width, real height returns thistype
352
        local thistype this = thistype.allocate()
353
        set width = width / 2
354
        set height = height / 2
355
        if .theRect == null then
356
            set .theRect = Rect(x - width, y - height, x + width, y + height)
357
            set .reg = CreateRegion()
358
            call RegionAddRect(.reg, .theRect)
359
        else
360
            call RegionClearRect(.reg, .theRect)
361
            call SetRect(.theRect, x - width, y - height, x + width, y + height)
362
            call RegionAddRect(.reg, .theRect)
363
        endif
364
        set .minXR = GetRectMinX(.theRect)
365
        set .minYR = GetRectMinY(.theRect)
366
        set .maxXR = GetRectMaxX(.theRect)
367
        set .maxYR = GetRectMaxY(.theRect)
368
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
369
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
370
        return this
371
    endmethod
372
  
373
    //Copies a rectwrap. Hey, someone might actually use this. Someday.
374
    method copy takes nothing returns thistype
375
        local thistype new = thistype.allocate()
376
        if new.theRect == null then
377
            set new.theRect = Rect(.minX, .minY, .maxX, .maxY)
378
            set .reg = CreateRegion()
379
            call RegionAddRect(.reg, .theRect)
380
        else
381
            call RegionClearRect(.reg, .theRect)
382
            call SetRect(new.theRect, .minX, .minY, .maxX, .maxY)
383
            call RegionAddRect(.reg, .theRect)
384
        endif
385
        set new.minXR = .minXR
386
        set new.minYR = .minYR
387
        set new.maxXR = .maxXR
388
        set new.maxYR = .maxYR
389
        set new.cenXR = .cenXR
390
        set new.cenYR = .cenYR
391
        set new.userData = .userData
392
        return new
393
    endmethod
394
  
395
    //Sets a rectwrap to an area, changing dimensions.
396
    method setTo takes real x1, real y1, real x2, real y2 returns nothing
397
        call RegionClearRect(.reg, .theRect)
398
        call SetRect(.theRect, x1, y1, x2, y2)
399
        call RegionAddRect(.reg, .theRect)
400
        set .minXR = GetRectMinX(.theRect)
401
        set .minYR = GetRectMinY(.theRect)
402
        set .maxXR = GetRectMaxX(.theRect)
403
        set .maxYR = GetRectMaxY(.theRect)
404
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
405
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
406
    endmethod
407
  
408
    //Moves a rectwrap, without changing dimensions.
409
    method moveTo takes real x, real y returns nothing
410
        call RegionClearRect(.reg, .theRect)
411
        call MoveRectTo(.theRect, x, y)
412
        call RegionAddRect(.reg, .theRect)
413
        set .minXR = GetRectMinX(.theRect)
414
        set .minYR = GetRectMinY(.theRect)
415
        set .maxXR = GetRectMaxX(.theRect)
416
        set .maxYR = GetRectMaxY(.theRect)
417
        set .cenXR = .minXR + (.maxXR - .minXR) / 2
418
        set .cenYR = .minYR + (.maxYR - .minYR) / 2
419
    endmethod
420
  
421
    //Iteration methods (credits to Romek for the original ReplaceTerrain)
422
  
423
    //These three variables are to be shared with the other iteration methods.
424
    private static real curX
425
    private static real curY
426
    private static thistype tempRW
427
  
428
    private static integer old
429
    private static integer new
430
  
431
    private static method ReplaceTerrainB takes nothing returns nothing
432
        loop
433
            if .old == 0 or GetTerrainType(.curX, .curY) == .old then
434
                call SetTerrainType(.curX, .curY, .new, -1, 1, 1)
435
            endif
436
            set .curX = .curX + 128
437
            exitwhen .curX > .tempRW.maxX
438
        endloop
439
    endmethod
440
  
441
    private static method ReplaceTerrainA takes nothing returns nothing
442
        loop
443
            set .curX = .tempRW.minX + 64
444
            call ReplaceTerrainB.execute()
445
            set .curY = .curY + 128
446
            exitwhen .curY > .tempRW.maxY
447
        endloop
448
    endmethod
449
  
450
    method replaceTerrain takes integer oldTerrain, integer terrain returns nothing
451
        set .old = oldTerrain
452
        set .new = terrain
453
        set .curX = .minX + 64
454
        set .curY = .minY + 64 //Magic numbers for the win.
455
        set .tempRW = this
456
        call ReplaceTerrainA.execute()
457
    endmethod
458
  
459
    //SetPathing methods
460
    private static pathingtype path
461
    private static boolean pathOn
462
  
463
    private static method SetPathingB takes nothing returns nothing
464
        loop
465
            call SetTerrainPathable(.curX, .curY, .path, .pathOn)
466
            set .curX = .curX + 32
467
            exitwhen .curX > .tempRW.maxX
468
        endloop
469
    endmethod
470
  
471
    private static method SetPathingA takes nothing returns nothing
472
        loop
473
            set .curX = .tempRW.minX + 16
474
            call SetPathingB.execute()
475
            set .curY = .curY + 32
476
            exitwhen .curY > .tempRW.maxY
477
        endloop
478
    endmethod
479
  
480
    method setPathing takes pathingtype path, boolean on returns nothing
481
        set .path = path
482
        set .pathOn = on
483
        set .curX = .minX + 16
484
        set .curY = .minY + 16 //Magic numbers for the win.
485
        set .tempRW = this
486
        call SetPathingA.execute()
487
    endmethod
488
  
489
    //Iteration methods
490
  
491
    private static real iterateDist
492
    private static IterateFilter iterateFunc
493
  
494
    private static method IterateThroughB takes nothing returns nothing
495
        loop
496
            call iterateFunc.execute(.curX, .curY)
497
            set .curX = .curX + .tempRW.iterateDist
498
            exitwhen .curX > .tempRW.maxX
499
        endloop
500
    endmethod
501
  
502
    private static method IterateThroughA takes nothing returns nothing
503
        loop
504
            set .curX = .tempRW.minX + .tempRW.iterateDist / 2
505
            call IterateThroughB.execute()
506
            set .curY = .curY + .tempRW.iterateDist
507
            exitwhen .curY > .tempRW.maxY
508
        endloop
509
    endmethod
510
  
511
    method iterateThrough takes IterateFilter func, real dist returns nothing
512
        set .iterateFunc = func
513
        set .iterateDist = dist
514
        set .curX = .minX + dist / 2
515
        set .curY = .minY + dist / 2
516
        set .tempRW = this
517
        call IterateThroughA.execute()
518
    endmethod
519
  
520
    //! textmacro Rectwraps__wrapperMethod takes NAME, ARGS, RETURNS, CODE
521
    method $NAME$ takes $ARGS$ returns $RETURNS$
522
        $CODE$
523
    endmethod
524
    //! endtextmacro
525
  
526
    //BJlike, shorter to type wrapper methods.
527
    //! runtextmacro Rectwraps__wrapperMethod("groupEnum", "group g, boolexpr b", "nothing", "call GroupEnumUnitsInRect(g, .theRect, b)")
528
    //! runtextmacro Rectwraps__wrapperMethod("createWeather", "integer i", "weathereffect", "return AddWeatherEffect(.theRect, i)")
529
    //! runtextmacro Rectwraps__wrapperMethod("addFog", "player p, fogstate f, boolean b1, boolean b2", "fogmodifier", "return CreateFogModifierRect(p, f, .theRect, b1, b2)")
530
    //! runtextmacro Rectwraps__wrapperMethod("enumDestructables","boolexpr filter, code enum","nothing","call EnumDestructablesInRect(.theRect, filter, enum)")
531
    //! runtextmacro Rectwraps__wrapperMethod("enumItems","boolexpr filter, code enum","nothing","call EnumItemsInRect(.theRect, filter, enum)")
532
    //! runtextmacro Rectwraps__wrapperMethod("setBlight","player p, boolean b","nothing","call SetBlightRect(p, .theRect, b)")
533
    //! runtextmacro Rectwraps__wrapperMethod("setDoodadAnimation","integer i, string s, boolean b","nothing","call SetDoodadAnimationRect(.theRect, i, s, b)")
534
    //! runtextmacro Rectwraps__wrapperMethod("setFogState","player p, fogstate f, boolean b","nothing","call SetFogStateRect(p, f, .theRect, b)")
535
    //! runtextmacro Rectwraps__wrapperMethod("coordsInRect","real x, real y","boolean","return x >= .minXR and x <= .maxXR and y >= .minYR and y <= .maxYR")
536
    //! runtextmacro Rectwraps__wrapperMethod("isPointOn","real x, real y","boolean","return IsPointInRegion(.reg, x, y)")
537
    //! runtextmacro Rectwraps__wrapperMethod("isUnitOn","unit u","boolean","return IsUnitInRegion(.reg, u)")
538
  
539
    //***************************************************
540
    //* Onto the nasty stuff (regions, triggers, etc.). *
541
    //***************************************************
542
  
543
    private Event EnEv
544
    private Event ExEv
545
  
546
    private trigger EnTrig
547
    private trigger ExTrig
548
  
549
  
550
    private static boolexpr OnEnter
551
    private static boolexpr OnExit
552
  
553
    //The function fired when a unit enters the rectwrap.
554
    private static method OnEnterFunc takes nothing returns boolean
555
        set TrigRec = GetTriggerExecCount(GetTriggeringTrigger())
556
        call TrigRec.EnEv.fire()
557
        set TrigRec = 0
558
        return false
559
    endmethod
560
  
561
    //Same as above, but when the unit leaves.
562
    private static method OnExitFunc takes nothing returns boolean
563
        set TrigRec = GetTriggerExecCount(GetTriggeringTrigger())
564
        call TrigRec.ExEv.fire()
565
        set TrigRec = 0
566
        return false
567
    endmethod
568
  
569
    private static method SetTrigData takes trigger t, integer i returns nothing
570
        loop
571
            exitwhen i == 0
572
            call TriggerExecute(t)
573
            set i = i - 1
574
        endloop
575
    endmethod
576
  
577
    //Readies a trigger to fire when the rectwrap is entered.
578
    method registerEnter takes trigger whichTrigger returns trigger
579
        if .EnEv == 0 then
580
            set .EnEv = Event.create()
581
        endif
582
        if .EnTrig == null then
583
            set .EnTrig = CreateTrigger()
584
            call thistype.SetTrigData.execute(.EnTrig, this)
585
            call TriggerRegisterEnterRegion(.EnTrig, .reg, null)
586
            call TriggerAddCondition(.EnTrig, .OnEnter)
587
        elseif not IsTriggerEnabled(.EnTrig) then
588
            call EnableTrigger(.EnTrig)
589
        endif
590
        call .EnEv.register(whichTrigger)
591
        return whichTrigger
592
    endmethod
593
  
594
    //Does the same as above, but for when a unit leaves.
595
    method registerExit takes trigger whichTrigger returns trigger
596
        if .ExEv == 0 then
597
            set .ExEv = Event.create()
598
        endif
599
        if .ExTrig == null then
600
            set .ExTrig = CreateTrigger()
601
            call thistype.SetTrigData.execute(.ExTrig, this)
602
            call TriggerRegisterLeaveRegion(.ExTrig, .reg, null)
603
            call TriggerAddCondition(.ExTrig, .OnExit)
604
        elseif not IsTriggerEnabled(.ExTrig) then
605
            call EnableTrigger(.ExTrig)
606
        endif
607
        call .ExEv.register(whichTrigger)
608
        return whichTrigger
609
    endmethod
610
  
611
    //registerCode methods. They return the trigger in case the user wants to destroy it.
612
    private static trigger tempTrig
613
  
614
    method registerEnterCode takes code c returns trigger
615
        set .tempTrig = CreateTrigger()
616
        call TriggerAddCondition(.registerEnter(.tempTrig), Condition(c))
617
        return .tempTrig
618
    endmethod
619
  
620
    method registerExitCode takes code c returns trigger
621
        set .tempTrig = CreateTrigger()
622
        call TriggerAddCondition(.registerExit(.tempTrig), Condition(c))
623
        return .tempTrig
624
    endmethod
625
  
626
    //Now, we clean everything up in the event that the rectwrap is destroyed.
627
    method onDestroy takes nothing returns nothing
628
        if .EnEv != 0 then
629
            call .EnEv.chainDestroy()
630
            set .EnEv = 0
631
        endif
632
        if .ExEv != 0 then
633
            call .ExEv.chainDestroy()
634
            set .ExEv = 0
635
        endif
636
        if .EnTrig != null then
637
            call DisableTrigger(.EnTrig)
638
        endif
639
        if .ExTrig != null then
640
            call DisableTrigger(.ExTrig)
641
        endif
642
        //The rects, regions, and triggers are not destroyed.
643
        //They are recycled.
644
    endmethod
645
  
646
    //*************************
647
    //* Struct initialization *
648
    //*************************
649
  
650
    private static method onInit takes nothing returns nothing
651
        set .OnEnter = Filter(function thistype.OnEnterFunc)
652
        set .OnExit = Filter(function thistype.OnExitFunc)
653
    endmethod
654
  
655
endstruct
656
657
endlibrary
  • Rectwraps.w3m (28.83 KB)