#include "blocks.hpp" #include "global_vars.hpp" #include "objectids.hpp" #include "sprites.hpp" #include "editor_visitor.hpp" #include #include "mario_visitor.hpp" MarioBlock::MarioBlock( int x, int y, std::shared_ptr< SDLPP::Renderer > renderer, std::shared_ptr< SDLPP::Texture > texture, SDL_Rect src, bool destructible ) : RectangleRender( x * BLOCK_SIZE, 1 - ( 16 - y ) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, renderer, texture, src ) { _destructible = destructible; setMovementSpeed(1); } void MarioBlock::visit( SDLPP::Visitor &visitor ) { #ifdef EDITOR if ( !_tool && _terrain && visitor.getVisitorType() == VisitorType::Terrain ) { destroy(); } if ( !_tool && !_terrain && visitor.getVisitorType() == VisitorType::Modifier ) { destroy(); } #else if(visitor.getFromId() == MARIO_TOP_DETECT && dynamic_cast(visitor).canDestroy()) { if( _destructible ) { destroy(); } else { BounceVisitor bv; bv.setVisitorType(VisitorType::Terrain); setPos(getPos() - SDLPP::Vec2D(0, BLOCK_SIZE)); if(getCollisions().size() < 2) addCollision(SDLPP::RectColider(0.1, 0.1, 0.8, 0.8, 69)); updateSizeAndPosition(); g_playground->visitCollisions(*this, bv); setPos(getPos() + SDLPP::Vec2D(0, BLOCK_SIZE)); updateSizeAndPosition(); if(bv.canBounce()) bounce(); } } #endif visitor.visit( *this ); } void MarioBlock::setTool( bool tool ) { _tool = tool; } void MarioBlock::setTerrain( bool terrain ) { _terrain = terrain; } void MarioBlock::bounce() { if(_bouncing) return; _bouncing = true; og_pos = getPos(); setMovement(0, -0.5); } void MarioBlock::custom_move(int ticks) { if(!_bouncing) return; if(getMovement().getY() < 0) { ticks_to_bounce -= ticks; if(ticks_to_bounce < 0) { setMovement(0, 0.5); ticks_to_bounce = bounce_ticks; } } else { if(getPos().getY() >= og_pos.getY()) { setMovement(0, 0); setPos(getPos().getX(), og_pos.getY()); _bouncing = false; } } } void MarioBlock::setType(LandType::Value type) { _type = type; } LandType::Value MarioBlock::getType() const { return _type; } 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, }; const std::vector< uint64_t > possibleMods = { DESTRUCTIBLE_ID, }; const std::vector< uint64_t > possibleCharacters = { MARIO_ID, }; const std::vector< LandType::Value > possibleLands = { LandType::OVERWORLD, LandType::UNDERWORLD, LandType::WATER, LandType::BOWSER }; const std::unordered_map< uint64_t, const SDL_Rect * > block_mapping = { { FLOOR_ID, &FLOOR_SRC }, { HILL_INCLINE_ID, &HILL_INCLINE_SRC }, { HILL_DECLINE_ID, &HILL_DECLINE_SRC }, { HILL_DOTS_RIGHT_ID, &HILL_DOTS_RIGHT_SRC }, { HILL_DOTS_LEFT_ID, &HILL_DOTS_LEFT_SRC }, { HILL_FILL_ID, &HILL_FILL_SRC }, { HILL_TOP_ID, &HILL_TOP_SRC }, { BUSH_LEFT_ID, &BUSH_LEFT_SRC }, { BUSH_MIDDLE_ID, &BUSH_MIDDLE_SRC }, { BUSH_RIGHT_ID, &BUSH_RIGHT_SRC }, { CLOUD_LEFT_BOTTOM_ID, &CLOUD_LEFT_BOTTOM_SRC }, { CLOUD_MIDDLE_BOTTOM_ID, &CLOUD_MIDDLE_BOTTOM_SRC }, { CLOUD_RIGHT_BOTTOM_ID, &CLOUD_RIGHT_BOTTOM_SRC }, { CLOUD_LEFT_TOP_ID, &CLOUD_LEFT_TOP_SRC }, { CLOUD_MIDDLE_TOP_ID, &CLOUD_MIDDLE_TOP_SRC }, { CLOUD_RIGHT_TOP_ID, &CLOUD_RIGHT_TOP_SRC }, { PIPE_LEFT_BOTTOM_ID, &PIPE_LEFT_BOTTOM_SRC }, { PIPE_LEFT_TOP_ID, &PIPE_LEFT_TOP_SRC }, { PIPE_RIGHT_BOTTOM_ID, &PIPE_RIGHT_BOTTOM_SRC }, { PIPE_RIGHT_TOP_ID, &PIPE_RIGHT_TOP_SRC }, { CASTLE_LEFT_ID, &CASTLE_LEFT_SRC }, { CASTLE_RIGHT_ID, &CASTLE_RIGHT_SRC }, { CASTLE_BLACK_ID, &CASTLE_BLACK_SRC }, { CASTLE_ENTRY_ID, &CASTLE_ENTRY_SRC }, { CASTLE_TOWER_ID, &CASTLE_TOWER_SRC }, { CASTLE_TOWER_FILLED_ID, &CASTLE_TOWER_FILLED_SRC }, { VINE_TOP_ID, &VINE_TOP_SRC }, { VINE_BOTTOM_ID, &VINE_BOTTOM_SRC }, { POLE_TOP_ID, &POLE_TOP_SRC }, { POLE_BOTTOM_ID, &POLE_BOTTOM_SRC }, { FLAG_ID, &FLAG_SRC }, { STEP_ID, &STEP_SRC }, { BRICK_ID, &BRICK_SRC }, { BRICK_TOP_ID, &BRICK_TOP_SRC }, { SIDEWAY_PIPE_END_TOP_ID, &SIDEWAY_PIPE_END_TOP_SRC }, { SIDEWAY_PIPE_END_BOTTOM_ID, &SIDEWAY_PIPE_END_BOTTOM_SRC }, { SIDEWAY_PIPE_MIDDLE_TOP_ID, &SIDEWAY_PIPE_MIDDLE_TOP_SRC }, { SIDEWAY_PIPE_MIDDLE_BOTTOM_ID, &SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC }, { SIDEWAY_PIPE_CONNECTOR_TOP_ID, &SIDEWAY_PIPE_CONNECTOR_TOP_SRC }, { SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID, &SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC }, { TREE_PLATFORM_TOP_LEFT_ID, &TREE_PLATFORM_TOP_LEFT_SRC }, { TREE_PLATFORM_TOP_MIDDLE_ID, &TREE_PLATFORM_TOP_MIDDLE_SRC }, { TREE_PLATFORM_TOP_RIGHT_ID, &TREE_PLATFORM_TOP_RIGHT_SRC }, { TREE_PLATFORM_BARK_ID, &TREE_PLATFORM_BARK_SRC }, { WATER_TOP_ID, &WATER_TOP_SRC }, { WATER_FILL_ID, &WATER_FILL_SRC }, { MUSHROOM_PLATFORM_TOP_LEFT_ID, &MUSHROOM_PLATFORM_TOP_LEFT_SRC }, { MUSHROOM_PLATFORM_TOP_MIDDLE_ID, &MUSHROOM_PLATFORM_TOP_MIDDLE_SRC }, { MUSHROOM_PLATFORM_TOP_RIGHT_ID, &MUSHROOM_PLATFORM_TOP_RIGHT_SRC }, { MUSHROOM_PLATFORM_BARK_TOP_ID, &MUSHROOM_PLATFORM_BARK_TOP_SRC }, { MUSHROOM_PLATFORM_BARK_BOTTOM_ID, &MUSHROOM_PLATFORM_BARK_BOTTOM_SRC }, { TREE_BARK_ID, &TREE_BARK_SRC }, { TREE_LEAVES_SMALL_ID, &TREE_LEAVES_SMALL_SRC }, { TREE_LEAVES_TOP_ID, &TREE_LEAVES_TOP_SRC }, { TREE_LEAVES_BOTTOM_ID, &TREE_LEAVES_BOTTOM_SRC }, { CANNON_TOWER_ID, &CANNON_TOWER_SRC }, { CANNON_PEDESTAL_ID, &CANNON_PEDESTAL_SRC }, { CANNON_ID, &CANNON_SRC }, { MARIO_ID, &MARIO_STANDING_SRC }, { DESTRUCTIBLE_ID, &DESTRUCTIBLE_SRC }, }; std::shared_ptr< SDLPP::RectangleRender > createBlock( std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y, std::shared_ptr< SDLPP::Texture > &texture, const SDL_Rect &src, uint64_t id, LandType::Value land_type, bool collision = false, bool destructible = false ) { auto block = std::make_shared< MarioBlock >( x, y, renderer, texture, src, destructible ); block->setId( id ); block->setAlignment( SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER ); block->setStatic(); block->setType(land_type); if ( collision ) block->addCollision( SDLPP::RectColider( 0, 0, 1, 1 ) ); return block; } SDL_Rect getSourceRectByID( uint64_t id, LandType::Value type ) { if ( block_mapping.find( id ) == block_mapping.end() ) return {}; SDL_Rect ret_src = *block_mapping.at( id ); switch ( type ) { case LandType::OVERWORLD: ret_src.x += OVERWORLD_SHIFT.getX(); ret_src.y += OVERWORLD_SHIFT.getY(); break; case LandType::UNDERWORLD: ret_src.x += UNDERWORLD_SHIFT.getX(); ret_src.y += UNDERWORLD_SHIFT.getY(); break; case LandType::WATER: ret_src.x += WATER_SHIFT.getX(); ret_src.y += WATER_SHIFT.getY(); break; case LandType::BOWSER: ret_src.x += BOWSER_SHIFT.getX(); ret_src.y += BOWSER_SHIFT.getY(); break; } return ret_src; } std::shared_ptr< SDLPP::RectangleRender > createTerrainBlock( uint64_t block_id, LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y, std::shared_ptr< SDLPP::Texture > texture, bool collision, bool destructible ) { return createBlock( renderer, x, y, texture, getSourceRectByID( block_id, type ), block_id, type, collision, destructible ); } std::shared_ptr< SDLPP::RectangleRender > createTerrainBlock( uint64_t block_id, LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer, std::shared_ptr< SDLPP::Texture > texture, bool collision, bool destructible ) { return createTerrainBlock( block_id, type, renderer, 0, 0, texture, collision, destructible ); } std::shared_ptr< SDLPP::RectangleRender > createTerrainBlock( uint64_t block_id, LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y, bool collision, bool destructible ) { return createTerrainBlock( block_id, type, renderer, x, y, g_terrain_texture, collision, destructible ); } std::shared_ptr< SDLPP::RectangleRender > createTerrainBlock( uint64_t block_id, LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer, bool collision, bool destructible ) { return createTerrainBlock( block_id, type, renderer, g_terrain_texture, collision, destructible ); } std::shared_ptr< SDLPP::RectangleRender > createMario( LandType::Value type, std::shared_ptr< SDLPP::Renderer > &renderer, int x, int y ) { // TODO add type additions auto mario = createBlock( renderer, x, y, g_mario_texture, MARIO_STANDING_SRC, MARIO_ID, type, true ); dynamic_cast< MarioBlock & >( *mario ).setTerrain( false ); return mario; } enum BlockRole::Value getBlockRole( uint64_t id ) { if ( id >= 0x7000 ) return BlockRole::TERRAIN; if ( id == MARIO_ID ) return BlockRole::MARIO; if ( id < MARIO_ID ) return BlockRole::MODIFIER; // TODO modifier/character return BlockRole::MODIFIER; }