2021-04-25 20:42:55 +00:00
|
|
|
#include "blocks.hpp"
|
|
|
|
#include "global_vars.hpp"
|
|
|
|
#include "objectids.hpp"
|
|
|
|
#include "sprites.hpp"
|
2021-05-08 22:43:53 +00:00
|
|
|
#include "editor_visitor.hpp"
|
2021-07-24 18:50:24 +00:00
|
|
|
#include <memory>
|
2021-04-30 07:10:58 +00:00
|
|
|
#include <unordered_map>
|
2021-08-04 22:32:17 +00:00
|
|
|
#include "visitors/mario_visitor.hpp"
|
|
|
|
#include "visitors/bounce_visitor.hpp"
|
2021-07-22 22:08:05 +00:00
|
|
|
#include "blocks/simpleblocks.hpp"
|
2021-07-24 17:59:25 +00:00
|
|
|
#include "blocks/coineditorblock.hpp"
|
2021-07-24 18:50:24 +00:00
|
|
|
#include "blocks/coinblock.hpp"
|
2021-08-07 19:39:15 +00:00
|
|
|
#include "blocks/mushroomblock.hpp"
|
2021-08-08 19:22:44 +00:00
|
|
|
#include "blocks/goombablock.hpp"
|
2021-07-22 22:08:05 +00:00
|
|
|
#include "mario.hpp"
|
2021-04-30 07:10:58 +00:00
|
|
|
|
2021-05-31 16:54:59 +00:00
|
|
|
#define CAN_BE_DESTROYED_FLAG 0x0000000000000001
|
2021-07-22 22:08:05 +00:00
|
|
|
#define HAS_COLLISION 0x0000000000000002
|
2021-05-31 16:54:59 +00:00
|
|
|
|
2021-05-08 22:46:10 +00:00
|
|
|
MarioBlock::MarioBlock( int x, int y,
|
2021-07-22 22:08:05 +00:00
|
|
|
const std::shared_ptr< SDLPP::Renderer > &renderer,
|
|
|
|
std::shared_ptr< SDLPP::Texture > texture, SDL_Rect src,
|
|
|
|
bool can_be_destroyed, bool destructible )
|
2021-05-08 22:46:10 +00:00
|
|
|
: RectangleRender( x * BLOCK_SIZE, 1 - ( 16 - y ) * BLOCK_SIZE,
|
2021-05-23 22:07:40 +00:00
|
|
|
BLOCK_SIZE, BLOCK_SIZE, renderer, texture, src ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
_can_be_destroyed = can_be_destroyed;
|
|
|
|
_destructible = can_be_destroyed && destructible;
|
|
|
|
setMovementSpeed( 1 );
|
|
|
|
_coins = 0;
|
|
|
|
_mushroom = false;
|
2021-07-24 17:59:25 +00:00
|
|
|
_base_src = src;
|
2021-05-23 22:07:40 +00:00
|
|
|
}
|
2021-05-02 12:14:11 +00:00
|
|
|
void MarioBlock::visit( SDLPP::Visitor &visitor ) {
|
2021-05-25 14:34:44 +00:00
|
|
|
#ifdef EDITOR
|
2021-05-08 22:46:10 +00:00
|
|
|
if ( !_tool && _terrain &&
|
|
|
|
visitor.getVisitorType() == VisitorType::Terrain ) {
|
2021-05-07 21:17:05 +00:00
|
|
|
destroy();
|
|
|
|
}
|
2021-05-08 22:46:10 +00:00
|
|
|
if ( !_tool && !_terrain &&
|
2021-08-08 19:22:44 +00:00
|
|
|
(visitor.getVisitorType() == VisitorType::Modifier ||
|
|
|
|
visitor.getVisitorType() == VisitorType::Character)) {
|
2021-05-02 12:14:11 +00:00
|
|
|
destroy();
|
|
|
|
}
|
2021-05-25 14:34:44 +00:00
|
|
|
#else
|
2021-07-22 22:08:05 +00:00
|
|
|
if ( visitor.getFromId() == MARIO_TOP_DETECT &&
|
|
|
|
dynamic_cast< MarioVisitor & >( visitor ).canDestroy() ) {
|
2021-05-31 16:54:59 +00:00
|
|
|
// TODO if big mario and _can_be_destroyed
|
2021-07-22 22:08:05 +00:00
|
|
|
if ( _destructible && !hasCoin() ) {
|
2021-05-25 20:05:50 +00:00
|
|
|
destroy();
|
|
|
|
} else {
|
2021-05-26 16:24:09 +00:00
|
|
|
BounceVisitor bv;
|
2021-07-22 22:08:05 +00:00
|
|
|
bv.setVisitorType( VisitorType::Terrain );
|
2021-05-26 16:24:09 +00:00
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
setPos( getPos() - SDLPP::Vec2D< double >( 0, BLOCK_SIZE ) );
|
|
|
|
if ( getCollisions().size() < 2 )
|
2021-08-04 22:32:17 +00:00
|
|
|
addCollision( SDLPP::RectColider( 0.1, 0.1, 0.8, 0.8, BOUNCE_COLLISION ) );
|
2021-05-26 16:24:09 +00:00
|
|
|
updateSizeAndPosition();
|
2021-07-22 22:08:05 +00:00
|
|
|
g_playground->visitCollisions( *this, bv );
|
|
|
|
setPos( getPos() + SDLPP::Vec2D< double >( 0, BLOCK_SIZE ) );
|
2021-05-26 16:24:09 +00:00
|
|
|
updateSizeAndPosition();
|
2021-07-22 22:08:05 +00:00
|
|
|
if ( bv.canBounce() )
|
2021-05-26 16:24:09 +00:00
|
|
|
bounce();
|
2021-05-25 20:05:50 +00:00
|
|
|
}
|
2021-07-22 22:08:05 +00:00
|
|
|
if ( hasCoin() ) {
|
|
|
|
removeCoin();
|
2021-07-24 18:50:24 +00:00
|
|
|
auto coin = createTerrainBlock(COIN_ID, LandType::OVERWORLD, renderer);
|
|
|
|
coin->setPos(getPos());
|
|
|
|
std::dynamic_pointer_cast<CoinBlock>(coin)->setParent(this);
|
2021-07-22 22:08:05 +00:00
|
|
|
dynamic_cast< MarioVisitor & >( visitor ).setCoin();
|
2021-07-24 18:50:24 +00:00
|
|
|
dynamic_cast< MarioVisitor & >( visitor ).setCoinBlock(coin);
|
2021-07-22 22:08:05 +00:00
|
|
|
}
|
2021-08-07 19:39:15 +00:00
|
|
|
if ( hasMushroom() ) {
|
|
|
|
removeMushroom();
|
|
|
|
auto mushroom = createTerrainBlock(MUSHROOM_ID, LandType::OVERWORLD, renderer);
|
|
|
|
mushroom->setPos(getPos());
|
|
|
|
std::dynamic_pointer_cast<MushroomBlock>(mushroom)->setParent(this);
|
|
|
|
dynamic_cast< MarioVisitor & >( visitor ).setMushroomBlock(mushroom);
|
|
|
|
}
|
2021-05-23 22:07:40 +00:00
|
|
|
}
|
2021-05-25 14:34:44 +00:00
|
|
|
#endif
|
2021-05-08 22:46:10 +00:00
|
|
|
visitor.visit( *this );
|
2021-05-02 12:14:11 +00:00
|
|
|
}
|
2021-05-08 22:46:10 +00:00
|
|
|
void MarioBlock::setTool( bool tool ) {
|
2021-05-02 12:14:11 +00:00
|
|
|
_tool = tool;
|
|
|
|
}
|
2021-05-08 22:46:10 +00:00
|
|
|
void MarioBlock::setTerrain( bool terrain ) {
|
2021-05-07 21:17:05 +00:00
|
|
|
_terrain = terrain;
|
2021-05-02 12:43:15 +00:00
|
|
|
}
|
2021-05-02 12:14:11 +00:00
|
|
|
|
2021-05-25 20:05:50 +00:00
|
|
|
void MarioBlock::bounce() {
|
2021-08-07 19:39:15 +00:00
|
|
|
if ( _bouncing ) {
|
2021-05-25 20:05:50 +00:00
|
|
|
return;
|
2021-08-07 19:39:15 +00:00
|
|
|
}
|
2021-05-25 20:05:50 +00:00
|
|
|
_bouncing = true;
|
|
|
|
og_pos = getPos();
|
2021-07-24 18:50:24 +00:00
|
|
|
ticks_to_bounce = bounce_ticks;
|
|
|
|
setMovement( 0, -bounce_speed );
|
|
|
|
}
|
|
|
|
|
2021-08-07 19:39:15 +00:00
|
|
|
void MarioBlock::travelToPos(const SDLPP::Vec2D<double> &target) {
|
|
|
|
if(_traveling) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_traveling = true;
|
|
|
|
_target = target;
|
|
|
|
|
|
|
|
auto movement = (_target - getPos());
|
|
|
|
auto abs_mov_x = movement.getX();
|
|
|
|
if(abs_mov_x < 0) {
|
|
|
|
abs_mov_x *= -1;
|
|
|
|
}
|
|
|
|
auto abs_mov_y = movement.getY();
|
|
|
|
if(abs_mov_y < 0) {
|
|
|
|
abs_mov_y *= -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
movement = movement / (abs_mov_x > abs_mov_y ? abs_mov_x : abs_mov_y);
|
|
|
|
movement = movement * travel_speed;
|
|
|
|
setMovement(movement.getX(), movement.getY());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MarioBlock::gravity(int ticks) {
|
|
|
|
if(_on_ground) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_ticks_till_gravity -= ticks;
|
|
|
|
if(_ticks_till_gravity < 0) {
|
|
|
|
addMovement(0, _gravity_acceleration);
|
|
|
|
_ticks_till_gravity = _base_gravity_ticks;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MarioBlock::isBouncing() const {
|
2021-07-24 18:50:24 +00:00
|
|
|
return _bouncing;
|
2021-05-25 20:05:50 +00:00
|
|
|
}
|
|
|
|
|
2021-08-07 19:39:15 +00:00
|
|
|
bool MarioBlock::isTraveling() const {
|
|
|
|
return _traveling;
|
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
void MarioBlock::custom_move( int ticks ) {
|
2021-08-07 19:39:15 +00:00
|
|
|
if ( !_bouncing && !_traveling ) {
|
2021-05-25 20:05:50 +00:00
|
|
|
return;
|
2021-08-07 19:39:15 +00:00
|
|
|
}
|
|
|
|
if( _bouncing ) {
|
|
|
|
if ( getMovement().getY() < 0 ) {
|
|
|
|
ticks_to_bounce -= ticks;
|
|
|
|
if ( ticks_to_bounce < 0 ) {
|
|
|
|
setMovement( 0, bounce_speed );
|
|
|
|
ticks_to_bounce = bounce_ticks;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( getPos().getY() >= og_pos.getY() ) {
|
|
|
|
setMovement( 0, 0 );
|
|
|
|
setPos( getPos().getX(), og_pos.getY() );
|
|
|
|
_bouncing = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(_traveling) {
|
|
|
|
bool overshot_x = (getMovement().getX() < 0 &&
|
|
|
|
getPos().getX() <= _target.getX()) ||
|
|
|
|
(getMovement().getX() > 0 &&
|
|
|
|
getPos().getX() >= _target.getX());
|
|
|
|
bool overshot_y = (getMovement().getY() < 0 &&
|
|
|
|
getPos().getY() <= _target.getY()) ||
|
|
|
|
(getMovement().getY() > 0 &&
|
|
|
|
getPos().getY() >= _target.getY());
|
|
|
|
if(overshot_x) {
|
|
|
|
setPos(_target.getX(), getPos().getY());
|
|
|
|
setMovement(0, getMovement().getY());
|
2021-05-25 20:05:50 +00:00
|
|
|
}
|
2021-08-07 19:39:15 +00:00
|
|
|
if(overshot_y) {
|
|
|
|
setPos(getPos().getX(), _target.getY());
|
|
|
|
setMovement(getMovement().getX(), 0);
|
|
|
|
}
|
|
|
|
if(getMovement() == SDLPP::Vec2D<double>(0,0)) {
|
|
|
|
_traveling = false;
|
2021-05-25 20:05:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
void MarioBlock::setType( LandType::Value type ) {
|
2021-05-31 12:03:11 +00:00
|
|
|
_type = type;
|
2021-07-22 22:08:05 +00:00
|
|
|
setWorldTypeSrc( _type );
|
2021-05-31 12:03:11 +00:00
|
|
|
}
|
|
|
|
LandType::Value MarioBlock::getType() const {
|
|
|
|
return _type;
|
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
bool MarioBlock::hasCoin() {
|
|
|
|
return _coins > 0;
|
|
|
|
}
|
|
|
|
bool MarioBlock::hasMushroom() {
|
|
|
|
return _mushroom;
|
|
|
|
}
|
|
|
|
void MarioBlock::removeCoin() {
|
|
|
|
_coins--;
|
|
|
|
}
|
|
|
|
void MarioBlock::removeMushroom() {
|
|
|
|
_mushroom = false;
|
|
|
|
}
|
2021-08-07 19:39:15 +00:00
|
|
|
void MarioBlock::addMushroom() {
|
|
|
|
_mushroom = true;
|
|
|
|
}
|
2021-07-22 22:08:05 +00:00
|
|
|
void MarioBlock::setCoinCount( int coins ) {
|
|
|
|
_coins = coins;
|
|
|
|
}
|
|
|
|
void MarioBlock::setDestructible( bool destructible ) {
|
|
|
|
_destructible = destructible;
|
|
|
|
}
|
|
|
|
void MarioBlock::ensureCollision() {
|
|
|
|
if ( getCollisions().size() == 0 ) {
|
|
|
|
addCollision( SDLPP::RectColider( 0, 0, 1, 1 ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void MarioBlock::setWorldTypeSrc( LandType::Value world ) {
|
2021-07-24 17:59:25 +00:00
|
|
|
auto rect = _base_src;
|
2021-07-22 22:08:05 +00:00
|
|
|
switch ( world ) {
|
|
|
|
case LandType::OVERWORLD:
|
|
|
|
rect.x += OVERWORLD_SHIFT.getX();
|
|
|
|
rect.y += OVERWORLD_SHIFT.getY();
|
|
|
|
break;
|
|
|
|
case LandType::UNDERWORLD:
|
|
|
|
rect.x += UNDERWORLD_SHIFT.getX();
|
|
|
|
rect.y += UNDERWORLD_SHIFT.getY();
|
|
|
|
break;
|
|
|
|
case LandType::WATER:
|
|
|
|
rect.x += WATER_SHIFT.getX();
|
|
|
|
rect.y += WATER_SHIFT.getY();
|
|
|
|
break;
|
|
|
|
case LandType::BOWSER:
|
|
|
|
rect.x += BOWSER_SHIFT.getX();
|
|
|
|
rect.y += BOWSER_SHIFT.getY();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
setTextureSourceRect( rect );
|
|
|
|
}
|
|
|
|
|
2021-05-08 22:46:10 +00:00
|
|
|
const std::vector< uint64_t > possibleBlocks = {
|
|
|
|
FLOOR_ID,
|
|
|
|
STEP_ID,
|
|
|
|
HILL_TOP_ID,
|
|
|
|
HILL_DOTS_LEFT_ID,
|
|
|
|
HILL_FILL_ID,
|
|
|
|
HILL_INCLINE_ID,
|
|
|
|
HILL_DOTS_RIGHT_ID,
|
|
|
|
HILL_DECLINE_ID,
|
|
|
|
CLOUD_LEFT_TOP_ID,
|
|
|
|
CLOUD_MIDDLE_TOP_ID,
|
|
|
|
CLOUD_RIGHT_TOP_ID,
|
|
|
|
VINE_TOP_ID,
|
|
|
|
CLOUD_LEFT_BOTTOM_ID,
|
|
|
|
CLOUD_MIDDLE_BOTTOM_ID,
|
|
|
|
CLOUD_RIGHT_BOTTOM_ID,
|
|
|
|
VINE_BOTTOM_ID,
|
|
|
|
BRICK_TOP_ID,
|
|
|
|
BRICK_ID,
|
|
|
|
FLAG_ID,
|
|
|
|
WATER_TOP_ID,
|
|
|
|
BUSH_LEFT_ID,
|
|
|
|
BUSH_MIDDLE_ID,
|
|
|
|
BUSH_RIGHT_ID,
|
|
|
|
WATER_FILL_ID,
|
|
|
|
PIPE_LEFT_TOP_ID,
|
|
|
|
PIPE_RIGHT_TOP_ID,
|
|
|
|
CASTLE_TOWER_ID,
|
|
|
|
CASTLE_TOWER_FILLED_ID,
|
|
|
|
PIPE_LEFT_BOTTOM_ID,
|
|
|
|
PIPE_RIGHT_BOTTOM_ID,
|
|
|
|
CASTLE_LEFT_ID,
|
|
|
|
CASTLE_RIGHT_ID,
|
|
|
|
POLE_TOP_ID,
|
|
|
|
CASTLE_ENTRY_ID,
|
|
|
|
SIDEWAY_PIPE_END_TOP_ID,
|
|
|
|
SIDEWAY_PIPE_MIDDLE_TOP_ID,
|
|
|
|
POLE_BOTTOM_ID,
|
|
|
|
CASTLE_BLACK_ID,
|
|
|
|
SIDEWAY_PIPE_END_BOTTOM_ID,
|
|
|
|
SIDEWAY_PIPE_MIDDLE_BOTTOM_ID,
|
|
|
|
SIDEWAY_PIPE_CONNECTOR_TOP_ID,
|
|
|
|
TREE_PLATFORM_TOP_LEFT_ID,
|
|
|
|
TREE_PLATFORM_TOP_MIDDLE_ID,
|
|
|
|
TREE_PLATFORM_TOP_RIGHT_ID,
|
|
|
|
SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID,
|
|
|
|
MUSHROOM_PLATFORM_TOP_LEFT_ID,
|
|
|
|
MUSHROOM_PLATFORM_TOP_MIDDLE_ID,
|
|
|
|
MUSHROOM_PLATFORM_TOP_RIGHT_ID,
|
|
|
|
TREE_PLATFORM_BARK_ID,
|
|
|
|
MUSHROOM_PLATFORM_BARK_TOP_ID,
|
|
|
|
TREE_LEAVES_TOP_ID,
|
|
|
|
TREE_LEAVES_SMALL_ID,
|
|
|
|
CANNON_TOWER_ID,
|
|
|
|
MUSHROOM_PLATFORM_BARK_BOTTOM_ID,
|
|
|
|
TREE_LEAVES_BOTTOM_ID,
|
|
|
|
TREE_BARK_ID,
|
|
|
|
CANNON_PEDESTAL_ID,
|
|
|
|
CANNON_ID,
|
2021-05-28 17:51:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const std::vector< uint64_t > possibleMods = {
|
2021-06-07 21:48:28 +00:00
|
|
|
DESTRUCTIBLE_MODIFIER_ID,
|
2021-06-21 17:40:29 +00:00
|
|
|
BACKGROUND_MODIFIER_ID,
|
2021-06-24 18:53:58 +00:00
|
|
|
COIN_MODIFIER_ID,
|
|
|
|
MUSHROOM_MODIFIER_ID,
|
2021-05-07 21:17:05 +00:00
|
|
|
};
|
2021-04-30 07:10:58 +00:00
|
|
|
|
2021-05-28 17:51:02 +00:00
|
|
|
const std::vector< uint64_t > possibleCharacters = {
|
|
|
|
MARIO_ID,
|
2021-08-08 19:22:44 +00:00
|
|
|
GOOMBA_ID,
|
2021-05-28 17:51:02 +00:00
|
|
|
};
|
|
|
|
|
2021-05-31 12:03:11 +00:00
|
|
|
const std::vector< LandType::Value > possibleLands = {
|
2021-07-22 22:08:05 +00:00
|
|
|
LandType::OVERWORLD, LandType::UNDERWORLD, LandType::WATER, LandType::BOWSER
|
2021-05-31 12:03:11 +00:00
|
|
|
};
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
std::shared_ptr< MarioBlock >
|
|
|
|
createBlockById( uint64_t id, int x, int y,
|
|
|
|
std::shared_ptr< SDLPP::Renderer > &renderer ) {
|
|
|
|
std::shared_ptr< MarioBlock > result = nullptr;
|
|
|
|
switch ( id ) {
|
|
|
|
case FLOOR_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< FloorBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_INCLINE_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillInclineBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_DECLINE_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillDeclineBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_DOTS_RIGHT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillDotsRightBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_DOTS_LEFT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillDotsLeftBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_FILL_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillFillBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case HILL_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< HillTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case BUSH_LEFT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< BushLeftBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case BUSH_MIDDLE_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< BushMiddleBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case BUSH_RIGHT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< BushRightBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_LEFT_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudLeftBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_MIDDLE_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudMiddleBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_RIGHT_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudRightBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_LEFT_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudLeftTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_MIDDLE_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudMiddleTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CLOUD_RIGHT_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CloudRightTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case PIPE_LEFT_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PipeLeftBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case PIPE_RIGHT_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PipeRightBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case PIPE_LEFT_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PipeLeftTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case PIPE_RIGHT_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PipeRightTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_LEFT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleLeftBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_RIGHT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleRightBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_BLACK_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleBlackBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_ENTRY_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleEntryBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_TOWER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleTowerBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CASTLE_TOWER_FILLED_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CastleTowerFilledBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case VINE_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< VineTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case VINE_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< VineBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case POLE_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PoleTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case POLE_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< PoleBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case FLAG_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< FlagBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case STEP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< StepBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case BRICK_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< BrickBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case BRICK_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< BrickTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_END_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeEndTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_END_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeEndBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_MIDDLE_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeMiddleTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeMiddleBottomBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_CONNECTOR_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeConnectorTopBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< SidewayPipeConnectorBottomBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_PLATFORM_TOP_LEFT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreePlatformTopLeftBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_PLATFORM_TOP_MIDDLE_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreePlatformTopMiddleBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_PLATFORM_TOP_RIGHT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreePlatformTopRightBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_PLATFORM_BARK_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreePlatformBarkBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case WATER_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< WaterTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case WATER_FILL_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< WaterFillBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case MUSHROOM_PLATFORM_TOP_LEFT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomPlatformTopLeftBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case MUSHROOM_PLATFORM_TOP_MIDDLE_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomPlatformTopMiddleBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case MUSHROOM_PLATFORM_TOP_RIGHT_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomPlatformTopRightBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case MUSHROOM_PLATFORM_BARK_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomPlatformBarkTopBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case MUSHROOM_PLATFORM_BARK_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomPlatformBarkBottomBlock >( x, y,
|
|
|
|
renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_BARK_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreeBarkBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_LEAVES_SMALL_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreeLeavesSmallBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_LEAVES_TOP_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreeLeavesTopBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case TREE_LEAVES_BOTTOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< TreeLeavesBottomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CANNON_TOWER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CannonTowerBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CANNON_PEDESTAL_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CannonPedestalBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case CANNON_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CannonBlock >( x, y, renderer ) );
|
|
|
|
break;
|
|
|
|
case MARIO_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
2021-07-24 17:59:25 +00:00
|
|
|
std::make_shared< Mario >( x, y, renderer ) );
|
2021-07-22 22:08:05 +00:00
|
|
|
break;
|
2021-08-08 19:22:44 +00:00
|
|
|
case GOOMBA_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< GoombaBlock >( x, y, renderer ) );
|
|
|
|
break;
|
2021-07-22 22:08:05 +00:00
|
|
|
case DESTRUCTIBLE_MODIFIER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
2021-07-24 17:59:25 +00:00
|
|
|
std::make_shared< DestructibleModifierBlock >( x, y, renderer ) );
|
2021-07-22 22:08:05 +00:00
|
|
|
break;
|
|
|
|
case BACKGROUND_MODIFIER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
2021-07-24 17:59:25 +00:00
|
|
|
std::make_shared< BackgroundModifierBlock >( x, y, renderer ) );
|
2021-07-22 22:08:05 +00:00
|
|
|
break;
|
2021-08-04 22:32:17 +00:00
|
|
|
#ifdef EDITOR
|
2021-07-22 22:08:05 +00:00
|
|
|
case COIN_MODIFIER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
2021-07-24 17:59:25 +00:00
|
|
|
std::make_shared< CoinEditorBlock >( x, y, renderer ) );
|
2021-07-22 22:08:05 +00:00
|
|
|
break;
|
2021-08-04 22:32:17 +00:00
|
|
|
#endif
|
2021-07-22 22:08:05 +00:00
|
|
|
case MUSHROOM_MODIFIER_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
2021-07-24 17:59:25 +00:00
|
|
|
std::make_shared< MushroomModifierBlock >( x, y, renderer ) );
|
2021-07-22 22:08:05 +00:00
|
|
|
break;
|
2021-08-04 22:32:17 +00:00
|
|
|
#ifndef EDITOR
|
2021-07-24 18:50:24 +00:00
|
|
|
case COIN_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< CoinBlock >( x, y, renderer ) );
|
|
|
|
break;
|
2021-08-07 19:39:15 +00:00
|
|
|
case MUSHROOM_ID:
|
|
|
|
result = std::static_pointer_cast< MarioBlock >(
|
|
|
|
std::make_shared< MushroomBlock >( x, y, renderer ) );
|
|
|
|
break;
|
2021-08-04 22:32:17 +00:00
|
|
|
#endif
|
2021-07-22 22:08:05 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr< MarioBlock >
|
2021-05-02 12:14:11 +00:00
|
|
|
createBlock( std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y,
|
2021-07-22 22:08:05 +00:00
|
|
|
uint64_t id, LandType::Value land_type, bool destructible,
|
|
|
|
bool editor ) {
|
|
|
|
auto block = createBlockById( id, x, y, renderer );
|
2021-07-24 17:59:25 +00:00
|
|
|
if ( block == nullptr ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
return nullptr;
|
2021-05-31 16:54:59 +00:00
|
|
|
}
|
2021-04-27 13:56:13 +00:00
|
|
|
block->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER );
|
2021-04-25 20:42:55 +00:00
|
|
|
block->setStatic();
|
2021-07-22 22:08:05 +00:00
|
|
|
block->setType( land_type );
|
2021-07-24 17:59:25 +00:00
|
|
|
if ( destructible ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
block->setDestructible();
|
|
|
|
}
|
|
|
|
if ( editor ) {
|
|
|
|
block->ensureCollision();
|
2021-05-31 16:54:59 +00:00
|
|
|
}
|
2021-04-25 20:42:55 +00:00
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
// TODO coin count
|
|
|
|
std::shared_ptr< MarioBlock >
|
2021-05-08 22:43:53 +00:00
|
|
|
createTerrainBlock( uint64_t block_id, LandType::Value type,
|
2021-05-08 22:46:10 +00:00
|
|
|
std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y,
|
2021-05-31 16:54:59 +00:00
|
|
|
bool destructible, bool editor ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
return createBlock( renderer, x, y, block_id, type, destructible, editor );
|
2021-04-25 20:42:55 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
std::shared_ptr< MarioBlock >
|
2021-05-08 22:43:53 +00:00
|
|
|
createTerrainBlock( uint64_t block_id, LandType::Value type,
|
2021-04-27 13:56:13 +00:00
|
|
|
std::shared_ptr< SDLPP::Renderer > &renderer,
|
2021-05-31 16:54:59 +00:00
|
|
|
bool destructible, bool editor ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
return createTerrainBlock( block_id, type, renderer, 0, 0, destructible,
|
|
|
|
editor );
|
2021-05-01 19:55:43 +00:00
|
|
|
}
|
|
|
|
|
2021-07-22 22:08:05 +00:00
|
|
|
std::shared_ptr< MarioBlock >
|
2021-05-08 22:46:10 +00:00
|
|
|
createMario( LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer,
|
2021-07-22 22:08:05 +00:00
|
|
|
int x, int y, bool editor ) {
|
2021-05-08 22:46:10 +00:00
|
|
|
// TODO add type additions
|
2021-07-24 17:59:25 +00:00
|
|
|
auto mario = createBlock( renderer, x, y, MARIO_ID, type, false, true );
|
|
|
|
if ( editor ) {
|
2021-07-22 22:08:05 +00:00
|
|
|
mario->setTerrain( false );
|
|
|
|
mario->removeCollisions();
|
|
|
|
mario->ensureCollision();
|
|
|
|
}
|
2021-05-02 12:43:15 +00:00
|
|
|
return mario;
|
2021-04-25 20:42:55 +00:00
|
|
|
}
|
2021-05-08 22:43:53 +00:00
|
|
|
|
2021-05-08 22:46:10 +00:00
|
|
|
enum BlockRole::Value getBlockRole( uint64_t id ) {
|
|
|
|
if ( id >= 0x7000 )
|
2021-05-08 22:43:53 +00:00
|
|
|
return BlockRole::TERRAIN;
|
2021-05-08 22:46:10 +00:00
|
|
|
if ( id == MARIO_ID )
|
2021-05-08 22:43:53 +00:00
|
|
|
return BlockRole::MARIO;
|
2021-05-25 22:46:19 +00:00
|
|
|
if ( id < MARIO_ID )
|
2021-08-08 19:22:44 +00:00
|
|
|
return BlockRole::CHARACTER;
|
2021-05-08 22:43:53 +00:00
|
|
|
return BlockRole::MODIFIER;
|
|
|
|
}
|
2021-08-07 19:39:15 +00:00
|
|
|
|
|
|
|
void MarioBlock::setBaseRect(SDL_Rect rect) {
|
|
|
|
_base_src = rect;
|
|
|
|
setType(getType());
|
|
|
|
}
|
2021-08-07 20:25:32 +00:00
|
|
|
void MarioBlock::checkVisibility(double rightmost_x) {
|
|
|
|
// we assume that object's X > 0 as otherwise it would be destroyed
|
|
|
|
if(!getHidden() && getAbsolutePos().getX() < rightmost_x) {
|
|
|
|
_was_visible = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool MarioBlock::wasVisible() const {
|
|
|
|
return _was_visible;
|
|
|
|
}
|