• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

WonderRect

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Overview

WonderRect is a happy, little library to create ALICE objects out of pre-placed rects. It emulates regions without using the native type. WonderRegions expand native regions by allowing triangular shapes, giving you the ability to compute the distance of an object to the nearest edge of the region, as well as providing a way to enumerate objects inside of it with ALICE_EnumObjectsInRegion.

In addition, WonderRect offers convenient, automatic grouping of rects and merges them into regions based on their names. If you're not using ALICE, you might still find this automatic rect grouping useful. You can remove all mentions of ALICE from the code and modify the library to fit your own needs.


How to Use

WonderRect creates a list of all preplaced rects (as their name) in the RectList global. You can use this table to access your rects manually.

For WonderRect to create regions out of our preplaced rects successfully, they must be grouped by name. The rects' names should be formatted as:
Lua:
<prefix><Name><X><modifiers>

Prefix
Only necessary when using the WonderRect.CreateAll function.

Name
The name of our rect batch.

X
An integer. All rects with the same prefix and name, but different integers are joined together into one region.

modifiers
These are optional and modify the shape or the active edges of the final region. Rects can also be modified with the respective API functions instead of by using modifiers.

Example:
Lua:
--Our list of preplaced rects
gg_rct_fogModifierTemple1
gg_rct_fogModifierTemple2bottomleft
gg_rct_fogModifierForest1TTTF
gg_rct_fogModifierForest2
gg_rct_killZoneNorth
gg_rct_killZoneSouth

--Create a data table for our fog modifiers:
local DATA = {
    temple = {
        density = 2
    },
    forest = {
        color = blue
    }
}

--Create a region for each fog modifier:
WonderRect.CreateAll("fogModifier", {camera = AdjustFog}, DATA, true)

--Create the kill zones north and south.
DATA = {
    --Callback for WonderRect.Event.
    onEnter = function(wonderRegion, unit)
        KillUnit(unit)
    end
}
WonderRect.CreateAll("killZone", {unit = WonderRect.Event}, DATA)

Modifiers

Modifiers are put after the rect number and are ignored in search patterns. You can create more complex region shapes with non-perpendicular edges by turning one or more rects into triangles. You do so by appending the vertex that is missing from the rect at the end of its name:
Lua:
"topleft"
"topright"
"bottomleft"
"bottomright"

Edge flags, on the other hand, modify which edges are considered when calculating the edge distance with WonderRect.GetEdgeDistance. This lets you control how far "into the region" an object inside a region is considered when you're changing a state continuously, like, for example, the fog density as it is done in the test map.

The edge flag is a string of four T or F. Each denotes if an edge is active (true or false), starting with the right edge and going counter-clockwise.
Lua:
gg_rct_fogModifierForest1FFFT --only the bottom edge is active
When joining multiple rects for one region, all rect edges that are touching another rect are automatically removed and do not need to be disabled manually.


Installation

Follow the ALICE installation guide. WonderRect itself can be installed simply by copy&pasting the script file into your map.
Contents

WonderRect (Map)

WonderRect (Binary)

The RectList concept is cool, as well as the underlying concept of creating more unique shapes like triangles or polygons from rectangles :)

But IMO I think the modifiers and the way triangles are integrated (by subtracting vertices) is a bit counterintuitive/clunky. I feel like I'd need to go back to the reference documentation each time to make a triangle, and I wouldn't be super confident of getting the order right so I think it'd be a bit frustrating for the user. Not to mention the name, since once something is a triangle, it is no longer a Rect(angle). :grin: I think I'm also still having a hard time understanding why modifiers are needed.

If you want to support triangles, I'd personally make a separate class for a Triangle and a Rect--and then they can share some common function API (e.g. ContainsUnit). And maybe a polygon/N-gon class for making a shape out of multiple rects. Maybe it could be a "WonderShape" library. :thumbs_up: In my head that'd be a bit more intuitive. And maybe leaning a bit more on function-based APIs--less on naming and string-based APIs since those are a little harder to get intellisense assistance on.
 

Antares

Spell Reviewer
Level 33
Joined
Dec 13, 2009
Messages
1,001
The name suffixes are one way to modify the rects, the other is with the functions SetActiveEdges and ConvertToTriangle. I found it cumbersome to use those functions, so I added the string suffixes, but you can definitely just use the API functions instead. But I am actually a dingus and completely forgot to add a function list at the top of the library. I will fix that.

It is true that a triangle is no longer a rectangle, but the library is named after the native type and I can't rename that one :pcry:.

What do you think is the most intuitive way to declare what orientation you want the triangle to have?

Creating different classes is not something I'm a fan of (not a fan of OOP/inheritance in general).
 
Oh sweet, thanks for adding the docs! That helps. And no worries about the lib name haha, I was just teasing. :pir:

As for the triangle concept, the most intuitive way for me personally is to just have a function that lets you create a triangle by providing an (x1, y1), (x2, y2), (x3, y3) set of coordinates. BUT after looking at the sample map I see now that you designed it that way so you can more easily make the shape you want via pre-placed regions. So I think it is great as you have it.

I might've gotten it confused with the edge flags syntax (FFFT), which I think I only sorta understood once I took a look at the sample map (it seems like you use it to determine how far "into" a region a unit is, to control the fog density). I think I understand it better now. For others who try to check out this system, it might be good to list some small examples of what you can do with your system (e.g. detecting when a unit enters a complexly shaped zone, controlling fog depending on how "deep" you are in the region) somewhere in the description just to help clarify why the features like the modifiers are useful. :thumbs_up: I think I also couldn't see innately what the "interactions" are (maybe that is an ALICE thing?).

But overall, after checking out the sample map I got a better idea of what you could do with it. Cool stuff!
 
Top