Map and terrain (Civ5)

From Civilization Modding Wiki
Revision as of 13:18, 21 September 2012 by DonQuich (talk | contribs)
Jump to navigationJump to search

This page is a part of the Lua and UI Reference.

Hexagonal layout

Coordinates systems

Civ5 uses three different coordinates systems for plots:

  • The world coordinates. The coordinates of the plot's graphics in the 3D space where the world is rendered. This system is only used when you want to display an icon over the map, through a WorldAnchor.
  • The grid coordinates. The logical coordinates of a plot. This is the system returned by Plot:GetX() and Plot:GetY()
  • The hex coordinates. The logical coordinates of a plot. Some computations are easier to perform in this system.
The grid coordinates: horizontal and vertical axes are orthogonal.
The hex coordinates: the vertical axis makes a 60° angle with the horizontal axis.

The reason behind the coexistence of the grid and hex coordinates is because most computations are easier to perform in the hex system. For example, if you wish to examine the neighbors of a plot...

  • In the grid coordinates, you first need to test whether y is odd or even. Depending on the result, the offsets of the top plots will be { (0,1), (1,1) } or { (-1,1), (0,1)}.
  • However no such test is required in the hex system: the top offsets are always { (-1,1), (0,1) }.


Helpful functions

The following global functions will help you:

Vector2 Vector2(int x, int y) makes a 2D vector.
int, int ToGridFromHex(int x, int y)
int, int, int GridToWorld(int x, int y)
Vector2 ToHexFromGrid(Vector2 hexPos)
Vector3 HexToWorld(Vector2 hexPos)


Plots indexing

The function Map.GetPlotByIndex(int index) takes an index and returns a plot. This index can be computed as follow:

local w = Map.GetGridSize()
local index = gridX + gridY * w


Enumerating plots

If you need to enumerate plots in specific orders, you should look at Border and plots iterator, a great library from Whoward69 who provides nice iterators for different scan orders.

Otherwise, Map.PlotXYWithRangeCheck offers a simple way to scan all plots within a certain range.

local x, y = ... -- Initialize those
local range = 5
for dx = -range, range do
    for dy = -range, range do
       local plot = Map.PlotXYWithRangeCheck(x, y, dx, dy, range)
       if plot then
            -- Do whatever you want with this plot
       end
    end
end


Rivers

Come back later!