diff --git a/debugdraw.c b/debugdraw.c index 47607ff..58f8cf8 100644 --- a/debugdraw.c +++ b/debugdraw.c @@ -16,13 +16,13 @@ typedef struct Command union { // rect - V2 center; + cpVect center; // line struct { - V2 from; - V2 to; + cpVect from; + cpVect to; }; }; } Command; @@ -47,15 +47,15 @@ void dbg_drawall() { case rect: { - V2 center = commands[i].center; - V2 upper_left = cpvadd(center, (V2){.x = -size / 2.0, .y = -size / 2.0}); + cpVect center = commands[i].center; + cpVect upper_left = cpvadd(center, (cpVect){.x = -size / 2.0, .y = -size / 2.0}); sgp_draw_filled_rect((float)upper_left.x, (float)upper_left.y, (float)size, (float)size); break; } case line: { - V2 from = commands[i].from; - V2 to = commands[i].to; + cpVect from = commands[i].from; + cpVect to = commands[i].to; sgp_draw_line((float)from.x, (float)from.y, (float)to.x, (float)to.y); break; } @@ -65,7 +65,7 @@ void dbg_drawall() command_i = 0; } -void dbg_line(V2 from, V2 to) +void dbg_line(cpVect from, cpVect to) { commands[command_i] = (Command){ .type = line, @@ -76,7 +76,7 @@ void dbg_line(V2 from, V2 to) command_i %= MAX_COMMANDS; } -void dbg_rect(V2 center) +void dbg_rect(cpVect center) { commands[command_i] = (Command){ .type = rect, diff --git a/gamestate.c b/gamestate.c index 4f5ca7e..3c39378 100644 --- a/gamestate.c +++ b/gamestate.c @@ -193,8 +193,8 @@ void box_remove_from_boxes(GameState *gs, Entity *box) box->prev_box = (EntityID){0}; } -V2 player_vel(GameState *gs, Entity *e); -V2 entity_vel(GameState *gs, Entity *e) +cpVect player_vel(GameState *gs, Entity *e); +cpVect entity_vel(GameState *gs, Entity *e) { assert(e->is_box || e->is_player || e->body != NULL || e->is_explosion); if (e->is_box) @@ -206,7 +206,7 @@ V2 entity_vel(GameState *gs, Entity *e) if (e->is_explosion) return e->explosion_vel; assert(false); - return (V2){0}; + return (cpVect){0}; } static THREADLOCAL double to_face = 0.0; @@ -219,7 +219,7 @@ static void on_missile_shape(cpShape *shape, cpContactPointSet *points, void *da GameState *gs = entitys_gamestate(launcher); assert(other->is_box || other->is_player || other->is_missile); - V2 to = cpvsub(entity_pos(other), entity_pos(launcher)); + cpVect to = cpvsub(entity_pos(other), entity_pos(launcher)); bool should_attack = true; if (other->is_box && box_grid(other) == box_grid(launcher)) should_attack = false; @@ -232,14 +232,14 @@ static void on_missile_shape(cpShape *shape, cpContactPointSet *points, void *da nearest_dist = cpvlength(to); // lookahead by their velocity - V2 rel_velocity = cpvsub(entity_vel(gs, other), entity_vel(gs, launcher)); + cpVect rel_velocity = cpvsub(entity_vel(gs, other), entity_vel(gs, launcher)); double dist = cpvdist(entity_pos(other), entity_pos(launcher)); double time_of_travel = sqrt((2.0 * dist) / (MISSILE_BURN_FORCE / MISSILE_MASS)); - V2 other_future_pos = cpvadd(entity_pos(other), cpvmult(rel_velocity, time_of_travel)); + cpVect other_future_pos = cpvadd(entity_pos(other), cpvmult(rel_velocity, time_of_travel)); - V2 adjusted_to = cpvsub(other_future_pos, entity_pos(launcher)); + cpVect adjusted_to = cpvsub(other_future_pos, entity_pos(launcher)); to_face = cpvangle(adjusted_to); } @@ -338,7 +338,7 @@ Entity *new_entity(GameState *gs) } // pos, mass, radius -EntityID create_sun(GameState *gs, Entity *new_sun, V2 pos, V2 vel, double mass, double radius) +EntityID create_sun(GameState *gs, Entity *new_sun, cpVect pos, cpVect vel, double mass, double radius) { assert(new_sun != NULL); new_sun->is_sun = true; @@ -366,7 +366,7 @@ void create_body(GameState *gs, Entity *e) cpBodySetUserData(e->body, (void *)e); } -V2 player_vel(GameState *gs, Entity *player) +cpVect player_vel(GameState *gs, Entity *player) { assert(player->is_player); Entity *potential_seat = get_entity(gs, player->currently_inside_of_box); @@ -398,7 +398,7 @@ void entity_set_rotation(Entity *e, double rot) cpBodySetAngle(e->body, rot); } -void entity_set_pos(Entity *e, V2 pos) +void entity_set_pos(Entity *e, cpVect pos) { assert(e->is_grid); assert(e->body != NULL); @@ -406,7 +406,7 @@ void entity_set_pos(Entity *e, V2 pos) } // size is (1/2 the width, 1/2 the height) -void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, V2 pos, V2 size, double mass) +void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, cpVect pos, cpVect size, double mass) { if (e->shape != NULL) { @@ -453,7 +453,7 @@ void create_player(Player *player) void create_missile(GameState *gs, Entity *e) { create_body(gs, e); - create_rectangle_shape(gs, e, e, (V2){0}, cpvmult(MISSILE_COLLIDER_SIZE, 0.5), PLAYER_MASS); + create_rectangle_shape(gs, e, e, (cpVect){0}, cpvmult(MISSILE_COLLIDER_SIZE, 0.5), PLAYER_MASS); e->is_missile = true; } @@ -462,7 +462,7 @@ void create_player_entity(GameState *gs, Entity *e) e->is_player = true; e->no_save_to_disk = true; create_body(gs, e); - create_rectangle_shape(gs, e, e, (V2){0}, cpvmult(PLAYER_SIZE, 0.5), PLAYER_MASS); + create_rectangle_shape(gs, e, e, (cpVect){0}, cpvmult(PLAYER_SIZE, 0.5), PLAYER_MASS); cpShapeSetFilter(e->shape, PLAYER_SHAPE_FILTER); } @@ -479,7 +479,7 @@ void box_add_to_boxes(GameState *gs, Entity *grid, Entity *box_to_add) // box must be passed as a parameter as the box added to chipmunk uses this pointer in its // user data. pos is in local coordinates. Adds the box to the grid's chain of boxes -void box_create(GameState *gs, Entity *new_box, Entity *grid, V2 pos) +void box_create(GameState *gs, Entity *new_box, Entity *grid, cpVect pos) { new_box->is_box = true; assert(gs->space != NULL); @@ -487,18 +487,18 @@ void box_create(GameState *gs, Entity *new_box, Entity *grid, V2 pos) double halfbox = BOX_SIZE / 2.0; - create_rectangle_shape(gs, new_box, grid, pos, (V2){halfbox, halfbox}, 1.0); + create_rectangle_shape(gs, new_box, grid, pos, (cpVect){halfbox, halfbox}, 1.0); cpShapeSetFilter(new_box->shape, cpShapeFilterNew(CP_NO_GROUP, BOXES, CP_ALL_CATEGORIES)); box_add_to_boxes(gs, grid, new_box); } -V2 box_compass_vector(Entity *box) +cpVect box_compass_vector(Entity *box) { assert(box->is_box); - V2 to_return = (V2){.x = 1.0, .y = 0.0}; + cpVect to_return = (cpVect){.x = 1.0, .y = 0.0}; to_return = cpvspin(to_return, rotangle(box->compass_rotation)); return to_return; @@ -564,32 +564,32 @@ static void grid_correct_for_holes(GameState *gs, struct Entity *grid) cur_separate_grid_size++; processed_boxes++; - V2 cur_local_pos = entity_shape_pos(N); - const V2 dirs[] = { - (V2){ + cpVect cur_local_pos = entity_shape_pos(N); + const cpVect dirs[] = { + (cpVect){ .x = -1.0, .y = 0.0}, - (V2){ + (cpVect){ .x = 1.0, .y = 0.0}, - (V2){ + (cpVect){ .x = 0.0, .y = 1.0}, - (V2){ + (cpVect){ .x = 0.0, .y = -1.0}, }; int num_dirs = sizeof(dirs) / sizeof(*dirs); for (int ii = 0; ii < num_dirs; ii++) { - V2 dir = dirs[ii]; + cpVect dir = dirs[ii]; EntityID box_in_direction = (EntityID){0}; // @Robust @Speed faster method, not O(N^2), of getting the box // in the direction currently needed - V2 compass_vect = box_compass_vector(N); + cpVect compass_vect = box_compass_vector(N); if (N->box_type == BoxMerge && N->wants_disconnect && cpvnear(compass_vect, dir, 0.01)) { } else { - V2 wanted_local_pos = cpvadd(cur_local_pos, cpvmult(dir, BOX_SIZE)); + 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)) @@ -696,7 +696,7 @@ static void on_damage(cpArbiter *arb, cpSpace *space, cpDataPointer userData) for (int i = 0; i < count; i++) { cpVect collision_point = getPointFunc(arb, i); - V2 local_collision_point = (cpBodyWorldToLocal(missile->body, collision_point)); + cpVect local_collision_point = (cpBodyWorldToLocal(missile->body, collision_point)); if (local_collision_point.x > MISSILE_COLLIDER_SIZE.x * 0.2) { missile->damage += MISSILE_DAMAGE_THRESHOLD * 2.0; @@ -761,28 +761,28 @@ void destroy(GameState *gs) gs->cur_next_entity = 0; } // center of mass, not the literal position -V2 grid_com(Entity *grid) +cpVect grid_com(Entity *grid) { return (cpBodyLocalToWorld(grid->body, cpBodyGetCenterOfGravity(grid->body))); } -V2 grid_vel(Entity *grid) +cpVect grid_vel(Entity *grid) { return (cpBodyGetVelocity(grid->body)); } -V2 grid_world_to_local(Entity *grid, V2 world) +cpVect grid_world_to_local(Entity *grid, cpVect world) { return (cpBodyWorldToLocal(grid->body, (world))); } -V2 grid_local_to_world(Entity *grid, V2 local) +cpVect grid_local_to_world(Entity *grid, cpVect local) { assert(grid->is_grid); return (cpBodyLocalToWorld(grid->body, (local))); } // returned snapped position is in world coordinates -V2 grid_snapped_box_pos(Entity *grid, V2 world) +cpVect grid_snapped_box_pos(Entity *grid, cpVect world) { - V2 local = grid_world_to_local(grid, world); + cpVect local = grid_world_to_local(grid, world); local.x /= BOX_SIZE; local.y /= BOX_SIZE; local.x = round(local.x); @@ -815,7 +815,7 @@ Entity *box_grid(Entity *box) return (Entity *)cpBodyGetUserData(cpShapeGetBody(box->shape)); } // in local space -V2 entity_shape_pos(Entity *box) +cpVect entity_shape_pos(Entity *box) { return (cpShapeGetCenterOfGravity(box->shape)); } @@ -829,7 +829,7 @@ double box_rotation(Entity *box) return (float)cpBodyGetAngle(cpShapeGetBody(box->shape)); } -V2 entity_pos(Entity *e) +cpVect entity_pos(Entity *e) { if (e->is_box) { @@ -852,8 +852,8 @@ V2 entity_pos(Entity *e) struct BodyData { - V2 pos; - V2 vel; + cpVect pos; + cpVect vel; double rotation; double angular_velocity; }; @@ -997,7 +997,7 @@ enum GameVersion }; // @Robust probably get rid of this as separate function, just use SER_VAR -SerMaybeFailure ser_V2(SerState *ser, V2 *var) +SerMaybeFailure ser_V2(SerState *ser, cpVect *var) { SER_VAR(&var->x); SER_VAR(&var->y); @@ -1008,7 +1008,7 @@ SerMaybeFailure ser_V2(SerState *ser, V2 *var) // for when you only need 32 bit float precision in a vector2, // but it's a double -SerMaybeFailure ser_fV2(SerState *ser, V2 *var) +SerMaybeFailure ser_fV2(SerState *ser, cpVect *var) { float x; float y; @@ -1138,7 +1138,7 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e) Entity *parent = get_entity(gs, e->shape_parent_entity); SER_ASSERT(parent != NULL); - V2 shape_pos; + cpVect shape_pos; if (ser->serializing) shape_pos = entity_shape_pos(e); SER_MAYBE_RETURN(ser_fV2(ser, &shape_pos)); @@ -1689,7 +1689,7 @@ static void closest_point_callback_func(cpShape *shape, cpContactPointSet *point // filter func null means everything is ok, if it's not null and returns false, that means // exclude it from the selection. This returns the closest box entity! -Entity *closest_box_to_point_in_radius(struct GameState *gs, V2 point, double radius, bool (*filter_func)(Entity *)) +Entity *closest_box_to_point_in_radius(struct GameState *gs, cpVect point, double radius, bool (*filter_func)(Entity *)) { closest_to_point_in_radius_result = NULL; closest_to_point_in_radius_result_largest_dist = 0.0; @@ -1721,15 +1721,15 @@ static bool scanner_filter(Entity *e) } static double cur_explosion_damage = 0.0; -static V2 explosion_origin = {0}; +static cpVect explosion_origin = {0}; static double explosion_push_strength = 0.0; static void explosion_callback_func(cpShape *shape, cpContactPointSet *points, void *data) { GameState *gs = (GameState *)data; cp_shape_entity(shape)->damage += cur_explosion_damage; Entity *parent = get_entity(gs, cp_shape_entity(shape)->shape_parent_entity); - V2 from_pos = entity_pos(cp_shape_entity(shape)); - V2 impulse = cpvmult(cpvnormalize(cpvsub(from_pos, explosion_origin)), explosion_push_strength); + cpVect from_pos = entity_pos(cp_shape_entity(shape)); + cpVect impulse = cpvmult(cpvnormalize(cpvsub(from_pos, explosion_origin)), explosion_push_strength); assert(parent->body != NULL); cpBodyApplyImpulseAtWorldPoint(parent->body, (impulse), (from_pos)); } @@ -1749,10 +1749,10 @@ static void do_explosion(GameState *gs, Entity *explosion, double dt) cpBodyFree(tmpbody); } -V2 box_facing_vector(Entity *box) +cpVect box_facing_vector(Entity *box) { assert(box->is_box); - V2 to_return = (V2){.x = 1.0, .y = 0.0}; + cpVect to_return = (cpVect){.x = 1.0, .y = 0.0}; to_return = box_compass_vector(box); to_return = cpvspin(to_return, box_rotation(box)); @@ -1760,17 +1760,17 @@ V2 box_facing_vector(Entity *box) return to_return; } -enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Entity *grid_facing_vector_from, V2 facing_vector) +enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Entity *grid_facing_vector_from, cpVect facing_vector) { assert(grid_to_transplant_to->body != NULL); assert(grid_to_transplant_to->is_grid); - V2 local_to_from = grid_world_to_local(grid_facing_vector_from, cpvadd(entity_pos(grid_facing_vector_from), facing_vector)); + cpVect local_to_from = grid_world_to_local(grid_facing_vector_from, cpvadd(entity_pos(grid_facing_vector_from), facing_vector)); Log("local %f %f\n", local_to_from.x, local_to_from.y); - V2 from_target = cpvadd(entity_pos(grid_to_transplant_to), facing_vector); - V2 local_target = grid_world_to_local(grid_to_transplant_to, from_target); - V2 local_facing = local_target; + cpVect from_target = cpvadd(entity_pos(grid_to_transplant_to), facing_vector); + cpVect local_target = grid_world_to_local(grid_to_transplant_to, from_target); + cpVect local_facing = local_target; enum CompassRotation dirs[] = { Right, @@ -1782,7 +1782,7 @@ enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Ent double smallest_dist = INFINITY; for (int i = 0; i < ARRLEN(dirs); i++) { - V2 point = cpvspin((V2){.x = 1.0}, rotangle(dirs[i])); + cpVect point = cpvspin((cpVect){.x = 1.0}, rotangle(dirs[i])); double dist = cpvdist(point, local_facing); if (dist < smallest_dist) { @@ -1794,7 +1794,7 @@ enum CompassRotation facing_vector_to_compass(Entity *grid_to_transplant_to, Ent return dirs[smallest]; } -V2 thruster_force(Entity *box) +cpVect thruster_force(Entity *box) { return cpvmult(box_facing_vector(box), -box->thrust * THRUSTER_FORCE); } @@ -1804,12 +1804,12 @@ uint64_t tick(GameState *gs) return (uint64_t)floor(gs->time / ((double)TIMESTEP)); } -Entity *grid_to_build_on(GameState *gs, V2 world_hand_pos) +Entity *grid_to_build_on(GameState *gs, cpVect world_hand_pos) { return box_grid(closest_box_to_point_in_radius(gs, world_hand_pos, BUILD_BOX_SNAP_DIST_TO_SHIP, NULL)); } -V2 potentially_snap_hand_pos(GameState *gs, V2 world_hand_pos) +cpVect potentially_snap_hand_pos(GameState *gs, cpVect world_hand_pos) { Entity *potential_grid = grid_to_build_on(gs, world_hand_pos); if (potential_grid != NULL) @@ -1819,7 +1819,7 @@ V2 potentially_snap_hand_pos(GameState *gs, V2 world_hand_pos) return world_hand_pos; } -V2 get_world_hand_pos(GameState *gs, InputFrame *input, Entity *player) +cpVect get_world_hand_pos(GameState *gs, InputFrame *input, Entity *player) { return potentially_snap_hand_pos(gs, cpvadd(entity_pos(player), input->hand_pos)); } @@ -1888,15 +1888,15 @@ double entity_mass(Entity *m) } } -V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun) +cpVect sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun) { #ifdef NO_GRAVITY - return (V2){0}; + return (cpVect){0}; #else if (cpvlength(cpvsub(entity_pos(entity_with_gravity), entity_pos(sun))) > sun_dist_no_gravity(sun)) - return (V2){0}; - V2 rel_vector = cpvsub(entity_pos(entity_with_gravity), entity_pos(sun)); + return (cpVect){0}; + cpVect rel_vector = cpvsub(entity_pos(entity_with_gravity), entity_pos(sun)); double mass = entity_mass(entity_with_gravity); assert(mass != 0.0); double distance_sqr = cpvlengthsq(rel_vector); @@ -1911,12 +1911,12 @@ V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun) if (distance_sqr <= sun->sun_radius * 0.25) accel_magnitude = 0.0; } - V2 towards_sun = cpvnormalize(cpvmult(rel_vector, -1.0)); + cpVect towards_sun = cpvnormalize(cpvmult(rel_vector, -1.0)); return cpvmult(towards_sun, accel_magnitude); #endif // NO_GRAVITY } -void entity_set_velocity(Entity *e, V2 vel) +void entity_set_velocity(Entity *e, cpVect vel) { if (e->body != NULL) cpBodySetVelocity(e->body, (vel)); @@ -1931,12 +1931,12 @@ void entity_ensure_in_orbit(GameState *gs, Entity *e) cpVect total_new_vel = {0}; SUNS_ITER(gs) { - V2 gravity_accel = sun_gravity_accel_for_entity(e, i.sun); + cpVect gravity_accel = sun_gravity_accel_for_entity(e, i.sun); if (cpvlength(gravity_accel) > 0.0) { double dist = cpvlength(cpvsub(entity_pos(e), entity_pos(i.sun))); - V2 orthogonal_to_gravity = cpvnormalize(cpvspin(gravity_accel, PI / 2.0)); - V2 wanted_vel = cpvmult(orthogonal_to_gravity, sqrt(cpvlength(gravity_accel) * dist)); + cpVect orthogonal_to_gravity = cpvnormalize(cpvspin(gravity_accel, PI / 2.0)); + cpVect wanted_vel = cpvmult(orthogonal_to_gravity, sqrt(cpvlength(gravity_accel) * dist)); total_new_vel = cpvadd(total_new_vel, (wanted_vel)); } @@ -1949,14 +1949,14 @@ void entity_ensure_in_orbit(GameState *gs, Entity *e) // cpBodySetVelocity(e->body, cpvmult(cpvperp(pos), v)); } -V2 box_vel(Entity *box) +cpVect box_vel(Entity *box) { assert(box->is_box); Entity *grid = box_grid(box); return (cpBodyGetVelocityAtWorldPoint(grid->body, (entity_pos(box)))); } -void create_bomb_station(GameState *gs, V2 pos, enum BoxType platonic_type) +void create_bomb_station(GameState *gs, cpVect pos, enum BoxType platonic_type) { enum CompassRotation rot = Right; @@ -1976,36 +1976,36 @@ void create_bomb_station(GameState *gs, V2 pos, enum BoxType platonic_type) grid_create(gs, grid); entity_set_pos(grid, pos); Entity *platonic_box = new_entity(gs); - box_create(gs, platonic_box, grid, (V2){0}); + box_create(gs, platonic_box, grid, (cpVect){0}); platonic_box->box_type = platonic_type; platonic_box->is_platonic = true; - BOX_AT_TYPE(grid, ((V2){BOX_SIZE, 0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 2, 0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 3, 0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 4, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE, 0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 2, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 3, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 4, 0}), BoxHullpiece); indestructible = true; for (double y = -BOX_SIZE * 5.0; y <= BOX_SIZE * 5.0; y += BOX_SIZE) { - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 5.0, y}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 5.0, y}), BoxHullpiece); } for (double x = -BOX_SIZE * 5.0; x <= BOX_SIZE * 5.0; x += BOX_SIZE) { - BOX_AT_TYPE(grid, ((V2){x, BOX_SIZE * 5.0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){x, -BOX_SIZE * 5.0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){x, BOX_SIZE * 5.0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){x, -BOX_SIZE * 5.0}), BoxHullpiece); } indestructible = false; - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, BOX_SIZE * 5.0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, BOX_SIZE * 3.0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, BOX_SIZE * 1.0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, -BOX_SIZE * 2.0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, -BOX_SIZE * 3.0}), BoxExplosive); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, -BOX_SIZE * 5.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, BOX_SIZE * 5.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, BOX_SIZE * 3.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, BOX_SIZE * 1.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, -BOX_SIZE * 2.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, -BOX_SIZE * 3.0}), BoxExplosive); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 6.0, -BOX_SIZE * 5.0}), BoxExplosive); entity_ensure_in_orbit(gs, grid); } -void create_hard_shell_station(GameState *gs, V2 pos, enum BoxType platonic_type) +void create_hard_shell_station(GameState *gs, cpVect pos, enum BoxType platonic_type) { enum CompassRotation rot = Right; @@ -2015,23 +2015,23 @@ void create_hard_shell_station(GameState *gs, V2 pos, enum BoxType platonic_type grid_create(gs, grid); entity_set_pos(grid, pos); Entity *platonic_box = new_entity(gs); - box_create(gs, platonic_box, grid, (V2){0}); + box_create(gs, platonic_box, grid, (cpVect){0}); platonic_box->box_type = platonic_type; platonic_box->is_platonic = true; - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 2, 0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 3, 0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 4, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 2, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 3, 0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 4, 0}), BoxHullpiece); indestructible = true; for (double y = -BOX_SIZE * 5.0; y <= BOX_SIZE * 5.0; y += BOX_SIZE) { - BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 5.0, y}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 5.0, y}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE * 5.0, y}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE * 5.0, y}), BoxHullpiece); } for (double x = -BOX_SIZE * 5.0; x <= BOX_SIZE * 5.0; x += BOX_SIZE) { - BOX_AT_TYPE(grid, ((V2){x, BOX_SIZE * 5.0}), BoxHullpiece); - BOX_AT_TYPE(grid, ((V2){x, -BOX_SIZE * 5.0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){x, BOX_SIZE * 5.0}), BoxHullpiece); + BOX_AT_TYPE(grid, ((cpVect){x, -BOX_SIZE * 5.0}), BoxHullpiece); } entity_ensure_in_orbit(gs, grid); indestructible = false; @@ -2039,11 +2039,11 @@ void create_hard_shell_station(GameState *gs, V2 pos, enum BoxType platonic_type void create_initial_world(GameState *gs) { EntityID suns[] = { - create_sun(gs, new_entity(gs), ((V2){100.0, 0.0}), ((V2){0.0, 0.0}), 100000.0, 20.0), - create_sun(gs, new_entity(gs), ((V2){100.0, 50.0}), ((V2){10.0, 0.0}), 10000.0, 10.0), - create_sun(gs, new_entity(gs), ((V2){100.0, -50.0}), ((V2){-10.0, 0.0}), 10000.0, 10.0), - create_sun(gs, new_entity(gs), ((V2){50.0, 200.0}), ((V2){5.0, 0.0}), 400000.0, 30.0), - create_sun(gs, new_entity(gs), ((V2){-200.0, 200.0}), ((V2){-15.0, 0.0}), 900000.0, 60.0), + create_sun(gs, new_entity(gs), ((cpVect){100.0, 0.0}), ((cpVect){0.0, 0.0}), 100000.0, 20.0), + create_sun(gs, new_entity(gs), ((cpVect){100.0, 50.0}), ((cpVect){10.0, 0.0}), 10000.0, 10.0), + create_sun(gs, new_entity(gs), ((cpVect){100.0, -50.0}), ((cpVect){-10.0, 0.0}), 10000.0, 10.0), + create_sun(gs, new_entity(gs), ((cpVect){50.0, 200.0}), ((cpVect){5.0, 0.0}), 400000.0, 30.0), + create_sun(gs, new_entity(gs), ((cpVect){-200.0, 200.0}), ((cpVect){-15.0, 0.0}), 900000.0, 60.0), }; for (int i = 0; i < ARRLEN(suns); i++) @@ -2054,27 +2054,27 @@ void create_initial_world(GameState *gs) #ifdef DEBUG_WORLD Log("Creating debug world\n"); // pos, mass, radius - create_bomb_station(gs, (V2){-5.0, 0.0}, BoxExplosive); - create_bomb_station(gs, (V2){0.0, 5.0}, BoxGyroscope); - create_hard_shell_station(gs, (V2){-5.0, 5.0}, BoxCloaking); + create_bomb_station(gs, (cpVect){-5.0, 0.0}, BoxExplosive); + create_bomb_station(gs, (cpVect){0.0, 5.0}, BoxGyroscope); + create_hard_shell_station(gs, (cpVect){-5.0, 5.0}, BoxCloaking); bool indestructible = false; double theta = deg2rad(65.0); - V2 from = (V2){BOX_SIZE * 4.0, -1}; + cpVect from = (cpVect){BOX_SIZE * 4.0, -1}; enum CompassRotation rot = Right; { Entity *grid = new_entity(gs); grid_create(gs, grid); - entity_set_pos(grid, cpvadd(from, cpvspin((V2){.x = -BOX_SIZE * 9.0}, theta))); + entity_set_pos(grid, cpvadd(from, cpvspin((cpVect){.x = -BOX_SIZE * 9.0}, theta))); cpBodySetAngle(grid->body, theta + PI); rot = Left; - BOX_AT_TYPE(grid, ((V2){0.0, 0.0}), BoxMerge); - BOX_AT(grid, ((V2){0.0, -BOX_SIZE})); - BOX_AT_TYPE(grid, ((V2){BOX_SIZE, 0.0}), BoxMerge); + BOX_AT_TYPE(grid, ((cpVect){0.0, 0.0}), BoxMerge); + BOX_AT(grid, ((cpVect){0.0, -BOX_SIZE})); + BOX_AT_TYPE(grid, ((cpVect){BOX_SIZE, 0.0}), BoxMerge); entity_ensure_in_orbit(gs, grid); } @@ -2084,27 +2084,27 @@ void create_initial_world(GameState *gs) entity_set_pos(grid, from); cpBodySetAngle(grid->body, theta); rot = Left; - BOX_AT_TYPE(grid, ((V2){-BOX_SIZE, 0.0}), BoxMerge); + BOX_AT_TYPE(grid, ((cpVect){-BOX_SIZE, 0.0}), BoxMerge); rot = Down; - BOX_AT_TYPE(grid, ((V2){0.0, 0.0}), BoxMerge); + BOX_AT_TYPE(grid, ((cpVect){0.0, 0.0}), BoxMerge); rot = Up; - BOX_AT_TYPE(grid, ((V2){0.0, BOX_SIZE}), BoxMerge); - cpBodySetVelocity(grid->body, (cpvspin((V2){-0.4, 0.0}, theta))); + BOX_AT_TYPE(grid, ((cpVect){0.0, BOX_SIZE}), BoxMerge); + cpBodySetVelocity(grid->body, (cpvspin((cpVect){-0.4, 0.0}, theta))); entity_ensure_in_orbit(gs, grid); } #else - create_bomb_station(gs, (V2){-200.0, 0.0}, BoxExplosive); - create_hard_shell_station(gs, (V2){0.0, 400.0}, BoxGyroscope); - create_bomb_station(gs, (V2){0.0, -150.0}, BoxCloaking); - create_bomb_station(gs, (V2){300.0, 300.0}, BoxMissileLauncher); - create_hard_shell_station(gs, (V2){50.0, 100.0}, BoxMerge); + create_bomb_station(gs, (cpVect){-200.0, 0.0}, BoxExplosive); + create_hard_shell_station(gs, (cpVect){0.0, 400.0}, BoxGyroscope); + create_bomb_station(gs, (cpVect){0.0, -150.0}, BoxCloaking); + create_bomb_station(gs, (cpVect){300.0, 300.0}, BoxMissileLauncher); + create_hard_shell_station(gs, (cpVect){50.0, 100.0}, BoxMerge); #endif } void exit_seat(GameState *gs, Entity *seat_in, Entity *p) { - V2 pilot_seat_exit_spot = cpvadd(entity_pos(seat_in), cpvmult(box_facing_vector(seat_in), BOX_SIZE)); + cpVect pilot_seat_exit_spot = cpvadd(entity_pos(seat_in), cpvmult(box_facing_vector(seat_in), BOX_SIZE)); cpBodySetPosition(p->body, (pilot_seat_exit_spot)); // cpBodySetVelocity(p->body, (player_vel(gs, p))); cpBodySetVelocity(p->body, cpBodyGetVelocity(box_grid(seat_in)->body)); @@ -2125,7 +2125,7 @@ void process(GameState *gs, double dt) SUNS_ITER(gs) { Entity *from_sun = i.sun; - V2 accel = {0}; + cpVect accel = {0}; SUNS_ITER(gs) { Entity *other_sun = i.sun; @@ -2221,10 +2221,10 @@ void process(GameState *gs, double dt) { p->goldness += 0.1; p->damage = 0.0; - gs->goldpos = (V2){.x = hash11((float)gs->time) * 20.0, .y = hash11((float)gs->time - 13.6) * 20.0}; + gs->goldpos = (cpVect){.x = hash11((float)gs->time) * 20.0, .y = hash11((float)gs->time - 13.6) * 20.0}; } #if 1 - V2 world_hand_pos = get_world_hand_pos(gs, &player->input, p); + cpVect world_hand_pos = get_world_hand_pos(gs, &player->input, p); if (player->input.seat_action) { player->input.seat_action = false; // "handle" the input @@ -2279,12 +2279,12 @@ void process(GameState *gs, double dt) // process movement { // no cheating by making movement bigger than length 1 - V2 movement_this_tick = (V2){0}; + cpVect movement_this_tick = (cpVect){0}; double rotation_this_tick = 0.0; if (cpvlength(player->input.movement) > 0.0) { movement_this_tick = cpvmult(cpvnormalize(player->input.movement), clamp(cpvlength(player->input.movement), 0.0, 1.0)); - player->input.movement = (V2){0}; + player->input.movement = (cpVect){0}; } if (fabs(player->input.rotation) > 0.0) { @@ -2330,7 +2330,7 @@ void process(GameState *gs, double dt) { Entity *g = get_entity(gs, seat_inside_of->shape_parent_entity); - V2 target_direction = {0}; + cpVect target_direction = {0}; if (cpvlength(movement_this_tick) > 0.0) { target_direction = cpvnormalize(movement_this_tick); @@ -2359,7 +2359,7 @@ void process(GameState *gs, double dt) player->input.dobuild = false; // handle the input. if didn't do this, after destruction of hovered box, would try to build on its grid with grid_index... cpPointQueryInfo info = {0}; - V2 world_build = world_hand_pos; + cpVect world_build = world_hand_pos; // @Robust sanitize this input so player can't build on any grid in the world Entity *target_grid = grid_to_build_on(gs, world_hand_pos); @@ -2378,7 +2378,7 @@ void process(GameState *gs, double dt) { // creating a box p->damage += DAMAGE_TO_PLAYER_PER_BLOCK; - V2 created_box_position; + cpVect created_box_position; if (p->damage < 1.0) // player can't create a box that kills them by making it { if (target_grid == NULL) @@ -2388,7 +2388,7 @@ void process(GameState *gs, double dt) entity_set_pos(new_grid, world_build); cpBodySetVelocity(new_grid->body, (player_vel(gs, p))); target_grid = new_grid; - created_box_position = (V2){0}; + created_box_position = (cpVect){0}; } else { @@ -2473,8 +2473,8 @@ void process(GameState *gs, double dt) if (e->body != NULL) { - V2 accel = sun_gravity_accel_for_entity(e, i.sun); - V2 new_vel = entity_vel(gs, e); + cpVect accel = sun_gravity_accel_for_entity(e, i.sun); + cpVect new_vel = entity_vel(gs, e); new_vel = cpvadd(new_vel, cpvmult(accel, dt)); cpBodySetVelocity(e->body, (new_vel)); } @@ -2497,7 +2497,7 @@ void process(GameState *gs, double dt) if (is_burning(e)) { e->time_burned_for += dt; - cpBodyApplyForceAtWorldPoint(e->body, (cpvspin((V2){.x = MISSILE_BURN_FORCE, .y = 0.0}, entity_rotation(e))), (entity_pos(e))); + cpBodyApplyForceAtWorldPoint(e->body, (cpvspin((cpVect){.x = MISSILE_BURN_FORCE, .y = 0.0}, entity_rotation(e))), (entity_pos(e))); } if (e->damage >= MISSILE_DAMAGE_THRESHOLD && e->time_burned_for >= MISSILE_ARM_TIME) { @@ -2553,13 +2553,13 @@ void process(GameState *gs, double dt) // using this stuff to detect if when the other grid's boxes are snapped, they'll be snapped // to be next to the from merge box - V2 actual_new_pos = grid_snapped_box_pos(from_grid, entity_pos(other_merge)); - V2 needed_new_pos = cpvadd(entity_pos(from_merge), cpvmult(box_facing_vector(from_merge), BOX_SIZE)); + cpVect actual_new_pos = grid_snapped_box_pos(from_grid, entity_pos(other_merge)); + cpVect needed_new_pos = cpvadd(entity_pos(from_merge), cpvmult(box_facing_vector(from_merge), BOX_SIZE)); if (from_facing_other && other_facing_from && cpvnear(needed_new_pos, actual_new_pos, 0.01)) { // do the merge - V2 facing_vector_needed = cpvmult(box_facing_vector(from_merge), -1.0); - V2 current_facing_vector = box_facing_vector(other_merge); + cpVect facing_vector_needed = cpvmult(box_facing_vector(from_merge), -1.0); + cpVect current_facing_vector = box_facing_vector(other_merge); double angle_diff = cpvanglediff(current_facing_vector, facing_vector_needed); if (angle_diff == FLT_MIN) angle_diff = 0.0; @@ -2567,11 +2567,11 @@ void process(GameState *gs, double dt) cpBodySetAngle(other_grid->body, cpBodyGetAngle(other_grid->body) + angle_diff); - V2 moved_because_angle_change = cpvsub(needed_new_pos, entity_pos(other_merge)); + cpVect moved_because_angle_change = cpvsub(needed_new_pos, entity_pos(other_merge)); cpBodySetPosition(other_grid->body, (cpvadd(entity_pos(other_grid), moved_because_angle_change))); - // V2 snap_movement_vect = cpvsub(actual_new_pos, entity_pos(other_merge)); - V2 snap_movement_vect = (V2){0}; + // cpVect snap_movement_vect = cpvsub(actual_new_pos, entity_pos(other_merge)); + cpVect snap_movement_vect = (cpVect){0}; Entity *cur = get_entity(gs, other_grid->boxes); @@ -2579,10 +2579,10 @@ void process(GameState *gs, double dt) while (cur != NULL) { Entity *next = get_entity(gs, cur->next_box); - V2 world = entity_pos(cur); + cpVect world = entity_pos(cur); enum CompassRotation new_rotation = facing_vector_to_compass(from_grid, other_grid, box_facing_vector(cur)); cur->compass_rotation = new_rotation; - V2 new_cur_pos = grid_snapped_box_pos(from_grid, cpvadd(snap_movement_vect, world)); + cpVect new_cur_pos = grid_snapped_box_pos(from_grid, cpvadd(snap_movement_vect, world)); box_create(gs, cur, from_grid, grid_world_to_local(from_grid, new_cur_pos)); // destroys next/prev fields on cur assert(box_grid(cur) == box_grid(from_merge)); cur = next; @@ -2715,7 +2715,7 @@ void process(GameState *gs, double dt) create_missile(gs, new_missile); new_missile->owning_squad = cur_box->owning_squad; // missiles have teams and attack eachother! double missile_spawn_dist = sqrt((BOX_SIZE / 2.0) * (BOX_SIZE / 2.0) * 2.0) + MISSILE_COLLIDER_SIZE.x / 2.0 + 0.1; - cpBodySetPosition(new_missile->body, (cpvadd(entity_pos(cur_box), cpvspin((V2){.x = missile_spawn_dist, 0.0}, target.facing_angle)))); + cpBodySetPosition(new_missile->body, (cpvadd(entity_pos(cur_box), cpvspin((cpVect){.x = missile_spawn_dist, 0.0}, target.facing_angle)))); cpBodySetAngle(new_missile->body, target.facing_angle); cpBodySetVelocity(new_missile->body, (box_vel(cur_box))); } @@ -2729,16 +2729,16 @@ void process(GameState *gs, double dt) if (energy_unconsumed >= SCANNER_ENERGY_USE * dt) { cur_box->platonic_detection_strength = 0.0; - cur_box->platonic_nearest_direction = (V2){0}; + cur_box->platonic_nearest_direction = (cpVect){0}; } else { - V2 from_pos = entity_pos(cur_box); - V2 nearest = {0}; + cpVect from_pos = entity_pos(cur_box); + cpVect nearest = {0}; double nearest_dist = INFINITY; for (int i = 0; i < MAX_BOX_TYPES; i++) { - V2 cur_pos = gs->platonic_positions[i]; + cpVect cur_pos = gs->platonic_positions[i]; if (cpvlength(cur_pos) > 0.0) // zero is uninitialized, the platonic solid doesn't exist (probably) @Robust do better { double length_to_cur = cpvdist(from_pos, cur_pos); @@ -2756,7 +2756,7 @@ void process(GameState *gs, double dt) } else { - cur_box->platonic_nearest_direction = (V2){0}; + cur_box->platonic_nearest_direction = (cpVect){0}; cur_box->platonic_detection_strength = 0.0; } } diff --git a/main.c b/main.c index 347c247..0365e3b 100644 --- a/main.c +++ b/main.c @@ -49,7 +49,7 @@ typedef struct KeyPressed uint64_t frame; } KeyPressed; static KeyPressed keypressed[MAX_KEYDOWN] = {0}; -static V2 mouse_pos = {0}; +static cpVect mouse_pos = {0}; static bool fullscreened = false; static bool picking_new_boxtype = false; @@ -67,7 +67,7 @@ static EntityID maybe_inviting_this_player = {0}; bool confirm_invite_this_player = false; bool accept_invite = false; bool reject_invite = false; -static V2 camera_pos = {0}; // it being a global variable keeps camera at same +static cpVect camera_pos = {0}; // it being a global variable keeps camera at same // position after player death static double player_scaling = 1.0; @@ -701,33 +701,33 @@ static void set_pipeline_and_pull_color(sg_pipeline pip) #define pipeline_scope(pipeline) DeferLoop(set_pipeline_and_pull_color(pipeline), sgp_reset_pipeline()) -static void draw_color_rect_centered(V2 center, double size) +static void draw_color_rect_centered(cpVect center, double size) { double halfbox = size / 2.0; draw_filled_rect(center.x - halfbox, center.y - halfbox, size, size); } -static void draw_texture_rectangle_centered(V2 center, V2 width_height) +static void draw_texture_rectangle_centered(cpVect center, cpVect width_height) { - V2 halfsize = cpvmult(width_height, 0.5); + cpVect halfsize = cpvmult(width_height, 0.5); draw_textured_rect(center.x - halfsize.x, center.y - halfsize.y, width_height.x, width_height.y); } -static void draw_texture_centered(V2 center, double size) +static void draw_texture_centered(cpVect center, double size) { - draw_texture_rectangle_centered(center, (V2){size, size}); + draw_texture_rectangle_centered(center, (cpVect){size, size}); } -sgp_point V2point(V2 v) +sgp_point V2point(cpVect v) { return (sgp_point){.x = (float)v.x, .y = (float)v.y}; } -V2 pointV2(sgp_point p) +cpVect pointV2(sgp_point p) { - return (V2){.x = p.x, .y = p.y}; + return (cpVect){.x = p.x, .y = p.y}; } -static void draw_circle(V2 point, double radius) +static void draw_circle(cpVect point, double radius) { #define POINTS 64 sgp_line lines[POINTS]; @@ -735,9 +735,9 @@ static void draw_circle(V2 point, double radius) { double progress = (float)i / (float)POINTS; double next_progress = (float)(i + 1) / (float)POINTS; - lines[i].a = V2point((V2){.x = cos(progress * 2.0 * PI) * radius, + lines[i].a = V2point((cpVect){.x = cos(progress * 2.0 * PI) * radius, .y = sin(progress * 2.0 * PI) * radius}); - lines[i].b = V2point((V2){.x = cos(next_progress * 2.0 * PI) * radius, + lines[i].b = V2point((cpVect){.x = cos(next_progress * 2.0 * PI) * radius, .y = sin(next_progress * 2.0 * PI) * radius}); lines[i].a = V2point(cpvadd(pointV2(lines[i].a), point)); lines[i].b = V2point(cpvadd(pointV2(lines[i].b), point)); @@ -765,23 +765,23 @@ static void setup_hueshift(enum Squad squad) sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t)); } -static V2 screen_to_world(double width, double height, V2 screen) +static cpVect screen_to_world(double width, double height, cpVect screen) { - V2 world = screen; - world = cpvsub(world, (V2){.x = width / 2.0, .y = height / 2.0}); + cpVect world = screen; + world = cpvsub(world, (cpVect){.x = width / 2.0, .y = height / 2.0}); world.x /= zoom; world.y /= -zoom; world = cpvadd(world, camera_pos); return world; } -static V2 world_to_screen(double width, double height, V2 world) +static cpVect world_to_screen(double width, double height, cpVect world) { - V2 screen = world; + cpVect screen = world; screen = cpvsub(screen, camera_pos); screen.x *= zoom; screen.y *= -zoom; - screen = cpvadd(screen, (V2){.x = width / 2.0, .y = height / 2.0}); + screen = cpvadd(screen, (cpVect){.x = width / 2.0, .y = height / 2.0}); return screen; } @@ -918,9 +918,9 @@ static void ui(bool draw, double dt, double width, double height) double buttons_y = invite_y + size / 2.0; bool yes_hovered = - invited && cpvdist(mouse_pos, (V2){yes_x, buttons_y}) < yes_size / 2.0; + invited && cpvdist(mouse_pos, (cpVect){yes_x, buttons_y}) < yes_size / 2.0; bool no_hovered = - invited && cpvdist(mouse_pos, (V2){no_x, buttons_y}) < no_size / 2.0; + invited && cpvdist(mouse_pos, (cpVect){no_x, buttons_y}) < no_size / 2.0; yes_size = lerp(yes_size, yes_hovered ? 75.0 : 50.0, dt * 9.0); no_size = lerp(no_size, no_hovered ? 75.0 : 50.0, dt * 9.0); @@ -951,7 +951,7 @@ static void ui(bool draw, double dt, double width, double height) scale_at(1.0, -1.0, x, invite_y); // images upside down by default :( sgp_set_image(0, image_squad_invite); - draw_texture_centered((V2){x, invite_y}, size); + draw_texture_centered((cpVect){x, invite_y}, size); sgp_reset_image(0); } } @@ -964,7 +964,7 @@ static void ui(bool draw, double dt, double width, double height) sgp_set_image(0, image_check); pipeline_scope(goodpixel_pipeline) { - draw_texture_centered((V2){yes_x, buttons_y}, yes_size); + draw_texture_centered((cpVect){yes_x, buttons_y}, yes_size); } sgp_reset_image(0); } @@ -977,7 +977,7 @@ static void ui(bool draw, double dt, double width, double height) sgp_set_image(0, image_no); pipeline_scope(goodpixel_pipeline) { - draw_texture_centered((V2){no_x, buttons_y}, no_size); + draw_texture_centered((cpVect){no_x, buttons_y}, no_size); } sgp_reset_image(0); } @@ -989,15 +989,15 @@ static void ui(bool draw, double dt, double width, double height) Entity *inviting = get_entity(&gs, maybe_inviting_this_player); if (inviting != NULL && myplayer() != NULL) { - V2 top_of_head = world_to_screen( + cpVect top_of_head = world_to_screen( width, height, cpvadd(entity_pos(inviting), - (V2){.y = player_scaling * PLAYER_SIZE.y / 2.0})); - V2 pos = cpvadd(top_of_head, (V2){.y = -30.0}); - V2 to_mouse = cpvsub(mouse_pos, + (cpVect){.y = player_scaling * PLAYER_SIZE.y / 2.0})); + cpVect pos = cpvadd(top_of_head, (cpVect){.y = -30.0}); + cpVect to_mouse = cpvsub(mouse_pos, world_to_screen(width, height, entity_pos(inviting))); bool selecting_to_invite = - cpvdot(cpvnormalize(to_mouse), (V2){0.0, -1.0}) > 0.5 && + cpvdot(cpvnormalize(to_mouse), (cpVect){0.0, -1.0}) > 0.5 && cpvlength(to_mouse) > 15.0; if (!mousedown[SAPP_MOUSEBUTTON_RIGHT]) { @@ -1031,7 +1031,7 @@ static void ui(bool draw, double dt, double width, double height) } // draw flags - static V2 flag_pos[SquadLast] = {0}; + static cpVect flag_pos[SquadLast] = {0}; static double flag_rot[SquadLast] = {0}; static double flag_scaling_increase[SquadLast] = {0}; static bool choosing_flags = false; @@ -1043,7 +1043,7 @@ static void ui(bool draw, double dt, double width, double height) { FLAG_ITER(i) { - V2 target_pos = {0}; + cpVect target_pos = {0}; double target_rot = 0.0; double flag_progress = (float)i / (float)(SquadLast - 1.0); if (choosing_flags) @@ -1324,7 +1324,7 @@ static void ui(bool draw, double dt, double width, double height) sgp_pop_transform(); } -static void draw_dots(V2 camera_pos, double gap) +static void draw_dots(cpVect camera_pos, double gap) { set_color_values(1.0, 1.0, 1.0, 1.0); // const int num = 100; @@ -1351,7 +1351,7 @@ static void draw_dots(V2 camera_pos, double gap) { for (int y = initial_y; y < final_y; y++) { - V2 star = (V2){(float)x * gap, (float)y * gap}; + cpVect star = (cpVect){(float)x * gap, (float)y * gap}; star.x += hash11(star.x * 100.0 + star.y * 67.0) * gap; star.y += hash11(star.y * 93.0 + star.x * 53.0) * gap; if (cpvlengthsq(cpvsub(star, camera_pos)) > VISION_RADIUS * VISION_RADIUS) @@ -1362,12 +1362,12 @@ static void draw_dots(V2 camera_pos, double gap) } } -static V2 get_global_hand_pos(V2 world_mouse_pos, bool *hand_at_arms_length) +static cpVect get_global_hand_pos(cpVect world_mouse_pos, bool *hand_at_arms_length) { if (myentity() == NULL) - return (V2){0}; + return (cpVect){0}; - V2 global_hand_pos = cpvsub(world_mouse_pos, entity_pos(myentity())); + cpVect global_hand_pos = cpvsub(world_mouse_pos, entity_pos(myentity())); double hand_len = cpvlength(global_hand_pos); if (hand_len > MAX_HAND_REACH) { @@ -1540,23 +1540,23 @@ static void frame(void) // gameplay ui(false, dt, width, height); // if ui button is pressed before game logic, set the pressed to // false so it doesn't propagate from the UI modal/button - V2 build_target_pos = {0}; + cpVect build_target_pos = {0}; double build_target_rotation = 0.0; struct BuildPreviewInfo { - V2 grid_pos; + cpVect grid_pos; double grid_rotation; } build_preview = {0}; - V2 global_hand_pos = {0}; // world coords! world star! + cpVect global_hand_pos = {0}; // world coords! world star! bool hand_at_arms_length = false; recalculate_camera_pos(); - V2 world_mouse_pos = screen_to_world(width, height, mouse_pos); + cpVect world_mouse_pos = screen_to_world(width, height, mouse_pos); { // interpolate zoom zoom = lerp(zoom, zoom_target, dt * 12.0); // calculate build preview stuff - V2 local_hand_pos = {0}; + cpVect local_hand_pos = {0}; global_hand_pos = get_global_hand_pos(world_mouse_pos, &hand_at_arms_length); @@ -1587,7 +1587,7 @@ static void frame(void) // without frustration by the server. Resulting in authoritative game // state that looks and feels good. - V2 input = (V2){ + cpVect input = (cpVect){ .x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A], .y = (float)keydown[SAPP_KEYCODE_W] - (float)keydown[SAPP_KEYCODE_S], }; @@ -1745,7 +1745,7 @@ static void frame(void) #if 1 // space background transform_scope { - V2 scaled_camera_pos = cpvmult( + cpVect scaled_camera_pos = cpvmult( camera_pos, 0.0005); // this is how strong/weak the parallax is translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); @@ -1762,7 +1762,7 @@ static void frame(void) } transform_scope { - V2 scaled_camera_pos = cpvmult( + cpVect scaled_camera_pos = cpvmult( camera_pos, 0.005); // this is how strong/weak the parallax is translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); @@ -1782,14 +1782,14 @@ static void frame(void) #if 1 // parallaxed dots transform_scope { - V2 scaled_camera_pos = cpvmult(camera_pos, 0.25); + cpVect scaled_camera_pos = cpvmult(camera_pos, 0.25); translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); draw_dots(scaled_camera_pos, 3.0); } transform_scope { - V2 scaled_camera_pos = cpvmult(camera_pos, 0.5); + cpVect scaled_camera_pos = cpvmult(camera_pos, 0.5); translate(-scaled_camera_pos.x, -scaled_camera_pos.y); set_color(WHITE); draw_dots(scaled_camera_pos, 2.0); @@ -1998,7 +1998,7 @@ static void frame(void) if (b->platonic_detection_strength > 0.0) { set_color(colhexcode(0xf2d75c)); - V2 to = cpvadd(entity_pos(b), cpvmult(b->platonic_nearest_direction, b->platonic_detection_strength)); + cpVect to = cpvadd(entity_pos(b), cpvmult(b->platonic_nearest_direction, b->platonic_detection_strength)); dbg_rect(to); dbg_rect(entity_pos(b)); draw_line(entity_pos(b).x, entity_pos(b).y, to.x, to.y); @@ -2064,7 +2064,7 @@ static void frame(void) // instant death set_color(RED); - draw_circle((V2){0}, INSTANT_DEATH_DISTANCE_FROM_CENTER); + draw_circle((cpVect){0}, INSTANT_DEATH_DISTANCE_FROM_CENTER); // the SUN SUNS_ITER(&gs) @@ -2074,7 +2074,7 @@ static void frame(void) translate(entity_pos(i.sun).x, entity_pos(i.sun).y); set_color(WHITE); sgp_set_image(0, image_sun); - draw_texture_centered((V2){0}, i.sun->sun_radius * 2.0); + draw_texture_centered((cpVect){0}, i.sun->sun_radius * 2.0); sgp_reset_image(0); // can draw at 0,0 because everything relative to sun now! @@ -2082,7 +2082,7 @@ static void frame(void) // sun DEATH RADIUS set_color(BLUE); - draw_circle((V2){0}, sun_dist_no_gravity(i.sun)); + draw_circle((cpVect){0}, sun_dist_no_gravity(i.sun)); } } @@ -2095,8 +2095,8 @@ static void frame(void) { set_color_values(1.0, 1.0, 1.0, myentity()->damage); sgp_set_image(0, image_low_health); - draw_texture_rectangle_centered((V2){width / 2.0, height / 2.0}, - (V2){width, height}); + draw_texture_rectangle_centered((cpVect){width / 2.0, height / 2.0}, + (cpVect){width, height}); sgp_reset_image(0); } @@ -2219,7 +2219,7 @@ void event(const sapp_event *e) case SAPP_EVENTTYPE_MOUSE_MOVE: if (!mouse_frozen) { - mouse_pos = (V2){.x = e->mouse_x, .y = e->mouse_y}; + mouse_pos = (cpVect){.x = e->mouse_x, .y = e->mouse_y}; } if (right_mouse_down) { diff --git a/server.c b/server.c index 573ba60..d8818d8 100644 --- a/server.c +++ b/server.c @@ -141,9 +141,9 @@ void server(void *info_raw) { Entity *grid = new_entity(&gs); grid_create(&gs, grid); - entity_set_pos(grid, (V2){-BOX_SIZE * 2, 0.0}); + entity_set_pos(grid, (cpVect){-BOX_SIZE * 2, 0.0}); Entity *box = new_entity(&gs); - box_create(&gs, box, grid, (V2){0}); + box_create(&gs, box, grid, (cpVect){0}); } // rotation test @@ -151,16 +151,16 @@ void server(void *info_raw) { Entity *grid = new_entity(&gs); grid_create(&gs, grid); - entity_set_pos(grid, (V2){-BOX_SIZE * 2, 0.0}); + entity_set_pos(grid, (cpVect){-BOX_SIZE * 2, 0.0}); entity_set_rotation(grid, PI / 1.7); cpBodySetVelocity(grid->body, cpv(-0.1, 0.0)); cpBodySetAngularVelocity(grid->body, 1.0); - BOX_AT(grid, ((V2){0})); - BOX_AT(grid, ((V2){BOX_SIZE, 0})); - BOX_AT(grid, ((V2){2.0 * BOX_SIZE, 0})); - BOX_AT(grid, ((V2){2.0 * BOX_SIZE, BOX_SIZE})); - BOX_AT(grid, ((V2){0.0 * BOX_SIZE, -BOX_SIZE})); + BOX_AT(grid, ((cpVect){0})); + BOX_AT(grid, ((cpVect){BOX_SIZE, 0})); + BOX_AT(grid, ((cpVect){2.0 * BOX_SIZE, 0})); + BOX_AT(grid, ((cpVect){2.0 * BOX_SIZE, BOX_SIZE})); + BOX_AT(grid, ((cpVect){0.0 * BOX_SIZE, -BOX_SIZE})); } if (enet_initialize() != 0) diff --git a/types.h b/types.h index d667070..db0d06f 100644 --- a/types.h +++ b/types.h @@ -10,7 +10,7 @@ #define MAX_ENTITIES 1024 * 25 #define BOX_SIZE 0.25f #define MERGE_MAX_DIST (BOX_SIZE / 2.0f + 0.01f) -#define PLAYER_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE}) +#define PLAYER_SIZE ((cpVect){.x = BOX_SIZE, .y = BOX_SIZE}) #define PLAYER_MASS 0.5f #define PLAYER_JETPACK_FORCE 2.0f #define PLAYER_JETPACK_TORQUE 0.05f @@ -23,8 +23,8 @@ #define MISSILE_DAMAGE_THRESHOLD 0.2f #define MISSILE_CHARGE_RATE 0.5f // centered on the sprite -#define MISSILE_SPRITE_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE}) -#define MISSILE_COLLIDER_SIZE ((V2){.x = BOX_SIZE * 0.5f, .y = BOX_SIZE * 0.5f}) +#define MISSILE_SPRITE_SIZE ((cpVect){.x = BOX_SIZE, .y = BOX_SIZE}) +#define MISSILE_COLLIDER_SIZE ((cpVect){.x = BOX_SIZE * 0.5f, .y = BOX_SIZE * 0.5f}) // #define PLAYER_JETPACK_FORCE 20.0f // distance at which things become geostationary and no more solar power! #define PLAYER_JETPACK_ROTATION_ENERGY_PER_SECOND 0.2f @@ -136,8 +136,6 @@ typedef int opus_int32; #endif -typedef cpVect V2; - #define Log(...) \ { \ fprintf(stdout, "%s:%d | ", __FILE__, __LINE__); \ @@ -198,7 +196,7 @@ static bool entityids_same(EntityID a, EntityID b) typedef struct InputFrame { uint64_t tick; - V2 movement; + cpVect movement; double rotation; int take_over_squad; // -1 means not taking over any squad @@ -207,7 +205,7 @@ typedef struct InputFrame 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 seat_action; - V2 hand_pos; // local to player transationally but not rotationally + cpVect hand_pos; // local to player transationally but not rotationally // @BeforeShip bounds check on the hand_pos so that players can't reach across the entire map bool dobuild; @@ -236,7 +234,7 @@ typedef struct Entity // @Robust remove shape_parent_entity from this struct, use the shape's body to figure out // what the shape's parent entity is EntityID shape_parent_entity; // can't be zero if shape is nonzero - V2 shape_size; + cpVect shape_size; // player bool is_player; @@ -247,16 +245,16 @@ typedef struct Entity // explosion bool is_explosion; - V2 explosion_pos; - V2 explosion_vel; + cpVect explosion_pos; + cpVect explosion_vel; double explosion_progress; // in seconds double explosion_push_strength; double explosion_radius; // sun bool is_sun; - V2 sun_vel; - V2 sun_pos; + cpVect sun_vel; + cpVect sun_pos; double sun_mass; double sun_radius; @@ -308,7 +306,7 @@ typedef struct Entity BOX_UNLOCKS_TYPE blueprints_learned; // @Robust make this same type as blueprints double scanner_head_rotate_speed; // not serialized, cosmetic double scanner_head_rotate; - V2 platonic_nearest_direction; // normalized + cpVect platonic_nearest_direction; // normalized double platonic_detection_strength; // from zero to one } Entity; @@ -341,12 +339,12 @@ typedef struct GameState // Like a whole timestep then a double for subtimestep double time; // @Robust separate tick integer not prone to precision issues. Could be very large as is saved to disk! - V2 goldpos; + cpVect goldpos; Player players[MAX_PLAYERS]; EntityID suns[MAX_SUNS]; // can't have holes in it for serialization - V2 platonic_positions[MAX_BOX_TYPES]; // don't want to search over every entity to get the nearest platonic box! + cpVect platonic_positions[MAX_BOX_TYPES]; // don't want to search over every entity to get the nearest platonic box! bool server_side_computing; // some things only the server should know and calculate, like platonic locations @@ -424,7 +422,7 @@ void initialize(struct GameState *gs, void *entity_arena, size_t entity_arena_si void destroy(struct GameState *gs); void process_fixed_timestep(GameState *gs); void process(struct GameState *gs, double dt); // does in place -Entity *closest_box_to_point_in_radius(struct GameState *gs, V2 point, double radius, bool (*filter_func)(Entity *)); +Entity *closest_box_to_point_in_radius(struct GameState *gs, cpVect point, double radius, bool (*filter_func)(Entity *)); uint64_t tick(struct GameState *gs); double sun_dist_no_gravity(Entity *sun); @@ -439,9 +437,9 @@ bool is_burning(Entity *missile); Entity *get_entity(struct GameState *gs, EntityID id); Entity *new_entity(struct GameState *gs); EntityID get_id(struct GameState *gs, Entity *e); -V2 entity_pos(Entity *e); +cpVect entity_pos(Entity *e); void entity_set_rotation(Entity *e, double rot); -void entity_set_pos(Entity *e, V2 pos); +void entity_set_pos(Entity *e, cpVect pos); double entity_rotation(Entity *e); void entity_ensure_in_orbit(GameState *gs, Entity *e); void entity_destroy(GameState *gs, Entity *e); @@ -456,26 +454,26 @@ LauncherTarget missile_launcher_target(GameState *gs, Entity *launcher); // grid void grid_create(struct GameState *gs, Entity *e); -void box_create(struct GameState *gs, Entity *new_box, Entity *grid, V2 pos); +void box_create(struct GameState *gs, Entity *new_box, Entity *grid, cpVect pos); Entity *box_grid(Entity *box); -V2 grid_com(Entity *grid); -V2 grid_vel(Entity *grid); -V2 box_vel(Entity *box); -V2 grid_local_to_world(Entity *grid, V2 local); -V2 grid_world_to_local(Entity *grid, V2 world); -V2 grid_snapped_box_pos(Entity *grid, V2 world); // returns the snapped pos in world coords +cpVect grid_com(Entity *grid); +cpVect grid_vel(Entity *grid); +cpVect box_vel(Entity *box); +cpVect grid_local_to_world(Entity *grid, cpVect local); +cpVect grid_world_to_local(Entity *grid, cpVect world); +cpVect grid_snapped_box_pos(Entity *grid, cpVect world); // returns the snapped pos in world coords double entity_angular_velocity(Entity *grid); -V2 entity_shape_pos(Entity *box); +cpVect entity_shape_pos(Entity *box); double box_rotation(Entity *box); // thruster -V2 box_facing_vector(Entity *box); -V2 thruster_force(Entity *box); +cpVect box_facing_vector(Entity *box); +cpVect thruster_force(Entity *box); // debug draw void dbg_drawall(); -void dbg_line(V2 from, V2 to); -void dbg_rect(V2 center); +void dbg_line(cpVect from, cpVect to); +void dbg_rect(cpVect center); typedef struct ServerThreadInfo { @@ -490,7 +488,7 @@ typedef struct AABB double x, y, width, height; } AABB; -static inline AABB centered_at(V2 point, V2 size) +static inline AABB centered_at(cpVect point, cpVect size) { return (AABB){ .x = point.x - size.x / 2.0f, @@ -500,28 +498,28 @@ static inline AABB centered_at(V2 point, V2 size) }; } -static inline bool has_point(AABB aabb, V2 point) +static inline bool has_point(AABB aabb, cpVect point) { return point.x > aabb.x && point.x < aabb.x + aabb.width && point.y > aabb.y && point.y < aabb.y + aabb.height; } -static inline double cpvprojectval(V2 vec, V2 onto) +static inline double cpvprojectval(cpVect vec, cpVect onto) { double length_onto = cpvlength(onto); return cpvdot(vec, onto) / (length_onto * length_onto); } // spins around by theta -static inline V2 cpvspin(V2 vec, double theta) +static inline cpVect cpvspin(cpVect vec, double theta) { - return (V2){ + return (cpVect){ .x = vec.x * cos(theta) - vec.y * sin(theta), .y = vec.x * sin(theta) + vec.y * cos(theta), }; } // also known as atan2 -static inline double cpvangle(V2 vec) +static inline double cpvangle(cpVect vec) { return atan2(vec.y, vec.x); } @@ -548,7 +546,7 @@ static inline double clamp(double f, double minimum, double maximum) return f; } -static inline double cpvanglediff(V2 a, V2 b) +static inline double cpvanglediff(cpVect a, cpVect b) { double acos_input = cpvdot(a, b) / (cpvlength(a) * cpvlength(b)); acos_input = clamp(acos_input, -1.0f, 1.0f); @@ -573,14 +571,14 @@ static inline double lerp_angle(double p_from, double p_to, double p_weight) return p_from + distance * p_weight; } -static inline V2 cpvfloor(V2 p) +static inline cpVect cpvfloor(cpVect p) { - return (V2){floor(p.x), floor(p.y)}; + return (cpVect){floor(p.x), floor(p.y)}; } -static inline V2 cpvfract(V2 p) +static inline cpVect cpvfract(cpVect p) { - return (V2){fract(p.x), fract(p.y)}; + return (cpVect){fract(p.x), fract(p.y)}; } // for random generation