diff --git a/gamestate.c b/gamestate.c index 4b8d30b..bdda240 100644 --- a/gamestate.c +++ b/gamestate.c @@ -313,6 +313,8 @@ void ser_grid(char **out, struct Grid *g) ser_float(out, grid_rotation(g)); ser_float(out, grid_angular_velocity(g)); + ser_float(out, g->total_energy_capacity); + for (int i = 0; i < MAX_BOXES_PER_GRID; i++) { bool exists = g->boxes[i].shape != NULL; @@ -350,6 +352,8 @@ void des_grid(char **in, struct Grid *g, struct GameState *gs) cpBodySetAngle(g->body, rot); cpBodySetAngularVelocity(g->body, angular_vel); + des_float(in, &g->total_energy_capacity); + for (int i = 0; i < MAX_BOXES_PER_GRID; i++) { bool exists = false; @@ -543,15 +547,6 @@ struct Grid *closest_to_point_in_radius(struct GameState *gs, V2 point, float ra return NULL; } -// for random generation -static float hash11(float p) -{ - p = fract(p * .1031); - p *= p + 33.33; - p *= p + p; - return fract(p); -} - V2 thruster_direction(struct Box *box) { assert(box->type == BoxThruster); @@ -676,6 +671,8 @@ void process(struct GameState *gs, float dt) // set thruster thrust from movement { + float energy_available = g->total_energy_capacity; + V2 target_direction = {0}; if (V2length(p->input.movement) > 0.0f) { @@ -690,7 +687,13 @@ void process(struct GameState *gs, float dt) float wanted_thrust = -V2dot(target_direction, thruster_direction(&g->boxes[ii])); wanted_thrust = clamp01(wanted_thrust); - g->boxes[ii].thrust = wanted_thrust; + float needed_energy = wanted_thrust * THRUSTER_ENERGY_USED_PER_SECOND * dt; + energy_available -= needed_energy; + + if(energy_available > 0.0f) + g->boxes[ii].thrust = wanted_thrust; + else + g->boxes[ii].thrust = 0.0f; } } // cpBodyApplyForceAtWorldPoint(g->body, v2_to_cp(V2scale(p->input.movement, 5.0f)), v2_to_cp(grid_com(g))); @@ -814,6 +817,12 @@ void process(struct GameState *gs, float dt) } } } + + gs->grids[i].total_energy_capacity = 0.0f; + for(int ii = 0; ii < batteries_len; ii++) + { + gs->grids[i].total_energy_capacity += 1.0f - batteries[ii]->energy_used; + } } cpSpaceStep(gs->space, dt); diff --git a/loaded/thruster.png b/loaded/thruster.png index f1c69ce..2a6851b 100644 Binary files a/loaded/thruster.png and b/loaded/thruster.png differ diff --git a/loaded/thrusterburn.png b/loaded/thrusterburn.png new file mode 100644 index 0000000..d1e3964 Binary files /dev/null and b/loaded/thrusterburn.png differ diff --git a/main.c b/main.c index 63a77c1..cdad778 100644 --- a/main.c +++ b/main.c @@ -41,6 +41,7 @@ static float zoom_target = 300.0f; static float zoom = 300.0f; static sg_image image_itemframe; static sg_image image_itemframe_selected; +static sg_image image_thrusterburn; static int cur_editing_boxtype = -1; static int cur_editing_rotation = 0; @@ -133,6 +134,7 @@ static void init(void) { boxes[i].image = load_image(boxes[i].image_path); } + image_thrusterburn = load_image("loaded/thrusterburn.png"); image_itemframe = load_image("loaded/itemframe.png"); image_itemframe_selected = load_image("loaded/itemframe_selected.png"); } @@ -185,24 +187,37 @@ static void init(void) } } -static void drawbox(V2 boxpos, float rot, float damage, enum BoxType type, enum Rotation rotation) -{ - float halfbox = BOX_SIZE / 2.0f; - sgp_push_transform(); - sgp_rotate_at(rot, boxpos.x, boxpos.y); +// static void drawbox(V2 boxpos, float rot, float damage, enum BoxType type, enum Rotation rotation) +// { - sgp_set_image(0, boxinfo(type).image); - sgp_rotate_at(rotangle(rotation), boxpos.x, boxpos.y); - sgp_draw_textured_rect(boxpos.x - halfbox, boxpos.y - halfbox, BOX_SIZE, BOX_SIZE); - sgp_reset_image(0); +// sgp_push_transform(); +// sgp_rotate_at(rot, boxpos.x, boxpos.y); - if (damage > 0.0f) - { - sgp_set_color(0.5f, 0.1f, 0.1f, damage); - sgp_draw_filled_rect(boxpos.x - halfbox, boxpos.y - halfbox, BOX_SIZE, BOX_SIZE); - } +// sgp_set_image(0, boxinfo(type).image); +// sgp_rotate_at(rotangle(rotation), boxpos.x, boxpos.y); + +// sgp_reset_image(0); + +// if (damage > 0.0f) +// { +// sgp_set_color(0.5f, 0.1f, 0.1f, damage); + +// } + +// sgp_pop_transform(); +// } - sgp_pop_transform(); +static void draw_color_rect_centered(V2 center, float size) +{ + float halfbox = size / 2.0f; + + sgp_draw_filled_rect(center.x - halfbox, center.y - halfbox, size, size); +} + +static void draw_texture_centered(V2 center, float size) +{ + float halfbox = size / 2.0f; + sgp_draw_textured_rect(center.x - halfbox, center.y - halfbox, BOX_SIZE, BOX_SIZE); } static void draw_circle(V2 point, float radius) @@ -435,12 +450,12 @@ static void frame(void) }; cur_input_frame.movement = input; cur_input_frame.inhabit = keypressed[SAPP_KEYCODE_G].pressed; - cur_input_frame.dobuild = mouse_pressed; - cur_input_frame.grid_index = grid_index; - if (cur_input_frame.dobuild) + if (mouse_pressed && cur_editing_boxtype != -1) { + cur_input_frame.dobuild = mouse_pressed; cur_input_frame.build_type = cur_editing_boxtype; cur_input_frame.build_rotation = cur_editing_rotation; + cur_input_frame.grid_index = grid_index; if (grid_index != -1) { cur_input_frame.build = grid_world_to_local(&gs.grids[cur_input_frame.grid_index], build_preview.pos); @@ -535,9 +550,19 @@ static void frame(void) } // building preview - if(cur_editing_boxtype != -1){ + if (cur_editing_boxtype != -1) + { sgp_set_color(0.5f, 0.5f, 0.5f, (sin(time * 9.0f) + 1.0) / 3.0f + 0.2); - drawbox(build_preview.pos, build_preview.grid_rotation, 0.0f, cur_editing_boxtype, cur_editing_rotation); + + sgp_push_transform(); + + sgp_set_image(0, boxinfo(cur_editing_boxtype).image); + sgp_rotate_at(build_preview.grid_rotation + rotangle(cur_editing_rotation), build_preview.pos.x, build_preview.pos.y); + draw_texture_centered(build_preview.pos, BOX_SIZE); + // drawbox(build_preview.pos, build_preview.grid_rotation, 0.0f, cur_editing_boxtype, cur_editing_rotation); + sgp_reset_image(0); + + sgp_pop_transform(); } // grids @@ -560,7 +585,7 @@ static void frame(void) dbg_line(box_pos(b), V2add(box_pos(b), V2scale(thruster_force(b), -1.0f))); } } - if(b->type == BoxBattery) + if (b->type == BoxBattery) { float cur_alpha = sgp_get_color().a; Color from = WHITE; @@ -568,7 +593,36 @@ static void frame(void) Color result = Collerp(from, to, b->energy_used); sgp_set_color(result.r, result.g, result.b, cur_alpha); } - drawbox(box_pos(b), grid_rotation(g), b->damage, b->type, b->rotation); + sgp_push_transform(); + + sgp_rotate_at(grid_rotation(g) + rotangle(b->rotation), box_pos(b).x, box_pos(b).y); + + if (b->type == BoxThruster) + { + sgp_push_transform(); + sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); + sgp_set_image(0, image_thrusterburn); + // float scaling = 1.0 + (hash11(time*3.0)/2.0)*lerp(0.0, 0.07, b->thrust); + // printf("%f\n", b->thrust); + float scaling = 0.95 + lerp(0.0, 0.3,b->thrust); + // float scaling = 1.1; + // sgp_translate(-(scaling*BOX_SIZE - BOX_SIZE), 0.0); + // sgp_scale(scaling, 1.0); + sgp_scale_at(scaling, 1.0, box_pos(b).x, box_pos(b).y); + draw_texture_centered(box_pos(b), BOX_SIZE); + sgp_reset_image(0); + sgp_pop_transform(); + } + + + sgp_set_image(0, boxinfo(b->type).image); + draw_texture_centered(box_pos(b), BOX_SIZE); + sgp_reset_image(0); + + sgp_set_color(0.5f, 0.1f, 0.1f, b->damage); + draw_color_rect_centered(box_pos(b), BOX_SIZE); + + sgp_pop_transform(); } sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); V2 vel = grid_vel(&gs.grids[i]); @@ -650,7 +704,7 @@ void event(const sapp_event *e) } int key_num = e->key_code - SAPP_KEYCODE_0; int target_box = key_num - 1; - if(target_box < BoxLast) + if (target_box < BoxLast) { cur_editing_boxtype = target_box; } diff --git a/server.c b/server.c index b0d8ad7..47e928d 100644 --- a/server.c +++ b/server.c @@ -21,13 +21,17 @@ void server(void *data) box_new(&gs.grids[0].boxes[0], &gs, &gs.grids[0], (V2){0}); box_new(&gs.grids[0].boxes[1], &gs, &gs.grids[0], (V2){0, BOX_SIZE}); box_new(&gs.grids[0].boxes[2], &gs, &gs.grids[0], (V2){0, BOX_SIZE*2.0}); + gs.grids[0].boxes[2].type = BoxBattery; + box_new(&gs.grids[0].boxes[3], &gs, &gs.grids[0], (V2){BOX_SIZE, BOX_SIZE*2.0}); gs.grids[0].boxes[3].type = BoxThruster; gs.grids[0].boxes[3].rotation = Right; + box_new(&gs.grids[0].boxes[4], &gs, &gs.grids[0], (V2){0, BOX_SIZE*3.0}); gs.grids[0].boxes[4].type = BoxThruster; gs.grids[0].boxes[4].rotation = Up; + grid_new(&gs.grids[1], &gs, (V2){.x = -BOX_SIZE*1.5, .y = 0.0}); box_new(&gs.grids[1].boxes[0], &gs, &gs.grids[1], (V2){0}); @@ -158,7 +162,6 @@ void server(void *data) continue; // don't reprocess inputs already processed struct InputFrame cur_input = received.inputs[i]; gs.players[player_slot].input.movement = cur_input.movement; - gs.players[player_slot].input.grid_index = cur_input.grid_index; // for these "event" inputs, only modify the current input if the event is true. // while processing the gamestate, will mark it as false once processed. This @@ -169,6 +172,7 @@ void server(void *data) } if (cur_input.dobuild) { + gs.players[player_slot].input.grid_index = cur_input.grid_index; gs.players[player_slot].input.build = cur_input.build; gs.players[player_slot].input.dobuild = cur_input.dobuild; gs.players[player_slot].input.build_type = cur_input.build_type; diff --git a/types.h b/types.h index 2f57e85..c09f690 100644 --- a/types.h +++ b/types.h @@ -126,6 +126,7 @@ struct GameState struct Grid { cpBody *body; + float total_energy_capacity; // updated every frame by thruster logic struct Box { @@ -338,6 +339,15 @@ static V2 V2lerp(V2 a, V2 b, float factor) return to_return; } +// for random generation +static float hash11(float p) +{ + p = fract(p * .1031); + p *= p + 33.33; + p *= p + p; + return fract(p); +} + typedef struct Color { float r, g, b, a;