798 lines
27 KiB
C++
798 lines
27 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "scumm/he/moonbase/map_katton.h"
|
|
|
|
namespace Scumm {
|
|
|
|
KattonGenerator::KattonGenerator(int seed) {
|
|
_seed = seed;
|
|
}
|
|
|
|
int KattonGenerator::getRandomNumber() {
|
|
// This is the exact linear congruential generator
|
|
// algorithm used on MSVCRT (Windows Visual C++ Runtime), with
|
|
// RAND_MAX being 0x7fff (32767). This is implemented here
|
|
// to match the RNG between the original Moonbase Console
|
|
// program and ScummVM.
|
|
//
|
|
// (Common::RandomSource uses Xorshift and uses unsigned
|
|
// integers compared to MSVCRT's rand)
|
|
_seed = _seed * 214013 + 2531011;
|
|
return (_seed >> 16) & 0x7fff;
|
|
}
|
|
|
|
MapFile *KattonGenerator::generateMap(int water, int tileSet, int mapSize, int energy, int terrain) {
|
|
_size = mapSize;
|
|
_tileset = tileSet;
|
|
int inEnergy = energy;
|
|
int inTerrain = terrain;
|
|
int inWater = water;
|
|
|
|
if (!(inEnergy == 0)) {
|
|
inEnergy = inEnergy * 14 + plusminus(14);
|
|
}
|
|
|
|
if (!(inTerrain == 0)) {
|
|
inTerrain = inTerrain * 14 + plusminus(14);
|
|
}
|
|
|
|
if (!(inWater == 0)) {
|
|
inWater = inWater * 14 + plusminus(14);
|
|
}
|
|
|
|
float terrainpercent = ((float)inTerrain) / 100;
|
|
float waterpercent = ((float)inWater) / 100;
|
|
|
|
//****************************************Let the generation BEGIN!
|
|
|
|
fillboards(0);
|
|
|
|
// used everywhere
|
|
int i, j, k, l, x, y, z;
|
|
// used in making the basic landmass shapes
|
|
int numsplotches, length;
|
|
// used in making water
|
|
int numwaterplaces = 0, numwatersplotches, multiplier;
|
|
short int goodwater[1600][2];
|
|
// used in making energy
|
|
int maxnumclose = 0, maxnumfar = 0, maxnumrand = 0, smallmed = 0, goodplaceClose[300][2], goodplaceFar[300][2], numplaceClose, numplaceFar, placeFar[3], placeClose[2], counter, counterpools;
|
|
int stringiness, randomx, randomy;
|
|
|
|
//****************************************Make the basic landmass shapes.
|
|
|
|
numsplotches = (int)(_size / 4) + (int)((terrainpercent - 0.5) * _size / 2);
|
|
|
|
for (i = 0; i < numsplotches; i++) {
|
|
length = (int)(((1 - waterpercent) / 6 * _size * _size) / numsplotches);
|
|
length = length + plusminus((int)(length / 2));
|
|
stringiness = 1 + plusminus(1);
|
|
randomx = getRandomNumber() % _size;
|
|
randomy = getRandomNumber() % _size;
|
|
randomsplotch(length, 1 + stringiness, 2, randomx, randomy);
|
|
}
|
|
|
|
for (i = 0; i < (int)numsplotches / 4; i++) {
|
|
length = (int)(((1 - waterpercent) / 3 * _size * _size) / numsplotches);
|
|
length = length + plusminus((int)(length / 4));
|
|
stringiness = 1 + plusminus(1);
|
|
randomx = getRandomNumber() % _size;
|
|
randomy = getRandomNumber() % _size;
|
|
randomsplotch(length, stringiness, 1, randomx, randomy);
|
|
}
|
|
|
|
for (i = 0; i < (int)numsplotches / 2; i++) {
|
|
length = (int)(_size + plusminus((int)(_size / 2)));
|
|
stringiness = 1 + plusminus(1);
|
|
randomx = getRandomNumber() % _size;
|
|
randomy = getRandomNumber() % _size;
|
|
randomsplotch(length, stringiness, 0, randomx, randomy);
|
|
}
|
|
|
|
for (i = 0; i < (int)waterpercent * _size; i++) {
|
|
length = (int)(_size + plusminus((int)(_size / 2)));
|
|
stringiness = 1 + plusminus(1);
|
|
randomx = getRandomNumber() % _size;
|
|
randomy = getRandomNumber() % _size;
|
|
randomsplotch(length, stringiness, 0, randomx, randomy);
|
|
}
|
|
|
|
//****************************************Fatten up the landmasses
|
|
|
|
// make the highhills bigger
|
|
fattenall(-3, 2, NEVER_USED_NUM, TEMP_REPLACEMENT_NUMA);
|
|
replacenum(TEMP_REPLACEMENT_NUMA, 2);
|
|
|
|
// make the lowlands bigger, depending on wateriness
|
|
fattenall(-((int)(waterpercent * 3)), 0, NEVER_USED_NUM, TEMP_REPLACEMENT_NUMA);
|
|
replacenum(TEMP_REPLACEMENT_NUMA, 2);
|
|
|
|
// surround the high hills with at least one med
|
|
fattenall(2, 2, NEVER_USED_NUM, 1);
|
|
|
|
// fatten the medium hills
|
|
fattenall(-3, 1, 2, TEMP_REPLACEMENT_NUMA);
|
|
replacenum(TEMP_REPLACEMENT_NUMA, 1);
|
|
|
|
//****************************************Smooth out/rough up the landmasses
|
|
|
|
randomflip((int)(terrainpercent * terrainpercent * _size * _size / 4 + _size / 4), inWater);
|
|
|
|
//****************************************Make the start locations
|
|
|
|
findstartloc();
|
|
|
|
//****************************************Put down some water
|
|
|
|
for (i = 0; i < _size; i += 2) {
|
|
for (j = 0; j < _size; j += 2) {
|
|
if (goodforwater(i, j)) {
|
|
goodwater[numwaterplaces][0] = i;
|
|
goodwater[numwaterplaces][1] = j;
|
|
numwaterplaces++;
|
|
}
|
|
}
|
|
}
|
|
|
|
numwatersplotches = (int)(_size * waterpercent * waterpercent * 5);
|
|
|
|
if (numwaterplaces <= numwatersplotches) {
|
|
numwatersplotches = numwaterplaces;
|
|
}
|
|
if (numwatersplotches >= 1) {
|
|
multiplier = (int)((float)numwaterplaces / (float)numwatersplotches);
|
|
|
|
for (i = 0; i < numwatersplotches; i++) {
|
|
z = getRandomNumber() % multiplier + i * multiplier;
|
|
x = goodwater[z][0];
|
|
y = goodwater[z][1];
|
|
length = _size + plusminus(_size / 2);
|
|
stringiness = getRandomNumber() % 3;
|
|
randomwater(length, stringiness, x, y);
|
|
}
|
|
}
|
|
|
|
//****************************************Put down the energy
|
|
if (inEnergy >= 90) {
|
|
maxnumclose = 2;
|
|
maxnumfar = 3;
|
|
maxnumrand = (int)(_size * _size / 150);
|
|
smallmed = 2;
|
|
} else if (inEnergy >= 75) {
|
|
maxnumclose = 2;
|
|
maxnumfar = 1;
|
|
maxnumrand = (int)(_size * _size / 250) + 4;
|
|
smallmed = 3;
|
|
} else if (inEnergy >= 60) {
|
|
maxnumclose = 1;
|
|
maxnumfar = 2;
|
|
maxnumrand = (int)(_size * _size / 250);
|
|
smallmed = 4;
|
|
} else if (inEnergy >= 45) {
|
|
maxnumclose = 1;
|
|
maxnumfar = 1;
|
|
maxnumrand = (int)(_size * _size / 250);
|
|
smallmed = 6;
|
|
} else if (inEnergy >= 30) {
|
|
maxnumclose = 1;
|
|
maxnumfar = 0;
|
|
maxnumrand = (int)(_size * _size / 350) + 2;
|
|
smallmed = 8;
|
|
} else if (inEnergy >= 15) {
|
|
maxnumclose = 0;
|
|
maxnumfar = 1;
|
|
maxnumrand = (int)(_size * _size / 450);
|
|
smallmed = 10;
|
|
} else if (inEnergy >= 0) {
|
|
maxnumclose = 0;
|
|
maxnumfar = 0;
|
|
maxnumrand = 0;
|
|
smallmed = 1;
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
numplaceClose = 0;
|
|
numplaceFar = 0;
|
|
for (j = 0; j < _size; j++) {
|
|
for (k = 0; k < _size; k++) {
|
|
if ((goodforenergy(j, k, 0)) && (distance(_startloc[i][0], _startloc[i][1], j, k) >= (int)(_size / 10)) && (distance(_startloc[i][0], _startloc[i][1], j, k) <= (int)(_size / 8))) {
|
|
goodplaceClose[numplaceClose][0] = j;
|
|
goodplaceClose[numplaceClose][1] = k;
|
|
numplaceClose++;
|
|
} else if ((goodforenergy(j, k, 0)) && (distance(_startloc[i][0], _startloc[i][1], j, k) >= (int)(_size / 7)) && (distance(_startloc[i][0], _startloc[i][1], j, k) <= (int)(_size / 5))) {
|
|
goodplaceFar[numplaceFar][0] = j;
|
|
goodplaceFar[numplaceFar][1] = k;
|
|
numplaceFar++;
|
|
}
|
|
}
|
|
}
|
|
if (numplaceClose >= 1) {
|
|
placeClose[0] = getRandomNumber() % (int)(numplaceClose / 2) + 1;
|
|
}
|
|
if (numplaceClose >= 2) {
|
|
placeClose[1] = getRandomNumber() % (int)(numplaceClose / 2) + (int)(numplaceClose / 2) - 1;
|
|
}
|
|
|
|
if (numplaceClose >= maxnumclose) {
|
|
for (l = 0; l < maxnumclose; l++) {
|
|
_special[goodplaceClose[placeClose[l]][0]][goodplaceClose[placeClose[l]][1]] = 100;
|
|
}
|
|
} else {
|
|
for (l = 0; l < numplaceClose; l++) {
|
|
_special[goodplaceClose[placeClose[l]][0]][goodplaceClose[placeClose[l]][1]] = 100;
|
|
}
|
|
}
|
|
|
|
if (numplaceFar >= 1) {
|
|
placeFar[0] = getRandomNumber() % (int)(numplaceFar / 3) + 1;
|
|
}
|
|
if (numplaceFar >= 2) {
|
|
placeFar[1] = getRandomNumber() % (int)(numplaceFar / 3) + (int)(numplaceClose / 3);
|
|
}
|
|
if (numplaceFar >= 3) {
|
|
placeFar[2] = getRandomNumber() % (int)(numplaceFar / 3) + (int)(2 * numplaceClose / 3) - 1;
|
|
}
|
|
|
|
if (numplaceFar >= maxnumfar) {
|
|
for (l = 0; l < maxnumfar; l++) {
|
|
_special[goodplaceFar[placeFar[l]][0]][goodplaceFar[placeFar[l]][1]] = 100;
|
|
}
|
|
} else {
|
|
for (l = 0; l < numplaceFar; l++) {
|
|
_special[goodplaceFar[placeFar[l]][0]][goodplaceFar[placeFar[l]][1]] = 100;
|
|
}
|
|
}
|
|
}
|
|
|
|
counter = 0;
|
|
counterpools = 4 * (maxnumfar + maxnumclose);
|
|
for (k = 0; k < maxnumrand && counterpools < 50; k++) {
|
|
do {
|
|
i = getRandomNumber() % _size;
|
|
j = getRandomNumber() % _size;
|
|
counter++;
|
|
} while (!((distance(i, j, _startloc[0][0], _startloc[0][1]) >= 10) && (distance(i, j, _startloc[1][0], _startloc[1][1]) >= 10) && (distance(i, j, _startloc[2][0], _startloc[2][1]) >= 10) && (distance(i, j, _startloc[3][0], _startloc[3][1]) >= 10) && (goodforenergy(i, j, 1)) && (counter < 5000)));
|
|
if (getRandomNumber() % smallmed == 0) {
|
|
_special[i][j] = 200;
|
|
counterpools++;
|
|
} else {
|
|
_special[i][j] = 100;
|
|
counterpools++;
|
|
}
|
|
}
|
|
|
|
//****************************************Do that saving thing that you do, BABY!
|
|
MIF mif = MIF();
|
|
Common::sprintf_s(mif._name, "Katton %04X", (uint16)_seed);
|
|
mif._dimension = _size;
|
|
mif._mapType = _tileset;
|
|
for (j = 0; j < _size; j++) {
|
|
for (i = 0; i < _size; i++)
|
|
mif._cornerMap[i][j] = _board[i][j];
|
|
for (i = 0; i < _size; i++)
|
|
if (_special[i][j] == 0)
|
|
mif._centerMap[i][j] = '.';
|
|
else if (_special[i][j] == -1)
|
|
mif._centerMap[i][j] = 'W';
|
|
else if (_special[i][j] == 100)
|
|
mif._centerMap[i][j] = 'S';
|
|
else if (_special[i][j] == 200)
|
|
mif._centerMap[i][j] = 'M';
|
|
else if (_special[i][j] == 300)
|
|
mif._centerMap[i][j] = 'L';
|
|
else
|
|
mif._centerMap[i][j] = -_special[i][j];
|
|
}
|
|
|
|
// Generate new map:
|
|
MapFile *map = new MapFile();
|
|
mif.generateMap(map);
|
|
|
|
return map;
|
|
}
|
|
|
|
int KattonGenerator::distance(int x1, int y1, int x2, int y2) {
|
|
int dx, dy, disp;
|
|
dx = min((abs(x1 - x2)), (abs(x1 + _size - x2)), (abs(x2 + _size - x1)));
|
|
dy = min((abs(y1 - y2)), (abs(y1 + _size - y2)), (abs(y2 + _size - y1)));
|
|
disp = (int)sqrt((double)(dx * dx + dy * dy));
|
|
return disp;
|
|
}
|
|
|
|
int KattonGenerator::min(int a, int b, int c) {
|
|
if ((a <= b) && (a <= c)) {
|
|
return a;
|
|
} else if ((b < a) && (b <= c)) {
|
|
return b;
|
|
} else if ((c < a) && (c < b)) {
|
|
return c;
|
|
} else {
|
|
return a;
|
|
}
|
|
}
|
|
|
|
int KattonGenerator::goodforenergy(int x, int y, int poolsize) {
|
|
switch (poolsize) {
|
|
case 0:
|
|
if ((_board[x][y] == _board[findcoord(x, +1)][y]) && (_board[findcoord(x, +1)][y] == _board[x][findcoord(y, +1)]) && (_board[x][findcoord(y, +1)] == _board[findcoord(x, +1)][findcoord(y, +1)])) {
|
|
//check main map
|
|
if (_special[x][y] == 0) { //specials are clear
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
case 1:
|
|
if ((_board[x][y] == _board[findcoord(x, +1)][y]) && (_board[findcoord(x, +1)][y] == _board[x][findcoord(y, +1)]) && (_board[x][findcoord(y, +1)] == _board[findcoord(x, +1)][findcoord(y, +1)])) { //check main map
|
|
if ((_special[x][y] == 0) && (_special[findcoord(x, +1)][y] == 0) && (_special[x][findcoord(y, +1)] == 0) && (_special[findcoord(x, +1)][findcoord(y, +1)] == 0)) { //specials are clear
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int KattonGenerator::plusminus(int max) {
|
|
int result = getRandomNumber() % (max + 1);
|
|
if (getRandomNumber() % 2 == 0) {
|
|
result *= (-1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int KattonGenerator::fillboards(int num) {
|
|
int i, j;
|
|
for (i = 0; i < _size; i++) {
|
|
for (j = 0; j < _size; j++) {
|
|
_board[i][j] = num;
|
|
_special[i][j] = num;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::randomplace(int numberofplaces, int placer) {
|
|
int i, randx, randy;
|
|
for (i = 0; i < numberofplaces; i++) {
|
|
randx = (getRandomNumber() % _size);
|
|
randy = (getRandomNumber() % _size);
|
|
_board[randx][randy] = placer;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::randomsplotch(int length, int stringiness, int placer, int x, int y) {
|
|
int currx, curry, direction = 10, prevdirection, movex = 0, movey = 0, i = 0;
|
|
currx = x;
|
|
curry = y;
|
|
while (i <= length) {
|
|
_board[currx][curry] = placer;
|
|
prevdirection = direction;
|
|
direction = (getRandomNumber() % 4);
|
|
if ((((direction + 2) == prevdirection) || ((direction - 2) == prevdirection)) && (stringiness == 2)) {
|
|
direction = prevdirection;
|
|
}
|
|
if (!((((direction + 2) == prevdirection) || ((direction - 2) == prevdirection)) && (stringiness == 1))) {
|
|
switch (direction) {
|
|
case 0:
|
|
movex = 0;
|
|
movey = 1;
|
|
break;
|
|
case 1:
|
|
movex = 1;
|
|
movey = 0;
|
|
break;
|
|
case 2:
|
|
movex = 0;
|
|
movey = -1;
|
|
break;
|
|
case 3:
|
|
movex = -1;
|
|
movey = 0;
|
|
break;
|
|
}
|
|
currx = findcoord(currx, movex);
|
|
curry = findcoord(curry, movey);
|
|
i++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::findcoord(int value, int move) {
|
|
move = move % _size;
|
|
int final = value + move;
|
|
if (final < 0) {
|
|
final = _size + final;
|
|
}
|
|
if (final >= _size) {
|
|
final = final % _size;
|
|
}
|
|
return final;
|
|
}
|
|
|
|
int KattonGenerator::replacenum(int replacee, int replacer) {
|
|
int i, j;
|
|
for (j = 0; j < _size; j++) {
|
|
for (i = 0; i < _size; i++) {
|
|
if (_board[i][j] == replacee) {
|
|
_board[i][j] = replacer;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::fattenall(int howfat, int middle, int ignorer, int replacer) {
|
|
int i, j, temp;
|
|
for (j = 0; j < _size; j++) {
|
|
for (i = 0; i < _size; i++) {
|
|
if (_board[i][j] == middle) {
|
|
if (howfat <= 0) {
|
|
temp = (int)(abs(howfat) + plusminus(2));
|
|
if (temp <= 1) {
|
|
temp = 2;
|
|
} else if (temp >= 6) {
|
|
temp = 5;
|
|
}
|
|
fattenone(i, j, temp, middle, ignorer, replacer);
|
|
} else {
|
|
fattenone(i, j, howfat, middle, ignorer, replacer);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
int KattonGenerator::fattenone(int x, int y, int howfat, int middle, int ignorer, int replacer) {
|
|
if (howfat == -100) {
|
|
_board[x][y] = replacer;
|
|
_board[findcoord(x, +1)][y] = replacer;
|
|
_board[x][findcoord(y, +1)] = replacer;
|
|
_board[findcoord(x, +1)][findcoord(y, +1)] = replacer;
|
|
}
|
|
if (howfat >= 1) {
|
|
_board[x][findcoord(y, -1)] = ((_board[x][findcoord(y, -1)] == middle) || (_board[x][findcoord(y, -1)] == ignorer)) ? _board[x][findcoord(y, -1)] : replacer;
|
|
_board[x][findcoord(y, +1)] = ((_board[x][findcoord(y, +1)] == middle) || (_board[x][findcoord(y, +1)] == ignorer)) ? _board[x][findcoord(y, +1)] : replacer;
|
|
_board[findcoord(x, -1)][y] = ((_board[findcoord(x, -1)][y] == middle) || (_board[findcoord(x, -1)][y] == ignorer)) ? _board[findcoord(x, -1)][y] : replacer;
|
|
_board[findcoord(x, +1)][y] = ((_board[findcoord(x, +1)][y] == middle) || (_board[findcoord(x, +1)][y] == ignorer)) ? _board[findcoord(x, +1)][y] : replacer;
|
|
}
|
|
if (howfat >= 2) {
|
|
_board[findcoord(x, -1)][findcoord(y, -1)] = ((_board[findcoord(x, -1)][findcoord(y, -1)] == middle) || (_board[findcoord(x, -1)][findcoord(y, -1)] == ignorer)) ? _board[findcoord(x, -1)][findcoord(y, -1)] : replacer;
|
|
_board[findcoord(x, -1)][findcoord(y, +1)] = ((_board[findcoord(x, -1)][findcoord(y, +1)] == middle) || (_board[findcoord(x, -1)][findcoord(y, +1)] == ignorer)) ? _board[findcoord(x, -1)][findcoord(y, +1)] : replacer;
|
|
_board[findcoord(x, +1)][findcoord(y, -1)] = ((_board[findcoord(x, +1)][findcoord(y, -1)] == middle) || (_board[findcoord(x, +1)][findcoord(y, -1)] == ignorer)) ? _board[findcoord(x, +1)][findcoord(y, -1)] : replacer;
|
|
_board[findcoord(x, +1)][findcoord(y, +1)] = ((_board[findcoord(x, +1)][findcoord(y, +1)] == middle) || (_board[findcoord(x, +1)][findcoord(y, +1)] == ignorer)) ? _board[findcoord(x, +1)][findcoord(y, +1)] : replacer;
|
|
}
|
|
if (howfat >= 3) {
|
|
_board[x][findcoord(y, -2)] = ((_board[x][findcoord(y, -2)] == middle) || (_board[x][findcoord(y, -2)] == ignorer)) ? _board[x][findcoord(y, -2)] : replacer;
|
|
_board[x][findcoord(y, +2)] = ((_board[x][findcoord(y, +2)] == middle) || (_board[x][findcoord(y, +2)] == ignorer)) ? _board[x][findcoord(y, +2)] : replacer;
|
|
_board[findcoord(x, -2)][y] = ((_board[findcoord(x, -2)][y] == middle) || (_board[findcoord(x, -2)][y] == ignorer)) ? _board[findcoord(x, -2)][y] : replacer;
|
|
_board[findcoord(x, +2)][y] = ((_board[findcoord(x, +2)][y] == middle) || (_board[findcoord(x, +2)][y] == ignorer)) ? _board[findcoord(x, +2)][y] : replacer;
|
|
}
|
|
if (howfat >= 4) {
|
|
_board[findcoord(x, -1)][findcoord(y, -2)] = ((_board[findcoord(x, -1)][findcoord(y, -2)] == middle) || (_board[findcoord(x, -1)][findcoord(y, -2)] == ignorer)) ? _board[findcoord(x, -1)][findcoord(y, -2)] : replacer;
|
|
_board[findcoord(x, -1)][findcoord(y, +2)] = ((_board[findcoord(x, -1)][findcoord(y, +2)] == middle) || (_board[findcoord(x, -1)][findcoord(y, +2)] == ignorer)) ? _board[findcoord(x, -1)][findcoord(y, +2)] : replacer;
|
|
_board[findcoord(x, +1)][findcoord(y, -2)] = ((_board[findcoord(x, +1)][findcoord(y, -2)] == middle) || (_board[findcoord(x, +1)][findcoord(y, -2)] == ignorer)) ? _board[findcoord(x, +1)][findcoord(y, -2)] : replacer;
|
|
_board[findcoord(x, +1)][findcoord(y, +2)] = ((_board[findcoord(x, +1)][findcoord(y, +2)] == middle) || (_board[findcoord(x, +1)][findcoord(y, +2)] == ignorer)) ? _board[findcoord(x, +1)][findcoord(y, +2)] : replacer;
|
|
|
|
_board[findcoord(x, -2)][findcoord(y, -1)] = ((_board[findcoord(x, -2)][findcoord(y, -1)] == middle) || (_board[findcoord(x, -2)][findcoord(y, -1)] == ignorer)) ? _board[findcoord(x, -2)][findcoord(y, -1)] : replacer;
|
|
_board[findcoord(x, -2)][findcoord(y, +1)] = ((_board[findcoord(x, -2)][findcoord(y, +1)] == middle) || (_board[findcoord(x, -2)][findcoord(y, +1)] == ignorer)) ? _board[findcoord(x, -2)][findcoord(y, +1)] : replacer;
|
|
_board[findcoord(x, +2)][findcoord(y, -1)] = ((_board[findcoord(x, +2)][findcoord(y, -1)] == middle) || (_board[findcoord(x, +2)][findcoord(y, -1)] == ignorer)) ? _board[findcoord(x, +2)][findcoord(y, -1)] : replacer;
|
|
_board[findcoord(x, +2)][findcoord(y, +1)] = ((_board[findcoord(x, +2)][findcoord(y, +1)] == middle) || (_board[findcoord(x, +2)][findcoord(y, +1)] == ignorer)) ? _board[findcoord(x, +2)][findcoord(y, +1)] : replacer;
|
|
}
|
|
if (howfat >= 5) {
|
|
_board[findcoord(x, -2)][findcoord(y, -2)] = ((_board[findcoord(x, -2)][findcoord(y, -2)] == middle) || (_board[findcoord(x, -2)][findcoord(y, -2)] == ignorer)) ? _board[findcoord(x, -2)][findcoord(y, -2)] : replacer;
|
|
_board[findcoord(x, -2)][findcoord(y, +2)] = ((_board[findcoord(x, -2)][findcoord(y, +2)] == middle) || (_board[findcoord(x, -2)][findcoord(y, +2)] == ignorer)) ? _board[findcoord(x, -2)][findcoord(y, +2)] : replacer;
|
|
_board[findcoord(x, +2)][findcoord(y, -2)] = ((_board[findcoord(x, +2)][findcoord(y, -2)] == middle) || (_board[findcoord(x, +2)][findcoord(y, -2)] == ignorer)) ? _board[findcoord(x, +2)][findcoord(y, -2)] : replacer;
|
|
_board[findcoord(x, +2)][findcoord(y, +2)] = ((_board[findcoord(x, +2)][findcoord(y, +2)] == middle) || (_board[findcoord(x, +2)][findcoord(y, +2)] == ignorer)) ? _board[findcoord(x, +2)][findcoord(y, +2)] : replacer;
|
|
|
|
_board[x][findcoord(y, -3)] = ((_board[x][findcoord(y, -3)] == middle) || (_board[x][findcoord(y, -3)] == ignorer)) ? _board[x][findcoord(y, -3)] : replacer;
|
|
_board[x][findcoord(y, +3)] = ((_board[x][findcoord(y, +3)] == middle) || (_board[x][findcoord(y, +3)] == ignorer)) ? _board[x][findcoord(y, +3)] : replacer;
|
|
_board[findcoord(x, -3)][y] = ((_board[findcoord(x, -3)][y] == middle) || (_board[findcoord(x, -3)][y] == ignorer)) ? _board[findcoord(x, -3)][y] : replacer;
|
|
_board[findcoord(x, +3)][y] = ((_board[findcoord(x, +3)][y] == middle) || (_board[findcoord(x, +3)][y] == ignorer)) ? _board[findcoord(x, +3)][y] : replacer;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::findstartloc() {
|
|
int temp, i, j, shiftx, shifty, secondshift;
|
|
int start[4][2];
|
|
shiftx = getRandomNumber() % _size;
|
|
shifty = getRandomNumber() % _size;
|
|
start[0][0] = findcoord((int)_size / 4, (plusminus(3) + shiftx));
|
|
start[0][1] = findcoord((int)_size / 4, (plusminus(3) + shifty));
|
|
start[1][0] = findcoord((int)3 * _size / 4, (plusminus(3) + shiftx));
|
|
start[1][1] = findcoord((int)_size / 4, (plusminus(3) + shifty));
|
|
start[2][0] = findcoord((int)_size / 4, (plusminus(3) + shiftx));
|
|
start[2][1] = findcoord((int)3 * _size / 4, (plusminus(3) + shifty));
|
|
start[3][0] = findcoord((int)3 * _size / 4, (plusminus(3) + shiftx));
|
|
start[3][1] = findcoord((int)3 * _size / 4, (plusminus(3) + shifty));
|
|
|
|
temp = getRandomNumber() % 2;
|
|
secondshift = getRandomNumber() % _size;
|
|
|
|
if (temp == 0) {
|
|
start[0][0] = findcoord(start[0][0], secondshift);
|
|
start[1][0] = findcoord(start[1][0], secondshift);
|
|
}
|
|
|
|
else {
|
|
start[1][1] = findcoord(start[1][1], secondshift);
|
|
start[3][1] = findcoord(start[3][1], secondshift);
|
|
}
|
|
|
|
temp = whatheightstartloc(start[0][0], start[0][1]);
|
|
fattenone(start[0][0], start[0][1], -100, temp, NEVER_USED_NUM, temp);
|
|
|
|
temp = whatheightstartloc(start[1][0], start[1][1]);
|
|
fattenone(start[1][0], start[1][1], -100, temp, NEVER_USED_NUM, temp);
|
|
|
|
temp = whatheightstartloc(start[2][0], start[2][1]);
|
|
fattenone(start[2][0], start[2][1], -100, temp, NEVER_USED_NUM, temp);
|
|
|
|
temp = whatheightstartloc(start[3][0], start[3][1]);
|
|
fattenone(start[3][0], start[3][1], -100, temp, NEVER_USED_NUM, temp);
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
for (i = 0; i < 2; i++) {
|
|
_startloc[j][i] = start[j][i];
|
|
}
|
|
}
|
|
|
|
temp = getRandomNumber() % 4;
|
|
j = 4;
|
|
for (i = 0; i < 4; i++) {
|
|
if (temp == i) {
|
|
} else {
|
|
_startloc[j][0] = start[i][0];
|
|
_startloc[j][1] = start[i][1];
|
|
j++;
|
|
}
|
|
}
|
|
|
|
_startloc[7][0] = _startloc[4][0];
|
|
_startloc[7][1] = _startloc[4][1];
|
|
_startloc[8][0] = _startloc[6][0];
|
|
_startloc[8][1] = _startloc[6][1];
|
|
|
|
for (j = 9; j < 13; j++) {
|
|
for (i = 0; i < 2; i++) {
|
|
_startloc[j][i] = start[j - 9][i];
|
|
}
|
|
}
|
|
|
|
for (j = 13; j < 17; j++) {
|
|
for (i = 0; i < 2; i++) {
|
|
_startloc[j][i] = start[j - 13][i];
|
|
}
|
|
}
|
|
|
|
for (j = 17; j < 20; j++) {
|
|
for (i = 0; i < 2; i++) {
|
|
_startloc[j][i] = _startloc[j - 13][i];
|
|
}
|
|
}
|
|
|
|
// place on special map
|
|
for (i = 0; i < 4; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 1;
|
|
}
|
|
for (i = 4; i < 7; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 2;
|
|
}
|
|
for (i = 7; i < 9; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 4;
|
|
}
|
|
for (i = 9; i < 13; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 8;
|
|
}
|
|
for (i = 13; i < 17; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 16;
|
|
}
|
|
for (i = 17; i < 20; i++) {
|
|
_special[_startloc[i][0]][_startloc[i][1]] += 32;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::whatheightstartloc(int x, int y) {
|
|
int heightfield[3] = {0, 0, 0};
|
|
|
|
heightfield[_board[findcoord(x, +2)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, +2)][y]]++;
|
|
heightfield[_board[findcoord(x, +2)][findcoord(y, +1)]]++;
|
|
heightfield[_board[findcoord(x, +2)][findcoord(y, +2)]]++;
|
|
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, -1)][y]]++;
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, +1)]]++;
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, +2)]]++;
|
|
|
|
heightfield[_board[x][findcoord(y, -1)]]++;
|
|
heightfield[_board[x][y]]++;
|
|
heightfield[_board[x][findcoord(y, +1)]]++;
|
|
heightfield[_board[x][findcoord(y, +2)]]++;
|
|
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, +1)][y]]++;
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, +1)]]++;
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, +2)]]++;
|
|
|
|
if (heightfield[0] == 0) {
|
|
if (heightfield[1] >= heightfield[2]) {
|
|
return 1;
|
|
} else {
|
|
return 2;
|
|
}
|
|
} else if (heightfield[1] == 0) {
|
|
if (heightfield[0] >= heightfield[2]) {
|
|
return 0;
|
|
} else {
|
|
return 2;
|
|
}
|
|
} else if (heightfield[2] == 0) {
|
|
if (heightfield[1] >= heightfield[0]) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int KattonGenerator::goodforwater(int x, int y) {
|
|
if ((_board[x][y] == 0) && (_board[findcoord(x, +1)][y] == 0) && (_board[x][findcoord(y, +1)] == 0) && (_board[findcoord(x, +1)][findcoord(y, +1)] == 0)) { //check main map
|
|
if ((_special[x][y] <= 0) && (_special[x][findcoord(y, 1)] <= 0) && (_special[findcoord(x, 1)][findcoord(y, 1)] <= 0) && (_special[findcoord(x, 1)][y] <= 0) && (_special[findcoord(x, 1)][findcoord(y, -1)] <= 0) && (_special[x][findcoord(y, -1)] <= 0) && (_special[findcoord(x, -1)][findcoord(y, -1)] <= 0) && (_special[findcoord(x, -1)][y] <= 0) && (_special[findcoord(x, -1)][findcoord(y, 1)] <= 0)) { //specials are clear
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int KattonGenerator::randomwater(int length, int stringiness, int x, int y) {
|
|
int currx, curry, direction = 10, prevdirection, i = 0;
|
|
currx = x;
|
|
curry = y;
|
|
while (i <= length) {
|
|
_special[currx][curry] = -1;
|
|
prevdirection = direction;
|
|
direction = (getRandomNumber() % 4);
|
|
if ((((direction + 2) == prevdirection) || ((direction - 2) == prevdirection)) && (stringiness == 2)) {
|
|
direction = prevdirection;
|
|
}
|
|
if (!((((direction + 2) == prevdirection) || ((direction - 2) == prevdirection)) && (stringiness == 1))) {
|
|
switch (direction) {
|
|
|
|
case 0: //north
|
|
if (goodforwater(currx, findcoord(curry, 1))) {
|
|
curry = findcoord(curry, 1);
|
|
}
|
|
break;
|
|
|
|
case 1: //east
|
|
if (goodforwater(findcoord(currx, 1), curry)) {
|
|
currx = findcoord(currx, 1);
|
|
}
|
|
break;
|
|
|
|
case 2: //south
|
|
if (goodforwater(currx, findcoord(curry, -1))) {
|
|
curry = findcoord(curry, -1);
|
|
}
|
|
break;
|
|
|
|
case 3: //west
|
|
if (goodforwater(findcoord(currx, -1), curry)) {
|
|
currx = findcoord(currx, -1);
|
|
}
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int KattonGenerator::tileaverage(int x, int y, int threshold) {
|
|
int heightfield[3] = {0, 0, 0};
|
|
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, -1)][y]]++;
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, +1)]]++;
|
|
|
|
heightfield[_board[x][findcoord(y, -1)]]++;
|
|
heightfield[_board[x][y]]++;
|
|
heightfield[_board[x][findcoord(y, +1)]]++;
|
|
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, +1)][y]]++;
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, +1)]]++;
|
|
|
|
if ((heightfield[2] == 0) && (heightfield[1] < heightfield[0]) && (heightfield[0] >= threshold)) {
|
|
_board[x][y] = 0;
|
|
return 0;
|
|
} else if ((heightfield[0] == 0) && (heightfield[1] < heightfield[2]) && (heightfield[2] >= threshold)) {
|
|
_board[x][y] = 2;
|
|
return 2;
|
|
} else if (heightfield[1] >= threshold) {
|
|
_board[x][y] = 1;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int KattonGenerator::randomflip(int numberofplaces, int inWater) {
|
|
int i, x, y, temp;
|
|
for (i = 0; i < numberofplaces; i++) {
|
|
x = getRandomNumber() % _size;
|
|
y = getRandomNumber() % _size;
|
|
if (_board[x][y] == 0) {
|
|
if (inWater == 0) {
|
|
temp = 0;
|
|
} else {
|
|
temp = getRandomNumber() % inWater;
|
|
}
|
|
|
|
if (temp <= 50) {
|
|
_board[x][y] = 1;
|
|
}
|
|
} else if (_board[x][y] == 2) {
|
|
_board[x][y] = 1;
|
|
} else if (_board[x][y] == 1) {
|
|
|
|
temp = getRandomNumber() % 2;
|
|
int heightfield[3] = {0, 0, 0};
|
|
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, -1)][y]]++;
|
|
heightfield[_board[findcoord(x, -1)][findcoord(y, +1)]]++;
|
|
|
|
heightfield[_board[x][findcoord(y, -1)]]++;
|
|
heightfield[_board[x][findcoord(y, +1)]]++;
|
|
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, -1)]]++;
|
|
heightfield[_board[findcoord(x, +1)][y]]++;
|
|
heightfield[_board[findcoord(x, +1)][findcoord(y, +1)]]++;
|
|
temp = getRandomNumber() % 2;
|
|
if (heightfield[0] == 0) {
|
|
_board[x][y] = 2;
|
|
} else if (heightfield[2] == 0) {
|
|
_board[x][y] = 0;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
} // End of namespace Scumm
|