1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-16 11:33:03 +01:00

Format Fountain as C++

This commit is contained in:
Ted John
2017-03-23 18:36:20 +00:00
parent 7fb653d1a7
commit f9f516c372
2 changed files with 386 additions and 370 deletions

View File

@@ -14,429 +14,432 @@
*****************************************************************************/
#pragma endregion
#include "../game.h"
#include "../scenario/scenario.h"
#include "Fountain.h"
#include "map.h"
#include "scenery.h"
#include "sprite.h"
#include "footpath.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
#ifdef __cplusplus
extern "C"
{
#include "../game.h"
#include "../scenario/scenario.h"
#include "footpath.h"
#include "map.h"
#include "scenery.h"
#include "sprite.h"
}
#endif
enum class PATTERN
{
CYCLIC_SQUARES,
CONTINUOUS_CHASERS,
BOUNCING_PAIRS,
SPROUTING_BLOOMS,
RACING_PAIRS,
SPLITTING_CHASERS,
DOPEY_JUMPERS,
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
namespace FOUNTAIN_FLAG
{
const uint32 FAST = 1 << 0;
const uint32 GOTO_EDGE = 1 << 1;
const uint32 SPLIT = 1 << 2;
const uint32 TERMINATE = 1 << 3;
const uint32 BOUNCE = 1 << 4;
const uint32 DIRECTION = 1 << 7;
};
const rct_xy16 dword_97F000[] = {
{ -32, 0 },
{ -32, -32 },
{ 0, 0 },
{ -32, 0 },
{ 0, 0 },
{ 0, -32 },
{ 0, -32 },
{ -32, -32 },
static const rct_xy16 _fountainDirectionsNegative[] =
{
{ -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 },
{ 0, 32 },
{ 32, 32 },
{ 32, 32 },
{ 32, 0 },
{ 0, 0 },
{ 0, 32 }
static const rct_xy16 _fountainDirectionsPositive[] =
{
{ 32, 0 },
{ 0, 0 },
{ 0, 32 },
{ 32, 32 },
{ 32, 32 },
{ 32, 0 },
{ 0, 0 },
{ 0, 32 }
};
// 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 };
const uint8 _fountainDirectionFlags[] = { 0, 0, FOUNTAIN_FLAG::DIRECTION, FOUNTAIN_FLAG::DIRECTION, FOUNTAIN_FLAG::DIRECTION, FOUNTAIN_FLAG::DIRECTION, 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
FOUNTAIN_FLAG::TERMINATE, // CYCLIC_SQUARES
FOUNTAIN_FLAG::FAST | FOUNTAIN_FLAG::GOTO_EDGE, // CONTINUOUS_CHASERS
FOUNTAIN_FLAG::BOUNCE, // BOUNCING_PAIRS
FOUNTAIN_FLAG::FAST | FOUNTAIN_FLAG::SPLIT, // SPROUTING_BLOOMS
FOUNTAIN_FLAG::GOTO_EDGE, // RACING_PAIRS
FOUNTAIN_FLAG::FAST | FOUNTAIN_FLAG::GOTO_EDGE | FOUNTAIN_FLAG::SPLIT, // SPLITTING_CHASERS
0, // DOPEY_JUMPERS
FOUNTAIN_FLAG::FAST // FAST_RANDOM_CHASERS
};
static void jumping_fountain_continue(rct_jumping_fountain *jumpingFountain);
static sint32 jumping_fountain_get_type(const rct_jumping_fountain * jumpingFountain);
static void jumping_fountain_continue(rct_jumping_fountain * jumpingFountain);
static bool is_jumping_fountain(sint32 type, sint32 x, sint32 y, sint32 z);
static void jumping_fountain_goto_edge(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_bounce(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_split(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_random(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_create_next(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 direction);
static void jumping_fountain_goto_edge(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_bounce(rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_split(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_random(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections);
static void jumping_fountain_create_next(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 direction);
/**
*
* rct2: 0x00673DBA (water)
* rct2: 0x00673F51 (snow)
*/
void jumping_fountain_begin(sint32 type, sint32 x, sint32 y, rct_map_element *mapElement)
extern "C"
{
sint32 i, randomIndex;
sint32 z = mapElement->base_height * 8;
void jumping_fountain_begin(sint32 type, sint32 x, sint32 y, const rct_map_element * mapElement)
{
sint32 randomIndex;
sint32 z = mapElement->base_height * 8;
// Change pattern approximately every 51 seconds
sint32 pattern = (gCurrentTicks >> 11) & 7;
switch (pattern) {
case PATTERN_CYCLIC_SQUARES:
// 0, 1, 2, 3
for (i = 0; i < 4; i++) {
jumping_fountain_create(
type,
x + dword_97F020[i].x,
y + dword_97F020[i].y,
z,
_fountainDirections[i],
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
0
);
}
break;
case PATTERN_BOUNCING_PAIRS:
// random [0, 2 or 1, 3]
randomIndex = scenario_rand() & 1;
for (i = randomIndex; i < 4; i += 2) {
jumping_fountain_create(
type,
x + dword_97F020[i].x,
y + dword_97F020[i].y,
z,
_fountainDirections[i],
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
0
);
}
break;
case PATTERN_RACING_PAIRS:
// random [0 - 3 and 4 - 7]
z = mapElement->base_height * 8;
randomIndex = scenario_rand() & 3;
jumping_fountain_create(
type,
x + dword_97F020[randomIndex].x,
y + dword_97F020[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
randomIndex += 4;
jumping_fountain_create(
type,
x + dword_97F020[randomIndex].x,
y + dword_97F020[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
break;
default:
// random [0 - 7]
randomIndex = scenario_rand() & 7;
jumping_fountain_create(
type,
x + dword_97F020[randomIndex].x,
y + dword_97F020[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
break;
}
// Change pattern approximately every 51 seconds
uint32 pattern = (gCurrentTicks >> 11) & 7;
switch ((PATTERN)pattern) {
case PATTERN::CYCLIC_SQUARES:
// 0, 1, 2, 3
for (sint32 i = 0; i < 4; i++)
{
jumping_fountain_create(
type,
x + _fountainDirectionsPositive[i].x,
y + _fountainDirectionsPositive[i].y,
z,
_fountainDirections[i],
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
0
);
}
break;
case PATTERN::BOUNCING_PAIRS:
// random [0, 2 or 1, 3]
randomIndex = scenario_rand() & 1;
for (sint32 i = randomIndex; i < 4; i += 2)
{
jumping_fountain_create(
type,
x + _fountainDirectionsPositive[i].x,
y + _fountainDirectionsPositive[i].y,
z,
_fountainDirections[i],
_fountainDirectionFlags[i] | _fountainPatternFlags[pattern],
0
);
}
break;
case PATTERN::RACING_PAIRS:
// random [0 - 3 and 4 - 7]
randomIndex = scenario_rand() & 3;
jumping_fountain_create(
type,
x + _fountainDirectionsPositive[randomIndex].x,
y + _fountainDirectionsPositive[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
randomIndex += 4;
jumping_fountain_create(
type,
x + _fountainDirectionsPositive[randomIndex].x,
y + _fountainDirectionsPositive[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
break;
default:
// random [0 - 7]
randomIndex = scenario_rand() & 7;
jumping_fountain_create(
type,
x + _fountainDirectionsPositive[randomIndex].x,
y + _fountainDirectionsPositive[randomIndex].y,
z,
_fountainDirections[randomIndex],
_fountainDirectionFlags[randomIndex] | _fountainPatternFlags[pattern],
0
);
break;
}
}
void jumping_fountain_create(sint32 type, sint32 x, sint32 y, sint32 z, sint32 direction, sint32 flags, sint32 iteration)
{
rct_jumping_fountain * jumpingFountain = (rct_jumping_fountain *)create_sprite(SPRITE_IDENTIFIER_MISC);
if (jumpingFountain != nullptr)
{
jumpingFountain->iteration = iteration;
jumpingFountain->var_2E = direction;
jumpingFountain->fountain_flags = flags;
jumpingFountain->sprite_direction = direction << 3;
jumpingFountain->var_14 = 33;
jumpingFountain->var_09 = 36;
jumpingFountain->var_15 = 12;
jumpingFountain->sprite_identifier = SPRITE_IDENTIFIER_MISC;
sprite_move(x, y, z, (rct_sprite *)jumpingFountain);
jumpingFountain->misc_identifier = type == JUMPING_FOUNTAIN_TYPE_SNOW ?
SPRITE_MISC_JUMPING_FOUNTAIN_SNOW :
SPRITE_MISC_JUMPING_FOUNTAIN_WATER;
jumpingFountain->var_26 = 0;
}
}
void jumping_fountain_update(rct_jumping_fountain * jumpingFountain)
{
sint32 original_var_26a = jumpingFountain->var_26a;
jumpingFountain->var_26a += 160;
if (original_var_26a <= 255 - 160)
{
return;
}
invalidate_sprite_0((rct_sprite *)jumpingFountain);
jumpingFountain->var_26b++;
switch (jumpingFountain->misc_identifier) {
case SPRITE_MISC_JUMPING_FOUNTAIN_WATER:
if (jumpingFountain->var_26b == 11 && (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::FAST))
{
jumping_fountain_continue(jumpingFountain);
}
if (jumpingFountain->var_26b == 16 && !(jumpingFountain->fountain_flags & FOUNTAIN_FLAG::FAST))
{
jumping_fountain_continue(jumpingFountain);
}
break;
case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW:
if (jumpingFountain->var_26b == 16)
{
jumping_fountain_continue(jumpingFountain);
}
break;
}
if (jumpingFountain->var_26b == 16)
{
sprite_remove((rct_sprite*)jumpingFountain);
}
}
}
/**
*
* rct2: 0x0067396A (water)
* rct2: 0x006739A4 (snow)
*/
void jumping_fountain_create(sint32 type, sint32 x, sint32 y, sint32 z, sint32 direction, sint32 flags, sint32 iteration)
static sint32 jumping_fountain_get_type(const rct_jumping_fountain * jumpingFountain)
{
rct_jumping_fountain *jumpingFountain;
jumpingFountain = (rct_jumping_fountain*)create_sprite(SPRITE_IDENTIFIER_MISC);
if (jumpingFountain == NULL)
return;
jumpingFountain->iteration = iteration;
jumpingFountain->var_2E = direction;
jumpingFountain->fountain_flags = flags;
jumpingFountain->sprite_direction = direction << 3;
jumpingFountain->var_14 = 33;
jumpingFountain->var_09 = 36;
jumpingFountain->var_15 = 12;
jumpingFountain->sprite_identifier = SPRITE_IDENTIFIER_MISC;
sprite_move(x, y, z, (rct_sprite*)jumpingFountain);
jumpingFountain->misc_identifier = type == JUMPING_FOUNTAIN_TYPE_SNOW ?
SPRITE_MISC_JUMPING_FOUNTAIN_SNOW :
SPRITE_MISC_JUMPING_FOUNTAIN_WATER;
jumpingFountain->var_26 = 0;
sint32 type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
JUMPING_FOUNTAIN_TYPE_SNOW :
JUMPING_FOUNTAIN_TYPE_WATER;
return type;
}
/**
*
* rct2: 0x006733CB (water)
* rct2: 0x00673407 (snow)
*/
void jumping_fountain_update(rct_jumping_fountain *jumpingFountain)
static void jumping_fountain_continue(rct_jumping_fountain * jumpingFountain)
{
sint32 original_var_26a = jumpingFountain->var_26a;
jumpingFountain->var_26a += 160;
if (original_var_26a <= 255 - 160)
return;
sint32 type = jumping_fountain_get_type(jumpingFountain);
sint32 direction = (jumpingFountain->sprite_direction >> 3) & 7;
sint32 x = jumpingFountain->x + TileDirectionDelta[direction].x;
sint32 y = jumpingFountain->y + TileDirectionDelta[direction].y;
sint32 z = jumpingFountain->z;
invalidate_sprite_0((rct_sprite*)jumpingFountain);
jumpingFountain->var_26b++;
sint32 availableDirections = 0;
for (sint32 i = 0; i < 8; i++)
{
if (is_jumping_fountain(type, x + _fountainDirectionsNegative[i].x, y + _fountainDirectionsNegative[i].y, z))
{
availableDirections |= 1 << i;
}
}
switch (jumpingFountain->misc_identifier) {
case SPRITE_MISC_JUMPING_FOUNTAIN_WATER:
if (jumpingFountain->var_26b == 11 && (jumpingFountain->fountain_flags & FOUNTAIN_FLAG_FAST))
jumping_fountain_continue(jumpingFountain);
if (availableDirections == 0)
{
return;
}
if (jumpingFountain->var_26b == 16 && !(jumpingFountain->fountain_flags & FOUNTAIN_FLAG_FAST))
jumping_fountain_continue(jumpingFountain);
break;
case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW:
if (jumpingFountain->var_26b == 16)
jumping_fountain_continue(jumpingFountain);
break;
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::TERMINATE)
{
return;
}
if (jumpingFountain->var_26b == 16)
sprite_remove((rct_sprite*)jumpingFountain);
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::GOTO_EDGE)
{
jumping_fountain_goto_edge(jumpingFountain, x, y, z, availableDirections);
return;
}
/**
*
* rct2: 0x006739DE (water)
* rct2: 0x00673BCC (snow)
*/
static void jumping_fountain_continue(rct_jumping_fountain *jumpingFountain)
{
sint32 direction = (jumpingFountain->sprite_direction >> 3) & 7;
sint32 x = jumpingFountain->x + TileDirectionDelta[direction].x;
sint32 y = jumpingFountain->y + TileDirectionDelta[direction].y;
sint32 z = jumpingFountain->z;
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::BOUNCE)
{
jumping_fountain_bounce(jumpingFountain, x, y, z, availableDirections);
return;
}
sint32 type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
JUMPING_FOUNTAIN_TYPE_SNOW :
JUMPING_FOUNTAIN_TYPE_WATER;
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::SPLIT)
{
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
return;
}
sint32 availableDirections = 0;
for (sint32 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->fountain_flags & FOUNTAIN_FLAG_TERMINATE)
return;
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG_GOTO_EDGE) {
jumping_fountain_goto_edge(jumpingFountain, x, y, z, availableDirections);
return;
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG_BOUNCE) {
jumping_fountain_bounce(jumpingFountain, x, y, z, availableDirections);
return;
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG_SPLIT) {
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
return;
}
jumping_fountain_random(jumpingFountain, x, y, z, availableDirections);
jumping_fountain_random(jumpingFountain, x, y, z, availableDirections);
}
static bool is_jumping_fountain(sint32 type, sint32 x, sint32 y, sint32 z)
{
z = z >> 3;
z = z >> 3;
sint32 pathBitFlagMask = type == JUMPING_FOUNTAIN_TYPE_SNOW ?
PATH_BIT_FLAG_JUMPING_FOUNTAIN_SNOW :
PATH_BIT_FLAG_JUMPING_FOUNTAIN_WATER;
sint32 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 (footpath_element_path_scenery_is_ghost(mapElement))
continue;
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 (footpath_element_path_scenery_is_ghost(mapElement)) continue;
if (!footpath_element_has_path_scenery(mapElement)) continue;
if (!footpath_element_has_path_scenery(mapElement))
continue;
uint8 additionIndex = footpath_element_get_path_scenery_index(mapElement);
rct_scenery_entry * sceneryEntry = get_footpath_item_entry(additionIndex);
if (sceneryEntry->path_bit.flags & pathBitFlagMask)
{
return true;
}
}
while (!map_element_is_last_for_tile(mapElement++));
uint8 additionIndex = footpath_element_get_path_scenery_index(mapElement);
rct_scenery_entry *sceneryEntry = get_footpath_item_entry(additionIndex);
if (!(sceneryEntry->path_bit.flags & pathBitFlagMask))
continue;
return true;
} while (!map_element_is_last_for_tile(mapElement++));
return false;
return false;
}
/**
*
* rct2: 0x00673B6E
*/
static void jumping_fountain_goto_edge(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
static void jumping_fountain_goto_edge(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
{
sint32 direction = (jumpingFountain->sprite_direction >> 3) << 1;
if (availableDirections & (1 << direction)) {
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
return;
}
sint32 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;
}
direction++;
if (availableDirections & (1 << direction))
{
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
return;
}
uint32 randomIndex = scenario_rand();
if ((randomIndex & 0xFFFF) < 0x3333)
return;
uint32 randomIndex = scenario_rand();
if ((randomIndex & 0xFFFF) < 0x3333)
{
return;
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG_SPLIT) {
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
return;
}
if (jumpingFountain->fountain_flags & FOUNTAIN_FLAG::SPLIT)
{
jumping_fountain_split(jumpingFountain, x, y, z, availableDirections);
return;
}
direction = randomIndex & 7;
while (!(availableDirections & (1 << direction)))
direction = (direction + 1) & 7;
direction = randomIndex & 7;
while (!(availableDirections & (1 << direction)))
{
direction = (direction + 1) & 7;
}
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
}
/**
*
* rct2: 0x00673B45
*/
static void jumping_fountain_bounce(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
static void jumping_fountain_bounce(rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
{
jumpingFountain->iteration++;
if (jumpingFountain->iteration >= 8)
return;
sint32 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);
jumpingFountain->iteration++;
if (jumpingFountain->iteration < 8)
{
sint32 direction = ((jumpingFountain->sprite_direction >> 3) ^ 2) << 1;
if (availableDirections & (1 << direction))
{
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
}
else
{
direction++;
if (availableDirections & (1 << direction))
{
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
}
}
}
}
/**
*
* rct2: 0x00673ACE
*/
static void jumping_fountain_split(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
static void jumping_fountain_split(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
{
if (jumpingFountain->iteration >= 3)
return;
if (jumpingFountain->iteration < 3)
{
sint32 type = jumping_fountain_get_type(jumpingFountain);
sint32 direction = ((jumpingFountain->sprite_direction >> 3) ^ 2) << 1;
availableDirections &= ~(1 << direction);
availableDirections &= ~(1 << (direction + 1));
sint32 type = jumpingFountain->misc_identifier == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW ?
JUMPING_FOUNTAIN_TYPE_SNOW :
JUMPING_FOUNTAIN_TYPE_WATER;
sint32 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->fountain_flags & ~FOUNTAIN_FLAG_7,
jumpingFountain->iteration + 1
);
}
direction++;
if (availableDirections & (1 << direction)) {
jumping_fountain_create(
type,
x, y, z,
direction >> 1,
jumpingFountain->fountain_flags | FOUNTAIN_FLAG_7,
jumpingFountain->iteration + 1
);
}
}
for (direction = 0; direction < 8; direction++)
{
if (availableDirections & (1 << direction))
{
jumping_fountain_create(
type,
x, y, z,
direction >> 1,
jumpingFountain->fountain_flags & ~FOUNTAIN_FLAG::DIRECTION,
jumpingFountain->iteration + 1
);
}
direction++;
if (availableDirections & (1 << direction))
{
jumping_fountain_create(
type,
x, y, z,
direction >> 1,
jumpingFountain->fountain_flags | FOUNTAIN_FLAG::DIRECTION,
jumpingFountain->iteration + 1
);
}
}
}
}
/**
*
* rct2: 0x00673AAC
*/
static void jumping_fountain_random(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
static void jumping_fountain_random(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 availableDirections)
{
uint32 randomIndex = scenario_rand();
if ((randomIndex & 0xFFFF) < 0x2000)
return;
sint32 direction = randomIndex & 7;
while (!(availableDirections & (1 << direction)))
direction = (direction + 1) & 7;
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
uint32 randomIndex = scenario_rand();
if ((randomIndex & 0xFFFF) >= 0x2000)
{
sint32 direction = randomIndex & 7;
while (!(availableDirections & (1 << direction)))
{
direction = (direction + 1) & 7;
}
jumping_fountain_create_next(jumpingFountain, x, y, z, direction);
}
}
/**
*
* rct2: 0x00673B45
*/
static void jumping_fountain_create_next(rct_jumping_fountain *jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 direction)
static void jumping_fountain_create_next(const rct_jumping_fountain * jumpingFountain, sint32 x, sint32 y, sint32 z, sint32 direction)
{
sint32 flags = jumpingFountain->fountain_flags & ~FOUNTAIN_FLAG_7;
if (direction & 1)
flags |= FOUNTAIN_FLAG_7;
sint32 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);
sint32 type = jumping_fountain_get_type(jumpingFountain);
sint32 flags = jumpingFountain->fountain_flags & ~FOUNTAIN_FLAG::DIRECTION;
if (direction & 1)
{
flags |= FOUNTAIN_FLAG::DIRECTION;
}
jumping_fountain_create(type, x, y, z, direction >> 1, flags, jumpingFountain->iteration);
}

View File

@@ -14,20 +14,33 @@
*****************************************************************************/
#pragma endregion
#ifndef _WORLD_FOUNTAIN_H_
#define _WORLD_FOUNTAIN_H_
#pragma once
#include "../common.h"
#include "map.h"
#include "sprite.h"
enum {
JUMPING_FOUNTAIN_TYPE_WATER,
JUMPING_FOUNTAIN_TYPE_SNOW
#ifdef __cplusplus
extern "C"
{
#endif
#include "map.h"
#include "sprite.h"
#ifdef __cplusplus
}
#endif
enum
{
JUMPING_FOUNTAIN_TYPE_WATER,
JUMPING_FOUNTAIN_TYPE_SNOW
};
void jumping_fountain_begin(sint32 type, sint32 x, sint32 y, rct_map_element *mapElement);
void jumping_fountain_create(sint32 type, sint32 x, sint32 y, sint32 z, sint32 direction, sint32 flags, sint32 iteration);
void jumping_fountain_update(rct_jumping_fountain *jumpingFountain);
#ifdef __cplusplus
extern "C"
{
#endif
void jumping_fountain_begin(sint32 type, sint32 x, sint32 y, const rct_map_element * mapElement);
void jumping_fountain_create(sint32 type, sint32 x, sint32 y, sint32 z, sint32 direction, sint32 flags, sint32 iteration);
void jumping_fountain_update(rct_jumping_fountain * jumpingFountain);
#ifdef __cplusplus
}
#endif