From 434b73226ef6ba1fa577d6f420dc903a7adadd25 Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Sun, 10 Nov 2024 01:17:53 +0000
Subject: [PATCH] Add helper functions and set_x_movement in state functions

---
 player.c | 114 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 75 insertions(+), 39 deletions(-)

diff --git a/player.c b/player.c
index 843ee2e..1a33eb9 100644
--- a/player.c
+++ b/player.c
@@ -11,13 +11,19 @@
 #define SPRITE_WIDTH 100
 #define SPRITE_HEIGHT 64
 
-void  get_player_controls(Player *player);
-State *update_state      (Player *player, uint32_t state);
-State *idle_state        (StateMachine *sm, Player *player);
-State *walk_state        (StateMachine *sm, Player *player);
-State *dash_state        (StateMachine *sm, Player *player);
-State *jump_state        (StateMachine *sm, Player *player);
-State *fall_state        (StateMachine *sm, Player *player);
+void    get_player_controls(Player *player);
+void    set_x_movement     (Player *player);
+void    player_dash        (Player *player);
+void    player_jump        (Player *player);
+void    player_fall        (Player *player);
+int32_t player_gravity     (Player *player);
+bool    player_on_ground   (Player *player);
+State   *update_state      (Player *player, uint32_t state);
+State   *idle_state        (StateMachine *sm, Player *player);
+State   *walk_state        (StateMachine *sm, Player *player);
+State   *dash_state        (StateMachine *sm, Player *player);
+State   *jump_state        (StateMachine *sm, Player *player);
+State   *fall_state        (StateMachine *sm, Player *player);
 
 void player_init(Player *player, SDL_Renderer *renderer, SDL_Rect position) {
 	player->base_y      = position.y;
@@ -50,17 +56,6 @@ void player_init(Player *player, SDL_Renderer *renderer, SDL_Rect position) {
 
 void player_update(Player *player, uint32_t ticks) {
 	get_player_controls(player);
-
-	if (player->controls.walk_left) {
-		player->movement.x  = PLAYER_DIRECTION_LEFT * player->velocity;
-		player->x_direction = PLAYER_DIRECTION_LEFT;
-	} else if (player->controls.walk_right) {
-		player->movement.x  = PLAYER_DIRECTION_RIGHT * player->velocity;
-		player->x_direction = PLAYER_DIRECTION_RIGHT;
-	} else if (!(player->controls.walk_left) && !(player->controls.walk_right)) {
-		player->movement.x = 0;
-	}
-
 	sm_run(&(player->state_machine), (void *)player);
 
 	player->position.x += player->movement.x;
@@ -68,6 +63,7 @@ void player_update(Player *player, uint32_t ticks) {
 	if (player->position.y > player->base_y) {
 		player->position.y = player->base_y;
 	}
+
 	ap_update(&(player->animations[player->current_state]), ticks);
 }
 
@@ -90,6 +86,38 @@ void get_player_controls(Player *player) {
 	player->controls.dash          = player->controls.lctrl_last && !(player->controls.lctrl_pressed);
 }
 
+void set_x_movement(Player *player) {
+	if (player->controls.walk_left) {
+		player->movement.x  = PLAYER_DIRECTION_LEFT * player->velocity;
+		player->x_direction = PLAYER_DIRECTION_LEFT;
+	} else if (player->controls.walk_right) {
+		player->movement.x  = PLAYER_DIRECTION_RIGHT * player->velocity;
+		player->x_direction = PLAYER_DIRECTION_RIGHT;
+	} else if (!(player->controls.walk_left) && !(player->controls.walk_right)) {
+		player->movement.x = 0;
+	}
+}
+
+void player_dash(Player *player) {
+	player->movement.x = player->x_direction * player->velocity * 2;
+}
+
+void player_jump(Player *player) {
+	player->movement.y = player->velocity * 6 * -1;
+}
+
+void player_fall(Player *player) {
+	player->movement.y = player->velocity * 6;
+}
+
+int32_t player_gravity(Player *player) {
+	return player->velocity * 0.5;
+}
+
+bool player_on_ground(Player *player) {
+	return player->position.y == player->base_y;
+}
+
 State *update_state(Player *player, uint32_t state) {
 	if (state >= COUNT_PLAYER_STATES) {
 		return &(player->states[player->current_state]);
@@ -103,14 +131,16 @@ State *idle_state(StateMachine *sm, Player *player) {
 	uint32_t state = PLAYER_STATE_IDLE;
 
 	if (player->controls.jump) {
-		player->movement.y = player->velocity * 6 * -1;
-		state              = PLAYER_STATE_JUMP;
+		player_jump(player);
+		state = PLAYER_STATE_JUMP;
 	} else if (player->controls.walk_left) {
 		state = PLAYER_STATE_WALK;
 	} else if (player->controls.walk_right) {
 		state = PLAYER_STATE_WALK;
 	}
 
+	set_x_movement(player);
+
 	return update_state(player, state);
 }
 
@@ -118,18 +148,20 @@ State *walk_state(StateMachine *sm, Player *player) {
 	uint32_t state         = PLAYER_STATE_WALK;
 
 	if (player->controls.jump) {
-		player->movement.y = player->velocity * 6 * -1;
-		state              = PLAYER_STATE_JUMP;
+		player_jump(player);
+		state = PLAYER_STATE_JUMP;
 	} else if (player->controls.dash) {
-		player->controls.dash_in_air = false;
-		player->movement.x           = player->x_direction * player->velocity * 2;
-		state                        = PLAYER_STATE_DASH;
+		player_dash(player);
+		player->controls.jump_dash = false;
+		state                      = PLAYER_STATE_DASH;
 	}
 
 	if (!(player->controls.walk_left) && !(player->controls.walk_right)) {
 		state = PLAYER_STATE_IDLE;
 	}
 
+	set_x_movement(player);
+
 	return update_state(player, state);
 }
 
@@ -137,12 +169,12 @@ State *dash_state(StateMachine *sm, Player *player) {
 	bool reset     = false;
 	uint32_t state = PLAYER_STATE_DASH;
 
-	player->movement.x += player->x_direction * 20;
+	player->movement.x += player->x_direction * (int32_t)player->velocity * 0.5;
 
 	if (player->animations[PLAYER_STATE_DASH].finished) {
-		if (player->controls.dash_in_air) {
-			player->movement.y = player->velocity * 6;
-			state              = PLAYER_STATE_FALL;
+		if (player->controls.jump_dash) {
+			player_fall(player);
+			state = PLAYER_STATE_FALL;
 		} else {
 			player->movement.x = 0;
 			state              = PLAYER_STATE_IDLE;
@@ -162,24 +194,26 @@ State *jump_state(StateMachine *sm, Player *player) {
 	bool reset     = false;
 	uint32_t state = PLAYER_STATE_JUMP;
 
-	player->movement.y += player->velocity * 0.5;
+	player->movement.y += player_gravity(player);
 
 	if (player->controls.dash) {
-		player->controls.dash_in_air = true;
-		player->movement.x           = player->x_direction * player->velocity * 2;
-		player->movement.y           = player->velocity * 0.5;
-		reset                        = true;
-		state                        = PLAYER_STATE_DASH;
+		player_dash(player);
+		player->controls.jump_dash = true;
+		player->movement.y         = player_gravity(player);
+		reset                      = true;
+		state                      = PLAYER_STATE_DASH;
 	} else if (player->animations[PLAYER_STATE_JUMP].finished) {
-		player->movement.y = player->velocity * 6;
-		reset              = true;
-		state              = PLAYER_STATE_FALL;
+		player_fall(player);
+		reset = true;
+		state = PLAYER_STATE_FALL;
 	}
 
 	if (reset) {
 		ap_reset(&(player->animations[PLAYER_STATE_JUMP]));
 	}
 
+	set_x_movement(player);
+
 	return update_state(player, state);
 }
 
@@ -187,7 +221,7 @@ State *fall_state(StateMachine *sm, Player *player) {
 	bool reset     = false;
 	uint32_t state = PLAYER_STATE_FALL;
 
-	if (player->animations[PLAYER_STATE_FALL].finished) {
+	if (player->animations[PLAYER_STATE_FALL].finished || player_on_ground(player)) {
 		player->movement.y = 0;
 		reset              = true;
 		state              = PLAYER_STATE_IDLE;
@@ -197,5 +231,7 @@ State *fall_state(StateMachine *sm, Player *player) {
 		ap_reset(&(player->animations[PLAYER_STATE_FALL]));
 	}
 
+	set_x_movement(player);
+
 	return update_state(player, state);
 }