Many suns

main
Cameron Murphy Reikes 2 years ago
parent 7b2b09c42f
commit 082d3a8e42

@ -347,6 +347,19 @@ Entity *new_entity(GameState *gs)
return to_return; return to_return;
} }
// pos, mass, radius
EntityID create_sun(GameState *gs, Entity *new_sun, V2 pos, V2 vel, float mass, float radius)
{
assert(new_sun != NULL);
new_sun->is_sun = true;
new_sun->sun_pos = pos;
new_sun->sun_vel = vel;
new_sun->sun_mass = mass;
new_sun->sun_radius = radius;
return get_id(gs, new_sun);
}
void create_body(GameState *gs, Entity *e) void create_body(GameState *gs, Entity *e)
{ {
assert(gs->space != NULL); assert(gs->space != NULL);
@ -830,6 +843,10 @@ V2 entity_pos(Entity *e)
{ {
return e->explosion_pos; return e->explosion_pos;
} }
else if (e->is_sun)
{
return e->sun_pos;
}
else else
{ {
assert(e->body != NULL); assert(e->body != NULL);
@ -980,8 +997,6 @@ SerMaybeFailure ser_var(SerState *ser, char *var_pointer, size_t var_size, const
enum GameVersion enum GameVersion
{ {
VInitial, VInitial,
VMoreBoxes,
VMissileMerge,
VMax, // this minus one will be the version used VMax, // this minus one will be the version used
}; };
@ -1121,10 +1136,9 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
} }
} }
if (ser->version >= VMoreBoxes && !ser->save_or_load_from_disk) if (!ser->save_or_load_from_disk)
SER_VAR(&e->time_was_last_cloaked); SER_VAR(&e->time_was_last_cloaked);
if (ser->version >= VMissileMerge)
SER_VAR(&e->owning_squad); SER_VAR(&e->owning_squad);
SER_VAR(&e->is_player); SER_VAR(&e->is_player);
@ -1133,10 +1147,6 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_ASSERT(e->no_save_to_disk); SER_ASSERT(e->no_save_to_disk);
SER_MAYBE_RETURN(ser_entityid(ser, &e->currently_inside_of_box)); SER_MAYBE_RETURN(ser_entityid(ser, &e->currently_inside_of_box));
if (ser->version < VMissileMerge)
{
SER_VAR_NAME(&e->owning_squad, "&e->presenting_squad");
}
SER_VAR(&e->squad_invited_to); SER_VAR(&e->squad_invited_to);
SER_VAR(&e->goldness); SER_VAR(&e->goldness);
} }
@ -1149,6 +1159,15 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_VAR(&e->explosion_progresss); SER_VAR(&e->explosion_progresss);
} }
SER_VAR(&e->is_sun);
if (e->is_sun)
{
SER_MAYBE_RETURN(ser_V2(ser, &e->sun_vel));
SER_MAYBE_RETURN(ser_V2(ser, &e->sun_pos));
SER_VAR(&e->sun_mass);
SER_VAR(&e->sun_radius);
}
SER_VAR(&e->is_grid); SER_VAR(&e->is_grid);
if (e->is_grid) if (e->is_grid)
{ {
@ -1156,14 +1175,11 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_MAYBE_RETURN(ser_entityid(ser, &e->boxes)); SER_MAYBE_RETURN(ser_entityid(ser, &e->boxes));
} }
if (ser->version >= VMissileMerge)
{
SER_VAR(&e->is_missile) SER_VAR(&e->is_missile)
if (e->is_missile) if (e->is_missile)
{ {
SER_VAR(&e->time_burned_for); SER_VAR(&e->time_burned_for);
} }
}
SER_VAR(&e->is_box); SER_VAR(&e->is_box);
if (e->is_box) if (e->is_box)
@ -1171,7 +1187,6 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_VAR(&e->box_type); SER_VAR(&e->box_type);
SER_VAR(&e->is_platonic); SER_VAR(&e->is_platonic);
if (ser->version >= VMoreBoxes)
SER_VAR(&e->owning_squad); SER_VAR(&e->owning_squad);
SER_VAR(&e->always_visible); SER_VAR(&e->always_visible);
@ -1311,6 +1326,16 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s)
} }
} }
} }
for (int i = 0; i < MAX_SUNS; i++)
{
bool suns_done = get_entity(gs, gs->suns[i]) == NULL;
SER_VAR(&suns_done);
if (suns_done)
break;
SER_MAYBE_RETURN(ser_entityid(ser, &gs->suns[i]));
}
if (ser->serializing) if (ser->serializing)
{ {
bool entities_done = false; bool entities_done = false;
@ -1805,13 +1830,13 @@ float batteries_use_energy(GameState *gs, Entity *grid, float *energy_left_over,
return energy_to_use; return energy_to_use;
} }
float sun_dist_no_gravity() float sun_dist_no_gravity(Entity *sun)
{ {
// return (GRAVITY_CONSTANT * (SUN_MASS * mass / (distance * distance))) / mass; // return (GRAVITY_CONSTANT * (SUN_MASS * mass / (distance * distance))) / mass;
// 0.01f = (GRAVITY_CONSTANT * (SUN_MASS / (distance_sqr))); // 0.01f = (GRAVITY_CONSTANT * (SUN_MASS / (distance_sqr)));
// 0.01f / GRAVITY_CONSTANT = SUN_MASS / distance_sqr; // 0.01f / GRAVITY_CONSTANT = SUN_MASS / distance_sqr;
// distance = sqrt( SUN_MASS / (0.01f / GRAVITY_CONSTANT) ) // distance = sqrt( SUN_MASS / (0.01f / GRAVITY_CONSTANT) )
return sqrtf( SUN_MASS / (GRAVITY_SMALLEST / GRAVITY_CONSTANT) ); return sqrtf(sun->sun_mass / (GRAVITY_SMALLEST / GRAVITY_CONSTANT));
} }
float entity_mass(Entity *m) float entity_mass(Entity *m)
@ -1820,6 +1845,8 @@ float entity_mass(Entity *m)
return (float)cpBodyGetMass(m->body); return (float)cpBodyGetMass(m->body);
else if (m->is_box) else if (m->is_box)
return BOX_MASS; return BOX_MASS;
else if (m->is_sun)
return m->sun_mass;
else else
{ {
assert(false); assert(false);
@ -1827,40 +1854,61 @@ float entity_mass(Entity *m)
} }
} }
V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity) V2 sun_gravity_accel_for_entity(Entity *entity_with_gravity, Entity *sun)
{ {
if (V2length(V2sub(entity_pos(entity_with_gravity), SUN_POS)) > sun_dist_no_gravity()) #ifdef NO_GRAVITY
return (V2){0};
#else
if (V2length(V2sub(entity_pos(entity_with_gravity), entity_pos(sun))) > sun_dist_no_gravity(sun))
return (V2){0}; return (V2){0};
V2 rel_vector = V2sub(entity_pos(entity_with_gravity), SUN_POS); V2 rel_vector = V2sub(entity_pos(entity_with_gravity), entity_pos(sun));
float mass = entity_mass(entity_with_gravity); float mass = entity_mass(entity_with_gravity);
assert(mass != 0.0f); assert(mass != 0.0f);
float distance_sqr = V2lengthsqr(rel_vector); float distance_sqr = V2lengthsqr(rel_vector);
// return (GRAVITY_CONSTANT * (SUN_MASS * mass / (distance * distance))) / mass; // return (GRAVITY_CONSTANT * (SUN_MASS * mass / (distance * distance))) / mass;
// the mass divides out // the mass divides out
float accel_magnitude = (GRAVITY_CONSTANT * (SUN_MASS / (distance_sqr)));
// on top
float accel_magnitude = (GRAVITY_CONSTANT * (sun->sun_mass / (distance_sqr)));
if (distance_sqr <= sun->sun_radius)
{
accel_magnitude *= -1.0f;
if (distance_sqr <= sun->sun_radius * 0.25f)
accel_magnitude = 0.0f;
}
V2 towards_sun = V2normalize(V2scale(rel_vector, -1.0f)); V2 towards_sun = V2normalize(V2scale(rel_vector, -1.0f));
return V2scale(towards_sun, accel_magnitude); return V2scale(towards_sun, accel_magnitude);
#endif // NO_GRAVITY
} }
void entity_set_velocity(Entity *e, V2 vel) void entity_set_velocity(Entity *e, V2 vel)
{ {
assert(e->body != NULL); if (e->body != NULL)
cpBodySetVelocity(e->body, v2_to_cp(vel)); cpBodySetVelocity(e->body, v2_to_cp(vel));
else if (e->is_sun)
e->sun_vel = vel;
else
assert(false);
} }
void entity_ensure_in_orbit(Entity *e) void entity_ensure_in_orbit(GameState *gs, Entity *e)
{ {
assert(e->body != NULL); cpVect total_new_vel = {0};
SUNS_ITER(gs)
V2 gravity_accel = sun_gravity_accel_for_entity(e);
if (V2length(gravity_accel) > 0.00f)
{ {
float dist = V2length(V2sub(entity_pos(e), SUN_POS)); V2 gravity_accel = sun_gravity_accel_for_entity(e, i.sun);
if (V2length(gravity_accel) > 0.0f)
{
float dist = V2length(V2sub(entity_pos(e), entity_pos(i.sun)));
V2 orthogonal_to_gravity = V2normalize(V2rotate(gravity_accel, PI / 2.0f)); V2 orthogonal_to_gravity = V2normalize(V2rotate(gravity_accel, PI / 2.0f));
V2 wanted_vel = V2scale(orthogonal_to_gravity, sqrtf(V2length(gravity_accel) * dist)); V2 wanted_vel = V2scale(orthogonal_to_gravity, sqrtf(V2length(gravity_accel) * dist));
cpBodySetVelocity(e->body, v2_to_cp(wanted_vel)); total_new_vel = cpvadd(total_new_vel, v2_to_cp(wanted_vel));
}
} }
entity_set_velocity(e, cp_to_v2(total_new_vel));
// cpVect pos = v2_to_cp(V2sub(entity_pos(e), SUN_POS)); // cpVect pos = v2_to_cp(V2sub(entity_pos(e), SUN_POS));
// cpFloat r = cpvlength(pos); // cpFloat r = cpvlength(pos);
// cpFloat v = cpfsqrt(sun_gravity_accel_at_point(cp_to_v2(pos), e) / r) / r; // cpFloat v = cpfsqrt(sun_gravity_accel_at_point(cp_to_v2(pos), e) / r) / r;
@ -1920,7 +1968,7 @@ void create_bomb_station(GameState *gs, V2 pos, enum BoxType platonic_type)
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 * 3.0}), BoxExplosive);
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 * 5.0}), BoxExplosive);
entity_ensure_in_orbit(grid); 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, V2 pos, enum BoxType platonic_type)
@ -1951,13 +1999,27 @@ void create_hard_shell_station(GameState *gs, V2 pos, enum BoxType platonic_type
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, ((V2){x, -BOX_SIZE * 5.0}), BoxHullpiece); BOX_AT_TYPE(grid, ((V2){x, -BOX_SIZE * 5.0}), BoxHullpiece);
} }
entity_ensure_in_orbit(grid); entity_ensure_in_orbit(gs, grid);
indestructible = false; indestructible = false;
} }
void create_initial_world(GameState *gs) void create_initial_world(GameState *gs)
{ {
EntityID suns[] = {
create_sun(gs, new_entity(gs), ((V2){100.0f, 0.0f}), ((V2){0.0f, 0.0f}), 100000.0f, 20.0f),
create_sun(gs, new_entity(gs), ((V2){100.0f, 50.0f}), ((V2){10.0f, 0.0f}), 10000.0f, 10.0f),
create_sun(gs, new_entity(gs), ((V2){100.0f, -50.0f}), ((V2){-10.0f, 0.0f}), 10000.0f, 10.0f),
create_sun(gs, new_entity(gs), ((V2){50.0f, 200.0f}), ((V2){5.0f, 0.0f}), 400000.0f, 30.0f),
create_sun(gs, new_entity(gs), ((V2){-200.0f, 200.0f}), ((V2){-15.0f, 0.0f}), 900000.0f, 60.0f),
};
for (int i = 0; i < ARRLEN(suns); i++)
{
gs->suns[i] = suns[i];
}
#ifdef DEBUG_WORLD #ifdef DEBUG_WORLD
Log("Creating debug world\n"); Log("Creating debug world\n");
// pos, mass, radius
create_bomb_station(gs, (V2){-5.0f, 0.0f}, BoxExplosive); create_bomb_station(gs, (V2){-5.0f, 0.0f}, BoxExplosive);
create_bomb_station(gs, (V2){0.0f, 5.0f}, BoxGyroscope); create_bomb_station(gs, (V2){0.0f, 5.0f}, BoxGyroscope);
create_hard_shell_station(gs, (V2){-5.0f, 5.0f}, BoxCloaking); create_hard_shell_station(gs, (V2){-5.0f, 5.0f}, BoxCloaking);
@ -1970,6 +2032,7 @@ void create_initial_world(GameState *gs)
enum CompassRotation rot = Right; enum CompassRotation rot = Right;
{ {
Entity *grid = new_entity(gs); Entity *grid = new_entity(gs);
grid_create(gs, grid); grid_create(gs, grid);
entity_set_pos(grid, V2add(from, V2rotate((V2){.x = -BOX_SIZE * 9.0f}, theta))); entity_set_pos(grid, V2add(from, V2rotate((V2){.x = -BOX_SIZE * 9.0f}, theta)));
@ -1978,7 +2041,7 @@ void create_initial_world(GameState *gs)
BOX_AT_TYPE(grid, ((V2){0.0f, 0.0f}), BoxMerge); BOX_AT_TYPE(grid, ((V2){0.0f, 0.0f}), BoxMerge);
BOX_AT(grid, ((V2){0.0f, -BOX_SIZE})); BOX_AT(grid, ((V2){0.0f, -BOX_SIZE}));
BOX_AT_TYPE(grid, ((V2){BOX_SIZE, 0.0f}), BoxMerge); BOX_AT_TYPE(grid, ((V2){BOX_SIZE, 0.0f}), BoxMerge);
entity_ensure_in_orbit(grid); entity_ensure_in_orbit(gs, grid);
} }
{ {
@ -1993,13 +2056,15 @@ void create_initial_world(GameState *gs)
rot = Up; rot = Up;
BOX_AT_TYPE(grid, ((V2){0.0f, BOX_SIZE}), BoxMerge); BOX_AT_TYPE(grid, ((V2){0.0f, BOX_SIZE}), BoxMerge);
cpBodySetVelocity(grid->body, v2_to_cp(V2rotate((V2){-0.4f, 0.0f}, theta))); cpBodySetVelocity(grid->body, v2_to_cp(V2rotate((V2){-0.4f, 0.0f}, theta)));
entity_ensure_in_orbit(grid); entity_ensure_in_orbit(gs, grid);
} }
#else #else
create_bomb_station(gs, (V2){-50.0f, 0.0f}, BoxExplosive); EntityID suns[] = {};
create_hard_shell_station(gs, (V2){0.0f, 100.0f}, BoxGyroscope); create_bomb_station(gs, (V2){-200.0f, 0.0f}, BoxExplosive);
create_bomb_station(gs, (V2){0.0f, -100.0f}, BoxCloaking); create_hard_shell_station(gs, (V2){0.0f, 400.0f}, BoxGyroscope);
create_bomb_station(gs, (V2){100.0f, 100.0f}, BoxMissileLauncher); create_bomb_station(gs, (V2){0.0f, -150.0f}, BoxCloaking);
create_bomb_station(gs, (V2){300.0f, 300.0f}, BoxMissileLauncher);
create_hard_shell_station(gs, (V2){50.0f, 100.0f}, BoxMerge); create_hard_shell_station(gs, (V2){50.0f, 100.0f}, BoxMerge);
#endif #endif
} }
@ -2023,6 +2088,31 @@ void process(GameState *gs, float dt)
gs->time += dt; gs->time += dt;
// process sun gravity
SUNS_ITER(gs)
{
Entity *from_sun = i.sun;
V2 accel = {0};
SUNS_ITER(gs)
{
Entity *other_sun = i.sun;
if (other_sun != from_sun)
{
accel = V2add(accel, sun_gravity_accel_for_entity(from_sun, other_sun));
}
}
#ifndef NO_GRAVITY
from_sun->sun_vel = V2add(from_sun->sun_vel, V2scale(accel, dt));
from_sun->sun_pos = V2add(from_sun->sun_pos, V2scale(from_sun->sun_vel, dt));
if (V2length(from_sun->sun_pos) >= INSTANT_DEATH_DISTANCE_FROM_CENTER)
{
from_sun->sun_vel = V2scale(from_sun->sun_vel, -0.8f);
from_sun->sun_pos = V2scale(V2normalize(from_sun->sun_pos), INSTANT_DEATH_DISTANCE_FROM_CENTER);
}
#endif
}
// process input // process input
PLAYERS_ITER(gs->players, player) PLAYERS_ITER(gs->players, player)
{ {
@ -2065,7 +2155,7 @@ void process(GameState *gs, float dt)
create_player_entity(gs, p); create_player_entity(gs, p);
player->entity = get_id(gs, p); player->entity = get_id(gs, p);
Entity *medbay = get_entity(gs, player->last_used_medbay); Entity *medbay = get_entity(gs, player->last_used_medbay);
entity_ensure_in_orbit(p); entity_ensure_in_orbit(gs, p);
if (medbay != NULL) if (medbay != NULL)
{ {
exit_seat(gs, medbay, p); exit_seat(gs, medbay, p);
@ -2301,11 +2391,10 @@ void process(GameState *gs, float dt)
if (!e->exists) if (!e->exists)
continue; continue;
// sun processing // instant death
{ {
cpVect pos_rel_sun = v2_to_cp(V2sub(entity_pos(e), SUN_POS)); cpFloat dist_from_center = cpvlengthsq(v2_to_cp(entity_pos(e)));
cpFloat sqdist = cpvlengthsq(pos_rel_sun); if (e->body != NULL && dist_from_center > (INSTANT_DEATH_DISTANCE_FROM_CENTER * INSTANT_DEATH_DISTANCE_FROM_CENTER))
if (e->body != NULL && sqdist > (INSTANT_DEATH_DISTANCE_FROM_SUN * INSTANT_DEATH_DISTANCE_FROM_SUN))
{ {
bool platonic_found = false; bool platonic_found = false;
if (e->is_grid) if (e->is_grid)
@ -2323,8 +2412,8 @@ void process(GameState *gs, float dt)
{ {
cpBody *body = e->body; cpBody *body = e->body;
cpBodySetVelocity(body, cpvmult(cpBodyGetVelocity(body), -0.5)); cpBodySetVelocity(body, cpvmult(cpBodyGetVelocity(body), -0.5));
cpVect rel_to_sun = cpvsub(cpBodyGetPosition(body), v2_to_cp(SUN_POS)); cpVect rel_to_center = cpvsub(cpBodyGetPosition(body), (cpVect){0});
cpBodySetPosition(body, cpvadd(v2_to_cp(SUN_POS), cpvmult(cpvnormalize(rel_to_sun), INSTANT_DEATH_DISTANCE_FROM_SUN))); cpBodySetPosition(body, cpvmult(cpvnormalize(rel_to_center), INSTANT_DEATH_DISTANCE_FROM_CENTER));
} }
else else
{ {
@ -2332,10 +2421,18 @@ void process(GameState *gs, float dt)
} }
continue; continue;
} }
}
// sun processing for this current entity
{
SUNS_ITER(gs)
{
cpVect pos_rel_sun = v2_to_cp(V2sub(entity_pos(e), (entity_pos(i.sun))));
cpFloat sqdist = cpvlengthsq(pos_rel_sun);
if (!e->is_grid) // grids aren't damaged (this edge case sucks!) if (!e->is_grid) // grids aren't damaged (this edge case sucks!)
{ {
sqdist = cpvlengthsq(cpvsub(v2_to_cp(entity_pos(e)), v2_to_cp(SUN_POS))); sqdist = cpvlengthsq(cpvsub(v2_to_cp(entity_pos(e)), v2_to_cp(entity_pos(i.sun))));
if (sqdist < (SUN_RADIUS * SUN_RADIUS)) if (sqdist < (i.sun->sun_radius * i.sun->sun_radius))
{ {
e->damage += 10.0f * dt; e->damage += 10.0f * dt;
} }
@ -2343,15 +2440,11 @@ void process(GameState *gs, float dt)
if (e->body != NULL) if (e->body != NULL)
{ {
V2 accel = sun_gravity_accel_for_entity(e, i.sun);
// cpVect g = cpvmult(pos_rel_sun, -sun_gravity_accel_at_point(entity_pos(e), e) / (sqdist * cpfsqrt(sqdist)));
// sun gravitational pull
V2 accel = sun_gravity_accel_for_entity(e);
V2 new_vel = entity_vel(gs, e); V2 new_vel = entity_vel(gs, e);
new_vel = V2add(new_vel, V2scale(accel, dt)); new_vel = V2add(new_vel, V2scale(accel, dt));
cpBodySetVelocity(e->body, v2_to_cp(new_vel)); cpBodySetVelocity(e->body, v2_to_cp(new_vel));
// cpBodySetVelocity(e->body, ) }
// cpBodyUpdateVelocity(e->body, g, 1.0f, dt);
} }
} }
@ -2476,10 +2569,15 @@ void process(GameState *gs, float dt)
{ {
if (cur_box->box_type == BoxSolarPanel) if (cur_box->box_type == BoxSolarPanel)
{ {
cur_box->sun_amount = clamp01(V2dot(box_facing_vector(cur_box), V2normalize(V2sub(SUN_POS, entity_pos(cur_box))))); cur_box->sun_amount = 0.0f;
SUNS_ITER(gs)
{
float new_sun = clamp01(V2dot(box_facing_vector(cur_box), V2normalize(V2sub(entity_pos(i.sun), entity_pos(cur_box)))));
// less sun the farther away you are! // less sun the farther away you are!
cur_box->sun_amount *= lerp(1.0f, 0.0f, clamp01(V2length(V2sub(entity_pos(cur_box), SUN_POS)) / sun_dist_no_gravity())); new_sun *= lerp(1.0f, 0.0f, clamp01(V2length(V2sub(entity_pos(cur_box), entity_pos(i.sun))) / sun_dist_no_gravity(i.sun)));
cur_box->sun_amount += new_sun;
}
energy_to_add += cur_box->sun_amount * SOLAR_ENERGY_PER_SECOND * dt; energy_to_add += cur_box->sun_amount * SOLAR_ENERGY_PER_SECOND * dt;
} }
} }

@ -1940,23 +1940,29 @@ static void frame(void)
set_color(GOLD); set_color(GOLD);
sgp_draw_filled_rect(gs.goldpos.x, gs.goldpos.y, 0.1f, 0.1f); sgp_draw_filled_rect(gs.goldpos.x, gs.goldpos.y, 0.1f, 0.1f);
// instant death
set_color(RED);
draw_circle((V2){0}, INSTANT_DEATH_DISTANCE_FROM_CENTER);
// the SUN // the SUN
SUNS_ITER(&gs)
{
transform_scope transform_scope
{ {
sgp_translate(SUN_POS.x, SUN_POS.y); sgp_translate(entity_pos(i.sun).x, entity_pos(i.sun).y);
set_color(WHITE); set_color(WHITE);
sgp_set_image(0, image_sun); sgp_set_image(0, image_sun);
draw_texture_centered((V2){0}, SUN_RADIUS * 2.0f); draw_texture_centered((V2){0}, i.sun->sun_radius * 2.0f);
sgp_reset_image(0); sgp_reset_image(0);
// can draw at 0,0 because everything relative to sun now! // can draw at 0,0 because everything relative to sun now!
// sun DEATH RADIUS // sun DEATH RADIUS
set_color(RED);
draw_circle((V2){0}, INSTANT_DEATH_DISTANCE_FROM_SUN);
set_color(BLUE); set_color(BLUE);
draw_circle((V2){0}, sun_dist_no_gravity()); draw_circle((V2){0}, sun_dist_no_gravity(i.sun));
}
} }
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f);

@ -18,14 +18,3 @@ If WinActive("flightbuild")
} }
Send, {Blind} ; So it doesn't hold down ctrl after running! WTF Send, {Blind} ; So it doesn't hold down ctrl after running! WTF
return return
^+b::
WinKill, Flight Hosting
WinKill, Flight Not Hosting
WinActivate, flightbuild
If WinActive("flightbuild")
{
Send, {Enter}
Send, remedybg continue-execution && timeout 1 && remedybg.exe stop-debugging && msbuild && remedybg.exe start-debugging && sleep 0.2 && x64\Debug\Flight.exe {Enter}
}
return

@ -4,12 +4,13 @@
#define MAX_BOX_TYPES 64 #define MAX_BOX_TYPES 64
#define MAX_PLAYERS 16 #define MAX_PLAYERS 16
#define MAX_SUNS 8
#define MAX_ENTITIES 1024 * 25 #define MAX_ENTITIES 1024 * 25
#define BOX_SIZE 0.25f #define BOX_SIZE 0.25f
#define MERGE_MAX_DIST (BOX_SIZE / 2.0f + 0.01f) #define MERGE_MAX_DIST (BOX_SIZE / 2.0f + 0.01f)
#define PLAYER_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE}) #define PLAYER_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE})
#define PLAYER_MASS 0.5f #define PLAYER_MASS 0.5f
#define PLAYER_JETPACK_FORCE 1.5f #define PLAYER_JETPACK_FORCE 4.0f
#define PLAYER_JETPACK_TORQUE 0.05f #define PLAYER_JETPACK_TORQUE 0.05f
#define MISSILE_RANGE 4.0f #define MISSILE_RANGE 4.0f
#define MISSILE_BURN_TIME 1.5f #define MISSILE_BURN_TIME 1.5f
@ -33,7 +34,7 @@
#define BUILD_BOX_SNAP_DIST_TO_SHIP 0.2f #define BUILD_BOX_SNAP_DIST_TO_SHIP 0.2f
#define BOX_MASS 1.0f #define BOX_MASS 1.0f
#define COLLISION_DAMAGE_SCALING 0.15f #define COLLISION_DAMAGE_SCALING 0.15f
#define THRUSTER_FORCE 12.0f #define THRUSTER_FORCE 24.0f
#define THRUSTER_ENERGY_USED_PER_SECOND 0.005f #define THRUSTER_ENERGY_USED_PER_SECOND 0.005f
#define GYROSCOPE_ENERGY_USED_PER_SECOND 0.005f #define GYROSCOPE_ENERGY_USED_PER_SECOND 0.005f
#define GYROSCOPE_TORQUE 0.5f #define GYROSCOPE_TORQUE 0.5f
@ -44,14 +45,7 @@
#define MAX_CLIENT_TO_SERVER 1024 * 10 // maximum size of serialized inputs and mic data #define MAX_CLIENT_TO_SERVER 1024 * 10 // maximum size of serialized inputs and mic data
#define GRAVITY_CONSTANT 0.1f #define GRAVITY_CONSTANT 0.1f
#define GRAVITY_SMALLEST 0.01f // used to determine when gravity is clamped to 0.0f #define GRAVITY_SMALLEST 0.01f // used to determine when gravity is clamped to 0.0f
#define SUN_RADIUS 10.0f #define INSTANT_DEATH_DISTANCE_FROM_CENTER 2000.0f
#define INSTANT_DEATH_DISTANCE_FROM_SUN 2000.0f
#define SUN_POS ((V2){50.0f, 0.0f})
#ifdef NO_GRAVITY
#define SUN_MASS 0.0f
#else
#define SUN_MASS (10000.0f)
#endif
#define SOLAR_ENERGY_PER_SECOND 0.09f #define SOLAR_ENERGY_PER_SECOND 0.09f
#define DAMAGE_TO_PLAYER_PER_BLOCK 0.1f #define DAMAGE_TO_PLAYER_PER_BLOCK 0.1f
#define BATTERY_CAPACITY 1.5f #define BATTERY_CAPACITY 1.5f
@ -263,6 +257,13 @@ typedef struct Entity
V2 explosion_vel; V2 explosion_vel;
float explosion_progresss; // in seconds float explosion_progresss; // in seconds
// sun
bool is_sun;
V2 sun_vel;
V2 sun_pos;
float sun_mass;
float sun_radius;
// missile // missile
bool is_missile; bool is_missile;
float time_burned_for; // until MISSILE_BURN_TIME float time_burned_for; // until MISSILE_BURN_TIME
@ -324,6 +325,17 @@ typedef struct Player
EntityID last_used_medbay; EntityID last_used_medbay;
InputFrame input; InputFrame input;
} Player; } Player;
// use i.sun to access the current sun's pointer
typedef struct SunIter
{
int i;
Entity *sun;
} SunIter;
#define SUNS_ITER(gs_ptr) \
for (SunIter i = {0}; i.i < MAX_SUNS; i.i++) \
if ((i.sun = get_entity(gs_ptr, (gs_ptr)->suns[i.i])) != NULL)
// gotta update the serialization functions when this changes // gotta update the serialization functions when this changes
typedef struct GameState typedef struct GameState
{ {
@ -336,6 +348,7 @@ typedef struct GameState
V2 goldpos; V2 goldpos;
Player players[MAX_PLAYERS]; 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! V2 platonic_positions[MAX_BOX_TYPES]; // don't want to search over every entity to get the nearest platonic box!
@ -417,7 +430,7 @@ void process_fixed_timestep(GameState *gs);
void process(struct GameState *gs, float dt); // does in place void process(struct GameState *gs, float dt); // does in place
Entity *closest_box_to_point_in_radius(struct GameState *gs, V2 point, float radius, bool (*filter_func)(Entity *)); Entity *closest_box_to_point_in_radius(struct GameState *gs, V2 point, float radius, bool (*filter_func)(Entity *));
uint64_t tick(struct GameState *gs); uint64_t tick(struct GameState *gs);
float sun_dist_no_gravity(); float sun_dist_no_gravity(Entity *sun);
// all of these return if successful or not // all of these return if successful or not
bool server_to_client_serialize(struct ServerToClient *msg, unsigned char *bytes, size_t *out_len, size_t max_len, Entity *for_this_player, bool to_disk); bool server_to_client_serialize(struct ServerToClient *msg, unsigned char *bytes, size_t *out_len, size_t max_len, Entity *for_this_player, bool to_disk);
@ -434,7 +447,7 @@ V2 entity_pos(Entity *e);
void entity_set_rotation(Entity *e, float rot); void entity_set_rotation(Entity *e, float rot);
void entity_set_pos(Entity *e, V2 pos); void entity_set_pos(Entity *e, V2 pos);
float entity_rotation(Entity *e); float entity_rotation(Entity *e);
void entity_ensure_in_orbit(Entity *e); void entity_ensure_in_orbit(GameState *gs, Entity *e);
void entity_destroy(GameState *gs, Entity *e); void entity_destroy(GameState *gs, Entity *e);
#define BOX_CHAIN_ITER(gs, cur, starting_box) for (Entity *cur = get_entity(gs, starting_box); cur != NULL; cur = get_entity(gs, cur->next_box)) #define BOX_CHAIN_ITER(gs, cur, starting_box) for (Entity *cur = get_entity(gs, starting_box); cur != NULL; cur = get_entity(gs, cur->next_box))
#define BOXES_ITER(gs, cur, grid_entity_ptr) BOX_CHAIN_ITER(gs, cur, (grid_entity_ptr)->boxes) #define BOXES_ITER(gs, cur, grid_entity_ptr) BOX_CHAIN_ITER(gs, cur, (grid_entity_ptr)->boxes)

Loading…
Cancel
Save