• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Grid system

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
EDIT: See my bottom post for an updated version, this attempt at a decent system was crap (not CanFight's fault, my own).

I threw together a little grid system based on CanFight's system. It allows you to give each player their own grid with it's own size. I got a bit lazy with some things and I don't really know how to use Lua to it's full potential so it's not perfect. For demo purposes you can press the ESCAPE key to Show/Hide your grid and type -new to create a new grid somewhere else.

gs_gridStartX, gs_gridStartY, gs_gridWidth, and gs_gridHeight can be given default values in the DEFINE THESE VARIABLES section of the code. The first value in each of them represents Player 1's data, with each subsequent value representing the next player (p2, p3, p4, etc).

For the ability idea you would do something like this (assuming you've created a grid for the player already):
  • Events
    • Unit - A unit Starts the effect of an ability
  • Conditions
    • (Ability being cast) Equal to Toggle Grid
  • Actions
    • Set Variable PlayerNumber = (Player number of (Triggering player))
    • Custom script: gs_ShowHideGrid(udg_PlayerNumber - 1)
The system is indexed starting at 0 so Player 1 is 0, Player 2 is 1, Player 3 is 2, etc...
 
Last edited:
Level 12
Joined
Jan 10, 2023
Messages
191
Alright, I decided I wanted to give this a go, so I hope this is something like what you needed (in GUI).

A short description of how this works:
  • Any unit with the 'Grid' ability can use the grid, but only one at a time per player.
  • The grid will follow the 'host' unit around while the grid is active AND the unit is selected.
  • If the unit is deselected, the ability will deactivate and the grid will turn off. The ability can also be deactivated directly.
  • The hotkey for on/off is 'G'
  • The grid size can be changed by changing the assigned values of GridSizeX and GridSizeY in the 'GridInit' Trigger.
  • Opted for 64x64 squares since thats the smallest that a building moves on.
  • The grid does not need to be square, but odd numbers are recommended for the GridSize variables so that it will center properly.
  • The default number of players can be changed in the 'GridInit' trigger, default is 12. This must be as high as the highest number player slot used.
It does not have the same color potential as CanFight's system and is likely missing other features to be desired for, but if I understand what you wanted alright, I think it will meet your needs and is in GUI.

Feel free to change the icons or anything else. I made the grid piece myself so you don't have to worry about finding out who to credit it to lol.

I took a glance at CanFight's system and gave him credit in the Map Description, but I don't really want to assume that CanFight wants credit for my GUI system, so there's that.

On the other hand, I am basically illiterate at JASS and so could not have really stolen much from him.. I doubt they are really very similar...

EDIT: Accidentally had left it so that the Immolation flames still showed on the unit casting the grid, fixed that and re-uploaded it.

Here's what I came up with in GUI:
Description of variables you may want to change:

GridMaxPlayer (Integer) - Highest Player Number of Players Using Grid, Default of 12, change in 'GridInit'.
GridSizeX (Integer) - Horizontal size of the grid. I haven't tested the limits, default is 9. An odd number is recommended for visual reasons.
GridSizeY (Integer) - Vertical size of the grid. I haven't tested the limits, default is 9. An odd number is recommended for visual reasons.

You may also want to change the frequency at which the grid updates, I set it to once every 0.20 seconds by default.

Description of variables not to change:

GridRectSize (Integer) - GridSizeX x GridSizeY. No need to change this variable.
GridCoorX (Integer) - X coordinate used by the looper when making the grid. No need to change this variable.
GridCoorY (Integer) - Y coordinate used by the looper when making the grid. No need to change this variable.
GridImagesHash (Hashtable) - Stores the images in a hashtable to be referred to when they are moved/ shown/ hidden.
GridOnPlayer[] (Boolean) - Stores whether a players grid is on. Array index 0 is used to determine whether any grid is on.
GridHostUnit[] (Unit) - Stores the unit that the grid is following.
GrisPos (Point) - Stores the grid-point nearest to 'GridHostUnit'. (point is stored so it can be removed).
GridSubPos (Point) - Stores the grid-point for individual grid squares. (point is stored so it can be removed).
GridPlayerLoop (Integer) - Integer value used for looping through the players.
GridHashLoop (Integer) - Integer value used for looping through the player's grids.

"GridInit" is where you would input your grid X/Y using GridSizeX and GridSizeY
You will also have to set the number of players here, if you plan to use player slots higher than 12...
I set it to 12 by default because I don't see any issue with having the unused slot if a player is missing.
  • GridInit
    • Events
      • Time - Elapsed game time is 0.50 seconds
    • Conditions
    • Actions
      • Set VariableSet GridMaxPlayer = 12
      • Set VariableSet GridSizeX = 9
      • Set VariableSet GridSizeY = 9
      • Set VariableSet GridHashSize = (GridSizeX x GridSizeY)
      • Hashtable - Create a hashtable
      • Set VariableSet GridImagesHash = (Last created hashtable)
      • For each (Integer GridPlayerLoop) from 1 to GridMaxPlayer, do (Actions)
        • Loop - Actions
          • Set VariableSet GridSubPos = (Center of (Playable map area))
          • Set VariableSet GridPos = (GridSubPos offset by ((0.00 - ((X of GridSubPos) mod 64.00)), (0.00 - ((Y of GridSubPos) mod 64.00))))
          • Custom script: call RemoveLocation(udg_GridSubPos)
          • For each (Integer GridHashLoop) from 0 to (GridHashSize - 1), do (Actions)
            • Loop - Actions
              • Set VariableSet GridHashX = ((GridHashLoop mod GridSizeX) - (GridSizeX / 2))
              • Set VariableSet GridHashY = (((GridHashLoop - (GridHashLoop mod GridSizeX)) / GridSizeX) - (GridSizeY / 2))
              • Set VariableSet GridSubPos = (GridPos offset by ((64.00 x (Real(GridHashX))), (64.00 x (Real(GridHashY)))))
              • Image - Create an image using war3mapImported\Grid64.blp of size 64.00 at GridSubPos with Z offset 0.00 using image type Indicator
              • Hashtable - Save Handle Of(Last created image) as GridPlayerLoop of GridHashLoop in GridImagesHash.
              • Custom script: call RemoveLocation(udg_GridSubPos)
          • Custom script: call RemoveLocation(udg_GridPos)

If the unit that has the grid ability is already using an immolation-based ability you will need to change this ability. I assumed it would be a builder and wouldn't need immolation.

If other units are going to use immolation, you should add a condition here that 'Ordered unit' Equal to 'Grid-Ability-Guy' or 'Unit-type of Ordered Unit Equal to 'Grid-Ability-Guy-Type' - I'm assuming you are savvy enough for this one, but let me know if you don't understand me.
  • GridOn
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(immolation))
    • Actions
      • Set VariableSet GridHostUnit[(Player number of (Owner of (Ordered unit)))] = (Ordered unit)
      • Set VariableSet GridOnPlayer[(Player number of (Owner of (Ordered unit)))] = True
      • Trigger - Turn on GridLoop <gen>

This Trigger is meant to turn off the grid if you deselect the grid unit. I'm imagining in a tower defense game you might click on a tower and you wouldn't want the grid to persist, so this will hide the grid if you deselect a unit.

This system only makes one grid per player so you would need it to hide when deselecting if one player can have multiple builders. This way if I switch from builder A to builder B, the grid around builder A is hidden and I can now turn the grid on for builder B if I want to.

This trigger ultimately just gives the unit the order to deactivate immolation, thereby forcing the "GridOff" trigger.
  • GridDeselect
    • Events
      • Player - Player 1 (Red) Deselects a unit
      • Player - Player 2 (Blue) Deselects a unit
      • Player - Player 3 (Teal) Deselects a unit
      • Player - Player 4 (Purple) Deselects a unit
      • Player - Player 5 (Yellow) Deselects a unit
      • Player - Player 6 (Orange) Deselects a unit
      • Player - Player 7 (Green) Deselects a unit
      • Player - Player 8 (Pink) Deselects a unit
      • Player - Player 9 (Gray) Deselects a unit
      • Player - Player 10 (Light Blue) Deselects a unit
      • Player - Player 11 (Dark Green) Deselects a unit
      • Player - Player 12 (Brown) Deselects a unit
    • Conditions
      • GridOnPlayer[(Player number of (Owner of (Triggering unit)))] Equal to True
      • GridHostUnit[(Player number of (Owner of (Triggering unit)))] Equal to (Triggering unit)
    • Actions
      • Unit - Order (Triggering unit) to Night Elf Demon Hunter - Deactivate Immolation.

This is the trigger for turning the grid off via the normal method of turning the ability off. The deselect trigger just activates this trigger by giving the unit the order to deactivate immolation.
  • GridOff
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(unimmolation))
      • GridHostUnit[(Player number of (Owner of (Ordered unit)))] Equal to (Ordered unit)
    • Actions
      • Set VariableSet GridOnPlayer[(Player number of (Owner of (Ordered unit)))] = False

The Grid is always there, each player has there own, this trigger moves each players grid to the right place and ensures it is turned on.
If no players have a grid on, this trigger turns off. If just one player has the grid on, it stays on but only shows the grid of players with active grids.
  • GridLoop - (Initially Off)
    • Events
      • Time - Every 0.20 seconds of game time
    • Conditions
    • Actions
      • For each (Integer GridPlayerLoop) from 1 to GridMaxPlayer, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • GridOnPlayer[GridPlayerLoop] Equal to True
            • Then - Actions
              • Set VariableSet GridOnPlayer[0] = True
              • Set VariableSet GridPos = (Position of GridHostUnit[GridPlayerLoop])
              • Set VariableSet GridSubPos = (GridPos offset by (16.00, 16.00))
              • Custom script: call RemoveLocation(udg_GridPos)
              • Set VariableSet GridPos = (GridSubPos offset by ((0.00 - ((X of GridSubPos) mod 64.00)), (0.00 - ((Y of GridSubPos) mod 64.00))))
              • Custom script: call RemoveLocation(udg_GridSubPos)
              • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
                • Loop - Actions
                  • Set VariableSet GridCoorX = ((GridHashLoop mod GridSizeX) - (GridSizeX / 2))
                  • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridSizeX)) / GridSizeX) - (GridSizeY / 2))
                  • Set VariableSet GridSubPos = (GridPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
                  • Image - Change the position of (Load GridPlayerLoop of GridHashLoop in GridImagesHash.) to GridSubPos with Z offset 0.00
                  • Image - Change (Load GridPlayerLoop of GridHashLoop in GridImagesHash.): Enable render always state
                  • Image - Show (Load GridPlayerLoop of GridHashLoop in GridImagesHash.)
                  • Custom script: call RemoveLocation(udg_GridSubPos)
              • Custom script: call RemoveLocation(udg_GridPos)
            • Else - Actions
              • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
                • Loop - Actions
                  • Image - Hide (Load GridPlayerLoop of GridHashLoop in GridImagesHash.)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GridOnPlayer[0] Equal to True
        • Then - Actions
          • Set VariableSet GridOnPlayer[0] = False
        • Else - Actions
          • Trigger - Turn off (This trigger)

EDIT: Removed Upload - Latest Version is posted below!
 
Last edited:
Level 10
Joined
Jun 20, 2017
Messages
327
Thanks for the work and time you put into this, I really appreciate it.:peasant-bowing:

Tristronic, the size was too small so I changed it, and the second issue was the immolation which means it stays on your unit and follows you if you move your unit.
I want something like channel that you could point a target location, but I don't know if it is possible to toggle the channel on/offl?!
 
Last edited:
Level 12
Joined
Jan 10, 2023
Messages
191
Tristronic, the size was too small so I changed it, and the second issue was the immolation which means it stays on your unit and follows you if you move your unit.
I want something like channel that you could point a target location, but I don't know if it is possible to deactivate the channel?!

Those changes definitely can be made, however I am working until this weekend so I won't be able to look at it until Friday.

Channel cannot toggle, but it could be used nonetheless with triggers to make the difference, so it could be pointed somewhere. Honestly, this system would improve if I did that because currently it is possible to select multiple units and get buggy results. I didn't bother to do anything about it because this is solved by re-toggling so it's not a bug that causes any real issue.

However, if you plan to use the LUA script then I won't bother, but if it's still up in the air as to which you'll choose, I'll give it a go.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
It's a Grid-off :peasant-cool:
Lua:
    -- This creates a 2d, 3d, 4d, etc. array (table). It needs to be above the variable creation
    function gs_NewAutotable(dim)
        local MT = {};
        for i=1, dim do
            MT[i] = {__index = function(t, k)
                if i < dim then
                    t[k] = setmetatable({}, MT[i+1])
                    return t[k];
                end
            end}
        end
        return setmetatable({}, MT[1]);
    end

    ------------------------------------------------------------------------------------------------------
    ------------------------------------------------------------------------------------------------------
    -- DEFINE THESE VARIABLES:
    gs_gridStartX = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -- optional
    gs_gridStartY = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } -- optional
    gs_gridWidth  = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } -- optional
    gs_gridHeight = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 } -- optional
    gs_gridRed    = 200 --@type integer
    gs_gridGreen  = 200 --@type integer
    gs_gridBlue   = 200 --@type integer
    gs_gridAlpha  = 255 --@type integer

    -- Don't change these:
    gs_grid       = gs_NewAutotable(2) --@type integer/integer[][]
    gs_isVisible  = {} --@type boolean[]
    -------------------------------------------------------------------------------------------------------
    -------------------------------------------------------------------------------------------------------

    -- OPTIONAL - You don't need to run this function, instead you can manually create the grids yourself
    function gs_CreateGridForAllPlayers(isCentered)
        -- Uses the optional variables: gs_gridStartX, gs_gridStartY, gs_gridWidth, and gs_gridHeight
        for i = 0, bj_MAX_PLAYER_SLOTS do
            gs_CreateGridAtXY(i, gs_gridStartX[i], gs_gridStartY[i], gs_gridWidth[i], gs_gridHeight[i], isCentered)
        end
    end

    -- PARAMETERS: Player Id (0 - 27), starting X coordinate, starting Y coordinate, grid width, grid height, grid is centered (true/false)
    function gs_CreateGridAtXY(id, startX, startY, width, height, isCentered)
        gs_DestroyGrid(id)
        gs_isVisible[id] = false
        local i = 0 --@type integer
        local img --@type image
        local posX --@type real
        local posY --@type real
        startX = startX - 128
        startY = startY - 128
        height = height - 1
        width = width - 1
        if isCentered then
            startX = startX - (128 * (width / 2))
            startY = startY - (128 * (height / 2))
        end
        for x = 0, width do
            for y = 0, height do
                img = CreateImage("Gridplane.dds",128,128,0,0,0,0,1,1,1,1)
                SetImageRenderAlways(img, true)
                SetImageColor(img, 255, 255, 255, 0)
                posX = startX + x * 128
                posY = startY + y * 128
                SetImagePosition(img, posX, posY, 0)
                gs_grid[id][i] = img
                i = i + 1
            end
        end
    end

    -- PARAMETERS: Player Id (0 - 27), point, grid width, grid height, grid is centered (true/false)
    function gs_CreateGridAtPoint(id, point, width, height, isCentered)
        local startX = gs_GetTileXY(GetLocationX(point)) --@type real
        local startY = gs_GetTileXY(GetLocationY(point)) --@type real
        gs_CreateGridAtXY(id, startX, startY, width, height, isCentered)
    end

    -- PARAMETERS: Player Id (0 - 27), unit, grid width, grid height, grid is centered (true/false)
    function gs_CreateGridOnUnit(id, u, width, height, isCentered)
        local startX = gs_GetTileXY(GetUnitX(u)) --@type real
        local startY = gs_GetTileXY(GetUnitY(u)) --@type real
        gs_CreateGridAtXY(id, startX, startY, width, height, isCentered)
    end

    -- PARAMETERS: Player Id (0 - 27)
    function gs_ToggleGrid(id)
        if gs_isVisible[id] then
            gs_HideGrid(id)
            return false
        else
            gs_ShowGrid(id)
            return true
        end
    end
 
    -- PARAMETERS: Player Id (0 - 27)
    function gs_ShowGrid(id)
        gs_isVisible[id] = true
        if GetLocalPlayer() == Player(id) then
            for i = 0, #gs_grid[id] do
                SetImageColor(gs_grid[id][i], gs_gridRed, gs_gridGreen, gs_gridBlue, gs_gridAlpha)
            end
        end
    end

    -- PARAMETERS: Player Id (0 - 27)
    function gs_HideGrid(id)
        gs_isVisible[id] = false
        if GetLocalPlayer() == Player(id) then
            for i = 0, #gs_grid[id] do
                SetImageColor(gs_grid[id][i], 255, 255, 255, 0)
            end
        end
    end

    -- PARAMETERS: Player Id (0 - 27)
    function gs_DestroyGrid(id)
        if (gs_grid[id][0] ~= nil) then
            for i = 0, #gs_grid[id] do
                DestroyImage(gs_grid[id][i])
            end
        end
    end

    -- This converts an X or Y coordinate to the nearest multiple of 128 so it fits on the grid (don't touch)
    function gs_GetTileXY(num)
        return 128 * math.floor(num / 128 + 0.9)
    end
I think this should have everything you want. You can create the grid at x/y coordinates, at a point, or at the position of a unit. You can also choose to center the grid at that location or use the old method of starting from the bottom left corner and working up and to the right. Centering makes the most sense to me.

Here's the ability idea. It creates a 5x5 grid centered at the target point of your ability:
  • Create Grid At Point
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
    • Actions
      • Set VariableSet Point = (Target point of ability being cast)
      • Set VariableSet PN = ((Player number of (Triggering player)) - 1)
      • -------- --------
      • Custom script: gs_CreateGridAtPoint(udg_PN, udg_Point, 5, 5, true)
      • Custom script: gs_ShowGrid(udg_PN)
Just make sure you don't create any weird grids (0x1 for example), and odd numbers work best. Also, you may crash the game if you create a large enough grid too close to the edge of the map since it may attempt to create an Image somewhere offscreen.
 

Attachments

  • Grid System Uncle.w3m
    23.8 KB · Views: 11
Last edited:
Level 10
Joined
Jun 20, 2017
Messages
327
Channel cannot toggle
So I should just use the toggle ability? like defend etc...
Is there a way to make a channel that can be toggled on and off, maybe using the dummy unit/ability?!
Well my whole map is designed on gui :) but when I completed my map, and if I had time, I will rewrite it to lua.


Uncle, the problem is if you cast the ability and then if you select your worker to build something or click on anything, the grid will disappear!
I came up with an idea for the grid. Can you make the grid into a circle instead of a square? This way it can be used to check the range of your towers.
 
Last edited:

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
Lol, my friend, customize it! Why do you think you NEED those triggers? They're there to showcase what you can do with the system, they're not requirements.

For a circle, I'm sure that's possible but I'm not really interested in doing that at the moment since that'd mean each player would need two Grids (assuming you want the Tower Range AND the Build Grid able to be active at the same time), which will require a decent change to the code. If you only want one or the other active at a time it becomes a bit easier.
 
Last edited:
Level 12
Joined
Jan 10, 2023
Messages
191
I can definitely make something that will not deselect and will effectively toggle while also allowing to target a point. I added that all thinking it would be wanted, but assuming never got me that far lol I'm just sticking with it at this point for the sake of practice, not trying to step on any toes Uncle..
It seemed to me at first that AlwaysandForever might be more practiced in GUI, so that's why I figured it'd be good practice for me...

Idt I can really compete with Uncle on a best system, but kuckily this is somewhat simple of a concept
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
I can definitely make something that will not deselect and will effectively toggle while also allowing to target a point. I added that all thinking it would be wanted, but assuming never got me that far lol I'm just sticking with it at this point for the sake of practice, not trying to step on any toes Uncle..
It seemed to me at first that AlwaysandForever might be more practiced in GUI, so that's why I figured it'd be good practice for me...

Idt I can really compete with Uncle on a best system, but kuckily this is somewhat simple of a concept
No worries, we've gotten two systems out of this so far, one for Jass and one for Lua, it's a win win.
 
Level 12
Joined
Jan 10, 2023
Messages
191
Well, I might as well make the most of my presentation. Here's what I've come up with.

I added some color features and I decided I did want to have both a toggle and a point-target.
I made two abilities, a turn-on and a turn-off ability - each with two levels.
They both start at level 1, but at level 1 the Grid (Off) ability is not visible and at level 2 the Grid (On) ability is not visible; they are both visible in the opposite case.
Grid (Off) is 'Instant (No Target)' at both levels, but Grid (On) is 'Point Target' at level 1 and 'Instant (No Target)' at level 2.
Both abilities are hot-keyed to 'G' by default and are meant to have the same hotkey.
I could have done the same system with only one ability, but then I would have lost the opportunity to give the (On) and (Off) abilities different Icons (as far as I know this would be laborious or impossible with only GUI).
Tooltip changes for Grid (Off) should be made in the level 2 fields, or could just be identical for level 1 & 2 for both abilities.

Check it out, I think it's pretty clever!

Simple Grid System (GUI) by Tristronic​


What this system does:

Units with the Grid ability can create a pathing grid at a target location.
The grid can be deactivated by any unit that shares the grid ability and will remain on until turned off by the player.
The grid is color-coded to show what sort of pathing is allowed on that square of the grid:
  • Green - Buildable, Walkable
  • Yellow - Unbuildable, Walkable
  • Cyan - Shallow Water
  • Magenta - Deep Water
  • Red - Unbuildable, Unwalkable
  • Unflyable squares are hidden
The color settings can be easily modified or removed in the 'GridOn' trigger.
The size of the grid can be set in the 'GridInit' trigger and does not need to be square.
  • Default size is 35x35 building squares.
  • 99x99 squares caused a small lag spike in my testing.

How to enable the Grid ability for a unit:​

For a unit to use the Grid ability, the unit must have two abilities added to do this
  • Copy the Variables and Triggers to your map.
  • Copy the abilities 'Grid (On)' and 'Grid (Off)' to your map.
  • Add both of these abilities to any unit to give them the grid ability.
*Note: this ability requires that any unit with the 'Grid' ability is not using either the 'submerge' or 'unsubmerge' Order ID.

Triggers:​

Variables:
  • GridMaxPlayer (Integer) - Highest Player Number in use
  • GridMaxX (Integer) - X length of grid
  • GridMaxY (Integer) - Y length of grid
  • GridRectSize (Integer) - Area of grid (X*Y)
  • GridImagesHash (Hashtable) - Handle for the grid images
  • GridNumber (Integer) - Player Number of the player manipulating the grid
  • GridPos (Point) - Handles points to prevent memory leakage
  • GridSubPos (Point) - Handles points to prevent memory leakage
  • GridHashLoop (Integer) - Loop variable for handling the grid
  • GridCoorX (Integer) - Coorelates 'GridHashLoop' to an X coordinate
  • GridCoorY (Integer) - Coorelates 'GridHashLoop' to a Y coordinate
Triggers:
GridInit
  • GridInit
    • Events
      • Time - Elapsed game time is 0.50 seconds
    • Conditions
    • Actions
      • Set VariableSet GridMaxPlayer = 12
      • Set VariableSet GridMaxX = 25
      • Set VariableSet GridMaxY = 25
      • Set VariableSet GridRectSize = (GridMaxX x GridMaxY)
      • Hashtable - Create a hashtable
      • Set VariableSet GridImagesHash = (Last created hashtable)
      • For each (Integer GridNumber) from 1 to GridMaxPlayer, do (Actions)
        • Loop - Actions
          • Set VariableSet GridPos = (Center of (Playable map area))
          • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridSubPos) mod 64.00)), (0.00 - ((Y of GridSubPos) mod 64.00))))
          • Custom script: call RemoveLocation(udg_GridPos)
          • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
            • Loop - Actions
              • Set VariableSet GridCoorX = ((GridHashLoop mod GridMaxX) - (GridMaxX / 2))
              • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridMaxX)) / GridMaxX) - (GridMaxY / 2))
              • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
              • Image - Create an image using war3mapImported\Grid64.blp of size 64.00 at GridPos with Z offset 0.00 using image type Occlusion Mark
              • Hashtable - Save Handle Of(Last created image) as GridNumber of GridHashLoop in GridImagesHash.
              • Image - Change (Load GridNumber of GridHashLoop in GridImagesHash.): Enable render always state
              • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
              • Custom script: call RemoveLocation(udg_GridPos)
          • Custom script: call RemoveLocation(udg_GridSubPos)
GridOn
  • GridOn
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On) for (Picked unit) to 2
      • Set VariableSet GridPos = (Target point of issued order)
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
      • Custom script: call RemoveLocation(udg_GridPos)
      • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridMaxX) - (GridMaxX / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridMaxX)) / GridMaxX) - (GridMaxY / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
          • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain pathing at GridPos of type Flyability is off) Equal to False
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Terrain pathing at GridPos of type Buildability is off) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Terrain pathing at GridPos of type Floatability is off) Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 100.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 100.00%) with 0.00% transparency
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 0.00%) with 0.00% transparency
                • Else - Actions
                  • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 0.00%) with 0.00% transparency
              • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
            • Else - Actions
          • Custom script: call RemoveLocation(udg_GridPos)
      • Custom script: call RemoveLocation(udg_GridSubPos)
GridOff
  • GridOff
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(unsubmerge))
      • (Level of Grid (Off) for (Ordered unit)) Equal to 2
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 1
          • Unit - Set level of Grid (On) for (Picked unit) to 1
      • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
        • Loop - Actions
          • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)

EDIT: Removed Upload - Latest Version is posted below!
 
Last edited:
Level 10
Joined
Jun 20, 2017
Messages
327
Thanks Uncle, I customized everything and it worked as I wanted.
Well in this case I can't say if a player wants to use both of them at the same time or not! but it is better to use both options. I meant that a system based on this can be done.

Tristronic, wow, great job, that's what I was looking for, thank you so much.
So I tried adding unit ranges to the system and came up with this.
But I can't measure the unit size correctly!
  • GridOn Copy
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to (Order(submerge))
      • ((Ordered unit) is A structure) Equal to True
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On) for (Picked unit) to 2
      • Set VariableSet GridPos = (Position of (Triggering unit))
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod ((Current acquisition range of (Triggering unit)) + (Real((Current research level of Long Rifles for (Owner of (Triggering unit)))))))), (0.00 - ((Y of GridPos) mod ((Current acquisition range of (Triggering uni
      • Custom script: call RemoveLocation(udg_GridPos)
      • For each (Integer GridHashLoop) from 0 to (GridRectSize - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridMaxSizeX) - (GridMaxSizeX / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridMaxSizeX)) / GridMaxSizeX) - (GridMaxSizeY / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((((Current acquisition range of (Triggering unit)) + (Real((Current research level of Long Rifles for (Owner of (Triggering unit)))))) x (Real(GridCoorX))), (((Current acquisition range of (Triggering unit)) + (Real((Current research le
          • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
          • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
          • Custom script: call RemoveLocation(udg_GridPos)
      • Custom script: call RemoveLocation(udg_GridSubPos)

Range Checker
  • Untitled Trigger 001
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Check Range (TOWER RANGE)
    • Actions
      • Custom script: if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
      • Set VariableSet string_model = UI\Feedback\SelectionCircle\SelectionCircle.mdl
      • Custom script: endif
      • Special Effect - Create a special effect attached to the origin of (Triggering unit) using string_model
      • Special Effect - Set Position - X of (Last created special effect) to (Current acquisition range of (Triggering unit))
      • Special Effect - Set Position - Y of (Last created special effect) to (Current acquisition range of (Triggering unit))
      • Special Effect - Set Position - Z of (Last created special effect) to 0.00
      • Special Effect - Set Scale of (Last created special effect) to ((Current acquisition range of (Triggering unit)) / 50.00)
      • Special Effect - Set Color of (Last created special effect) to r: 255, g: 255, b: 255
      • Wait 10.00 seconds
      • Special Effect - Destroy (Last created special effect)
So I wrote all the code to the gui, but there is a problem that the circle stays at the top and not the bottom of the unit! as you can see in the pictures.
However, I do not like this method!
And how do I get the local player in the if condition as Chaosy did!
 

Attachments

  • Screenshot_3.png
    Screenshot_3.png
    19.2 KB · Views: 9
  • Screenshot_4.png
    Screenshot_4.png
    1.5 MB · Views: 9
  • Screenshot_5.png
    Screenshot_5.png
    1.4 MB · Views: 9
Last edited:
Level 38
Joined
Feb 27, 2007
Messages
4,951
    • Wait 10.00 seconds
    • Special Effect - Destroy (Last created special effect)
    That's really dangerous. You'll more than likely delete some other special effect you mean to remove. Make a new special effect variable and shadow it locally to make a local variable that GUI can interact with. You have to null it at the end to avoid a reference leak:
    • Actions
      • Custom script: local effect udg_RangeFX //must be the first line of the actions; match your variable name but keep the udg_ prefix
      • //...
      • Set RangeFX = (Last created special effect)
      • //..
      • Wait 10.00 seconds
      • Special Effect - Destroy RangeFX
      • Custom script: set udg_RangeFX = null //doesn't have to be last but needs to come after the SFX is destroyed
  • The way you are setting the string variable will not work in the long run. Why? You are not setting it 'for everyone' back to <empty string> before changing it locally to be the correct effect model path. Eventually everyone's copy of that variable will be assigned the selection circle model path and everyone will be able to see all of them:
    • Set string_model = <empty string>
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • GetLocalPlayer equal to (Owner of (Triggering Unit))
      • Then - Actions
        • Set string_model = "UI\Feedback\SelectionCircle\SelectionCircle.mdl"
      • Else - Actions
  • And how do I get the local player in the if condition as Chaosy did!
    It's a variable. Make it in the variable editor. Create the trigger sets it properly on map init. Refer to the variable as a player variable.
  • there is a problem that the circle stays at the top and not the bottom of the unit!
    Apparently the "origin" attachment point of towers is the same as "overhead". Try other attachment points or just don't attach it to a unit and instead create it on the unit's XY coordinates.
  • What you are doing with setting the SFX's X/Y does nothing because it's attached to a unit. If it did work, those do not define its size, rather its position on the coordinate grid. The Z line also does nothing since it's attached to a unit's attachment point.
  • ((Current acquisition range of (Triggering unit)) / 50.00) if you believe that math is correct then go for it. It would only be correct if the default selection circle model at 1.0 scale has a diameter of 50.
  • Setting the effect color to 255/255/255 is unnecessary because by default every effect has full tinting when created.
 
Level 12
Joined
Jan 10, 2023
Messages
191
EDIT: Question -> Is AlwaysandForever's custom script for his if/then and the enclosing 'custom script: endif', and 'custom script: else' what I should be doing to make my if/then statements more efficient? I have heard that these are unnecessarily inefficient in GUI and have been meaning to start converting my stuff to a better mode.

I notice you are using acquisition range and long rifles. Long Rifles only alters the attack range, not acquisition range.
The modulo equation got a little funny here too. I'm using it to reduce the x and y coordinates to the nearest multiple of 64, by changing the modulus to anything other than 64 is going to have weird results. 'X mod 64' means what remainder is there after removing all multiples of 64. Changing the divisor to the acquisition range means you are asking what the remainder is when we divide the units position by its acquisition range, and that's not a number we are interested in.

My modulo was saying, (take a target at position (32,32) for example): It divides 32 by 64, which is 0 remainder 32, but it returns just the remainder of 32.
In my function, I subtract that remainder from the target position (repeating as necessary for X and Y) so that it 'rounds down' to the nearest multiple of 64.

I wanted to make a suggestion of using the sight range of the unit rather than the attack range and here's why:
  • If a unit has no attack, like maybe your builder, the attack range can serve well as a value holder.
  • For units that do have an attack - melee units will see almost no grid.
  • If you decide to use attack 2 as the value holder, now you've limited your game to having only units with one attack, why do that without need?
  • Acquisition range might be a fine alternative, but this value has meaning toward combat.
  • Sight range might matter, but in my experience, TDs don't often use fog of war so the sight range is just a value we have freed up.
  • There are other unused unit values you might use, but those would be particular to your map so I don't want to guess to long at them, if there is one that you know you don't need, it should be an easy switch now, I'll make a note of what to change.
I set it up so that you can change the radius more easily based on what unit is casting the spell.
I wouldn't bother with checking if the unit is a structure unless if checking the target of the order like I am now doing.

Now I added a new ability 'Grid (On - Self)' which is an 'Instant (No Target)' ability, and I changed the former 'Grid (On)' to 'Grid (On -Target)' and changed it from having a 'Point Target' to now have a 'Unit or Point Target'. Give each unit the desired version; they still share the same 'Grid (Off)' ability. New trigger copies are added to handle the different types of targeting.
  • Point Target - Uses the caster's sight range as the range of the grid, centered on target point.
  • Unit Target - Uses the target's attack range as the range of the grid, centered on target unit. (Cancels if range is less than 64)
  • Instant Target - Uses the caster's attack range as the range of the grid, centered on the caster. (Cancels if range is less than 64)

Latest Update:​

Variables (some new)
  • GridMaxPlayer (Integer) - Highest Player Number in use
  • GridMaxSize (Integer) - Max X AND Y length of grid (GridMaxX and GridMaxY were not both needed for a square/circular grid)
  • GridMaxRect (Integer) - Max Area of grid (X*Y)
  • GridRadius (Integer) - NEW Variable used to get the range of the grid from a unit
  • GridSize (Integer) - NEW Variable used to set the number of tiles in the grid based on the range of the grid
  • GridSizeRect (Integer) - NEW Area of the grid (tiles) based on the determined range of the grid
  • GridImagesHash (Hashtable) - Handle for the grid images
  • GridNumber (Integer) - Player Number of the player manipulating the grid
  • GridPos (Point) - Handles points to prevent memory leakage
  • GridSubPos (Point) - Handles points to prevent memory leakage
  • GridHashLoop (Integer) - Loop variable for handling the grid
  • GridCoorX (Integer) - Coorelates 'GridHashLoop' to an X coordinate
  • GridCoorY (Integer) - Coorelates 'GridHashLoop' to a Y coordinate
Triggers (some new and changes)

GridInit​

  • GridInit
    • Events
      • Time - Elapsed game time is 0.50 seconds
    • Conditions
    • Actions
      • Set VariableSet GridMaxPlayer = 12
      • Set VariableSet GridMaxSize = 200
      • Set VariableSet GridMaxRect = (GridMaxSize x GridMaxSize)
      • Hashtable - Create a hashtable
      • Set VariableSet GridImagesHash = (Last created hashtable)
      • Set VariableSet GridPos = (Center of (Playable map area))
      • For each (Integer GridNumber) from 1 to GridMaxPlayer, do (Actions)
        • Loop - Actions
          • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
            • Loop - Actions
              • Set VariableSet GridCoorX = ((GridHashLoop mod GridMaxSize) - (GridMaxSize / 2))
              • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridMaxSize)) / GridMaxSize) - (GridMaxSize / 2))
              • Image - Create an image using war3mapImported\Grid64.blp of size 64.00 at GridPos with Z offset 0.00 using image type Occlusion Mark
              • Hashtable - Save Handle Of(Last created image) as GridNumber of GridHashLoop in GridImagesHash.
              • Image - Change (Load GridNumber of GridHashLoop in GridImagesHash.): Enable render always state
              • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
      • Custom script: call RemoveLocation(udg_GridPos)

GridOnPoint​

  • GridOnPoint
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Level of Grid (On - Target) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 2
      • Set VariableSet GridSize = (2 x ((GridRadius - (GridRadius mod 64)) / 64))
      • Set VariableSet GridSizeRect = (GridSize x GridSize)
      • Set VariableSet GridPos = (Target point of issued order)
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
      • Custom script: call RemoveLocation(udg_GridPos)
      • For each (Integer GridHashLoop) from 0 to (GridSizeRect - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridSize) - (GridSize / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridSize)) / GridSize) - (GridSize / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain pathing at GridPos of type Flyability is off) Equal to False
              • (Integer((Square root(((Power((Real(((2 x GridCoorX) + 1))), 2.00)) + (Power((Real(((2 x GridCoorY) + 1))), 2.00))))))) Less than GridSize
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Terrain pathing at GridPos of type Buildability is off) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Terrain pathing at GridPos of type Floatability is off) Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 100.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 100.00%) with 0.00% transparency
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 0.00%) with 0.00% transparency
                • Else - Actions
                  • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 0.00%) with 0.00% transparency
              • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
              • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
            • Else - Actions
          • Custom script: call RemoveLocation(udg_GridPos)
      • Custom script: call RemoveLocation(udg_GridSubPos)
*To make changes to the range of the grid, change this trigger:
  • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
*Default is set to the caster's Sight Radius.


GridOnUnit​

  • GridOnUnit
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Unit: (Target unit of issued order)'s Weapon Real Field: Attack Range ('ua1m') at Index:0) Greater than or equal to 64.00
      • (Level of Grid (On - Target) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridPos = (Position of (Target unit of issued order))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Target unit of issued order) is A structure) Equal to True
        • Then - Actions
          • Set VariableSet GridRadius = (Integer((Unit: (Target unit of issued order)'s Weapon Real Field: Attack Range ('ua1m') at Index:0)))
          • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
        • Else - Actions
          • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
          • Set VariableSet GridSubPos = (GridPos offset by ((32.00 - ((X of GridPos) mod 64.00)), (32.00 - ((Y of GridPos) mod 64.00))))
      • Custom script: call RemoveLocation(udg_GridPos)
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 2
      • If (((Target unit of issued order) is A structure) Equal to True) then do (Do nothing) else do (Do nothing)
      • Set VariableSet GridSize = (2 x ((GridRadius - (GridRadius mod 64)) / 64))
      • Set VariableSet GridSizeRect = (GridSize x GridSize)
      • For each (Integer GridHashLoop) from 0 to (GridSizeRect - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridSize) - (GridSize / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridSize)) / GridSize) - (GridSize / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain pathing at GridPos of type Flyability is off) Equal to False
              • (Integer((Square root(((Power((Real(((2 x GridCoorX) + 1))), 2.00)) + (Power((Real(((2 x GridCoorY) + 1))), 2.00))))))) Less than GridSize
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Terrain pathing at GridPos of type Buildability is off) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Terrain pathing at GridPos of type Floatability is off) Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 100.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 100.00%) with 0.00% transparency
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 0.00%) with 0.00% transparency
                • Else - Actions
                  • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 0.00%) with 0.00% transparency
              • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
              • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
            • Else - Actions
          • Custom script: call RemoveLocation(udg_GridPos)
      • Custom script: call RemoveLocation(udg_GridSubPos)
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • ((Target unit of issued order) is A structure) Equal to True
    • Then - Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Target unit of issued order)'s Weapon Real Field: Attack Range ('ua1m') at Index:0)))
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
    • Else - Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
      • Set VariableSet GridSubPos = (GridPos offset by ((32.00 - ((X of GridPos) mod 64.00)), (32.00 - ((Y of GridPos) mod 64.00))))
*Default is set to the target unit's Attack Range if the target is a building
*Default is set that if it is not a building, it uses the caster's Sight Radius (to prevent from using a targeted creep's Attack Range)
*No need to change the variable 'GridSubPos', it is being used to fix the offset of non-structure units.



GridOnSelf​

  • GridOnSelf
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Unit: (Ordered unit)'s Weapon Real Field: Attack Range ('ua1m') at Index:0) Greater than or equal to 64.00
      • (Level of Grid (On - Self) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Weapon Real Field: Attack Range ('ua1m') at Index:0)))
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 2
      • Set VariableSet GridSize = (2 x ((GridRadius - (GridRadius mod 64)) / 64))
      • Set VariableSet GridSizeRect = (GridSize x GridSize)
      • Set VariableSet GridPos = (Position of (Ordered unit))
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
      • Custom script: call RemoveLocation(udg_GridPos)
      • For each (Integer GridHashLoop) from 0 to (GridSizeRect - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridSize) - (GridSize / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridSize)) / GridSize) - (GridSize / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Terrain pathing at GridPos of type Flyability is off) Equal to False
              • (Integer((Square root(((Power((Real(((2 x GridCoorX) + 1))), 2.00)) + (Power((Real(((2 x GridCoorY) + 1))), 2.00))))))) Less than GridSize
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Terrain pathing at GridPos of type Buildability is off) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Terrain pathing at GridPos of type Floatability is off) Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 100.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 100.00%) with 0.00% transparency
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                        • Then - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 100.00%, 0.00%) with 0.00% transparency
                        • Else - Actions
                          • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (100.00%, 0.00%, 0.00%) with 0.00% transparency
                • Else - Actions
                  • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (0.00%, 100.00%, 0.00%) with 0.00% transparency
              • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
            • Else - Actions
          • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
          • Custom script: call RemoveLocation(udg_GridPos)
      • Custom script: call RemoveLocation(udg_GridSubPos)
*To make changes to the range of the grid, change this trigger:
  • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Weapon Real Field: Attack Range ('ua1m') at Index:0)))
*Default is set to the target unit's Attack Range.


GridOff​

  • GridOff
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(unsubmerge))
      • (Level of Grid (Off) for (Ordered unit)) Equal to 2
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 1
      • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
        • Loop - Actions
          • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)

 

Attachments

  • SimpleGridSystem(GUI)_ByTristronic_v1.0.w3m
    28.8 KB · Views: 9
Last edited:

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
 
Level 10
Joined
Jun 20, 2017
Messages
327
Thank you very much for your good and useful information.

The problems I have encountered,

1. If the target is a bit out of range, the tower can still attack the unit!
And I have an upgrade that can increase the range of a unit, so every time you upgrade it, it increases the range.
However I solved the upgrade part with this.
  • Set VariableSet GridRadius = ((Integer((Unit: (Ordered unit)'s Weapon Real Field: Attack Range ('ua1m') at Index:0))) + (Current research level of Long Rifles for (Owner of (Ordered unit))))
2. If you upgrade a unit and cast the grid on it, it still shows you the first grid!

3. Let's say this trigger shows you an attack range to a structure/unit which has an attack with upgrade, and else gives you a sight range.
The problem is that it doesn't show the sight range of a unit/structure that has no attacks!
I mean sure, I'd definitely want sight range as well, because as you mentioned if a unit/structure doesn't have an attack, it can be used in different colors such as blue.
Also, is there an upgrade that can increase sight?!
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • ((Target unit of issued order) is A structure) Equal to True
    • Then - Actions
      • Set VariableSet GridRadius = ((Integer((Unit: (Target unit of issued order)'s Weapon Real Field: Attack Range ('ua1m') at Index:0))) + (Current research level of Long Rifles for (Owner of (Target unit of issued order))))
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
    • Else - Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
      • Set VariableSet GridSubPos = (GridPos offset by ((32.00 - ((X of GridPos) mod 64.00)), (32.00 - ((Y of GridPos) mod 64.00))))

I have an idea for GridOnUnit, you can use this method to see the area of effect of an ability.
For example Unholy Aura with some level, level 1 has area of effect of 500, lvl 2 700, lvl 3 900 and so on....
In the game you don't know the effect range (you have to guess), so by selecting a unit you will know if it is within the effect range or not!


I don't want to have all the squares. I want to have a simple circle. I searched for a simple circle model but couldn't find one!

I have these 2 so far (GridOnPoint, GridOnSelf).
It's a variable. Make it in the variable editor. Create the trigger sets it properly on map init. Refer to the variable as a player variable.
I thought it was exist somewhere in the condition!
 

Attachments

  • Screenshot_2.png
    Screenshot_2.png
    2 MB · Views: 11
  • Screenshot_3.png
    Screenshot_3.png
    2 MB · Views: 10
  • Screenshot_4.png
    Screenshot_4.png
    2.1 MB · Views: 8
  • Screenshot_5.png
    Screenshot_5.png
    1.9 MB · Views: 9
  • Screenshot_6.png
    Screenshot_6.png
    2 MB · Views: 10
Level 38
Joined
Feb 27, 2007
Messages
4,951
If the target is a bit out of range, the tower can still attack the unit!
Yes because the target's collision size is taken into account. If it overlaps in any capacity it's "in range".
Also, is there an upgrade that can increase sight?!
Not directly but you can make one. Item Sight Range Bonus is an ability that can be given to units via an upgrade. It's a flat bonus to sight range, not multiplicative.
 
Level 12
Joined
Jan 10, 2023
Messages
191
My replies to AlwaysAndForever:
Thank you very much for your good and useful information.

The problems I have encountered,

1. If the target is a bit out of range, the tower can still attack the unit!
And I have an upgrade that can increase the range of a unit, so every time you upgrade it, it increases the range.
However I solved the upgrade part with this.
  • Set VariableSet GridRadius = ((Integer((Unit: (Ordered unit)'s Weapon Real Field: Attack Range ('ua1m') at Index:0))) + (Current research level of Long Rifles for (Owner of (Ordered unit))))

I understand you are interested in a round circle for this purpose; if it is well done, that will make the error window less, but it won't be perfect for the reason that Pyrogasm gave.

There really isn't a good answer here other than to say we ultimately have a choice to make:
  1. We make the grid slightly bigger than the range and tell the player things are in range when they aren't in range. (bad idea imo)
  2. We make the grid slightly smaller than the range and tell the player things are out of range, when they are in range. (best option)

2. If you upgrade a unit and cast the grid on it, it still shows you the first grid!

Solved. The grid never refreshed before, it's a good thing to include so I made a trigger to refresh the grid when a unit is upgraded or a research is completed. I got to say, we shouldn't have expected it to update the grid before, there was no trigger to do anything like that, but if you turned the grid off and then back on it would have reloaded the updated grid.

3. Let's say this trigger shows you an attack range to a structure/unit which has an attack with upgrade, and else gives you a sight range.
The problem is that it doesn't show the sight range of a unit/structure that has no attacks!
I mean sure, I'd definitely want sight range as well, because as you mentioned if a unit/structure doesn't have an attack, it can be used in different colors such as blue.
Also, is there an upgrade that can increase sight?!
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • ((Target unit of issued order) is A structure) Equal to True
    • Then - Actions
      • Set VariableSet GridRadius = ((Integer((Unit: (Target unit of issued order)'s Weapon Real Field: Attack Range ('ua1m') at Index:0))) + (Current research level of Long Rifles for (Owner of (Target unit of issued order))))
      • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
    • Else - Actions
      • Set VariableSet GridRadius = (Integer((Unit: (Ordered unit)'s Real Field: Sight Radius ('usir'))))
      • Set VariableSet GridSubPos = (GridPos offset by ((32.00 - ((X of GridPos) mod 64.00)), (32.00 - ((Y of GridPos) mod 64.00))))

You should stop adding the research consideration into this trigger, it is automatically accounted for by the unit because the unit's range increases when the research is completed. This would have required the grid to update, which did not used to be automatic, but it is now.

As for the Sight Range part, I've removed that aspect in this latest version I am posting. The issue was that when the grid would refresh when a unit was upgraded, if using the Sight Range it would return a number that was close to the average between the old unit and the new unit's Sight Range.
Having modified it to also use Attack Range, it now works without that weird bug.

Now a unit's Attack Range is used in either case, but if the 'Maximum Number of Targets' for the 2nd attack of 'GridHost[X]' is 0, then it will color it blue, so to make the grid blue (so to show that it is a 'Sight Range') and it would use the attack range of the 2nd attack you would set the Maximum Number of Targets to 0 for that unit's 2nd attack and you also have to have the number of dice set to 1 or more for the 2nd attack of the unit otherwise the game will count its 2nd attack range as 0. The 2nd attack does not need to be enabled!

This means you need to assign these values to a bunch of units maybe, any unit that you want to show the Sight Range (blue range) instead of Attack Range.

Keep in mind that this is meant to serve as an example. It isn't by any means the only way you could do it, but the new version aims to make that easier.

For other color assigning, I've rearranged the triggers to make it more user friendly, but now you should find it much more easy to tweak it to your needs.
I'll get more in to the details below where I describe the new version.

I have an idea for GridOnUnit, you can use this method to see the area of effect of an ability.
For example Unholy Aura with some level, level 1 has area of effect of 500, lvl 2 700, lvl 3 900 and so on....
In the game you don't know the effect range (you have to guess), so by selecting a unit you will know if it is within the effect range or not!

You can determine the effect range, I made an example to show how that works too. It will come up in the trigger 'GridRangeConditions' and I'll get into the details when I describe the new version below.

I don't want to have all the squares. I want to have a simple circle. I searched for a simple circle model but couldn't find one!

I understand you want a circle, we can get to that. As for why I moved forward with this design, I am knee deep in it and to make a circle version now would be one the one hand very easy, but on the other hand kind of distracting. We can whip that up when we're done with this if you want. I think this looks cooler and has better potential now and I might change your mind, but if not the circle thing will be easy

I have these 2 so far (GridOnPoint, GridOnSelf).

If you do take out the GridOnUnit trigger, I never thought of it being removed and haven't thought of the problems that might cause.. I kind of forget that version's details now.
You would have to make sure that you changed the Grid (On Target) ability to have only 'Point Target' and not 'Unit or Point Target' or it would definitely have issues.

I think you are(were) missing the bigger picture with GridOnUnit. If you target a unit other than a building, you likely meant to target the ground, but you can't because a unit is in the way and the ability can target units, and we need to target units so we can target our buildings. So if you target something that isn't a building, it will(would) change the GridHost[X] to be as if you targeted the ground - using the caster's grid size/range instead of the unit that's blocking the ground. If you do target a building it shows you that building's range.

I changed the triggers so that they streamline through common functions, this should make altering it much easier. You now only should have to make any changes to two triggers: 'GridInit' where you can change color values and 'GridRangeConditions' where you can change the type of range shown, anything from Attack Range to Aura Range, you name it.

I thought it was exist somewhere in the condition!

It's all was now, new version time! (I think I will change the version number after this version and consider this still to be the first version.. forgive me, I over-saved version 1.0



Simple Grid System (GUI) by Tristronic - Version 1.0b​


An Overview of this system:​


  • This system enables units to create a grid at a target location.
  • The grid can function in two ways; it can show pathing, or it can show the range of a target unit's attacks, auras, or other abilities.
  • The two grids are often later referred to as the 'Pathing Grid' and the 'Range Grid'.
  • The Pathing Grid has colors determined by the terrain pathing and is made if the 'Grid On' ability targets the ground.
  • The Range grid is one solid color, but that color can be different for the ranges of different auras, attacks, or abilities.
    • The Range grid is chosen if the 'Grid On' target is a building.
    • If the building has no attacks, auras, or abilities to get the range of, you will have to set the "back-up" range in the object editor.
    • More information about the "back-up" range is posted below in the 'GridRangeConditions' trigger section.
  • The colors used by the grid can be changed and more colors can easily be added.
  • The attacks, auras, and abilities to display the range of can easily be added to with some knowledge of nesting If/Then/Else statements.

Variables:​


  • Variables you might change
  • GridMaxPlayer- Must be at least as high as the highest number player slot used.
    • If your game uses slots 1, 2, 9, and 10, you should set this above 10.
    • Default is 12 and I suspect setting it to 24 or higher would be harmless.
    • If this does cause lag, try reducing the next variable 'GridMaxSize'.
    • If performance is poor, lowering this may help.

  • GridMaxSize- With a default setting of 200, this will show a range of up to 6400 ( 64 x ( GridMaxSize / 2 ) ).
    • This is likely far more than is needed.
    • This is the maximum range, the target/casting unit's sight/attack range will set the maximum up to this value, but no higher.
    • If performance is poor, lowering this may help.

  • GridRadius- This variable determines the range of the grid.
    • This will be set to the range of the attack, aura, or ability that determines the range of the grid.
    • This should be done n the trigger 'GridRangeConditions'.
    • More about the GridRangeConditions trigger is in the trigger section.

Color Variables:​

There are four GridColor arrays that can be used to set a color using the variable GridColorIndex as their index value.
  • GridColorR[X] - Red (%)
  • GridColorG[X] - Green (%)
  • GridColorB[X] - Blue (%)
  • GridColorO[X] - Opacity (% invisible)
    • X - GridColorIndex

The index for each array represents a color option. In the trigger 'GridInit' you will see 7 colors being initiated as the default colors for each index 0-6.
They each reference a value for the Red, Green, Blue, and Opacity levels of each color choice. Colors can be changed here or colors can be added by creating new initiation actions for the 'R', 'G', 'B', & 'O' values of another 'GridColor' index (Any index higher than 6).


The GridColorPath and GridColorRange variables are meant for ease of access for the game maker.
  • The GridColorPath values are hard-triggered to the pathing grid trigger, but the color of each pathing type can be changed in the initiation trigger. This is done so that the pathing grid can always be easily interpreted when changing colors. To change the color of a certain pathing type, shallow water to be yellow instead of cyan for example, set (GridColorPathingShallow = 2) because 2 is the GridColorIndex for yellow by default.
  • The GridColorRange triggers are made to be used by the different range types that may be used, by default there are three
    • GridColorRangeAttack - Red by default
    • GridColorRangeSight - Blue by default
    • GridColorRangeAura - Magenta by default
  • GridColorRange triggers are to be made and set in the trigger 'GridInit', but must also be used to set the GridColorIndex in the trigger 'GridRangeConditions'
  • More about the GridRangeConditions trigger is in the trigger section.
  • Variables you shouldn't change
  • GridMaxRect (Integer) - The area of the maximum grid size - determined by GridMaxSize
  • GridSize (Integer) - The size determined for the grid - determined by GridRadius
  • GridSizeRect (Integer) - The area of a specific grid - determined by GridSize
  • GridImagesHash (Hashtable) - The hashtable that handles the images - initialized in 'GridInit' trigger
  • GridNumber (Integer) - The index for GridImagesHash that handles the player number through the triggers
  • GridHashLoop (Integer) - The index for GridImagesHash that loops through the images handles
  • GridCoorX (Integer) - The X coordinate used by GridImagesHaash and GridHashLoop
  • GridCoorY (Integer) - The Y coordinate used by GridImagesHash and GridHashLoop
  • GridPos (Point) - The point used to track the grid tile positions
  • GridSubPos (Point) - The point used to track the grid target or to track the GridHost when the grid refreshes
  • GridHost[X] (Unit) - If the caster targets the ground GridHost is the caster, if it has a target then GridHost is the target
  • GridHostPos[X] (Point) - The point used to track the GridHost
  • GridIsOn[X] (Boolean) - Tracks whether the grid is on or not
  • GridIsPathing[X] (Boolean) - Determines which grid will be shown, the pathing grid or the range grid

Seriously don't mess with these.
* More information about how to change certain variables is found in the Triggers section below.

Triggers:​


  • Triggers should be copied after the variables in the following order
GridInit
  • This trigger contains some variables you may want to change:
    • GridMaxPlayer
    • GridMaxSize
    • GridColor variables
  • The changes that can be made to these variables are described in the "Variables you might change" section
    • GridColorRange variables may also require changes to be made in the trigger 'GridRangeConditions'
  • GridInit
    • Events
      • Time - Elapsed game time is 0.50 seconds
    • Conditions
    • Actions
      • Set VariableSet GridMaxPlayer = 12
      • Set VariableSet GridMaxSize = 200
      • -------- COLOR CHOICES ( % Red, Green, Blue, Opacity) --------
      • -------- Unflyable (INVISIBLE - GridColorPathNone) --------
      • Set VariableSet GridColorR[0] = 0.00
      • Set VariableSet GridColorG[0] = 0.00
      • Set VariableSet GridColorB[0] = 0.00
      • Set VariableSet GridColorO[0] = 100.00
      • -------- Unbuildable & Unwalkable (RED - GridColorPathNoWalk) --------
      • Set VariableSet GridColorR[1] = 100.00
      • Set VariableSet GridColorG[1] = 0.00
      • Set VariableSet GridColorB[1] = 0.00
      • Set VariableSet GridColorO[1] = 0.00
      • -------- Unbuildable & Walkable (YELLOW - GridColorPathNoBuild) --------
      • Set VariableSet GridColorR[2] = 100.00
      • Set VariableSet GridColorG[2] = 100.00
      • Set VariableSet GridColorB[2] = 0.00
      • Set VariableSet GridColorO[2] = 0.00
      • -------- Buildable (GREEN - GridColorPathWalk) --------
      • Set VariableSet GridColorR[3] = 0.00
      • Set VariableSet GridColorG[3] = 100.00
      • Set VariableSet GridColorB[3] = 0.00
      • Set VariableSet GridColorO[3] = 0.00
      • -------- Shallow Water (CYAN - GridColorPathShallow) --------
      • Set VariableSet GridColorR[4] = 0.00
      • Set VariableSet GridColorG[4] = 100.00
      • Set VariableSet GridColorB[4] = 100.00
      • Set VariableSet GridColorO[4] = 0.00
      • -------- Show Range Only (BLUE - GridColorPathBlight) --------
      • Set VariableSet GridColorR[5] = 0.00
      • Set VariableSet GridColorG[5] = 0.00
      • Set VariableSet GridColorB[5] = 100.00
      • Set VariableSet GridColorO[5] = 0.00
      • -------- Deep Water (MAGENTA - GridColorPathDeep) --------
      • Set VariableSet GridColorR[6] = 100.00
      • Set VariableSet GridColorG[6] = 0.00
      • Set VariableSet GridColorB[6] = 100.00
      • Set VariableSet GridColorO[6] = 0.00
      • -------- COLOR PICKER ( 0 - 6 CHOOSING FROM ABOVE DEFINED COLORS) --------
      • Set VariableSet GridColorRangeAttack = 1
      • Set VariableSet GridColorRangeAura = 6
      • Set VariableSet GridColorRangeSight = 5
      • Set VariableSet GridColorPathNone = 0
      • Set VariableSet GridColorPathNoWalk = 1
      • Set VariableSet GridColorPathNoBuild = 2
      • Set VariableSet GridColorPathWalk = 3
      • Set VariableSet GridColorPathShallow = 4
      • Set VariableSet GridColorPathBlight = 5
      • Set VariableSet GridColorPathDeep = 6
      • -------- END OF COLOR SECTION --------
      • Set VariableSet GridMaxRect = (GridMaxSize x GridMaxSize)
      • Hashtable - Create a hashtable
      • Set VariableSet GridImagesHash = (Last created hashtable)
      • Set VariableSet GridPos = (Center of (Playable map area))
      • For each (Integer GridNumber) from 1 to GridMaxPlayer, do (Actions)
        • Loop - Actions
          • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
            • Loop - Actions
              • Set VariableSet GridCoorX = ((GridHashLoop mod GridMaxSize) - (GridMaxSize / 2))
              • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridMaxSize)) / GridMaxSize) - (GridMaxSize / 2))
              • Image - Create an image using war3mapImported\Grid64.blp of size 64.00 at GridPos with Z offset 0.00 using image type Occlusion Mark
              • Hashtable - Save Handle Of(Last created image) as GridNumber of GridHashLoop in GridImagesHash.
              • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
      • Custom script: call RemoveLocation(udg_GridPos)
GridOn
  • There is one option in this trigger a user may want to consider using:
    • If the you find the action "Set VariableSet GridColorIndex = GridColorIndex" (there is a comment above the action in the triggers below) you can set that to any number corresponding to a color from the colors set in the trigger 'GridInit'
      • This will overwrite the range grid
      • This will not change the pathing grid
      • Use action "Set VariableSet GridColorIndex = GridColorIndex" to restore original one color (range) grid color functionality
      • The best way to change the color assignments is in the 'GridInit' trigger. Read the trigger comment in that trigger for more information.

  • No changes should be made to this trigger for system to function as intended! (Above comment is not a recommendation)
  • GridOn
    • Events
    • Conditions
    • Actions
      • Set VariableSet GridHostPos[GridNumber] = GridSubPos
      • Set VariableSet GridIsOn[GridNumber] = True
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 2
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 2
      • Set VariableSet GridSize = (2 x ((GridRadius - (GridRadius mod 64)) / 64))
      • Set VariableSet GridSizeRect = (GridSize x GridSize)
      • For each (Integer GridHashLoop) from 0 to (GridSizeRect - 1), do (Actions)
        • Loop - Actions
          • Set VariableSet GridCoorX = ((GridHashLoop mod GridSize) - (GridSize / 2))
          • Set VariableSet GridCoorY = (((GridHashLoop - (GridHashLoop mod GridSize)) / GridSize) - (GridSize / 2))
          • Set VariableSet GridPos = (GridSubPos offset by ((64.00 x (Real(GridCoorX))), (64.00 x (Real(GridCoorY)))))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Integer((Square root(((Power((Real(((2 x GridCoorX) + 1))), 2.00)) + (Power((Real(((2 x GridCoorY) + 1))), 2.00))))))) Less than GridSize
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • GridIsPathing[GridNumber] Equal to False
                • Then - Actions
                  • -------- Change the below value for the variable 'GridColorPicker' to set all one color (range) grids to be the set color. (Use action "Set VariableSet GridColorIndex = GridColorIndex" to restore original one color (range) grid color functionality) --------
                  • Set VariableSet GridColorIndex = GridColorIndex
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Terrain pathing at GridPos of type Flyability is off) Equal to True
                    • Then - Actions
                      • Set VariableSet GridColorIndex = GridColorPathNone
                    • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Terrain pathing at GridPos of type Buildability is off) Equal to False
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Terrain pathing at GridPos of type Blight Pathing is off) Equal to False
                            • Then - Actions
                              • Set VariableSet GridColorIndex = GridColorPathWalk
                            • Else - Actions
                              • Set VariableSet GridColorIndex = GridColorPathBlight
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Terrain pathing at GridPos of type Floatability is off) Equal to False
                            • Then - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                                • Then - Actions
                                  • Set VariableSet GridColorIndex = GridColorPathShallow
                                • Else - Actions
                                  • Set VariableSet GridColorIndex = GridColorPathDeep
                            • Else - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • (Terrain pathing at GridPos of type Walkability is off) Equal to False
                                • Then - Actions
                                  • Set VariableSet GridColorIndex = GridColorPathNoBuild
                                • Else - Actions
                                  • Set VariableSet GridColorIndex = GridColorPathNoWalk
              • Image - Change the color of (Load GridNumber of GridHashLoop in GridImagesHash.) to (GridColorR[GridColorIndex]%, GridColorG[GridColorIndex]%, GridColorB[GridColorIndex]%) with GridColorO[GridColorIndex]% transparency
              • Image - Change the position of (Load GridNumber of GridHashLoop in GridImagesHash.) to GridPos with Z offset 0.00
              • Image - Change (Load GridNumber of GridHashLoop in GridImagesHash.): Enable render always state
              • Image - Show (Load GridNumber of GridHashLoop in GridImagesHash.)
            • Else - Actions
          • Custom script: call RemoveLocation(udg_GridPos)
GridRangeConditions
  • This is the trigger that will require the most changing if you want to alter the color of the range grid.
  • The range grid is intended to show the range of auras, sight, or attack range, or anything else you might dream up.
ATTENTION
  • The first and second (two outermost) If/Then/Else statements are important ones to understand.
  1. The First If/Then/Else
    • Checks if the grid is targeting a unit or the ground by checking if the point GridHostPos[X] is equal to GridPos.
      • If they are not the same then it is targeting the ground and it will show the pathing grid.
      • If they are the same then it is targeting a unit and it will move to the 2nd If/Then/Else.
  2. The Second If/Then/Else
    • Checks if the GridHost[X] is a structure.
      • If it is not a structure then it will show the pathing grid.
        • this is to ensure non-structure units do not block the player from turning on the pathing grid
      • If it is a structure then it will show the range grid.
  • Within the 2nd IF/THEN/ELSE you should place your conditions for changing the color of the ranged grid.
Two example range conditions have been made by default: (Inside the Then section of the 2nd If/Then/Else statement)
  • The first is more complicated
    • The first checks the number of targets that GridHost[X] can target with its 2nd Attack and if it returns 0 targets allowed, then the grid will use the GridHost[X]'s 2nd Attack's attack range as the grid range, and it will draw the grid blue or whatever color 'GridRangeSight' is set to.
      • This also requires that the 'Number of Dice' for the unit's 2nd Attack damage must be 1 or more, without the Number of Dice being at least 1 for an attack, the Attack Range will return as 0.00.
      • The unit's Acquisition Range must be either 0 or higher than the Attack Range.
        • The Acquisition Range will set the max Attack Range if it is not set to 0
    • If the number of targets is not 0 (default is usually 1 in even in units without a 2nd Attack), then the grid will use the GridHost[X]'s 1st Attack's attack range as the grid range, and it will draw the grid red or whatever color 'GridRangeAttack' is set to.

  • The Second is more straightforward, but has more steps to explain
    • This condition also checks the number of targets that GridHist[X] can target with its 2nd Attack and if it returns 2 targets allowed, then the grid will use the range of the Aura at the level of the GridHost[X]'s aura.
      • This does not require that we change the number of dice or the acquisition range because we will not be checking the 2nd Attack's range.
    • If the number of targets is not 2, then we do nothing because the previous Grid Range Conditions have already assigned a range equal to the 1st Attack's range, and with the color set to red or whatever 'GridRangeAttack' is set to.

  • Use the example of the second example grid range condition, the second grid range condition after the first two important ones.
    • We can set the grid range and color in the 'Then' section of our new grid range conditions and leave the 'Else' section blank so that if the condition is not true, it will default to the color red or whatever 'GridRangeAttack' is set to.
  • Assign the desired range type with GridRadius and the color with a color value for GridColorPicker depending on your conditions. There is more information about color variables in the 'GridInit' trigger comments.
  • GridRangeConditions
    • Events
    • Conditions
    • Actions
      • Set VariableSet GridHostPos[GridNumber] = (Position of GridHost[GridNumber])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (X of GridHostPos[GridNumber]) Equal to (X of GridPos)
          • (Y of GridHostPos[GridNumber]) Equal to (Y of GridPos)
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (GridHost[GridNumber] is A structure) Equal to True
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit: GridHost[GridNumber]'s Weapon Integer Field: Attack Maximum Number Of Targets ('utc1') at Index:1) Equal to 0
                • Then - Actions
                  • Set VariableSet GridRadius = (Integer((Unit: GridHost[GridNumber]'s Weapon Real Field: Attack Range ('ua1m') at Index:1)))
                  • Set VariableSet GridColorIndex = GridColorRangeSight
                • Else - Actions
                  • Set VariableSet GridRadius = (Integer((Unit: GridHost[GridNumber]'s Weapon Real Field: Attack Range ('ua1m') at Index:0)))
                  • Set VariableSet GridColorIndex = GridColorRangeAttack
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Unit: GridHost[GridNumber]'s Weapon Integer Field: Attack Maximum Number Of Targets ('utc1') at Index:1) Equal to 2
                • Then - Actions
                  • Set VariableSet GridRadius = (Integer((Ability: (Unit: GridHost[GridNumber]'s Ability with Ability Code: Command Aura)'s Real Level Field Area of Effect ('aare'), of Level: ((Level of Command Aura for GridHost[GridNumber]) - 1))))
                  • Set VariableSet GridColorIndex = GridColorRangeAura
                • Else - Actions
              • Set VariableSet GridIsPathing[GridNumber] = False
              • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
            • Else - Actions
              • Set VariableSet GridHost[GridNumber] = (Ordered unit)
              • Set VariableSet GridRadius = (Integer((Unit: GridHost[GridNumber]'s Weapon Real Field: Attack Range ('ua1m') at Index:1)))
              • Set VariableSet GridIsPathing[GridNumber] = True
              • Set VariableSet GridSubPos = (GridPos offset by ((32.00 - ((X of GridPos) mod 64.00)), (32.00 - ((Y of GridPos) mod 64.00))))
        • Else - Actions
          • Set VariableSet GridRadius = (Integer((Unit: GridHost[GridNumber]'s Weapon Real Field: Attack Range ('ua1m') at Index:1)))
          • Set VariableSet GridIsPathing[GridNumber] = True
          • Set VariableSet GridSubPos = (GridPos offset by ((0.00 - ((X of GridPos) mod 64.00)), (0.00 - ((Y of GridPos) mod 64.00))))
      • Custom script: call RemoveLocation(udg_GridHostPos[udg_GridNumber])
      • Custom script: call RemoveLocation(udg_GridPos)
      • Trigger - Run GridOn <gen> (checking conditions)
GridOnPoint
  • No changes should be made to this trigger for system to function as intended!
  • GridOnPoint
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Level of Grid (Off) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Set VariableSet GridHost[GridNumber] = (Ordered unit)
      • Set VariableSet GridPos = (Target point of issued order)
      • Trigger - Run GridRangeConditions <gen> (checking conditions)
GridOnUnit
  • No changes should be made to this trigger for system to function as intended!
  • GridOnUnit
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
      • (Level of Grid (Off) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Set VariableSet GridHost[GridNumber] = (Target unit of issued order)
      • Set VariableSet GridPos = (Position of GridHost[GridNumber])
      • Trigger - Run GridRangeConditions <gen> (checking conditions)
GridOnSelf
  • No changes should be made to this trigger for system to function as intended!
  • GridOnSelf
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Level of Grid (Off) for (Ordered unit)) Equal to 1
      • (Issued order) Equal to (Order(submerge))
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Set VariableSet GridHost[GridNumber] = (Ordered unit)
      • Set VariableSet GridPos = (Position of GridHost[GridNumber])
      • Trigger - Run GridRangeConditions <gen> (checking conditions)
GridUpgrade
  • No changes should be made to this trigger for system to function as intended!
  • This trigger can be seen as a model to "refresh" the grid. If the grid is altered by something, it will need to be reset and this trigger is an example of how to do that.
  • This trigger could be copied and pasted as long as you make sure that the first action is finding the correct player number.
    • If your refresh trigger is not triggered by a unit, it will not have a triggering unit so you will need to change that part of the first action in your version of this trigger.
  • GridUpgrade
    • Events
      • Unit - A unit Finishes an upgrade
      • Unit - A unit Finishes research
    • Conditions
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Triggering unit)))
      • Set VariableSet GridHost[GridNumber] = GridHost[GridNumber]
      • Set VariableSet GridPos = GridHostPos[GridNumber]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GridIsOn[GridNumber] Equal to True
        • Then - Actions
          • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
            • Loop - Actions
              • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
          • Trigger - Run GridRangeConditions <gen> (checking conditions)
        • Else - Actions
GridHostDies
  • No changes should be made to this trigger for system to function as intended!
  • GridHostDies
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Dying unit) Equal to GridHost[(Player number of (Owner of (Dying unit)))]
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Dying unit)))
      • Custom script: call RemoveLocation(udg_GridHostPos[udg_GridNumber])
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 1
      • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
        • Loop - Actions
          • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
      • Set VariableSet GridIsOn[GridNumber] = False
GridOff
  • No changes should be made to this trigger for system to function as intended!
  • GridOff
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • (Issued order) Equal to (Order(unsubmerge))
      • (Level of Grid (Off) for (Ordered unit)) Equal to 2
    • Actions
      • Set VariableSet GridNumber = (Player number of (Owner of (Ordered unit)))
      • Custom script: call RemoveLocation(udg_GridHostPos[udg_GridNumber])
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units owned by (Player(GridNumber)).) and do (Actions)
        • Loop - Actions
          • Unit - Set level of Grid (Off) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Target) for (Picked unit) to 1
          • Unit - Set level of Grid (On - Self) for (Picked unit) to 1
      • For each (Integer GridHashLoop) from 0 to (GridMaxRect - 1), do (Actions)
        • Loop - Actions
          • Image - Hide (Load GridNumber of GridHashLoop in GridImagesHash.)
      • Set VariableSet GridIsOn[GridNumber] = False
 

Attachments

  • SimpleGridSystem(GUI)_ByTristronic_v1.0b.w3m
    34.5 KB · Views: 9
Level 10
Joined
Jun 20, 2017
Messages
327
Thanks, I read all your comments and I think I understood most of them.
I edited some things and ran into some problems!

1. If I upgrade a structure that has a range, the range will be added correctly, but for non-structure it still can't work properly! the same range that they have remains!
I tried changing this to this but same result!
Set VariableSet GridNumber = (Player number of (Owner of (Triggering unit)))
Set VariableSet GridNumber = (Player number of (Owner of (Researching unit)))
You should stop adding the research consideration into this trigger, it is automatically accounted for by the unit because the unit's range increases when the research is completed. This would have required the grid to update, which did not used to be automatic, but it is now.
I think I should add, because the added range for the non-structural unit was still not calculated!

2. Each unit has a sight range whether it can attack or not, even if the melee has 40 range or whatever, it should show you a light blue circle with a range of 40.

3. I put a paladin on the map, if I select his aura ability, the aura range still doesn't show, I believe it still shows the pathing grid!

4. Suppose if a unit has sight range, attack range and passive aura range, which one will the system show you first?!

Now a unit's Attack Range is used in either case, but if the 'Maximum Number of Targets' for the 2nd attack of 'GridHost[X]' is 0, then it will color it blue, so to make the grid blue (so to show that it is a 'Sight Range') and it would use the attack range of the 2nd attack you would set the Maximum Number of Targets to 0 for that unit's 2nd attack and you also have to have the number of dice set to 1 or more for the 2nd attack of the unit otherwise the game will count its 2nd attack range as 0. The 2nd attack does not need to be enabled!
Sorry, Can't use this method, some of my units using 2nd attack. I want to use this method instead (Status - Sight Radius day\night). If it cannot be used, we can use triggering.
 

Attachments

  • SimpleGridSystem(GUI)_ByTristronic_v1.0b.w3m
    34.1 KB · Views: 5
Last edited:
Level 12
Joined
Jan 10, 2023
Messages
191
Hey, I really want to make this work for you, I think I have been overlooking aspects of your design and have plans to add a toggle for the round grid when looking at a range.

The reason we keep having unit problems (I think) is because I have been assuming you have only buildings, I'm starting to think now that you have non-structure units.

If you're having trouble with buildings, I think it's a misunderstanding of use, or maybe a glitch to this version.

I have a final system in process but I don't want to overlook aspects that you may want in the final version.

Working today, so it will be not until wed/thursday that I can get back to you, but I want to get this hammered out.

Would you want to share a demo of the game with me?

If not, maybe just a really good description of the units having problems and if you could speak to my first question about whether or not you have non-structure units that would go a long way.

Current idea is to make a semi-transparent circle that can have its color changed to the same colors that will just show a solid circle (not just outline) If you would rather an outline, I can do that for you, but for my final system I think I'll do a filled circle.

I would hold off on making changes for now because I think the next ver is going to be well worth it, have some systems to make the auras more automatic and to cycle through relevant ranges (if something has 2 auras, or an attack and an aura it should cycle back and forth and so on for more than 2 ranges).


Just read the last bit about attack 2, we can make an alternative, but more the reason I'd like to learn more detail.

Next version I had planned to show both attack ranges as ranges but only to show it as blue if both attack 1&2 are off.

Assuming sight range isn't really something we care to show and was going to change its name to 'custom range' (is sight range a dummy or is it actually being used for sight range?)

The only issue had with normal sight range is that when a unit upgrades to something with a different sight range, for that first instance it shows the average sight range, refreshing the grid a moment later would solve this but the only other choice I can think of is to create a dummy of the unit and use the dummy's sight range, since the dummy won't be mid-upgrade when sight range is checked.

If you're Sight Range will be the same for all units or if upgraded units have the same sight range as their downgraded versions, we are safe to use sight range.
 
Last edited:
Level 10
Joined
Jun 20, 2017
Messages
327
Hey, I really want to make this work for you, I think I have been overlooking aspects of your design and have plans to add a toggle for the round grid when looking at a range.
Hey, I'm sure your system will work perfectly fine for those who need a grid system, not yet for my project but of course we can fix it.

The reason we keep having unit problems (I think) is because I have been assuming you have only buildings, I'm starting to think now that you have non-structure units.
Honestly, I have 3 unfinished projects, "Champion TD (If you have played legion td before it is like that)/Human vs Vampire (Like other vampirism maps)/Farmer vs Hunter". Overall I wanted a range system that I could use for all of them.

Working today, so it will be not until wed/thursday that I can get back to you, but I want to get this hammered out.
I'm not in rush, whenever you are/were free.

Would you want to share a demo of the game with me?
Of course, I will send it to you in a conversation.

Current idea is to make a semi-transparent circle that can have its color changed to the same colors that will just show a solid circle (not just outline) If you would rather an outline, I can do that for you, but for my final system I think I'll do a filled circle.
I want a simple circle, not a puzzle circle please. It would be great if you could change the grid file to a circle, like the image I attached.
 

Attachments

  • dota-2-enchantress.jpg
    dota-2-enchantress.jpg
    475.4 KB · Views: 9
Last edited:
Level 12
Joined
Jan 10, 2023
Messages
191
I want a simple circle, not a puzzle circle please. It would be great if you could change the grid file to a circle, like the image I attached.

When you say simple circle:

Do you mean just an outline?

Is a partly transparent solid color okay?

Do you mean many circles replacing each of the square tiles (as in circle tiles)?

I was thinking for ranges I would do a regular circle, not a bunch of squares or little circles.

For pathing (showing the cliffs/ blight/ water), circle of squares or little circles makes more sense to me
- but maybe you don't care about pathing.

For range, I thought a solid transparent color, not just an outline would be best, but this is a very easy change so I wasn't too worried about it.
 
Level 10
Joined
Jun 20, 2017
Messages
327
There are a lot of systems/examples of Range indicators that exist already on these forums. This sort of thing doesn't need to be associated with a grid system.
Yes I know, I always search before asking. I already have a range system, which I don't like.
Here is the trigger,
  • Range Checker
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Range Checker
    • Actions
      • Set VariableSet Points_CheckRange[1] = (Position of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Or - Any (Conditions) are true
            • Conditions
              • (Unit-type of (Casting unit)) Equal to Guard Tower
              • (Unit-type of (Casting unit)) Equal to Boulder Tower
              • (Unit-type of (Casting unit)) Equal to Boulder Tower (Super)
              • (Unit-type of (Casting unit)) Equal to Boulder Tower (Ultra)
        • Then - Actions
          • Unit - Create 1 Check Range [Dummy] for (Owner of (Triggering unit)) at Points_CheckRange[1] facing Default building facing degrees
          • Animation - Change (Last created unit)'s size to (800.00%, 800.00%, 800.00%) of its original size
          • Unit - Add a 10.00 second Generic expiration timer to (Last created unit)
        • Else - Actions
      • Custom script: call RemoveLocation(udg_Points_CheckRange[1])
 
Last edited:
Level 10
Joined
Jun 20, 2017
Messages
327
Is a partly transparent solid color okay?
I'm not sure I have to see it first!

Do you mean just an outline?
I mean, it shouldn't be tile, just a simple circle that can be resized.

Do you mean many circles replacing each of the square tiles (as in circle tiles)?
No. Like this system you use a lot of tiles to show the range which I don't like. It gets very crowded and confusing for a range indicator.

I was thinking for ranges I would do a regular circle, not a bunch of squares or little circles.
Yes.

For pathing (showing the cliffs/ blight/ water), circle of squares or little circles makes more sense to me
- but maybe you don't care about pathing.
Actually, I really liked it, so cool with those many colors. But for a grid system not range indicator. <3

This thread has been solved, as a gird!
 
Last edited:
Status
Not open for further replies.
Top