Pixel edge rendering fix, game design fixing!

main
Cameron Murphy Reikes 2 years ago
parent b5223ab09b
commit d8b8f2c925

@ -1441,20 +1441,46 @@ V2 get_world_hand_pos(GameState *gs, InputFrame *input, Entity *player)
return potentially_snap_hand_pos(gs, V2add(entity_pos(player), input->hand_pos)); return potentially_snap_hand_pos(gs, V2add(entity_pos(player), input->hand_pos));
} }
// return true if used the energy bool batteries_have_capacity_for(GameState *gs, Entity *grid, float *energy_left_over, float energy_to_use)
bool possibly_use_energy(GameState *gs, Entity *grid, float wanted_energy)
{ {
float seen_energy = 0.0f;
BOXES_ITER(gs, possible_battery, grid) BOXES_ITER(gs, possible_battery, grid)
{ {
if (possible_battery->box_type == BoxBattery && (BATTERY_CAPACITY - possible_battery->energy_used) > wanted_energy) if (possible_battery->box_type == BoxBattery)
{ {
possible_battery->energy_used += wanted_energy; Entity *battery = possible_battery;
seen_energy += BATTERY_CAPACITY - battery->energy_used;
if (seen_energy >= energy_to_use + *energy_left_over)
return true; return true;
} }
} }
return false; return false;
} }
// returns any energy unable to burn
float batteries_use_energy(GameState *gs, Entity *grid, float *energy_left_over, float energy_to_use)
{
if (*energy_left_over > 0.0f)
{
float energy_to_use_from_leftover = fminf(*energy_left_over, energy_to_use);
*energy_left_over -= energy_to_use_from_leftover;
energy_to_use -= energy_to_use_from_leftover;
}
BOXES_ITER(gs, possible_battery, grid)
{
if (possible_battery->box_type == BoxBattery)
{
Entity *battery = possible_battery;
float energy_to_burn_from_this_battery = fminf(BATTERY_CAPACITY - battery->energy_used, energy_to_use);
battery->energy_used += energy_to_burn_from_this_battery;
energy_to_use -= energy_to_burn_from_this_battery;
if (energy_to_use <= 0.0f)
return 0.0f;
}
}
return energy_to_use;
}
void entity_ensure_in_orbit(Entity *e) void entity_ensure_in_orbit(Entity *e)
{ {
cpVect pos = v2_to_cp(V2sub(entity_pos(e), SUN_POS)); cpVect pos = v2_to_cp(V2sub(entity_pos(e), SUN_POS));
@ -1573,17 +1599,19 @@ void process(GameState *gs, float dt)
possibly_to_invite->squad_invited_to = player->squad; possibly_to_invite->squad_invited_to = player->squad;
} }
Entity *p = get_entity(gs, player->entity); Entity *p = get_entity(gs, player->entity);
// player respawning
if (p == NULL) if (p == NULL)
{ {
p = new_entity(gs); p = new_entity(gs);
create_player(gs, p); create_player(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);
if (medbay != NULL) if (medbay != NULL)
{ {
exit_seat(gs, medbay, p); exit_seat(gs, medbay, p);
p->damage = 0.95f;
} }
entity_ensure_in_orbit(p);
} }
assert(p->is_player); assert(p->is_player);
p->presenting_squad = player->squad; p->presenting_squad = player->squad;
@ -1634,6 +1662,7 @@ void process(GameState *gs, float dt)
{ {
p->currently_inside_of_box = get_id(gs, potential_seat); p->currently_inside_of_box = get_id(gs, potential_seat);
potential_seat->player_who_is_inside_of_me = get_id(gs, p); potential_seat->player_who_is_inside_of_me = get_id(gs, p);
if (potential_seat->box_type == BoxMedbay)
player->last_used_medbay = p->currently_inside_of_box; player->last_used_medbay = p->currently_inside_of_box;
} }
} }
@ -1708,38 +1737,45 @@ void process(GameState *gs, float dt)
// @Robust sanitize this input so player can't build on any grid in the world // @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); Entity *target_grid = grid_to_build_on(gs, world_hand_pos);
cpShape *nearest = cpSpacePointQueryNearest(gs->space, v2_to_cp(world_build), 0.01f, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &info); cpShape *maybe_box_to_destroy = cpSpacePointQueryNearest(gs->space, v2_to_cp(world_build), 0.01f, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &info);
if (nearest != NULL) if (maybe_box_to_destroy != NULL)
{ {
Entity *cur_box = cp_shape_entity(nearest); Entity *cur_box = cp_shape_entity(maybe_box_to_destroy);
if (!cur_box->indestructible) if (!cur_box->indestructible)
{ {
Entity *cur_grid = cp_body_entity(cpShapeGetBody(nearest)); Entity *cur_grid = cp_body_entity(cpShapeGetBody(maybe_box_to_destroy));
p->damage -= DAMAGE_TO_PLAYER_PER_BLOCK * ((BATTERY_CAPACITY - cur_box->energy_used) / BATTERY_CAPACITY); p->damage -= DAMAGE_TO_PLAYER_PER_BLOCK * ((BATTERY_CAPACITY - cur_box->energy_used) / BATTERY_CAPACITY);
grid_remove_box(gs, cur_grid, cur_box); grid_remove_box(gs, cur_grid, cur_box);
} }
} }
else if (target_grid == NULL) else
{
// creating a box
p->damage += DAMAGE_TO_PLAYER_PER_BLOCK;
V2 created_box_position;
if (p->damage < 1.0f) // player can't create a box that kills them by making it
{
if (target_grid == NULL)
{ {
Entity *new_grid = new_entity(gs); Entity *new_grid = new_entity(gs);
grid_create(gs, new_grid); grid_create(gs, new_grid);
p->damage += DAMAGE_TO_PLAYER_PER_BLOCK;
entity_set_pos(new_grid, world_build); entity_set_pos(new_grid, world_build);
Entity *new_box = new_entity(gs);
box_create(gs, new_box, new_grid, (V2){0});
new_box->box_type = player->input.build_type;
new_box->compass_rotation = player->input.build_rotation;
cpBodySetVelocity(new_grid->body, v2_to_cp(player_vel(gs, p))); cpBodySetVelocity(new_grid->body, v2_to_cp(player_vel(gs, p)));
target_grid = new_grid;
created_box_position = (V2){0};
} }
else else
{ {
created_box_position = grid_world_to_local(target_grid, world_build);
}
Entity *new_box = new_entity(gs); Entity *new_box = new_entity(gs);
box_create(gs, new_box, target_grid, grid_world_to_local(target_grid, world_build)); box_create(gs, new_box, target_grid, created_box_position);
grid_correct_for_holes(gs, target_grid); // no holey ship for you! grid_correct_for_holes(gs, target_grid); // no holey ship for you!
new_box->box_type = player->input.build_type; new_box->box_type = player->input.build_type;
new_box->compass_rotation = player->input.build_rotation; new_box->compass_rotation = player->input.build_rotation;
p->damage += DAMAGE_TO_PLAYER_PER_BLOCK; if (new_box->box_type == BoxBattery)
new_box->energy_used = BATTERY_CAPACITY;
}
} }
} }
#endif #endif
@ -1847,16 +1883,21 @@ void process(GameState *gs, float dt)
assert(energy_to_add >= 0.0f); assert(energy_to_add >= 0.0f);
} }
// any energy_to_add existing now can also be used to power thrusters/medbay
float non_battery_energy_left_over = energy_to_add;
// use the energy, stored in the batteries, in various boxes // use the energy, stored in the batteries, in various boxes
BOXES_ITER(gs, cur, e) BOXES_ITER(gs, cur, e)
{ {
if (cur->box_type == BoxThruster) if (cur->box_type == BoxThruster)
{ {
float energy_to_consume = cur->wanted_thrust * THRUSTER_ENERGY_USED_PER_SECOND * dt; float energy_to_consume = cur->wanted_thrust * THRUSTER_ENERGY_USED_PER_SECOND * dt;
cur->thrust = 0.0f; if (energy_to_consume > 0.0f)
if (possibly_use_energy(gs, e, energy_to_consume))
{ {
cur->thrust = cur->wanted_thrust; cur->thrust = 0.0f;
float energy_unconsumed = batteries_use_energy(gs, e, &non_battery_energy_left_over, energy_to_consume);
cur->thrust = (1.0f - energy_unconsumed / energy_to_consume) * cur->wanted_thrust;
if (cur->thrust >= 0.0f)
cpBodyApplyForceAtWorldPoint(e->body, v2_to_cp(thruster_force(cur)), v2_to_cp(entity_pos(cur))); cpBodyApplyForceAtWorldPoint(e->body, v2_to_cp(thruster_force(cur)), v2_to_cp(entity_pos(cur)));
} }
} }
@ -1865,10 +1906,11 @@ void process(GameState *gs, float dt)
Entity *potential_meatbag_to_heal = get_entity(gs, cur->player_who_is_inside_of_me); Entity *potential_meatbag_to_heal = get_entity(gs, cur->player_who_is_inside_of_me);
if (potential_meatbag_to_heal != NULL) if (potential_meatbag_to_heal != NULL)
{ {
float energy_to_recharge = fminf(potential_meatbag_to_heal->damage, PLAYER_ENERGY_RECHARGE_PER_SECOND * dt); float wanted_energy_use = fminf(potential_meatbag_to_heal->damage, PLAYER_ENERGY_RECHARGE_PER_SECOND * dt);
if (possibly_use_energy(gs, e, energy_to_recharge)) if (wanted_energy_use > 0.0f)
{ {
potential_meatbag_to_heal->damage -= energy_to_recharge; float energy_unconsumed = batteries_use_energy(gs, e, &non_battery_energy_left_over, wanted_energy_use);
potential_meatbag_to_heal->damage -= (1.0f - energy_unconsumed / wanted_energy_use) * wanted_energy_use;
} }
} }
} }

@ -242,6 +242,7 @@ static sg_image load_image(const char *path)
.pixel_format = SG_PIXELFORMAT_RGBA8, .pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_NEAREST, .min_filter = SG_FILTER_NEAREST,
.mag_filter = SG_FILTER_NEAREST, .mag_filter = SG_FILTER_NEAREST,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.data.subimage[0][0] = { .data.subimage[0][0] = {
.ptr = image_data, .ptr = image_data,
.size = (size_t)(x * y * desired_channels), .size = (size_t)(x * y * desired_channels),

@ -24,14 +24,14 @@
#define INSTANT_DEATH_DISTANCE_FROM_SUN 2000.0f #define INSTANT_DEATH_DISTANCE_FROM_SUN 2000.0f
#define SUN_POS ((V2){50.0f, 0.0f}) #define SUN_POS ((V2){50.0f, 0.0f})
#ifdef NO_GRAVITY #ifdef NO_GRAVITY
#define SUN_GRAVITY_STRENGTH 0.1f #define SUN_GRAVITY_STRENGTH 0.0f
#else #else
#define SUN_GRAVITY_STRENGTH (9.0e2f) #define SUN_GRAVITY_STRENGTH (9.0e2f)
#endif #endif
#define SOLAR_ENERGY_PER_SECOND 0.02f #define SOLAR_ENERGY_PER_SECOND 0.04f
#define DAMAGE_TO_PLAYER_PER_BLOCK 0.1f #define DAMAGE_TO_PLAYER_PER_BLOCK 0.1f
#define BATTERY_CAPACITY DAMAGE_TO_PLAYER_PER_BLOCK * 0.7f #define BATTERY_CAPACITY 1.5f
#define PLAYER_ENERGY_RECHARGE_PER_SECOND 0.1f #define PLAYER_ENERGY_RECHARGE_PER_SECOND 0.2f
#define EXPLOSION_TIME 0.5f #define EXPLOSION_TIME 0.5f
#define EXPLOSION_PUSH_STRENGTH 5.0f #define EXPLOSION_PUSH_STRENGTH 5.0f
#define EXPLOSION_DAMAGE_PER_SEC 10.0f #define EXPLOSION_DAMAGE_PER_SEC 10.0f
@ -48,6 +48,7 @@
#define VOIP_PACKET_MAX_SIZE 4000 #define VOIP_PACKET_MAX_SIZE 4000
#define VOIP_DISTANCE_WHEN_CANT_HEAR (VISION_RADIUS * 0.8f) #define VOIP_DISTANCE_WHEN_CANT_HEAR (VISION_RADIUS * 0.8f)
// multiplayer
#define MAX_REPREDICTION_TIME (TIMESTEP * 50.0f) #define MAX_REPREDICTION_TIME (TIMESTEP * 50.0f)
#define TIME_BETWEEN_SEND_GAMESTATE (1.0f / 20.0f) #define TIME_BETWEEN_SEND_GAMESTATE (1.0f / 20.0f)
#define TIME_BETWEEN_INPUT_PACKETS (1.0f / 20.0f) #define TIME_BETWEEN_INPUT_PACKETS (1.0f / 20.0f)
@ -235,7 +236,7 @@ typedef struct Entity
bool indestructible; bool indestructible;
float wanted_thrust; // the thrust command applied to the thruster float wanted_thrust; // the thrust command applied to the thruster
float thrust; // the actual thrust it can provide based on energy sources in the grid float thrust; // the actual thrust it can provide based on energy sources in the grid
float energy_used; // battery float energy_used; // battery, between 0 battery capacity. You have to look through code to figure out what that is! haha sucker!
float sun_amount; // solar panel, between 0 and 1 float sun_amount; // solar panel, between 0 and 1
EntityID player_who_is_inside_of_me; EntityID player_who_is_inside_of_me;
} Entity; } Entity;

Loading…
Cancel
Save