Add cloaking device

main
Cameron Murphy Reikes 2 years ago
parent 669798caef
commit 2d84fbbf9c

Binary file not shown.

@ -73,6 +73,28 @@ Entity *get_entity(GameState *gs, EntityID id)
return to_return;
}
bool cloaking_active(GameState *gs, Entity *e)
{
// cloaking doesn't work for first 1/2 second of game because when initializing
// everything needs to be uncloaked
return gs->time >= 0.5 && (gs->time - e->time_was_last_cloaked) <= TIMESTEP * 2.0f;
}
bool is_cloaked(GameState *gs, Entity *e, Entity *this_players_perspective)
{
assert(this_players_perspective != NULL);
assert(this_players_perspective->is_player);
bool cloaked = cloaking_active(gs, e);
if (e->is_player)
{
return cloaked && e->presenting_squad != this_players_perspective->presenting_squad;
}
else
{
return cloaked && this_players_perspective->presenting_squad != e->last_cloaked_by_squad;
}
}
static BOX_UNLOCKS_TYPE box_unlock_number(enum BoxType box)
{
assert((BOX_UNLOCKS_TYPE)box < 64);
@ -129,6 +151,20 @@ static GameState *cp_space_gs(cpSpace *space)
return (GameState *)cpSpaceGetUserData(space);
}
static GameState *entitys_gamestate(Entity *e)
{
assert(e->body != NULL || e->shape != NULL);
if (e->shape != NULL)
{
return cp_space_gs(cpShapeGetSpace(e->shape));
}
if (e->body != NULL)
{
return cp_space_gs(cpBodyGetSpace(e->body));
}
return NULL;
}
int grid_num_boxes(GameState *gs, Entity *e)
{
assert(e->is_grid);
@ -316,6 +352,10 @@ void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, V2 pos, V2
void create_player(Player *player)
{
// default box unlocks, required for survival and growth
#ifdef UNLOCK_ALL
for (enum BoxType t = BoxInvalid + 1; t < BoxLast; t++)
unlock_box(player, t);
#else
unlock_box(player, BoxHullpiece);
unlock_box(player, BoxThruster);
unlock_box(player, BoxBattery);
@ -323,6 +363,7 @@ void create_player(Player *player)
unlock_box(player, BoxMedbay);
unlock_box(player, BoxSolarPanel);
unlock_box(player, BoxScanner);
#endif
}
void create_player_entity(GameState *gs, Entity *e)
@ -609,10 +650,17 @@ V2 grid_snapped_box_pos(Entity *grid, V2 world)
return cp_to_v2(cpBodyLocalToWorld(grid->body, v2_to_cp(local)));
}
float entity_rotation(Entity *grid)
// for boxes does not include box's compass rotation
float entity_rotation(Entity *e)
{
return (float)cpBodyGetAngle(grid->body);
assert(e->body != NULL || e->shape != NULL);
if (e->body != NULL)
return (float)cpBodyGetAngle(e->body);
else
return (float)cpBodyGetAngle(cpShapeGetBody(e->shape));
}
float entity_angular_velocity(Entity *grid)
{
return (float)cpBodyGetAngularVelocity(grid->body);
@ -798,6 +846,7 @@ SerMaybeFailure ser_var(SerState *ser, char *var_pointer, size_t var_size, const
enum GameVersion
{
VInitial,
VMoreBoxes,
VMax, // this minus one will be the version used
};
@ -855,6 +904,14 @@ SerMaybeFailure ser_inputframe(SerState *ser, InputFrame *i)
return ser_ok;
}
SerMaybeFailure ser_no_player(SerState *ser)
{
bool connected = false;
SER_VAR_NAME(&connected, "&p->connected");
return ser_ok;
}
SerMaybeFailure ser_player(SerState *ser, Player *p)
{
SER_VAR(&p->connected);
@ -929,6 +986,9 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
}
}
if (ser->version >= VMoreBoxes && !ser->save_or_load_from_disk)
SER_VAR(&e->time_was_last_cloaked);
SER_VAR(&e->is_player);
if (e->is_player)
{
@ -960,6 +1020,10 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
{
SER_VAR(&e->box_type);
SER_VAR(&e->is_platonic);
if (ser->version >= VMoreBoxes)
SER_VAR(&e->owning_squad);
SER_VAR(&e->always_visible);
SER_MAYBE_RETURN(ser_entityid(ser, &e->next_box));
SER_MAYBE_RETURN(ser_entityid(ser, &e->prev_box));
@ -991,6 +1055,9 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_VAR(&e->platonic_nearest_direction);
SER_VAR(&e->platonic_detection_strength);
break;
case BoxCloaking:
SER_VAR(&e->cloaking_power);
break;
default:
break;
}
@ -1076,12 +1143,19 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s)
SER_MAYBE_RETURN(ser_V2(ser, &gs->goldpos));
if (!ser->save_or_load_from_disk)
if (!ser->save_or_load_from_disk) // don't save player info to disk, this is filled on connection/disconnection
{
// @Robust save player data with their ID or something somehow. Like local backup of their account
for (size_t i = 0; i < MAX_PLAYERS; i++)
{
SER_MAYBE_RETURN(ser_player(ser, &gs->players[i]));
if (get_entity(gs, gs->players[i].entity) != NULL && is_cloaked(gs, get_entity(gs, gs->players[i].entity), ser->for_player))
{
SER_MAYBE_RETURN(ser_no_player(ser));
}
else
{
SER_MAYBE_RETURN(ser_player(ser, &gs->players[i]));
}
}
}
if (ser->serializing)
@ -1090,11 +1164,12 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s)
for (size_t i = 0; i < gs->cur_next_entity; i++)
{
Entity *e = &gs->entities[i];
#define DONT_SEND_BECAUSE_CLOAKED(entity) (!ser->save_or_load_from_disk && ser->for_player != NULL && is_cloaked(gs, entity, ser->for_player))
#define SER_ENTITY() \
SER_VAR(&entities_done); \
SER_VAR(&i); \
SER_MAYBE_RETURN(ser_entity(ser, gs, e))
if (e->exists && !(ser->save_or_load_from_disk && e->no_save_to_disk))
if (e->exists && !(ser->save_or_load_from_disk && e->no_save_to_disk) && !DONT_SEND_BECAUSE_CLOAKED(e))
{
if (!e->is_box && !e->is_grid)
{
@ -1105,10 +1180,14 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s)
bool serialized_grid_yet = false;
// serialize boxes always after bodies, so that by the time the boxes
// are loaded in the parent body is loaded in and can be referenced.
BOXES_ITER(gs, cur, e)
BOXES_ITER(gs, cur_box, e)
{
bool this_box_in_range = (ser->save_or_load_from_disk || ser->for_player == NULL || (ser->for_player != NULL && V2distsqr(entity_pos(ser->for_player), entity_pos(cur)) < VISION_RADIUS * VISION_RADIUS));
if (cur->always_visible)
bool this_box_in_range = ser->save_or_load_from_disk;
this_box_in_range |= ser->for_player == NULL;
this_box_in_range |= (ser->for_player != NULL && V2distsqr(entity_pos(ser->for_player), entity_pos(cur_box)) < VISION_RADIUS * VISION_RADIUS); // only in vision radius
if (DONT_SEND_BECAUSE_CLOAKED(cur_box))
this_box_in_range = false;
if (cur_box->always_visible)
this_box_in_range = true;
if (this_box_in_range)
{
@ -1119,12 +1198,12 @@ SerMaybeFailure ser_server_to_client(SerState *ser, ServerToClient *s)
}
// serialize this box
EntityID cur_id = get_id(gs, cur);
EntityID cur_id = get_id(gs, cur_box);
SER_ASSERT(cur_id.index < gs->max_entities);
SER_VAR(&entities_done);
size_t the_index = (size_t)cur_id.index; // super critical. Type of &i is size_t. @Robust add debug info in serialization for what size the expected type is, maybe string nameof the type
SER_VAR_NAME(&the_index, "&i");
SER_MAYBE_RETURN(ser_entity(ser, gs, cur));
SER_MAYBE_RETURN(ser_entity(ser, gs, cur_box));
}
}
}
@ -1358,6 +1437,16 @@ bool client_to_server_deserialize(GameState *gs, struct ClientToServer *msg, uns
}
}
static void cloaking_shield_callback_func(cpShape *shape, cpContactPointSet *points, void *data)
{
Entity *from_cloaking_box = (Entity *)data;
GameState *gs = entitys_gamestate(from_cloaking_box);
Entity *to_cloak = cp_shape_entity(shape);
to_cloak->time_was_last_cloaked = gs->time;
to_cloak->last_cloaked_by_squad = from_cloaking_box->owning_squad;
}
// has to be global var because can only get this information
static THREADLOCAL cpShape *closest_to_point_in_radius_result = NULL;
static THREADLOCAL float closest_to_point_in_radius_result_largest_dist = 0.0f;
@ -1545,7 +1634,7 @@ V2 box_vel(Entity *box)
return cp_to_v2(cpBodyGetVelocityAtWorldPoint(grid->body, v2_to_cp(entity_pos(box))));
}
void create_station(GameState *gs, V2 pos, enum BoxType platonic_type)
void create_bomb_station(GameState *gs, V2 pos, enum BoxType platonic_type)
{
#define BOX_AT_TYPE(grid, pos, type) \
@ -1562,10 +1651,10 @@ void create_station(GameState *gs, V2 pos, enum BoxType platonic_type)
grid_create(gs, grid);
entity_set_pos(grid, pos);
entity_ensure_in_orbit(grid);
Entity *explosion_box = new_entity(gs);
box_create(gs, explosion_box, grid, (V2){0});
explosion_box->box_type = platonic_type;
explosion_box->is_platonic = true;
Entity *platonic_box = new_entity(gs);
box_create(gs, platonic_box, grid, (V2){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);
@ -1590,15 +1679,54 @@ void create_station(GameState *gs, V2 pos, enum BoxType platonic_type)
BOX_AT_TYPE(grid, ((V2){-BOX_SIZE * 6.0, -BOX_SIZE * 5.0}), BoxExplosive);
}
void create_hard_shell_station(GameState *gs, V2 pos, enum BoxType platonic_type)
{
#define BOX_AT_TYPE(grid, pos, type) \
{ \
Entity *box = new_entity(gs); \
box_create(gs, box, grid, pos); \
box->box_type = type; \
box->indestructible = indestructible; \
}
#define BOX_AT(grid, pos) BOX_AT_TYPE(grid, pos, BoxHullpiece)
bool indestructible = false;
Entity *grid = new_entity(gs);
grid_create(gs, grid);
entity_set_pos(grid, pos);
entity_ensure_in_orbit(grid);
Entity *platonic_box = new_entity(gs);
box_create(gs, platonic_box, grid, (V2){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);
indestructible = true;
for (float y = -BOX_SIZE * 5.0; y <= BOX_SIZE * 5.0; y += BOX_SIZE)
{
BOX_AT_TYPE(grid, ((V2){BOX_SIZE * 5.0, y}), BoxHullpiece);
}
for (float 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);
}
indestructible = false;
}
void create_initial_world(GameState *gs)
{
#if 0
#ifdef DEBUG_WORLD
Log("Creating debug world\n");
create_station(gs, (V2){-5.0f,0.0f}, BoxExplosive);
create_station(gs, (V2){0.0f, 5.0f}, BoxGyroscope);
create_bomb_station(gs, (V2){-5.0f, 0.0f}, BoxExplosive);
create_bomb_station(gs, (V2){0.0f, 5.0f}, BoxGyroscope);
create_hard_shell_station(gs, (V2){-5.0f, 5.0f}, BoxCloaking);
#else
create_station(gs, (V2){-50.0f, 0.0f}, BoxExplosive);
create_station(gs, (V2){0.0f, 100.0f}, BoxGyroscope);
create_bomb_station(gs, (V2){-50.0f, 0.0f}, BoxExplosive);
create_hard_shell_station(gs, (V2){0.0f, 100.0f}, BoxGyroscope);
create_bomb_station(gs, (V2){0.0f, -100.0f}, BoxCloaking);
#endif
}
@ -1788,6 +1916,10 @@ void process(GameState *gs, float dt)
cpBodySetPosition(p->body, v2_to_cp(entity_pos(seat_inside_of)));
cpBodySetVelocity(p->body, v2_to_cp(box_vel(seat_inside_of)));
// share cloaking with box
p->time_was_last_cloaked = seat_inside_of->time_was_last_cloaked;
p->last_cloaked_by_squad = seat_inside_of->last_cloaked_by_squad;
// set thruster thrust from movement
if (seat_inside_of->box_type == BoxCockpit)
{
@ -1859,6 +1991,7 @@ void process(GameState *gs, float dt)
}
Entity *new_box = new_entity(gs);
box_create(gs, new_box, target_grid, created_box_position);
new_box->owning_squad = player->squad;
grid_correct_for_holes(gs, target_grid); // no holey ship for you!
new_box->box_type = player->input.build_type;
new_box->compass_rotation = player->input.build_rotation;
@ -1888,7 +2021,6 @@ void process(GameState *gs, float dt)
// sun processing
{
cpVect pos_rel_sun = v2_to_cp(V2sub(entity_pos(e), SUN_POS));
cpFloat sqdist = cpvlengthsq(pos_rel_sun);
if (e->body != NULL && sqdist > (INSTANT_DEATH_DISTANCE_FROM_SUN * INSTANT_DEATH_DISTANCE_FROM_SUN))
@ -2041,6 +2173,27 @@ void process(GameState *gs, float dt)
}
}
}
if (cur_box->box_type == BoxCloaking)
{
float energy_unconsumed = batteries_use_energy(gs, grid, &non_battery_energy_left_over, CLOAKING_ENERGY_USE * dt);
if (energy_unconsumed >= CLOAKING_ENERGY_USE * dt)
{
cur_box->cloaking_power = lerp(cur_box->cloaking_power, 0.0, dt * 3.0f);
}
else
{
cur_box->cloaking_power = lerp(cur_box->cloaking_power, 1.0, dt * 3.0f);
cpBody *tmp = cpBodyNew(0.0, 0.0);
cpBodySetPosition(tmp, v2_to_cp(entity_pos(cur_box)));
cpBodySetAngle(tmp, entity_rotation(cur_box));
// subtract a little from the panel size so that boxes just at the boundary of the panel
// aren't (sometimes cloaked)/(sometimes not) from floating point imprecision
cpShape *box_shape = cpBoxShapeNew(tmp, CLOAKING_PANEL_SIZE - 0.03f, CLOAKING_PANEL_SIZE - 0.03f, 0.0);
cpSpaceShapeQuery(gs->space, box_shape, cloaking_shield_callback_func, (void *)cur_box);
cpShapeFree(box_shape);
cpBodyFree(tmp);
}
}
if (cur_box->box_type == BoxScanner)
{
// set the nearest platonic solid! only on server as only the server sees everything

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -51,6 +51,7 @@ typedef struct KeyPressed
static KeyPressed keypressed[MAX_KEYDOWN] = {0};
static V2 mouse_pos = {0};
static bool fullscreened = false;
static bool picking_new_boxtype = false;
static bool build_pressed = false;
static bool interact_pressed = false;
@ -109,6 +110,7 @@ static sg_image image_no;
static sg_image image_solarpanel_charging;
static sg_image image_scanner_head;
static sg_image image_itemswitch;
static sg_image image_cloaking_panel;
static enum BoxType toolbar[TOOLBAR_SLOTS] = {
BoxHullpiece,
@ -185,6 +187,10 @@ static struct BoxInfo
.image_path = "loaded/gyroscope.png",
},
{
.type = BoxCloaking,
.image_path = "loaded/cloaking_device.png",
},
};
#define ENTITIES_ITER(cur) \
for (Entity *cur = gs.entities; cur < gs.entities + gs.cur_next_entity; \
@ -527,6 +533,7 @@ static void init(void)
image_solarpanel_charging = load_image("loaded/solarpanel_charging.png");
image_scanner_head = load_image("loaded/scanner_head.png");
image_itemswitch = load_image("loaded/itemswitch.png");
image_cloaking_panel = load_image("loaded/cloaking_panel.png");
}
// socket initialization
@ -634,6 +641,15 @@ bool can_build(int i)
allow_building = box_unlocked(myplayer(), box_type);
return allow_building;
}
static void setup_hueshift(enum Squad squad)
{
struct SquadMeta meta = squad_meta(squad);
hueshift_uniforms_t uniform = {
.is_colorless = meta.is_colorless,
.target_hue = meta.hue,
};
sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t));
}
static V2 screen_to_world(float width, float height, V2 screen)
{
@ -668,7 +684,6 @@ static void ui(bool draw, float dt, float width, float height)
sgp_push_transform();
// draw pick new box type menu
static bool picking_new_boxtype = false;
static float pick_opacity = 0.0f;
{
if (keypressed[SAPP_KEYCODE_ESCAPE].pressed)
@ -705,6 +720,7 @@ static void ui(bool draw, float dt, float width, float height)
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f * pick_opacity);
}
int boxes_per_row = (int)floorf(pick_modal.width / 128.0f);
boxes_per_row = boxes_per_row < 4 ? 4 : boxes_per_row;
float cell_width = pick_modal.width / (float)boxes_per_row;
float cell_height = cell_width;
float padding = 0.2f * cell_width;
@ -742,6 +758,7 @@ static void ui(bool draw, float dt, float width, float height)
if (item_being_hovered && build_pressed && picking_new_boxtype)
{
toolbar[cur_toolbar_slot] = info.type;
picking_new_boxtype = false;
build_pressed = false;
}
if (draw)
@ -816,12 +833,7 @@ static void ui(bool draw, float dt, float width, float height)
{
pipeline_scope(hueshift_pipeline)
{
struct SquadMeta meta = squad_meta(draw_as_squad);
hueshift_uniforms_t uniform = {
.is_colorless = meta.is_colorless,
.target_hue = meta.hue,
};
sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t));
setup_hueshift(draw_as_squad);
sgp_scale_at(1.0f, -1.0f, x,
invite_y); // images upside down by default :(
sgp_set_image(0, image_squad_invite);
@ -892,11 +904,7 @@ static void ui(bool draw, float dt, float width, float height)
}
pipeline_scope(hueshift_pipeline)
{
struct SquadMeta meta = squad_meta(myplayer()->squad);
hueshift_uniforms_t uniform = {0};
uniform.is_colorless = meta.is_colorless;
uniform.target_hue = meta.hue;
sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t));
setup_hueshift(myplayer()->squad);
sgp_scale_at(1.0f, -1.0f, pos.x,
pos.y); // images upside down by default :(
@ -1020,11 +1028,7 @@ static void ui(bool draw, float dt, float width, float height)
pipeline_scope(hueshift_pipeline)
{
struct SquadMeta meta = squad_meta(this_squad);
hueshift_uniforms_t uniform = {0};
uniform.is_colorless = meta.is_colorless;
uniform.target_hue = meta.hue;
sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t));
setup_hueshift(this_squad);
sgp_rotate_at(flag_rot[i], flag_pos[i].x, flag_pos[i].y);
sgp_scale_at(1.0f, -1.0f, flag_pos[i].x,
@ -1786,8 +1790,22 @@ static void frame(void)
{
set_color(GOLD);
}
pipeline_scope(goodpixel_pipeline)
// all of these box types show team colors so are drawn with the hue shifting shader
// used with the player
if (b->box_type == BoxCloaking)
{
pipeline_scope(hueshift_pipeline)
{
setup_hueshift(b->owning_squad);
draw_texture_centered(entity_pos(b), BOX_SIZE);
}
}
else
{
pipeline_scope(goodpixel_pipeline)
draw_texture_centered(entity_pos(b), BOX_SIZE);
}
sgp_reset_image(0);
if (b->box_type == BoxScanner)
@ -1795,9 +1813,11 @@ static void frame(void)
sgp_set_image(0, image_scanner_head);
transform_scope
{
sgp_rotate_at(b->scanner_head_rotate, entity_pos(b).x, entity_pos(b).y);
pipeline_scope(goodpixel_pipeline)
draw_texture_centered(entity_pos(b), BOX_SIZE);
{
sgp_rotate_at(b->scanner_head_rotate, entity_pos(b).x, entity_pos(b).y);
draw_texture_centered(entity_pos(b), BOX_SIZE);
}
}
sgp_reset_image(0);
set_color(WHITE);
@ -1811,12 +1831,21 @@ static void frame(void)
}
sgp_set_color(0.5f, 0.1f, 0.1f, b->damage);
draw_color_rect_centered(entity_pos(b), BOX_SIZE);
if (b->box_type == BoxCloaking)
{
sgp_set_color(1.0f, 1.0f, 1.0f, b->cloaking_power);
sgp_set_image(0, image_cloaking_panel);
pipeline_scope(goodpixel_pipeline)
draw_texture_centered(entity_pos(b), CLOAKING_PANEL_SIZE);
sgp_reset_image(0);
}
}
// outside of the transform scope
if (b->box_type == BoxScanner)
{
if (b->platonic_detection_strength > 0.0f)
if (b->platonic_detection_strength > 0.0)
{
set_color(colhexcode(0xf2d75c));
V2 to = V2add(entity_pos(b), V2scale(b->platonic_nearest_direction, b->platonic_detection_strength));
@ -1839,11 +1868,7 @@ static void frame(void)
pipeline_scope(hueshift_pipeline)
{
struct SquadMeta meta = squad_meta(e->presenting_squad);
hueshift_uniforms_t uniform = {0};
uniform.is_colorless = meta.is_colorless;
uniform.target_hue = meta.hue;
sgp_set_uniform(&uniform, sizeof(hueshift_uniforms_t));
setup_hueshift(e->presenting_squad);
sgp_set_image(0, image_player);
draw_texture_rectangle_centered(
entity_pos(e), V2scale(PLAYER_SIZE, player_scaling));
@ -1967,6 +1992,14 @@ void event(const sapp_event *e)
int target_slot = key_num - 1;
if (target_slot <= TOOLBAR_SLOTS && target_slot >= 0)
{
if (target_slot == cur_toolbar_slot)
{
picking_new_boxtype = !picking_new_boxtype;
}
else
{
picking_new_boxtype = false;
}
cur_toolbar_slot = target_slot;
}

@ -95,15 +95,9 @@ void server(void *info_raw)
OpusEncoder *player_encoders[MAX_PLAYERS] = {0};
OpusDecoder *player_decoders[MAX_PLAYERS] = {0};
// for (int i = 0; i < MAX_PLAYERS; i++)
//{
// int error = 0;
// player_encoders[i] = opus_encoder_create(VOIP_SAMPLE_RATE, 1, OPUS_APPLICATION_VOIP, &error);
// if (error != OPUS_OK) Log("Failed to create encoder\n");
// player_decoders[i] = opus_decoder_create(VOIP_SAMPLE_RATE, 1, &error);
// if (error != OPUS_OK) Log("Failed to create decoder\n");
// }
#ifdef DEBUG_WORLD
world_save_name = NULL;
#endif
if (world_save_name != NULL)
{
size_t read_game_data_buffer_size = entities_size;
@ -263,11 +257,6 @@ void server(void *info_raw)
player_decoders[player_slot] = opus_decoder_create(VOIP_SAMPLE_RATE, 1, &error);
if (error != OPUS_OK)
Log("Failed to create decoder: %d\n", error);
#ifdef UNLOCK_ALL
gs.players[player_slot].unlocked_bombs = true;
#endif
gs.players[player_slot].squad = SquadPurple;
}
}
break;

@ -9,6 +9,7 @@ SetWorkingDir, %A_ScriptDir%
^b::
WinKill, Flight Hosting
WinKill, Flight Not Hosting
WinActivate, flightbuild
If WinActive("flightbuild")
{
@ -18,14 +19,12 @@ If WinActive("flightbuild")
return
^+b::
WinKill, Flight
Sleep, 20
WinKill, Flight
Sleep, 20
WinKill, Flight
WinKill, Flight Hosting
WinKill, Flight Not Hosting
WinActivate, flightbuild
If WinActive("flightbuild")
{
Send, cd C:\Users\Cameron\Documents\flight{Enter} build_debug.bat && START /B flight_debug.exe && flight_debug.exe --host{Enter}
Send, {Enter}
Send, remedybg continue-execution && sleep 0.1 && remedybg.exe stop-debugging && msbuild && remedybg.exe start-debugging && sleep 0.2 && x64\Debug\Flight.exe {Enter}
}
return

@ -26,6 +26,8 @@
#define THRUSTER_ENERGY_USED_PER_SECOND 0.005f
#define GYROSCOPE_ENERGY_USED_PER_SECOND 0.005f
#define GYROSCOPE_TORQUE 0.5f
#define CLOAKING_ENERGY_USE 0.1f
#define CLOAKING_PANEL_SIZE BOX_SIZE*3.0f
#define VISION_RADIUS 12.0f
#define MAX_SERVER_TO_CLIENT 1024 * 512 // maximum size of serialized gamestate buffer
#define MAX_CLIENT_TO_SERVER 1024 * 10 // maximum size of serialized inputs and mic data
@ -151,6 +153,7 @@ enum BoxType
BoxExplosive,
BoxScanner,
BoxGyroscope,
BoxCloaking,
BoxLast,
};
@ -218,7 +221,13 @@ typedef struct Entity
float damage; // used by box and player
cpBody *body; // used by grid, player, and box
cpShape *shape; // must be a box so shape_size can be set appropriately, and serialized
// players and boxes can be cloaked
// If this is within 2 timesteps of the current game time, the entity is invisible.
double time_was_last_cloaked;
enum Squad last_cloaked_by_squad;
// for serializing the shape
// @Robust remove shape_parent_entity from this struct, use the shape's body to figure out
// what the shape's parent entity is
@ -227,7 +236,7 @@ typedef struct Entity
// player
bool is_player;
enum Squad presenting_squad;
enum Squad presenting_squad; // also controls what the player can see, because of cloaking!
EntityID currently_inside_of_box;
enum Squad squad_invited_to; // if squad none, then no squad invite
float goldness; // how much the player is a winner
@ -245,6 +254,7 @@ typedef struct Entity
// boxes
bool is_box;
enum Squad owning_squad; // which squad owns this box
enum BoxType box_type;
bool is_platonic; // can't be destroyed, unaffected by physical forces
bool always_visible; // always serialized to the player. @Robust check if not used
@ -267,6 +277,9 @@ typedef struct Entity
// only serialized when box_type is solar panel
float sun_amount; // solar panel, between 0 and 1
// cloaking only
float cloaking_power; // 0.0 if unable to be used because no power, 1.0 if fully cloaking!
// scanner only stuff!
EntityID currently_scanning;
float currently_scanning_progress; // when 1.0, scans it!
@ -292,6 +305,8 @@ typedef struct GameState
{
cpSpace *space;
// @Robust for the integer tick, also store a float for how much time has been processed.
// Like a whole timestep then a float for subtimestep
double time; // @Robust separate tick integer not prone to precision issues. Could be very large as is saved to disk!
V2 goldpos;

Loading…
Cancel
Save