1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-29 17:54:50 +01:00
Files
OpenRCT2/src/openrct2/world/Balloon.cpp
2018-01-11 13:25:09 +01:00

144 lines
3.8 KiB
C++

#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 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.
*
* A full copy of the GNU General Public License can be found in licence.txt
*****************************************************************************/
#pragma endregion
#include "../network/network.h"
#include "../audio/audio.h"
#include "../scenario/Scenario.h"
#include "../util/Util.h"
#include "Sprite.h"
bool rct_sprite::IsBalloon()
{
return this->balloon.sprite_identifier == SPRITE_IDENTIFIER_MISC &&
this->balloon.misc_identifier == SPRITE_MISC_BALLOON;
}
rct_balloon * rct_sprite::AsBalloon()
{
rct_balloon * result = nullptr;
if (IsBalloon())
{
result = (rct_balloon *)this;
}
return result;
}
void rct_balloon::Update()
{
invalidate_sprite_2((rct_sprite *)this);
if (popped == 1)
{
frame++;
if (frame >= 5)
{
sprite_remove((rct_sprite *)this);
}
}
else
{
time_to_move++;
if (time_to_move >= 3)
{
time_to_move = 0;
frame++;
sprite_move(x, y, z + 1, (rct_sprite*)this);
sint32 maxZ = 1967 - ((x ^ y) & 31);
if (z >= maxZ)
{
Pop();
}
}
}
}
void rct_balloon::Press()
{
if (popped != 1)
{
// There is a random chance that pressing the balloon will not pop it
// and instead shift it slightly
uint32 random = scenario_rand();
if ((sprite_index & 7) || (random & 0xFFFF) < 0x2000)
{
Pop();
}
else
{
sint16 shift = ((random & 0x80000000) ? -6 : 6);
sprite_move(x + shift, y, z, (rct_sprite *)this);
}
}
}
void rct_balloon::Pop()
{
popped = 1;
frame = 0;
audio_play_sound_at_location(SOUND_BALLOON_POP, x, y, z);
}
static money32 game_command_balloon_press(uint16 spriteIndex, uint8 flags)
{
rct_sprite * sprite = try_get_sprite(spriteIndex);
if (sprite == nullptr || !sprite->IsBalloon())
{
log_error("Tried getting invalid sprite for balloon: %u", spriteIndex);
return MONEY32_UNDEFINED;
}
else
{
if (flags & GAME_COMMAND_FLAG_APPLY)
{
sprite->AsBalloon()
->Press();
}
return 0;
}
}
extern "C"
{
void create_balloon(sint32 x, sint32 y, sint32 z, sint32 colour, bool isPopped)
{
rct_sprite* sprite = create_sprite(2);
if (sprite != nullptr)
{
sprite->balloon.sprite_width = 13;
sprite->balloon.sprite_height_negative = 22;
sprite->balloon.sprite_height_positive = 11;
sprite->balloon.sprite_identifier = SPRITE_IDENTIFIER_MISC;
sprite_move(x, y, z, sprite);
sprite->balloon.misc_identifier = SPRITE_MISC_BALLOON;
sprite->balloon.time_to_move = 0;
sprite->balloon.frame = 0;
sprite->balloon.colour = colour;
sprite->balloon.popped = (isPopped ? 1 : 0);
}
}
void balloon_update(rct_balloon * balloon)
{
balloon->Update();
}
void game_command_balloon_press(sint32 * eax, sint32 * ebx, sint32 * ecx, sint32 * edx, sint32 * esi, sint32 * edi, sint32 * ebp)
{
*ebx = game_command_balloon_press(*eax & 0xFFFF, *ebx & 0xFF);
}
}