diff options
Diffstat (limited to 'src/layer.cpp')
-rw-r--r-- | src/layer.cpp | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/layer.cpp b/src/layer.cpp new file mode 100644 index 000000000..b897c45a3 --- /dev/null +++ b/src/layer.cpp @@ -0,0 +1,137 @@ +/* $Id: map.cpp 23740 2012-01-03 21:32:51Z $ */ +/* + +Это модуль, для возможности полноценной игры в трех измерениях +(подземелье, метро, итп.) + + +Плоское игровое поле выглядит примерно так: +*-----------* +| | +| | +| | +*-----------* + +Мысленно нарежем его на одинаковые части: +*---*---*---* +| | | | +| | | | +| | | | +*---*---*---* + +Мысленно соберем части в вертикальную стопочку: +*---* +| *---* +| | *---* +| | | | +* | | | + * | | + *---* + +Таким образом имея плоскую карту мы описываем 3д пространство. + +Для простоты вся карта делится только по оси Y (разрезы параллельны оси X) +Деление происходит на 1, 2, 4, или 8 кусочков. + +Например было выбрано поле 64х64, с 4-мя слоями: +Создается карта 64х256, подразумевается, что: + + X Y + верхний слой 0--63 0--63 + второй слой 0--63 64--127 + третий слой 0--63 128--191 + четвертый слой 0--63 192--255 + + +Обычная карта + MapSizeX х (MapSizeY) + +Представление в виде слоев + LayerSizeX x (LayerSizeY x LayerCount) + +Иными словами игровые координаты "плоского" пространства + + MapX, MapY, MapZ + +переходят в координаты нового "3д" пространства + + // Константы + LayerCount = число кусочков... (1, или 2, или 4, итд.) + LayerSizeZ = сдвиг слоя по вертикали (например 1) + + // Аксиомы + MapSizeX == LayerSizeX + MapSizeY == LayerSizeY * LayerCount + + // Расчет координат + LayerIndex = MapY / LayerSizeY + + WorldX = MapX + WorldY = MapY - LayerIndex*LayerSizeY + WorldZ = MapZ + LayerIndex*LayerSizeZ +*/ + +/** @file map.cpp Base functions related to the map and distances on them. */ + +#include "stdafx.h" +#include "debug.h" +#include "core/alloc_func.hpp" +#include "void_map.h" +#include "layer_func.h" +#include "layer_type.h" +#include "landscape.h" + +#if defined(_MSC_VER) +/* Why the hell is that not in all MSVC headers?? */ +extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); +#endif + +uint _layer_size_x; ///< Size of the map along the X +uint _layer_size_y; ///< Size of the map along the Y +uint _layer_count; ///< The number of tiles on the map +uint _layer_count_log; +uint _layer_size; ///< Layer size (sizeX * sizeY) + +void InstallLayerSystem(uint size_x, uint size_y, uint layer_count) +{ + if (!IsInsideMM(layer_count, MIN_LAYER_COUNT, MAX_LAYER_COUNT)) + error("invalid layer count"); + + _layer_size_x = size_x; + _layer_size_y = size_y; + _layer_size = size_x * size_y; + _layer_count = layer_count; + _layer_count_log = FindFirstBit(layer_count); +} + +void FixUndergroundHeights() +{ + uint width = MapSizeX(); + uint height = MapSizeY(); + + /* Layer correct */ + for (uint row = 0; (uint)row < height; row++) { + + /* Граница между слоями */ + if (!(row % LayerSizeY())) + for (uint x = 0; x < width; x++) MakeVoid(width * row + x); + + for (uint col = 0; (uint)col < width; col++) { + uint tile = TileXY(row, col); + if (IsUnderground(tile)) + SetTileHeight(tile, 0); + } + } +} + +uint8 calculateLayer(const ViewPort *vp) +{ + // Функция ViewportDoDraw вызывается несколько раз с разными параметрами + // Нужно же найти только один слой. + // Опираемся на вьюпорт. + + Point pt = InverseRemapCoords(vp->virtual_left+(vp->virtual_width >> 1),vp->virtual_top+(vp->virtual_height >> 1)); + TileIndex center = TileVirtXY(pt.x, pt.y); + return LayerIndex(center); +} + |