2021-05-22 21:13:26 +00:00
# include "mario.hpp"
# include "global_vars.hpp"
# include "objectids.hpp"
# include "sprites.hpp"
2021-08-04 22:32:17 +00:00
# include "visitors/mario_visitor.hpp"
2021-05-22 21:13:26 +00:00
2021-07-22 22:08:05 +00:00
Mario : : Mario ( int x , int y , const std : : shared_ptr < SDLPP : : Renderer > & renderer ) : MarioBlock ( x , y , renderer , g_mario_texture , MARIO_STANDING_SRC ) {
2021-05-22 21:13:26 +00:00
setAnimationFrames ( MARIO_WALK_ANIM ) ;
setId ( MARIO_ID ) ;
setAlignment ( SDLPP : : OBJ_CENTER , SDLPP : : OBJ_CENTER ) ;
setAnimationSpeed ( 12.5 ) ;
pauseAnimation ( ) ;
setMovement ( 0 , 0 ) ;
2021-05-23 21:32:15 +00:00
setMovementSpeed ( 1 ) ;
2021-05-26 15:48:33 +00:00
auto bottom_detect = SDLPP : : RectColider ( 0.2 , 1 , 0.6 , 0 , MARIO_FLOOR_DETECT ) ;
2021-05-27 14:33:00 +00:00
bottom_detect . setColor ( " #FF0000 " ) ;
bottom_detect . setOutlineColor ( " #FF0000 " ) ;
2021-05-25 22:46:19 +00:00
bottom_detect . setMinHeight ( 1 ) ;
addCollision ( bottom_detect ) ;
2021-05-22 21:13:26 +00:00
addCollision (
2021-05-28 17:51:02 +00:00
SDLPP : : RectColider ( 0 , 0.25 , 0.1 , 0.6 , MARIO_LEFT_SIDE_DETECT ) ) ;
2021-05-22 21:13:26 +00:00
addCollision (
2021-05-28 17:51:02 +00:00
SDLPP : : RectColider ( 0.9 , 0.25 , 0.1 , 0.6 , MARIO_RIGHT_SIDE_DETECT ) ) ;
2021-05-23 21:45:45 +00:00
addCollision (
2021-05-27 14:33:00 +00:00
SDLPP : : RectColider ( 0 , 0 , 0.1 , 0.1 , MARIO_TOP_LEFT_DETECT ) ) ;
2021-05-25 10:26:04 +00:00
addCollision (
2021-05-27 14:33:00 +00:00
SDLPP : : RectColider ( 0.9 , 0 , 0.1 , 0.1 , MARIO_TOP_LEFT_DETECT ) ) ;
2021-05-25 20:05:50 +00:00
top_collision = std : : make_shared < SDLPP : : RectColider > ( 0.5 , 0 , 0.2 , 0.15 , MARIO_TOP_DETECT ) ;
addCollision ( top_collision ) ;
2021-05-27 14:33:00 +00:00
setColiderColor ( " #FF0000 " ) ;
2021-05-22 21:13:26 +00:00
setStatic ( false ) ;
}
2021-07-22 22:08:05 +00:00
Mario : : Mario ( const std : : shared_ptr < SDLPP : : Renderer > & renderer ) : Mario ( 0 , 0 , renderer ) { }
2021-05-22 21:13:26 +00:00
void Mario : : walkLeft ( ) {
2021-05-23 21:45:45 +00:00
if ( on_ground )
resumeAnimation ( ) ;
2021-05-22 21:13:26 +00:00
addMovement ( - side_movement , 0 ) ;
if ( getMovement ( ) . getX ( ) < 0 & & faces_right ) {
flipHorizontally ( ) ;
2021-05-25 20:05:50 +00:00
top_collision - > setPos ( 0.3 , 0 ) ;
updateSizeAndPosition ( ) ;
2021-05-22 21:13:26 +00:00
faces_right = false ;
}
}
void Mario : : walkRight ( ) {
2021-05-23 21:45:45 +00:00
if ( on_ground )
resumeAnimation ( ) ;
2021-05-22 21:13:26 +00:00
addMovement ( side_movement , 0 ) ;
if ( getMovement ( ) . getX ( ) > 0 & & ! faces_right ) {
flipHorizontally ( ) ;
2021-05-25 20:05:50 +00:00
top_collision - > setPos ( 0.5 , 0 ) ;
updateSizeAndPosition ( ) ;
2021-05-22 21:13:26 +00:00
faces_right = true ;
}
}
void Mario : : setStanding ( ) {
if ( getMovement ( ) . getX ( ) = = 0 ) {
pauseAnimation ( ) ;
}
}
2021-08-04 22:32:17 +00:00
void Mario : : handleVisitor ( SDLPP : : Visitor & visitor ) {
# ifndef EDITOR
2021-05-25 10:26:04 +00:00
// TODO - https://web.archive.org/web/20130807122227/http://i276.photobucket.com/albums/kk21/jdaster64/smb_playerphysics.png
2021-08-04 22:32:17 +00:00
auto & m_visitor = dynamic_cast < MarioVisitor & > ( visitor ) ;
2021-05-22 21:13:26 +00:00
// handle gravity
2021-08-04 22:32:17 +00:00
on_ground = m_visitor . isOnGround ( ) ;
2021-05-23 21:32:15 +00:00
if ( ! jumping & & on_ground ) {
2021-05-22 21:13:26 +00:00
resetMovementY ( ) ;
2021-05-23 21:45:45 +00:00
setTextureSourceRect ( MARIO_STANDING_SRC ) ;
if ( getMovement ( ) . getX ( ) ! = 0 )
resumeAnimation ( ) ;
2021-05-23 21:32:15 +00:00
// for some reason falling of the edge causes on_ground to be true, but
// visitor ground_y is 0
2021-08-04 22:32:17 +00:00
if ( m_visitor . getGroundY ( ) ! = 0 ) {
setPos ( getPos ( ) . getX ( ) , m_visitor . getGroundY ( ) - BLOCK_SIZE ) ;
2021-05-23 21:32:15 +00:00
}
2021-05-22 21:13:26 +00:00
}
2021-05-27 14:33:00 +00:00
// if we just left ground gravity didn't work in custom_move
if ( ! on_ground & & ! jumping & & getMovement ( ) . getY ( ) = = 0 ) {
addMovement ( 0 , 2 * gravity_add_falling ) ;
}
2021-08-04 22:32:17 +00:00
if ( m_visitor . topBlock ( ) & & getMovement ( ) . getY ( ) < 0 ) {
2021-05-23 21:57:29 +00:00
resetMovementY ( ) ;
2021-05-25 10:26:04 +00:00
stop_jump = true ;
2021-05-23 21:57:29 +00:00
}
2021-05-22 21:13:26 +00:00
// make sure Mario isn't stuck inside a wall
2021-05-25 10:26:04 +00:00
// TODO more readable function names
2021-08-04 22:32:17 +00:00
if ( m_visitor . isStopped ( ) ) {
setPos ( m_visitor . getStopX ( ) , getPos ( ) . getY ( ) ) ;
} else if ( m_visitor . canGoLeft ( ) ! = m_visitor . canGoRight ( ) & & ! ( on_ground & & m_visitor . getMovementBlockage ( ) . getY ( ) > getPos ( ) . getY ( ) + BLOCK_SIZE / 2 ) ) {
2021-05-27 14:57:21 +00:00
// only stop mario on ground if the block obstructs at least half of him (important for bug when mario lands from a high jump and is teleported if visitor is fired at wrong moment)
2021-08-04 22:32:17 +00:00
SDLPP : : Vec2D < double > next_pos = { m_visitor . getMovementBlockage ( ) . getX ( ) + ( m_visitor . canGoLeft ( ) * - 1 + m_visitor . canGoRight ( ) * 1 ) * BLOCK_SIZE , getPos ( ) . getY ( ) } ;
2021-05-25 22:46:19 +00:00
setPos ( next_pos ) ;
2021-08-04 22:32:17 +00:00
} else if ( m_visitor . moveTop ( ) & & jumping & & ! stop_jump ) {
auto objPos = m_visitor . getRightLeftPos ( ) ;
2021-05-25 10:26:04 +00:00
if ( objPos . getX ( ) < getPos ( ) . getX ( ) ) {
setPos ( objPos . getX ( ) + BLOCK_SIZE , getPos ( ) . getY ( ) ) ;
} else {
setPos ( objPos . getX ( ) - BLOCK_SIZE , getPos ( ) . getY ( ) ) ;
}
2021-05-22 21:13:26 +00:00
}
2021-08-04 22:32:17 +00:00
# endif
2021-05-22 21:13:26 +00:00
}
2021-05-22 21:54:01 +00:00
void Mario : : jump ( ) {
if ( ! on_ground )
return ;
jumping = true ;
stop_jump = false ;
max_jump = getPos ( ) . getY ( ) - 3 * BLOCK_SIZE ;
min_jump = getPos ( ) . getY ( ) - 1 * BLOCK_SIZE ;
slow_jump = getPos ( ) . getY ( ) - 2 * BLOCK_SIZE ;
2021-05-23 21:32:15 +00:00
addMovement ( 0 , - jump_movement ) ;
ticks_till_gravity = base_gravity_ticks ;
2021-05-23 21:45:45 +00:00
setTextureSourceRect ( MARIO_JUMP_SRC ) ;
pauseAnimation ( ) ;
2021-05-22 21:54:01 +00:00
}
void Mario : : stopJump ( ) {
stop_jump = true ;
}
2021-05-23 21:32:15 +00:00
void Mario : : custom_move ( int ticks ) {
if ( ! jumping & & on_ground )
return ;
if ( getMovement ( ) . getY ( ) > = 1.0625 * jump_movement )
return ;
ticks_till_gravity - = ticks ;
if ( ticks_till_gravity < 0 ) {
if ( getMovement ( ) . getY ( ) > 0 ) {
jumping = false ;
addMovement ( 0 , gravity_add_jumping ) ;
} else {
if ( stop_jump ) {
addMovement ( 0 , gravity_add_falling ) ;
} else {
addMovement ( 0 , gravity_add_jumping ) ;
}
}
ticks_till_gravity + = base_gravity_ticks ;
}
}
2021-07-22 22:08:05 +00:00
void Mario : : visit ( SDLPP : : Visitor & /*UNUSED*/ ) {
// TODO
}
void Mario : : setWorldTypeSrc ( LandType : : Value /*UNUSED*/ ) {
// TODO
}