summaryrefslogtreecommitdiff
path: root/src/layer.cpp
blob: fdf182e1f6ed7c9252948f11a03cbbe24245a57c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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);
}