diff --git a/gamestate.c b/gamestate.c index e5fb6d3..6758c90 100644 --- a/gamestate.c +++ b/gamestate.c @@ -815,24 +815,22 @@ bool could_learn_from_scanner(Player *for_player, Entity *box) return (for_player->box_unlocks | box->blueprints_learned) != for_player->box_unlocks; } +bool box_enterable(Entity *box) +{ + return box->box_type == BoxMedbay || box->box_type == BoxCockpit; +} + bool box_interactible(GameState *gs, Player *for_player, Entity *box) { flight_assert(box->is_box); - if (box->box_type == BoxCockpit || box->box_type == BoxMedbay) + if (box->box_type == BoxMerge) { - return true; + return merge_box_is_merged(gs, box); } else { - if (box->box_type == BoxMerge) - { - return merge_box_is_merged(gs, box); - } - else - { - return false; - } + return false; } } @@ -1399,6 +1397,7 @@ SerMaybeFailure ser_inputframe(SerState *ser, InputFrame *i) SER_MAYBE_RETURN(ser_entityid(ser, &i->invite_this_player)); SER_VAR(&i->seat_action); + SER_VAR(&i->interact_action); SER_MAYBE_RETURN(ser_fV2(ser, &i->hand_pos)); SER_VAR(&i->dobuild); @@ -2571,6 +2570,7 @@ void create_initial_world(GameState *gs) #endif // debug world } +// does not actually set seat in variables so can be used on respawn void exit_seat(GameState *gs, Entity *seat_in, Entity *p) { cpVect pilot_seat_exit_spot = cpvadd(entity_pos(seat_in), cpvmult(box_facing_vector(seat_in), BOX_SIZE)); @@ -2727,7 +2727,31 @@ void process(struct GameState *gs, double dt) p->damage = 0.0; #endif #if 1 + cpVect world_hand_pos = get_world_hand_pos(gs, &player->input, p); + if(player->input.interact_action) + { + player->input.interact_action = false; + cpPointQueryInfo query_info = {0}; + cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, FILTER_ONLY_BOXES, &query_info); + if (result != NULL) + { + Entity *potential_seat = cp_shape_entity(result); + flight_assert(potential_seat->is_box); + + // IMPORTANT: if you update these, make sure you update box_interactible so + // the button prompt still works + if (potential_seat->box_type == BoxMerge) // disconnect! + { + potential_seat->wants_disconnect = true; + grid_correct_for_holes(gs, box_grid(potential_seat)); + flight_assert(potential_seat->exists); + flight_assert(potential_seat->is_box); + flight_assert(potential_seat->box_type == BoxMerge); + } + } + } + if (player->input.seat_action) { player->input.seat_action = false; // "handle" the input @@ -2740,21 +2764,8 @@ void process(struct GameState *gs, double dt) { Entity *potential_seat = cp_shape_entity(result); flight_assert(potential_seat->is_box); - - // IMPORTANT: if you update these, make sure you update box_interactible so + // IMPORTANT: if you update these, make sure you update box_enterable so // the button prompt still works - if (potential_seat->box_type == BoxScanner) // learn everything from the scanner - { - player->box_unlocks |= potential_seat->blueprints_learned; - } - if (potential_seat->box_type == BoxMerge) // disconnect! - { - potential_seat->wants_disconnect = true; - grid_correct_for_holes(gs, box_grid(potential_seat)); - flight_assert(potential_seat->exists); - flight_assert(potential_seat->is_box); - flight_assert(potential_seat->box_type == BoxMerge); - } if (potential_seat->box_type == BoxCockpit || potential_seat->box_type == BoxMedbay) { // don't let players get inside of cockpits that somebody else is already inside of diff --git a/loaded/enter_exit.png b/loaded/enter_exit.png index cfe6720..e5a360b 100644 Binary files a/loaded/enter_exit.png and b/loaded/enter_exit.png differ diff --git a/main.c b/main.c index 4460e16..358f393 100644 --- a/main.c +++ b/main.c @@ -1695,6 +1695,7 @@ static void frame(void) build_pressed = mousepressed[SAPP_MOUSEBUTTON_LEFT].pressed; bool interact_pressed = mousepressed[SAPP_MOUSEBUTTON_RIGHT].pressed; + bool seat_pressed = keypressed[SAPP_KEYCODE_F].pressed; // networking PROFILE_SCOPE("networking") @@ -1923,7 +1924,10 @@ static void frame(void) } if (interact_pressed) - cur_input_frame.seat_action = interact_pressed; + cur_input_frame.interact_action = interact_pressed; + + if (seat_pressed) + cur_input_frame.seat_action = seat_pressed; cur_input_frame.hand_pos = local_hand_pos; if (take_over_squad >= 0) @@ -2410,7 +2414,9 @@ static void frame(void) set_color_values(1.0, 1.0, 1.0, 1.0 - b->sun_amount); } - if (myplayer() != NULL && box_interactible(&gs, myplayer(), b)) + bool interactible = box_interactible(&gs, myplayer(), b); + bool enterable = box_enterable(b); + if (myplayer() != NULL && interactible || enterable) { if (box_has_point((BoxCentered){ .pos = entity_pos(b), @@ -2425,7 +2431,15 @@ static void frame(void) { pipeline_scope(goodpixel_pipeline) { - sgp_set_image(0, image_rightclick); + if (interactible) + { + sgp_set_image(0, image_rightclick); + } + else + { + flight_assert(enterable); + sgp_set_image(0, image_enter_exit); + } cpVect draw_at = cpvadd(entity_pos(b), cpv(BOX_SIZE, 0)); rotate_at(-entity_rotation(b) - rotangle(b->compass_rotation), draw_at.x, draw_at.y); draw_texture_centered(draw_at, BOX_SIZE + sin(exec_time * 5.0) * BOX_SIZE * 0.1); diff --git a/types.h b/types.h index 5d86132..c34fcbd 100644 --- a/types.h +++ b/types.h @@ -250,6 +250,7 @@ typedef struct InputFrame bool reject_cur_squad_invite; EntityID invite_this_player; // null means inviting nobody! @Robust make it so just sends interact pos input, and server processes who to invite. This depends on client side prediction + proper input processing at the right tick. + bool interact_action; bool seat_action; cpVect hand_pos; // local to player transationally but not rotationally @@ -550,6 +551,7 @@ Entity *get_entity(struct GameState *gs, EntityID id); Entity *new_entity(struct GameState *gs); EntityID get_id(struct GameState *gs, Entity *e); cpVect entity_pos(Entity *e); +bool box_enterable(Entity *box); bool box_interactible(GameState *gs, Player *for_player, Entity *box); void entity_set_rotation(Entity *e, double rot); bool could_learn_from_scanner(Player *for_player, Entity *box);