mirror of https://github.com/OpenRCT2/OpenRCT2.git
finish implementing jumping fountains
This commit is contained in:
parent
308238ba67
commit
743c508065
|
@ -25,6 +25,37 @@
|
|||
#include "scenery.h"
|
||||
#include "sprite.h"
|
||||
|
||||
enum {
|
||||
PATTERN_CYCLIC_SQUARES,
|
||||
PATTERN_CONTINUOUS_CHASERS,
|
||||
PATTERN_BOUNCING_PAIRS,
|
||||
PATTERN_SPROUTING_BLOOMS,
|
||||
PATTERN_RACING_PAIRS,
|
||||
PATTERN_SPLITTING_CHASERS,
|
||||
PATTERN_DOPEY_JUMPERS,
|
||||
PATTERN_FAST_RANDOM_CHASERS
|
||||
};
|
||||
|
||||
enum {
|
||||
FOUNTAIN_FLAG_FAST = 1 << 0,
|
||||
FOUNTAIN_FLAG_GOTO_EDGE = 1 << 1,
|
||||
FOUNTAIN_FLAG_SPLIT = 1 << 2,
|
||||
FOUNTAIN_FLAG_TERMINATE = 1 << 3,
|
||||
FOUNTAIN_FLAG_BOUNCE = 1 << 4,
|
||||
FOUNTAIN_FLAG_7 = 1 << 7
|
||||
};
|
||||
|
||||
const rct_xy16 dword_97F000[] = {
|
||||
{ -32, 0 },
|
||||
{ -32, -32 },
|
||||
{ 0, 0 },
|
||||
{ -32, 0 },
|
||||
{ 0, 0 },
|
||||
{ 0, -32 },
|
||||
{ 0, -32 },
|
||||
{ -32, -32 },
|
||||
};
|
||||
|
||||
const rct_xy16 dword_97F020[] = {
|
||||
{ 32, 0 },
|
||||
{ 0, 0 },
|
||||
|
@ -36,9 +67,32 @@ const rct_xy16 dword_97F020[] = {
|
|||
{ 0, 32 }
|
||||
};
|
||||
|
||||
const uint8 byte_97F040[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
|
||||
const uint8 byte_97F048[] = { 0, 0, 128, 128, 128, 128, 0, 0 };
|
||||
const uint8 byte_97F050[] = { 8, 3, 16, 5, 2, 7, 0, 1 };
|
||||
// rct2: 0x0097F040
|
||||
const uint8 _fountainDirections[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
|
||||
|
||||
// rct2: 0x0097F048
|
||||
const uint8 _fountainDirectionFlags[] = { 0, 0, FOUNTAIN_FLAG_7, FOUNTAIN_FLAG_7, FOUNTAIN_FLAG_7, FOUNTAIN_FLAG_7, 0, 0 };
|
||||
|
||||
// rct2: 0x0097F050
|
||||
const uint8 _fountainPatternFlags[] = {
|
||||
FOUNTAIN_FLAG_TERMINATE, // PATTERN_CYCLIC_SQUARES
|
||||
FOUNTAIN_FLAG_FAST | FOUNTAIN_FLAG_GOTO_EDGE, // PATTERN_CONTINUOUS_CHASERS
|
||||
FOUNTAIN_FLAG_BOUNCE, // PATTERN_BOUNCING_PAIRS
|
||||
FOUNTAIN_FLAG_FAST | FOUNTAIN_FLAG_SPLIT, // PATTERN_SPROUTING_BLOOMS
|
||||
FOUNTAIN_FLAG_GOTO_EDGE, // PATTERN_RACING_PAIRS
|
||||
FOUNTAIN_FLAG_FAST | FOUNTAIN_FLAG_GOTO_EDGE | FOUNTAIN_FLAG_SPLIT, // PATTERN_SPLITTING_CHASERS
|
||||
0, // PATTERN_DOPEY_JUMPERS
|
||||
FOUNTAIN_FLAG_FAST // PATTERN_FAST_RANDOM_CHASERS
|
||||
};
|
||||
|
||||
static void jumping_fountain_continue(rct_jumping_fountain *jumpingFountain);
|
||||
static bool is_jumping_fountain(int type, int x, int y, int z);
|
||||
|
||||
static void jumping_fountain_goto_edge(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections);
|
||||
static void jumping_fountain_bounce(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections);
|
||||
static void jumping_fountain_split(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections);
|
||||
static void jumping_fountain_random(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections);
|
||||
static void jumping_fountain_create_next(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int direction);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -49,9 +103,11 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
{
|
||||
int i, randomIndex;
|
||||
int z = mapElement->base_height * 8;
|
||||
uint32 ticks = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) >> 11) & 7;
|
||||
switch (ticks) {
|
||||
case 0:
|
||||
|
||||
// Change pattern approximately every 51 seconds
|
||||
int pattern = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) >> 11) & 7;
|
||||
switch (pattern) {
|
||||
case PATTERN_CYCLIC_SQUARES:
|
||||
// 0, 1, 2, 3
|
||||
for (i = 0; i < 4; i++) {
|
||||
jumping_fountain_create(
|
||||
|
@ -59,13 +115,13 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
x + dword_97F020[i].x,
|
||||
y + dword_97F020[i].y,
|
||||
z,
|
||||
byte_97F040[i],
|
||||
byte_97F048[i] | byte_97F050[ticks],
|
||||
_fountainDirections[i],
|
||||
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case PATTERN_BOUNCING_PAIRS:
|
||||
// random [0, 2 or 1, 3]
|
||||
randomIndex = scenario_rand() & 1;
|
||||
for (i = randomIndex; i < 4; i += 2) {
|
||||
|
@ -74,13 +130,13 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
x + dword_97F020[i].x,
|
||||
y + dword_97F020[i].y,
|
||||
z,
|
||||
byte_97F040[i],
|
||||
byte_97F048[i] | byte_97F050[ticks],
|
||||
_fountainDirections[i],
|
||||
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case PATTERN_RACING_PAIRS:
|
||||
// random [0 - 3 and 4 - 7]
|
||||
z = mapElement->base_height * 8;
|
||||
randomIndex = scenario_rand() & 3;
|
||||
|
@ -89,8 +145,8 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
x + dword_97F020[randomIndex].x,
|
||||
y + dword_97F020[randomIndex].y,
|
||||
z,
|
||||
byte_97F040[randomIndex],
|
||||
byte_97F048[randomIndex] | byte_97F050[ticks],
|
||||
_fountainDirections[randomIndex],
|
||||
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
|
||||
0
|
||||
);
|
||||
randomIndex += 4;
|
||||
|
@ -99,8 +155,8 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
x + dword_97F020[randomIndex].x,
|
||||
y + dword_97F020[randomIndex].y,
|
||||
z,
|
||||
byte_97F040[randomIndex],
|
||||
byte_97F048[randomIndex] | byte_97F050[ticks],
|
||||
_fountainDirections[randomIndex],
|
||||
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
|
||||
0
|
||||
);
|
||||
break;
|
||||
|
@ -112,8 +168,8 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
x + dword_97F020[randomIndex].x,
|
||||
y + dword_97F020[randomIndex].y,
|
||||
z,
|
||||
byte_97F040[randomIndex],
|
||||
byte_97F048[randomIndex] | byte_97F050[ticks],
|
||||
_fountainDirections[randomIndex],
|
||||
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
|
||||
0
|
||||
);
|
||||
break;
|
||||
|
@ -125,7 +181,7 @@ void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement)
|
|||
* rct2: 0x0067396A (water)
|
||||
* rct2: 0x006739A4 (snow)
|
||||
*/
|
||||
void jumping_fountain_create(int type, int x, int y, int z, uint16 bl, uint16 bh, uint16 bp)
|
||||
void jumping_fountain_create(int type, int x, int y, int z, int direction, int flags, int iteration)
|
||||
{
|
||||
rct_jumping_fountain *jumpingFountain;
|
||||
|
||||
|
@ -133,9 +189,10 @@ void jumping_fountain_create(int type, int x, int y, int z, uint16 bl, uint16 bh
|
|||
if (jumpingFountain == NULL)
|
||||
return;
|
||||
|
||||
jumpingFountain->var_46 = bp;
|
||||
jumpingFountain->var_2E = (bh << 8) | bl;
|
||||
jumpingFountain->sprite_direction = bl << 3;
|
||||
jumpingFountain->iteration = iteration;
|
||||
jumpingFountain->var_2E = direction;
|
||||
jumpingFountain->flags = flags;
|
||||
jumpingFountain->sprite_direction = direction << 3;
|
||||
jumpingFountain->var_14 = 33;
|
||||
jumpingFountain->var_09 = 36;
|
||||
jumpingFountain->var_15 = 12;
|
||||
|
@ -154,12 +211,235 @@ void jumping_fountain_create(int type, int x, int y, int z, uint16 bl, uint16 bh
|
|||
*/
|
||||
void jumping_fountain_update(rct_jumping_fountain *jumpingFountain)
|
||||
{
|
||||
int original_var_26a = jumpingFountain->var_26a;
|
||||
jumpingFountain->var_26a += 160;
|
||||
if (original_var_26a <= 255 - 160)
|
||||
return;
|
||||
|
||||
RCT2_CALLPROC_X(0x006EC60B, 0, 0, 0, 0, (int)jumpingFountain, 0, 0);
|
||||
jumpingFountain->var_26b++;
|
||||
|
||||
switch (jumpingFountain->misc_identifier) {
|
||||
case SPRITE_MISC_JUMPING_FOUNTAIN_WATER:
|
||||
RCT2_CALLPROC_X(0x006733CB, 0, 0, 0, 0, (int)jumpingFountain, 0, 0);
|
||||
if (jumpingFountain->var_26b == 11 && (jumpingFountain->flags & FOUNTAIN_FLAG_FAST))
|
||||
jumping_fountain_continue(jumpingFountain);
|
||||
|
||||
if (jumpingFountain->var_26b == 16 && !(jumpingFountain->flags & FOUNTAIN_FLAG_FAST))
|
||||
jumping_fountain_continue(jumpingFountain);
|
||||
break;
|
||||
case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW:
|
||||
RCT2_CALLPROC_X(0x00673407, 0, 0, 0, 0, (int)jumpingFountain, 0, 0);
|
||||
if (jumpingFountain->var_26b == 16)
|
||||
jumping_fountain_continue(jumpingFountain);
|
||||
break;
|
||||
}
|
||||
|
||||
if (jumpingFountain->var_26b == 16)
|
||||
sprite_remove((rct_sprite*)jumpingFountain);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006739DE (water)
|
||||
* rct2: 0x00673BCC (snow)
|
||||
*/
|
||||
static void jumping_fountain_continue(rct_jumping_fountain *jumpingFountain)
|
||||
{
|
||||
int direction = (jumpingFountain->sprite_direction >> 3) & 7;
|
||||
int x = jumpingFountain->x + TileDirectionDelta[direction].x;
|
||||
int y = jumpingFountain->y + TileDirectionDelta[direction].y;
|
||||
int z = jumpingFountain->z;
|
||||
|
||||
int type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
|
||||
JUMPING_FOUNTAIN_TYPE_SNOW :
|
||||
JUMPING_FOUNTAIN_TYPE_WATER;
|
||||
|
||||
int availableDirections = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (is_jumping_fountain(type, x + dword_97F000[i].x, y + dword_97F000[i].y, z))
|
||||
availableDirections |= 1 << i;
|
||||
}
|
||||
|
||||
if (availableDirections == 0)
|
||||
return;
|
||||
|
||||
if (jumpingFountain->flags & FOUNTAIN_FLAG_TERMINATE)
|
||||
return;
|
||||
|
||||
if (jumpingFountain->flags & FOUNTAIN_FLAG_GOTO_EDGE) {
|
||||
jumping_fountain_goto_edge(jumpingFountain, x, y, z, availableDirections);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jumpingFountain->flags & FOUNTAIN_FLAG_BOUNCE) {
|
||||
jumping_fountain_bounce(jumpingFountain, x, y, z, availableDirections);
|
||||
return;
|
||||
}
|
||||
|
||||
if (jumpingFountain->flags & FOUNTAIN_FLAG_SPLIT) {
|
||||
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
|
||||
return;
|
||||
}
|
||||
|
||||
jumping_fountain_random(jumpingFountain, x, y, z, availableDirections);
|
||||
}
|
||||
|
||||
static bool is_jumping_fountain(int type, int x, int y, int z)
|
||||
{
|
||||
z = z >> 3;
|
||||
|
||||
int pathBitFlagMask = type == JUMPING_FOUNTAIN_TYPE_SNOW ?
|
||||
PATH_BIT_FLAG_JUMPING_FOUNTAIN_SNOW :
|
||||
PATH_BIT_FLAG_JUMPING_FOUNTAIN_WATER;
|
||||
|
||||
rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5);
|
||||
do {
|
||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
if (mapElement->base_height != z)
|
||||
continue;
|
||||
if (mapElement->properties.path.additions & 0x80)
|
||||
continue;
|
||||
|
||||
int additions = mapElement->properties.path.additions & 0x0F;
|
||||
if (additions == 0)
|
||||
continue;
|
||||
|
||||
rct_scenery_entry *sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!(sceneryEntry->path_bit.var_06 & pathBitFlagMask))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
} while (!map_element_is_last_for_tile(mapElement++));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct: 0x00673B6E
|
||||
*/
|
||||
static void jumping_fountain_goto_edge(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections)
|
||||
{
|
||||
int direction = (jumpingFountain->sprite_direction >> 3) << 1;
|
||||
if (availableDirections & (1 << direction)) {
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
return;
|
||||
}
|
||||
|
||||
direction++;
|
||||
if (availableDirections & (1 << direction)) {
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 randomIndex = scenario_rand();
|
||||
if ((randomIndex & 0xFFFF) < 0x3333)
|
||||
return;
|
||||
|
||||
if (jumpingFountain->flags & FOUNTAIN_FLAG_SPLIT) {
|
||||
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
|
||||
return;
|
||||
}
|
||||
|
||||
direction = randomIndex & 7;
|
||||
while (!(availableDirections & (1 << direction)))
|
||||
direction = (direction + 1) & 7;
|
||||
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct: 0x00673B45
|
||||
*/
|
||||
static void jumping_fountain_bounce(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections)
|
||||
{
|
||||
jumpingFountain->iteration++;
|
||||
if (jumpingFountain->iteration >= 8)
|
||||
return;
|
||||
|
||||
int direction = ((jumpingFountain->sprite_direction >> 3) ^ 2) << 1;
|
||||
if (availableDirections & (1 << direction)) {
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
return;
|
||||
}
|
||||
|
||||
direction++;
|
||||
if (availableDirections & (1 << direction))
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct: 0x00673ACE
|
||||
*/
|
||||
static void jumping_fountain_split(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections)
|
||||
{
|
||||
if (jumpingFountain->iteration >= 3)
|
||||
return;
|
||||
|
||||
int type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
|
||||
JUMPING_FOUNTAIN_TYPE_SNOW :
|
||||
JUMPING_FOUNTAIN_TYPE_WATER;
|
||||
|
||||
int direction = ((jumpingFountain->sprite_direction >> 3) ^ 2) << 1;
|
||||
availableDirections &= ~(1 << direction);
|
||||
direction++;
|
||||
availableDirections &= ~(1 << direction);
|
||||
|
||||
for (direction = 0; direction < 8; direction++) {
|
||||
if (availableDirections & (1 << direction)) {
|
||||
jumping_fountain_create(
|
||||
type,
|
||||
x, y, z,
|
||||
direction >> 1,
|
||||
jumpingFountain->flags & ~FOUNTAIN_FLAG_7,
|
||||
jumpingFountain->iteration + 1
|
||||
);
|
||||
}
|
||||
direction++;
|
||||
if (availableDirections & (1 << direction)) {
|
||||
jumping_fountain_create(
|
||||
type,
|
||||
x, y, z,
|
||||
direction >> 1,
|
||||
jumpingFountain->flags | FOUNTAIN_FLAG_7,
|
||||
jumpingFountain->iteration + 1
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct: 0x00673AAC
|
||||
*/
|
||||
static void jumping_fountain_random(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int availableDirections)
|
||||
{
|
||||
uint32 randomIndex = scenario_rand();
|
||||
if ((randomIndex & 0xFFFF) < 0x2000)
|
||||
return;
|
||||
|
||||
int direction = randomIndex & 7;
|
||||
while (!(availableDirections & (1 << direction)))
|
||||
direction = (direction + 1) & 7;
|
||||
|
||||
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct: 0x00673B45
|
||||
*/
|
||||
static void jumping_fountain_create_next(rct_jumping_fountain *jumpingFountain, int x, int y, int z, int direction)
|
||||
{
|
||||
int flags = jumpingFountain->flags & ~FOUNTAIN_FLAG_7;
|
||||
if (direction & 1)
|
||||
flags |= FOUNTAIN_FLAG_7;
|
||||
|
||||
int type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
|
||||
JUMPING_FOUNTAIN_TYPE_SNOW :
|
||||
JUMPING_FOUNTAIN_TYPE_WATER;
|
||||
|
||||
jumping_fountain_create(type, x, y, z, direction >> 1, flags, jumpingFountain->iteration);
|
||||
}
|
|
@ -31,7 +31,7 @@ enum {
|
|||
};
|
||||
|
||||
void jumping_fountain_begin(int type, int x, int y, rct_map_element *mapElement);
|
||||
void jumping_fountain_create(int type, int x, int y, int z, uint16 bl, uint16 bh, uint16 bp);
|
||||
void jumping_fountain_create(int type, int x, int y, int z, int direction, int flags, int iteration);
|
||||
void jumping_fountain_update(rct_jumping_fountain *jumpingFountain);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -134,19 +134,29 @@ typedef struct {
|
|||
uint16 previous; // 0x06
|
||||
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
|
||||
uint8 var_09;
|
||||
uint8 pad_0A[0xA];
|
||||
uint8 pad_0A[0x4];
|
||||
sint16 x; // 0x0E
|
||||
sint16 y; // 0x10
|
||||
sint16 z; // 0x12
|
||||
uint8 var_14;
|
||||
uint8 var_15;
|
||||
uint8 pad_16[0x8];
|
||||
uint8 sprite_direction; // 0x1E
|
||||
uint8 pad_1F[0x7];
|
||||
uint16 var_26;
|
||||
union {
|
||||
uint16 var_26;
|
||||
struct {
|
||||
uint8 var_26a;
|
||||
uint8 var_26b;
|
||||
};
|
||||
};
|
||||
uint8 pad_28[0x6];
|
||||
uint16 var_2E;
|
||||
uint8 var_2E;
|
||||
uint8 flags;
|
||||
sint16 target_x; // 0x30
|
||||
sint16 target_y; // 0x32
|
||||
uint8 pad_34[0x12];
|
||||
uint16 var_46;
|
||||
uint16 iteration;
|
||||
} rct_jumping_fountain;
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue