diff --git a/.gitignore b/.gitignore index 33d67bd..5d1da0b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ enc_temp_folder/ *.spall # profiling *.bin # world files debug_world.bin +no-suns.bin flight*.zip flight_server flight.zip diff --git a/buildsettings.h b/buildsettings.h index 835875f..6a52a6b 100644 --- a/buildsettings.h +++ b/buildsettings.h @@ -26,8 +26,8 @@ #define DEBUG_TOOLS #define CHIPMUNK_INTEGRITY_CHECK // #define FAT_THRUSTERS -// #define NO_GRAVITY -// #define NO_SUNS +#define NO_GRAVITY +#define NO_SUNS #else diff --git a/flight.rdbg b/flight.rdbg index 74c7381..30d4cfe 100644 Binary files a/flight.rdbg and b/flight.rdbg differ diff --git a/gamestate.c b/gamestate.c index 3d2ea03..91e379a 100644 --- a/gamestate.c +++ b/gamestate.c @@ -724,6 +724,64 @@ void fill_time_string(char *to_fill, size_t max_length) // to_fill[filled_length - 4] = '\0'; // remove the newline } +Entity *grid_box_at_local_pos(GameState *gs, Entity *grid, cpVect wanted_local_pos) +{ + Entity *box_in_direction = NULL; + BOXES_ITER(gs, cur, grid) + { + if (cpvnear(entity_shape_pos(cur), wanted_local_pos, 0.01)) + { + box_in_direction = cur; + break; + } + } + if (box_in_direction != NULL) + flight_assert(box_in_direction->is_box); + if (box_in_direction != NULL) + flight_assert(box_grid(box_in_direction) == grid); + return box_in_direction; +} + +bool merge_box_is_merged(GameState *gs, Entity *merge_box) +{ + flight_assert(merge_box->is_box); + flight_assert(merge_box->box_type == BoxMerge); + cpVect facing = box_compass_vector(merge_box); + Entity *potentially_merged_with = grid_box_at_local_pos(gs, box_grid(merge_box), cpvadd(entity_shape_pos(merge_box), cpvmult(facing, BOX_SIZE))); + if (potentially_merged_with != NULL && cpvnear(box_compass_vector(potentially_merged_with), cpvmult(facing, -1.0), 0.01)) + { + return true; + } + else + { + return false; + } +} +bool box_interactible(GameState *gs, Player *for_player, Entity *box) +{ + flight_assert(box->is_box); + + if (box->box_type == BoxCockpit || box->box_type == BoxMedbay) + { + return true; + } + else + { + if (box->box_type == BoxMerge) + { + return merge_box_is_merged(gs, box); + } + else if (box->box_type == BoxScanner) + { + return (for_player->box_unlocks | box->blueprints_learned) != for_player->box_unlocks; + } + else + { + return false; + } + } +} + // removes boxes from grid, then ensures that the rule that grids must not have // holes in them is applied. static void grid_correct_for_holes(GameState *gs, struct Entity *grid) @@ -803,20 +861,13 @@ static void grid_correct_for_holes(GameState *gs, struct Entity *grid) // @Robust @Speed faster method, not O(N^2), of getting the box // in the direction currently needed cpVect compass_vect = box_compass_vector(N); - if (N->box_type == BoxMerge && N->wants_disconnect && cpvnear(compass_vect, dir, 0.01)) + if (N->box_type == BoxMerge && N->wants_disconnect && cpvnear(compass_vect, dir, 0.01) && merge_box_is_merged(gs, N)) { } else { cpVect wanted_local_pos = cpvadd(cur_local_pos, cpvmult(dir, BOX_SIZE)); - BOXES_ITER(gs, cur, grid) - { - if (cpvnear(entity_shape_pos(cur), wanted_local_pos, 0.01)) - { - box_in_direction = get_id(gs, cur); - break; - } - } + box_in_direction = get_id(gs, grid_box_at_local_pos(gs, grid, wanted_local_pos)); } Entity *newbox = get_entity(gs, box_in_direction); @@ -2555,14 +2606,14 @@ 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 + // the button prompt still works if (potential_seat->box_type == BoxScanner) // learn everything from the scanner { - flight_assert(box_interactible(potential_seat->box_type)); player->box_unlocks |= potential_seat->blueprints_learned; } if (potential_seat->box_type == BoxMerge) // disconnect! { - flight_assert(box_interactible(potential_seat->box_type)); potential_seat->wants_disconnect = true; grid_correct_for_holes(gs, box_grid(potential_seat)); flight_assert(potential_seat->exists); @@ -2571,7 +2622,6 @@ void process(struct GameState *gs, double dt) } if (potential_seat->box_type == BoxCockpit || potential_seat->box_type == BoxMedbay) { - flight_assert(box_interactible(potential_seat->box_type)); // don't let players get inside of cockpits that somebody else is already inside of if (get_entity(gs, potential_seat->player_who_is_inside_of_me) == NULL) { @@ -3191,22 +3241,27 @@ void process(struct GameState *gs, double dt) { rel_vect = cpvmult(cpvnormalize(rel_vect), SCANNER_MAX_RANGE); } - + enum ScannerPointKind kind = Platonic; - Entity *body_entity =cp_body_entity(body_results[i]) ; - if(body_entity->is_grid) { + Entity *body_entity = cp_body_entity(body_results[i]); + if (body_entity->is_grid) + { kind = Neutral; BOXES_ITER(gs, cur_potential_platonic, body_entity) { - if(cur_potential_platonic->is_platonic) + if (cur_potential_platonic->is_platonic) { kind = Platonic; break; } } - } else if(body_entity->is_player) { + } + else if (body_entity->is_player) + { kind = Neutral; - } else { + } + else + { kind = Enemy; } cur_box->scanner_points[i] = (struct ScannerPoint){ diff --git a/main.c b/main.c index 7aeb30b..ae23189 100644 --- a/main.c +++ b/main.c @@ -734,6 +734,22 @@ static void draw_texture_centered(cpVect center, double size) { draw_texture_rectangle_centered(center, (cpVect){size, size}); } +static void draw_flipped_texture_rectangle_centered(cpVect center, cpVect width_height) +{ + transform_scope() + { + scale_at(1.0, -1.0, center.x, center.y); + draw_texture_rectangle_centered(center, width_height); + } +} +static void draw_flipped_texture_centered(cpVect center, double size) +{ + transform_scope() + { + scale_at(1.0, -1.0, center.x, center.y); + draw_texture_centered(center, size); + } +} sgp_point V2point(cpVect v) { @@ -827,14 +843,9 @@ static void ui(bool draw, double dt, double width, double height) set_color_values(1.0, 1.0, 1.0, alpha); sgp_set_image(0, image_rothelp); - cpVect draw_at = cpv(width / 2.0, height * 0.25); - transform_scope() - { - scale_at(1.0, -1.0, draw_at.x, draw_at.y); - pipeline_scope(goodpixel_pipeline) - draw_texture_centered(draw_at, 200.0); - sgp_reset_image(0); - } + pipeline_scope(goodpixel_pipeline) + draw_flipped_texture_centered(cpv(width / 2.0, height * 0.25), 200.0); + sgp_reset_image(0); } // zooming zoomeasy @@ -842,14 +853,9 @@ static void ui(bool draw, double dt, double width, double height) double alpha = 1.0 - clamp01(zoomeasy_learned); set_color_values(1.0, 1.0, 1.0, alpha); sgp_set_image(0, image_zoomeasyhelp); - cpVect draw_at = cpv(width * 0.1, height * 0.5); - transform_scope() - { - scale_at(1.0, -1.0, draw_at.x, draw_at.y); - pipeline_scope(goodpixel_pipeline) - draw_texture_centered(draw_at, 200.0); - sgp_reset_image(0); - } + pipeline_scope(goodpixel_pipeline) + draw_flipped_texture_centered(cpv(width * 0.1, height * 0.5), 200.0); + sgp_reset_image(0); } } @@ -941,13 +947,9 @@ static void ui(bool draw, double dt, double width, double height) { sgp_set_image(0, image_mystery); } - transform_scope() - { - scale_at(1.0, -1.0, item_x + item_width / 2.0, item_y + item_height / 2.0); - pipeline_scope(goodpixel_pipeline) - draw_textured_rect(item_x, item_y, item_width, item_height); - sgp_reset_image(0); - } + pipeline_scope(goodpixel_pipeline) + draw_flipped_texture_rectangle_centered(cpv(item_x + item_width / 2.0, item_y + item_width / 2.0), cpv(item_width, item_height)); + sgp_reset_image(0); } cur_column++; @@ -998,45 +1000,32 @@ static void ui(bool draw, double dt, double width, double height) if (invited) draw_as_squad = myentity()->squad_invited_to; - transform_scope() + pipeline_scope(hueshift_pipeline) { - pipeline_scope(hueshift_pipeline) - { - set_color_values(1.0, 1.0, 1.0, 1.0); - sgp_set_image(0, image_squad_invite); - setup_hueshift(draw_as_squad); - scale_at(1.0, -1.0, x, - invite_y); // images upside down by default :( - draw_texture_centered((cpVect){x, invite_y}, size); - sgp_reset_image(0); - } + set_color_values(1.0, 1.0, 1.0, 1.0); + sgp_set_image(0, image_squad_invite); + setup_hueshift(draw_as_squad); + draw_flipped_texture_centered(cpv(x, invite_y), size); + sgp_reset_image(0); } // yes - transform_scope() + set_color_values(1.0, 1.0, 1.0, 1.0); + sgp_set_image(0, image_check); + pipeline_scope(goodpixel_pipeline) { - set_color_values(1.0, 1.0, 1.0, 1.0); - scale_at(1.0, -1.0, yes_x, buttons_y); - sgp_set_image(0, image_check); - pipeline_scope(goodpixel_pipeline) - { - draw_texture_centered((cpVect){yes_x, buttons_y}, yes_size); - } - sgp_reset_image(0); + draw_flipped_texture_centered(cpv(yes_x, buttons_y), yes_size); } + sgp_reset_image(0); // no - transform_scope() + set_color_values(1.0, 1.0, 1.0, 1.0); + sgp_set_image(0, image_no); + pipeline_scope(goodpixel_pipeline) { - set_color_values(1.0, 1.0, 1.0, 1.0); - scale_at(1.0, -1.0, no_x, buttons_y); - sgp_set_image(0, image_no); - pipeline_scope(goodpixel_pipeline) - { - draw_texture_centered((cpVect){no_x, buttons_y}, no_size); - } - sgp_reset_image(0); + draw_flipped_texture_centered(cpv(no_x, buttons_y), no_size); } + sgp_reset_image(0); } } @@ -1050,16 +1039,9 @@ static void ui(bool draw, double dt, double width, double height) draw_circle(pos, 28.0 + sin(exec_time * 5.0) * 6.5); sgp_set_image(0, image_rightclick); - - cpVect draw_at = cpvadd(pos, cpv(0, 50.0)); - - transform_scope() + pipeline_scope(goodpixel_pipeline) { - pipeline_scope(goodpixel_pipeline) - { - scale_at(1.0, -1.0, draw_at.x, draw_at.y); - draw_texture_centered(draw_at, 100.0 + sin(exec_time * 5.0) * 10.0); - } + draw_flipped_texture_centered(cpvadd(pos, cpv(0, 50.0)), 100.0 + sin(exec_time * 5.0) * 10.0); } sgp_reset_image(0); @@ -1084,28 +1066,24 @@ static void ui(bool draw, double dt, double width, double height) confirm_invite_this_player = true; } if (draw) - transform_scope() - { - const double size = 64.0; - - if (selecting_to_invite) - { - set_color_values(0.5, 0.5, 0.5, 0.4); - draw_filled_rect(pos.x - size / 2.0, pos.y - size / 2.0, size, - size); - set_color_values(1.0, 1.0, 1.0, 1.0); - } - pipeline_scope(hueshift_pipeline) - { - setup_hueshift(myplayer()->squad); + { + const double size = 64.0; - scale_at(1.0, -1.0, pos.x, - pos.y); // images upside down by default :( - sgp_set_image(0, image_squad_invite); - draw_texture_centered(pos, size); - sgp_reset_image(0); - } + if (selecting_to_invite) + { + set_color_values(0.5, 0.5, 0.5, 0.4); + draw_filled_rect(pos.x - size / 2.0, pos.y - size / 2.0, size, + size); + set_color_values(1.0, 1.0, 1.0, 1.0); } + pipeline_scope(hueshift_pipeline) + { + setup_hueshift(myplayer()->squad); + sgp_set_image(0, image_squad_invite); + draw_flipped_texture_centered(pos, size); + sgp_reset_image(0); + } + } } } @@ -1224,9 +1202,7 @@ static void ui(bool draw, double dt, double width, double height) setup_hueshift(this_squad); rotate_at(flag_rot[i], flag_pos[i].x, flag_pos[i].y); - scale_at(1.0, -1.0, flag_pos[i].x, - flag_pos[i].y); // images upside down by default :( - draw_texture_centered(flag_pos[i], size); + draw_flipped_texture_centered(flag_pos[i], size); sgp_reset_image(0); } @@ -1266,9 +1242,7 @@ static void ui(bool draw, double dt, double width, double height) sgp_set_image(0, image_mic_unmuted); transform_scope() { - scale_at(1.0, -1.0, button.x + button.width / 2.0, - button.y + button.height / 2.0); - draw_textured_rect(button.x, button.y, button.width, button.height); + draw_flipped_texture_rectangle_centered(cpv(button.x + button.width / 2.0, button.y + button.height / 2.0), cpv(button.width, button.height)); sgp_reset_image(0); } } @@ -1348,8 +1322,6 @@ static void ui(bool draw, double dt, double width, double height) { double item_x = x + item_offset_x; double item_y = y + item_offset_y; - scale_at(1.0, -1.0, item_x + item_width / 2.0, - item_y + item_height / 2.0); pipeline_scope(goodpixel_pipeline) { @@ -1360,7 +1332,7 @@ static void ui(bool draw, double dt, double width, double height) sgp_set_image(0, info.image); else sgp_set_image(0, image_mystery); - draw_textured_rect(item_x, item_y, item_width, item_height); + draw_flipped_texture_rectangle_centered(cpv(item_x + item_width / 2.0, item_y + item_height / 2.0), cpv(item_width, item_height)); sgp_reset_image(0); } @@ -1371,7 +1343,7 @@ static void ui(bool draw, double dt, double width, double height) double switch_item_height = item_height * switch_scaling; item_x -= (switch_item_width - item_width) / 2.0; item_y -= (switch_item_height - item_height) / 2.0; - draw_textured_rect(item_x, item_y + 20.0, switch_item_width, switch_item_height); + draw_flipped_texture_rectangle_centered(cpv(item_x + switch_item_width / 2.0, item_y - 20.0 + switch_item_height / 2.0), cpv(switch_item_width, switch_item_height)); sgp_reset_image(0); } } @@ -2090,7 +2062,7 @@ static void frame(void) set_color_values(1.0, 1.0, 1.0, 1.0 - b->sun_amount); } - if (box_interactible(b->box_type)) + if (myplayer() != NULL && box_interactible(&gs, myplayer(), b)) { if (box_has_point((BoxCentered){ .pos = entity_pos(b), @@ -2225,28 +2197,27 @@ static void frame(void) sgp_set_image(0, image_radardot); for (int i = 0; i < SCANNER_MAX_POINTS; i++) { - if(b->scanner_points[i].x != 0 && b->scanner_points[i].y != 0) + if (b->scanner_points[i].x != 0 && b->scanner_points[i].y != 0) { struct ScannerPoint point = b->scanner_points[i]; - switch(point.kind) + switch (point.kind) { - case Platonic: - set_color(GOLD); - break; - case Neutral: - set_color(WHITE); - break; - case Enemy: - set_color(RED); - break; - default: - set_color(WHITE); // @Robust assert false in serialization if unexpected kind - break; + case Platonic: + set_color(GOLD); + break; + case Neutral: + set_color(WHITE); + break; + case Enemy: + set_color(RED); + break; + default: + set_color(WHITE); // @Robust assert false in serialization if unexpected kind + break; } cpVect rel = cpv( - ((double)point.x / 128.0) * SCANNER_RADIUS, - ((double)point.y / 128.0) * SCANNER_RADIUS - ); + ((double)point.x / 128.0) * SCANNER_RADIUS, + ((double)point.y / 128.0) * SCANNER_RADIUS); cpVect to = cpvadd(entity_pos(b), rel); dbg_rect(to); dbg_rect(entity_pos(b)); diff --git a/types.h b/types.h index 4752c8b..d2b9b44 100644 --- a/types.h +++ b/types.h @@ -188,20 +188,6 @@ enum BoxType BoxLast, }; -static inline bool box_interactible(enum BoxType type) -{ - enum BoxType types[] = { - BoxCockpit, - BoxMedbay, - BoxMerge, - BoxScanner, - }; - for (int i = 0; i < ARRLEN(types); i++) - if (types[i] == type) - return true; - return false; -} - enum CompassRotation { Right, @@ -507,6 +493,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_interactible(GameState *gs, Player *for_player, Entity *box); void entity_set_rotation(Entity *e, double rot); void entity_set_pos(Entity *e, cpVect pos); double entity_rotation(Entity *e);