Remove V2 from project

main
parent af2bf08607
commit 53afb37e52

@ -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,

@ -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;
}
}

106
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)
{

@ -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)

@ -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

Loading…
Cancel
Save