diff --git a/engine/EC/components.h b/engine/EC/components.h index 5e50f8d..c9ddcfc 100644 --- a/engine/EC/components.h +++ b/engine/EC/components.h @@ -38,7 +38,6 @@ typedef struct _CTransform_t { typedef struct _CMovementState_t { uint8_t ground_state; uint8_t water_state; - bool ladder_state; } CMovementState_t; // This is to store the occupying tiles @@ -67,6 +66,7 @@ typedef struct _CPlayerState_t { Vector2 player_dir; uint8_t jump_pressed; uint8_t is_crouch; + bool ladder_state; } CPlayerState_t; typedef enum ContainerItem { diff --git a/engine/editor_scene.c b/engine/editor_scene.c index 544e498..c49d6cc 100644 --- a/engine/editor_scene.c +++ b/engine/editor_scene.c @@ -52,10 +52,12 @@ static void level_scene_render_func(Scene_t* scene) { DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, ORANGE); } - else if (tilemap.tiles[i].water_level > 0) + + if (tilemap.tiles[i].water_level > 0) { // Draw water tile - DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, BLUE); + Color water_colour = ColorAlpha(BLUE, 0.5); + DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour); } } @@ -158,6 +160,8 @@ static void level_scene_render_func(Scene_t* scene) DrawText(buffer, tilemap.width * TILE_SIZE + 1, 90, 12, BLACK); sprintf(buffer, "Water: %s", p_mstate->water_state & 1? "YES":"NO"); DrawText(buffer, tilemap.width * TILE_SIZE + 1, 120, 12, BLACK); + sprintf(buffer, "Ladder: %u", p_pstate->ladder_state); + DrawText(buffer, tilemap.width * TILE_SIZE + 1, 150, 12, BLACK); } sprintf(buffer, "Spawn Entity: %u", current_spawn_selection); DrawText(buffer, tilemap.width * TILE_SIZE + 1, 240, 12, BLACK); @@ -266,7 +270,6 @@ static void toggle_block_system(Scene_t* scene) tilemap.tiles[tile_idx].tile_type = ONEWAY_TILE; tilemap.tiles[tile_idx].solid = ONE_WAY; } - tilemap.tiles[tile_idx].water_level = 0; break; case TOGGLE_LADDER: if (tilemap.tiles[tile_idx].tile_type == LADDER) @@ -292,7 +295,6 @@ static void toggle_block_system(Scene_t* scene) { tilemap.tiles[down_tile].solid = (tilemap.tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID; } - tilemap.tiles[tile_idx].water_level = 0; break; case SPAWN_CRATE: spawn_crate(scene, tile_idx, false); @@ -339,7 +341,6 @@ void level_do_action(Scene_t* scene, ActionType_t action, bool pressed) break; case ACTION_DOWN: p_playerstate->player_dir.y = (pressed)? 1 : 0; - //p_playerstate->is_crouch |= (pressed)? 0b10 : 0; break; case ACTION_LEFT: p_playerstate->player_dir.x = (pressed)? -1 : 0; diff --git a/engine/game_systems.c b/engine/game_systems.c index 6334079..7373a39 100644 --- a/engine/game_systems.c +++ b/engine/game_systems.c @@ -313,10 +313,85 @@ void player_movement_input_system(Scene_t* scene) CJump_t* p_cjump = get_component(&scene->ent_manager, p_player, CJUMP_COMP_T); CMovementState_t* p_mstate = get_component(&scene->ent_manager, p_player, CMOVEMENTSTATE_T); + // Ladder handling + if (!p_pstate->ladder_state) + { + if (p_pstate->player_dir.y < 0) + { + unsigned int tile_idx = get_tile_idx( + p_ctransform->position.x + p_bbox->half_size.x, + p_ctransform->position.y + p_bbox->half_size.y, + data->tilemap.width + ); + if (tilemap.tiles[tile_idx].tile_type == LADDER) + { + p_pstate->ladder_state = true; + + //p_ctransform->position.x = (tile_idx % tilemap.width) * TILE_SIZE; + if (p_mstate->ground_state & 1) + { + p_ctransform->position.y--; + } + } + } + else if (p_pstate->player_dir.y > 0) + { + unsigned int tile_idx; + + if (p_mstate->ground_state & 1) + { + tile_idx = get_tile_idx( + p_ctransform->position.x + p_bbox->half_size.x, + p_ctransform->position.y + p_bbox->size.y, + data->tilemap.width + ); + } + else + { + tile_idx = get_tile_idx( + p_ctransform->position.x + p_bbox->half_size.x, + p_ctransform->position.y + p_bbox->half_size.y, + data->tilemap.width + ); + } + if (tile_idx < tilemap.n_tiles && tilemap.tiles[tile_idx].tile_type == LADDER) + { + p_pstate->ladder_state = true; + //p_ctransform->position.x = (tile_idx % tilemap.width) * TILE_SIZE; + if (p_mstate->ground_state & 1) + { + p_ctransform->position.y += TILE_SIZE / 2; + } + } + } + } + else + { + unsigned int tile_x = (p_ctransform->position.x + p_bbox->half_size.x) / TILE_SIZE; + unsigned int tile_y1 = (p_ctransform->position.y + p_bbox->half_size.y) / TILE_SIZE; + unsigned int tile_y2 = (p_ctransform->position.y + p_bbox->size.y) / TILE_SIZE; + + p_pstate->ladder_state = false; + if (!(p_mstate->ground_state & 1)) + { + for(unsigned int tile_y = tile_y1; tile_y <= tile_y2; tile_y++) + { + unsigned int tile_idx = tile_y * tilemap.width + tile_x; + p_pstate->ladder_state |= tilemap.tiles[tile_idx].tile_type == LADDER; + } + } + if (p_pstate->ladder_state) + { + p_ctransform->velocity.y = p_pstate->player_dir.y * 150; + p_ctransform->velocity.x = p_pstate->player_dir.x * 40; + } + } + bool in_water = (p_mstate->water_state & 1); + p_pstate->is_crouch |= (p_pstate->player_dir.y > 0)? 0b10 : 0; if (!in_water) { - p_pstate->is_crouch |= (p_pstate->player_dir.y > 0)? 0b10 : 0; + p_pstate->player_dir.y = 0; p_ctransform->accel = Vector2Scale(Vector2Normalize(p_pstate->player_dir), MOVE_ACCEL); } @@ -368,10 +443,18 @@ void player_movement_input_system(Scene_t* scene) // Check if possible to jump when jump is pressed if (p_pstate->jump_pressed && p_cjump->jumps > 0 && p_cjump->jump_ready) { + p_pstate->ladder_state = false; p_cjump->jumps--; if (!in_water) { - p_ctransform->velocity.y = -p_cjump->jump_speed; + if (p_mstate->ground_state & 1) + { + p_ctransform->velocity.y = -p_cjump->jump_speed; + } + else + { + p_ctransform->velocity.y = -p_cjump->jump_speed / 1.4; + } } else { @@ -419,7 +502,7 @@ void player_bbox_update_system(Scene_t* scene) } else { - if (p_mstate->water_state & 1) + if ((p_mstate->water_state & 1) && !p_pstate->ladder_state) { new_bbox.x = PLAYER_C_WIDTH; new_bbox.y = PLAYER_C_HEIGHT; @@ -704,6 +787,16 @@ void global_external_forces_system(Scene_t* scene) } } + CPlayerState_t* p_pstate; + sc_map_foreach(&scene->ent_manager.component_map[CPLAYERSTATE_T], ent_idx, p_pstate) + { + Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx); + CTransform_t* p_ctransform = get_component(&scene->ent_manager, p_ent, CTRANSFORM_COMP_T); + if (p_pstate->ladder_state) + { + p_ctransform->accel = (Vector2){0,0}; + } + } } void movement_update_system(Scene_t* scene) @@ -753,7 +846,7 @@ void player_ground_air_transition_system(Scene_t* scene) // Handle Ground<->Air Transition bool in_water = (p_mstate->water_state & 1); // Landing or in water - if ((p_mstate->ground_state & 1 || in_water) && !p_pstate->jump_pressed ) + if ((p_mstate->ground_state & 1 || in_water || p_pstate->ladder_state) && !p_pstate->jump_pressed ) { // Recover jumps p_cjump->jumps = p_cjump->max_jumps;