Отрисовка обзора

Author: Vladimir Chebotarev aka ex-lend

Vision area calculation

В первую очередь формируются две вспомогательные таблицы (не зависящие от карты):

short a28000[41][41]; // вспомогательная таблица 1
char a22000[41][41][2]; // вспомогательная таблица 2 (корректировка координат)

// вспомогательные значения
int a2A004 = 7; // map.reg/Scanning/ScanShift (если не задано, то 7)
int a2A000 = 1 << a2A004;

for (int i = 0; i <= 20; ++i)
{
	for (int j = 0; j <= 20; ++j)
	{
		short d = i || j ? pow(i*i+j*j, 0.5)/max(i,j)*a2A000 : 0;

		a28000[20+i][20+j] = d;
		a28000[20+i][20-j] = d;
		a28000[20-i][20+j] = d;
		a28000[20-i][20-j] = d;

		if (j < (i / 2)) // тут мб неточно
		{
			a22000[20+i][20+j][0] = -1;
			a22000[20+i][20+j][1] = 0;
			a22000[20-i][20-j][0] = 1;
			a22000[20-i][20-j][1] = 0;
			a22000[20+i][20-j][0] = -1;
			a22000[20+i][20-j][1] = 0;
			a22000[20-i][20+j][0] = 1;
			a22000[20-i][20+j][1] = 0;
		}
		else if (j > (i * 2)) // тут мб неточно
		{
			a22000[20+i][20+j][0] = 0;
			a22000[20+i][20+j][1] = -1;
			a22000[20-i][20-j][0] = 0;
			a22000[20-i][20-j][1] = 1;
			a22000[20+i][20-j][0] = 0;
			a22000[20+i][20-j][1] = 1;
			a22000[20-i][20+j][0] = 0;
			a22000[20-i][20+j][1] = -1;
		}
		else
		{
			a22000[20+i][20+j][0] = -1;
			a22000[20+i][20+j][1] = -1;
			a22000[20-i][20-j][0] = 1;
			a22000[20-i][20-j][1] = 1;
			a22000[20+i][20-j][0] = -1;
			a22000[20+i][20-j][1] = 1;
			a22000[20-i][20+j][0] = 1;
			a22000[20-i][20+j][1] = -1;
		}
	}
}

// информация из allods2.exe:0055C324
 

При ScanShift == 7 таблицы выглядят так:

Таблица 1 (a28000[][]):

  0 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
 0  181 176 172 167 163 160 156 152 149 146 143 140 137 135 133 131 130 129 128 128 128 128 128 129 130 131 133 135 137 140 143 146 149 152 156 160 163 167 172 176 181
 1  176 181 176 171 167 163 158 155 151 147 144 141 138 136 134 132 130 129 128 128 128 128 128 129 130 132 134 136 138 141 144 147 151 155 158 163 167 171 176 181 176
 2  172 176 181 176 171 166 162 157 153 150 146 143 140 137 134 132 131 129 128 128 128 128 128 129 131 132 134 137 140 143 146 150 153 157 162 166 171 176 181 176 172
 3  167 171 176 181 175 170 165 161 156 152 148 144 141 138 135 133 131 129 128 128 128 128 128 129 131 133 135 138 141 144 148 152 156 161 165 170 175 181 176 171 167
 4  163 167 171 175 181 175 170 164 160 155 150 146 143 139 136 134 131 130 128 128 128 128 128 130 131 134 136 139 143 146 150 155 160 164 170 175 181 175 171 167 163
 5  160 163 166 170 175 181 175 169 163 158 153 149 145 141 137 134 132 130 129 128 128 128 129 130 132 134 137 141 145 149 153 158 163 169 175 181 175 170 166 163 160
 6  156 158 162 165 170 175 181 174 168 162 157 152 147 143 139 135 133 130 129 128 128 128 129 130 133 135 139 143 147 152 157 162 168 174 181 175 170 165 162 158 156
 7  152 155 157 161 164 169 174 181 174 167 161 155 150 145 140 137 133 131 129 128 128 128 129 131 133 137 140 145 150 155 161 167 174 181 174 169 164 161 157 155 152
 8  149 151 153 156 160 163 168 174 181 173 166 160 153 148 143 138 134 131 129 128 128 128 129 131 134 138 143 148 153 160 166 173 181 174 168 163 160 156 153 151 149
 9  146 147 150 152 155 158 162 167 173 181 172 165 158 151 145 140 136 132 130 128 128 128 130 132 136 140 145 151 158 165 172 181 173 167 162 158 155 152 150 147 146
 10  143 144 146 148 150 153 157 161 166 172 181 172 163 156 149 143 137 133 130 128 128 128 130 133 137 143 149 156 163 172 181 172 166 161 157 153 150 148 146 144 143
 11  140 141 143 144 146 149 152 155 160 165 172 181 171 162 153 146 140 134 131 128 128 128 131 134 140 146 153 162 171 181 172 165 160 155 152 149 146 144 143 141 140
 12  137 138 140 141 143 145 147 150 153 158 163 171 181 170 160 150 143 136 131 128 128 128 131 136 143 150 160 170 181 171 163 158 153 150 147 145 143 141 140 138 137
 13  135 136 137 138 139 141 143 145 148 151 156 162 170 181 168 157 147 139 133 129 128 129 133 139 147 157 168 181 170 162 156 151 148 145 143 141 139 138 137 136 135
 14  133 134 134 135 136 137 139 140 143 145 149 153 160 168 181 166 153 143 134 129 128 129 134 143 153 166 181 168 160 153 149 145 143 140 139 137 136 135 134 134 133
 15  131 132 132 133 134 134 135 137 138 140 143 146 150 157 166 181 163 149 137 130 128 130 137 149 163 181 166 157 150 146 143 140 138 137 135 134 134 133 132 132 131
 16  130 130 131 131 131 132 133 133 134 136 137 140 143 147 153 163 181 160 143 131 128 131 143 160 181 163 153 147 143 140 137 136 134 133 133 132 131 131 131 130 130
 17  129 129 129 129 130 130 130 131 131 132 133 134 136 139 143 149 160 181 153 134 128 134 153 181 160 149 143 139 136 134 133 132 131 131 130 130 130 129 129 129 129
 18  128 128 128 128 128 129 129 129 129 130 130 131 131 133 134 137 143 153 181 143 128 143 181 153 143 137 134 133 131 131 130 130 129 129 129 129 128 128 128 128 128
 19  128 128 128 128 128 128 128 128 128 128 128 128 128 129 129 130 131 134 143 181 128 181 143 134 131 130 129 129 128 128 128 128 128 128 128 128 128 128 128 128 128
 20  128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 0 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128
 21  128 128 128 128 128 128 128 128 128 128 128 128 128 129 129 130 131 134 143 181 128 181 143 134 131 130 129 129 128 128 128 128 128 128 128 128 128 128 128 128 128
 22  128 128 128 128 128 129 129 129 129 130 130 131 131 133 134 137 143 153 181 143 128 143 181 153 143 137 134 133 131 131 130 130 129 129 129 129 128 128 128 128 128
 23  129 129 129 129 130 130 130 131 131 132 133 134 136 139 143 149 160 181 153 134 128 134 153 181 160 149 143 139 136 134 133 132 131 131 130 130 130 129 129 129 129
 24  130 130 131 131 131 132 133 133 134 136 137 140 143 147 153 163 181 160 143 131 128 131 143 160 181 163 153 147 143 140 137 136 134 133 133 132 131 131 131 130 130
 25  131 132 132 133 134 134 135 137 138 140 143 146 150 157 166 181 163 149 137 130 128 130 137 149 163 181 166 157 150 146 143 140 138 137 135 134 134 133 132 132 131
 26  133 134 134 135 136 137 139 140 143 145 149 153 160 168 181 166 153 143 134 129 128 129 134 143 153 166 181 168 160 153 149 145 143 140 139 137 136 135 134 134 133
 27  135 136 137 138 139 141 143 145 148 151 156 162 170 181 168 157 147 139 133 129 128 129 133 139 147 157 168 181 170 162 156 151 148 145 143 141 139 138 137 136 135
 28  137 138 140 141 143 145 147 150 153 158 163 171 181 170 160 150 143 136 131 128 128 128 131 136 143 150 160 170 181 171 163 158 153 150 147 145 143 141 140 138 137
 29  140 141 143 144 146 149 152 155 160 165 172 181 171 162 153 146 140 134 131 128 128 128 131 134 140 146 153 162 171 181 172 165 160 155 152 149 146 144 143 141 140
 30  143 144 146 148 150 153 157 161 166 172 181 172 163 156 149 143 137 133 130 128 128 128 130 133 137 143 149 156 163 172 181 172 166 161 157 153 150 148 146 144 143
 31  146 147 150 152 155 158 162 167 173 181 172 165 158 151 145 140 136 132 130 128 128 128 130 132 136 140 145 151 158 165 172 181 173 167 162 158 155 152 150 147 146
 32  149 151 153 156 160 163 168 174 181 173 166 160 153 148 143 138 134 131 129 128 128 128 129 131 134 138 143 148 153 160 166 173 181 174 168 163 160 156 153 151 149
 33  152 155 157 161 164 169 174 181 174 167 161 155 150 145 140 137 133 131 129 128 128 128 129 131 133 137 140 145 150 155 161 167 174 181 174 169 164 161 157 155 152
 34  156 158 162 165 170 175 181 174 168 162 157 152 147 143 139 135 133 130 129 128 128 128 129 130 133 135 139 143 147 152 157 162 168 174 181 175 170 165 162 158 156
 35  160 163 166 170 175 181 175 169 163 158 153 149 145 141 137 134 132 130 129 128 128 128 129 130 132 134 137 141 145 149 153 158 163 169 175 181 175 170 166 163 160
 36  163 167 171 175 181 175 170 164 160 155 150 146 143 139 136 134 131 130 128 128 128 128 128 130 131 134 136 139 143 146 150 155 160 164 170 175 181 175 171 167 163
 37  167 171 176 181 175 170 165 161 156 152 148 144 141 138 135 133 131 129 128 128 128 128 128 129 131 133 135 138 141 144 148 152 156 161 165 170 175 181 176 171 167
 38  172 176 181 176 171 166 162 157 153 150 146 143 140 137 134 132 131 129 128 128 128 128 128 129 131 132 134 137 140 143 146 150 153 157 162 166 171 176 181 176 172
 39  176 181 176 171 167 163 158 155 151 147 144 141 138 136 134 132 130 129 128 128 128 128 128 129 130 132 134 136 138 141 144 147 151 155 158 163 167 171 176 181 176
 40  181 176 172 167 163 160 156 152 149 146 143 140 137 135 133 131 130 129 128 128 128 128 128 129 130 131 133 135 137 140 143 146 149 152 156 160 163 167 172 176 181

Таблица 2 (a22000[][][]):

  0 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
 0 
 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 

Далее, берем пустую таблицу размером 41x41 и записываем в центр (20; 20) число равное ((int)обзор << a2A004) + (1 << (a2A004 - 1)). Для обзора, например, 15.1 и ScanShift=7 получится 1984.
Теперь идем по всем направлениям от этой клетки.
(x0, y0) — клетка, где находится персонаж. Пусть мы находимся в клетке (x1, y1). Пусть известно значение в таблице в клетке (x2, y2),
x2 = x1 + a22000[y1][x1][0], y2 = y1 + a22000[y1][x1][1].
Иначе говоря, таблица a22000[][][] задает клетку относительно данной, из которой мы будем брать предыдущее значение видимости.
Так вот, видимость[y1][x1] = видимость[y2][x2] - высота[y1][x1] + высота[y0][x0] - a28000[y1][x1].
Если видимость больше 0, то клетка видна, иначе — нет.

Информация взята из подпрограмм:

allods2.exe:0055CC18(?, x_y) - вычисление области видимости для юнита
allods2.exe:0055CAE8(offsetX, offsetY, pointOffset, curAlt) - вычисление заданной ячейки таблицы видимости