Better damage and build box preview

main
Cameron Murphy Reikes 2 years ago
parent 1f96942dd2
commit f2ef6d8531

@ -93,17 +93,10 @@ static cpBool on_damage(cpArbiter *arb, cpSpace *space, cpDataPointer userData)
cpShape *a, *b; cpShape *a, *b;
cpArbiterGetShapes(arb, &a, &b); cpArbiterGetShapes(arb, &a, &b);
double total_depth = 0.0f; float damage = V2length(cp_to_v2(cpArbiterTotalImpulse(arb))) * 0.25f;
for (int i = 0; i < cpArbiterGetCount(arb); i++)
total_depth -= cpArbiterGetDepth(arb, i);
// getbox(a)->damage += ;
// float damage = (total_depth / 0.01) * 0.1f;
float damage = V2length(cp_to_v2(cpArbiterTotalImpulse(arb)));
Log("Collision with damage %f\n", damage*0.25f);
if (damage > 0.05f) if (damage > 0.05f)
{ {
Log("Collision with damage %f\n", damage);
getbox(a)->damage += damage; getbox(a)->damage += damage;
getbox(b)->damage += damage; getbox(b)->damage += damage;
} }
@ -191,6 +184,18 @@ V2 grid_vel(struct Grid *grid)
{ {
return cp_to_v2(cpBodyGetVelocity(grid->body)); return cp_to_v2(cpBodyGetVelocity(grid->body));
} }
V2 grid_snapped_box_pos(struct Grid *grid, V2 world)
{
V2 local = cp_to_v2(cpBodyWorldToLocal(grid->body, v2_to_cp(world)));
local.x /= BOX_SIZE;
local.y /= BOX_SIZE;
local.x = roundf(local.x);
local.y = roundf(local.y);
local.x *= BOX_SIZE;
local.y *= BOX_SIZE;
return cp_to_v2(cpBodyLocalToWorld(grid->body, v2_to_cp(local)));
}
float grid_rotation(struct Grid *grid) float grid_rotation(struct Grid *grid)
{ {
return cpBodyGetAngle(grid->body); return cpBodyGetAngle(grid->body);
@ -417,6 +422,42 @@ void from_bytes(struct ServerToClient *msg, char *bytes, int max_len)
} }
} }
// has to be global var because can only get this information
static cpShape *closest_to_point_in_radius_result = NULL;
static float closest_to_point_in_radius_result_largest_dist = 0.0f;
static void closest_point_callback_func(cpShape *shape, cpContactPointSet *points, void *data)
{
assert(points->count == 1);
float dist = V2length(cp_to_v2(cpvsub(points->points[0].pointA, points->points[0].pointB)));
// float dist = -points->points[0].distance;
if(dist > closest_to_point_in_radius_result_largest_dist)
{
closest_to_point_in_radius_result_largest_dist = dist;
closest_to_point_in_radius_result = shape;
}
}
struct Grid *closest_to_point_in_radius(struct GameState *gs, V2 point, float radius)
{
closest_to_point_in_radius_result = NULL;
closest_to_point_in_radius_result_largest_dist = 0.0f;
cpBody * tmpbody = cpBodyNew(0.0f, 0.0f);
cpShape *circle = cpCircleShapeNew(tmpbody, radius, v2_to_cp(point));
cpSpaceShapeQuery(gs->space, circle, closest_point_callback_func, NULL);
cpShapeFree(circle);
cpBodyFree(tmpbody);
if (closest_to_point_in_radius_result != NULL)
{
// @Robust query here for only boxes that are part of ships, could get nasty...
return (struct Grid *)cpBodyGetUserData(cpShapeGetBody(closest_to_point_in_radius_result));
}
return NULL;
}
void process(struct GameState *gs, float dt) void process(struct GameState *gs, float dt)
{ {
assert(gs->space != NULL); assert(gs->space != NULL);

@ -24,11 +24,13 @@ typedef struct KeyPressed
uint64_t frame; uint64_t frame;
} KeyPressed; } KeyPressed;
static KeyPressed keypressed[SAPP_KEYCODE_MENU] = {0}; static KeyPressed keypressed[SAPP_KEYCODE_MENU] = {0};
static V2 mouse_pos = {0};
static bool mouse_frozen = false; // @BeforeShip make this debug only thing
static float funval = 0.0f; // easy to play with value controlled by left mouse button when held down @BeforeShip remove on release builds static float funval = 0.0f; // easy to play with value controlled by left mouse button when held down @BeforeShip remove on release builds
static ENetHost *client; static ENetHost *client;
static ENetPeer *peer; static ENetPeer *peer;
void init(void) static void init(void)
{ {
// @BeforeShip make all fprintf into logging to file, warning dialog grids on failure instead of exit(-1), replace the macros in sokol with this as well, like assert // @BeforeShip make all fprintf into logging to file, warning dialog grids on failure instead of exit(-1), replace the macros in sokol with this as well, like assert
@ -98,6 +100,33 @@ void init(void)
} }
} }
static void drawbox(V2 gridpos, float rot, V2 bpos, float damage, bool offset_from_grid)
{
float halfbox = BOX_SIZE / 2.0f;
sgp_push_transform();
if (offset_from_grid)
{
sgp_rotate_at(rot, gridpos.x, gridpos.y);
}
else
{
sgp_rotate_at(rot, bpos.x, bpos.y);
}
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x - halfbox, bpos.y + halfbox); // left
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y - halfbox); // top
sgp_draw_line(bpos.x + halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y + halfbox); // right
sgp_draw_line(bpos.x - halfbox, bpos.y + halfbox, bpos.x + halfbox, bpos.y + halfbox); // bottom
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y + halfbox); // diagonal
if (damage > 0.0f)
{
sgp_set_color(0.5f, 0.1f, 0.1f, damage);
sgp_draw_filled_rect(bpos.x - halfbox, bpos.y - halfbox, BOX_SIZE, BOX_SIZE);
}
sgp_pop_transform();
}
static void frame(void) static void frame(void)
{ {
int width = sapp_width(), height = sapp_height(); int width = sapp_width(), height = sapp_height();
@ -158,6 +187,8 @@ static void frame(void)
} }
// gameplay // gameplay
V2 build_target_pos = {0};
float build_target_rotation = 0.0f;
{ {
// @Robust accumulate total time and send input at rate like 20 hz, not every frame // @Robust accumulate total time and send input at rate like 20 hz, not every frame
struct ClientToServer curmsg = {0}; struct ClientToServer curmsg = {0};
@ -168,6 +199,7 @@ static void frame(void)
curmsg.movement = input; curmsg.movement = input;
curmsg.inhabit = keypressed[SAPP_KEYCODE_G].pressed; curmsg.inhabit = keypressed[SAPP_KEYCODE_G].pressed;
// @BeforeShip figure out why tf the possess ship key is so unreliable
ENetPacket *packet = enet_packet_create((void *)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); ENetPacket *packet = enet_packet_create((void *)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
enet_peer_send(peer, 0, packet); enet_peer_send(peer, 0, packet);
@ -187,15 +219,22 @@ static void frame(void)
sgp_set_color(0.1f, 0.1f, 0.1f, 1.0f); sgp_set_color(0.1f, 0.1f, 0.1f, 1.0f);
sgp_clear(); sgp_clear();
// Drawing in world space now // sokol drawing library draw in world space
V2 world_mouse_pos = mouse_pos;
{
float zoom = 300.0f + funval;
sgp_translate(width / 2, height / 2); sgp_translate(width / 2, height / 2);
sgp_scale_at(300.0f + funval, 300.0f + funval, 0.0f, 0.0f); world_mouse_pos = V2sub(world_mouse_pos, (V2){.x = width / 2.0f, .y = height / 2.0f});
sgp_scale_at(zoom, zoom, 0.0f, 0.0f);
world_mouse_pos.x /= zoom;
world_mouse_pos.y /= zoom;
// camera go to player // camera go to player
if (myplayer != -1) if (myplayer != -1)
{ {
V2 pos = gs.players[myplayer].pos; V2 pos = gs.players[myplayer].pos;
sgp_translate(-pos.x, -pos.y); sgp_translate(-pos.x, -pos.y);
world_mouse_pos = V2add(world_mouse_pos, (V2){.x = pos.x, .y = pos.y});
}
} }
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f);
@ -236,6 +275,21 @@ static void frame(void)
// sgp_draw_line(grid_pos(p->grid).x, grid_pos(p->grid).y, to.x, to.y); // sgp_draw_line(grid_pos(p->grid).x, grid_pos(p->grid).y, to.x, to.y);
} }
// mouse
if (mouse_frozen)
{
sgp_set_color(1.0f, 0.0f, 0.0f, 0.5f);
sgp_draw_filled_rect(world_mouse_pos.x, world_mouse_pos.y, 0.1f, 0.1f);
}
struct Grid *placing_grid = closest_to_point_in_radius(&gs, world_mouse_pos, 0.35f);
if (placing_grid != NULL)
{
V2 pos = grid_snapped_box_pos(placing_grid, world_mouse_pos);
sgp_set_color(0.5f, 0.5f, 0.5f, (sin(time * 9.0f) + 1.0) / 3.0f + 0.2);
drawbox(grid_pos(placing_grid), grid_rotation(placing_grid), pos, 0.0f, false);
// sgp_draw_filled_rect(pos.x, pos.y, 0.1f, 0.1f);
}
// grids // grids
{ {
for (int i = 0; i < MAX_GRIDS; i++) for (int i = 0; i < MAX_GRIDS; i++)
@ -247,22 +301,11 @@ static void frame(void)
SKIPNULL(g->boxes[ii].shape); SKIPNULL(g->boxes[ii].shape);
struct Box *b = &g->boxes[ii]; struct Box *b = &g->boxes[ii];
sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f); sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f);
sgp_push_transform(); drawbox(grid_pos(g), grid_rotation(g), box_pos(b), b->damage, true);
sgp_rotate_at(box_rotation(b), grid_pos(g).x, grid_pos(g).y);
V2 bpos = box_pos(b);
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x - halfbox, bpos.y + halfbox); // left
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y - halfbox); // top
sgp_draw_line(bpos.x + halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y + halfbox); // right
sgp_draw_line(bpos.x - halfbox, bpos.y + halfbox, bpos.x + halfbox, bpos.y + halfbox); // bottom
sgp_draw_line(bpos.x - halfbox, bpos.y - halfbox, bpos.x + halfbox, bpos.y + halfbox); // diagonal
if (b->damage > 0.01f) if (b->damage > 0.01f)
{ {
Log("Damage: %f\n", b->damage); Log("Damage: %f\n", b->damage);
} }
sgp_set_color(0.5f, 0.1f, 0.1f, b->damage);
sgp_draw_filled_rect(box_pos(b).x - halfbox, box_pos(b).y - halfbox, BOX_SIZE, BOX_SIZE);
sgp_pop_transform();
} }
sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f);
V2 vel = grid_vel(&gs.grids[i]); V2 vel = grid_vel(&gs.grids[i]);
@ -302,6 +345,10 @@ void event(const sapp_event *e)
{ {
case SAPP_EVENTTYPE_KEY_DOWN: case SAPP_EVENTTYPE_KEY_DOWN:
keydown[e->key_code] = true; keydown[e->key_code] = true;
if (e->key_code == SAPP_KEYCODE_T)
{
mouse_frozen = !mouse_frozen;
}
if (keypressed[e->key_code].frame == 0) if (keypressed[e->key_code].frame == 0)
{ {
keypressed[e->key_code].pressed = true; keypressed[e->key_code].pressed = true;
@ -322,6 +369,10 @@ void event(const sapp_event *e)
mouse_down = false; mouse_down = false;
break; break;
case SAPP_EVENTTYPE_MOUSE_MOVE: case SAPP_EVENTTYPE_MOUSE_MOVE:
if (!mouse_frozen)
{
mouse_pos = (V2){.x = e->mouse_x, .y = e->mouse_y};
}
if (mouse_down) if (mouse_down)
{ {
funval += e->mouse_dx; funval += e->mouse_dx;

@ -2,8 +2,8 @@
#define MAX_PLAYERS 4 #define MAX_PLAYERS 4
#define BOX_SIZE 0.5f #define BOX_SIZE 0.5f
#define MAX_GRIDS 16 #define MAX_GRIDS 32
#define MAX_BOXES_PER_GRID 16 #define MAX_BOXES_PER_GRID 32
#define BOX_MASS 1.0f #define BOX_MASS 1.0f
// @Robust remove this include somehow, needed for sqrt and cos // @Robust remove this include somehow, needed for sqrt and cos
@ -96,6 +96,7 @@ void server(void *data); // data parameter required from thread api...
void initialize(struct GameState *gs); // must do this to place boxes into it and process void initialize(struct GameState *gs); // must do this to place boxes into it and process
void destroy(struct GameState *gs); void destroy(struct GameState *gs);
void process(struct GameState *gs, float dt); // does in place void process(struct GameState *gs, float dt); // does in place
struct Grid *closest_to_point_in_radius(struct GameState *gs, V2 point, float radius);
void into_bytes(struct ServerToClient *gs, char *out_bytes, int *out_len, int max_len); void into_bytes(struct ServerToClient *gs, char *out_bytes, int *out_len, int max_len);
void from_bytes(struct ServerToClient *gs, char *bytes, int max_len); void from_bytes(struct ServerToClient *gs, char *bytes, int max_len);
@ -107,6 +108,7 @@ void grid_new(struct Grid *to_modify, struct GameState *gs, V2 pos);
V2 grid_com(struct Grid *grid); V2 grid_com(struct Grid *grid);
V2 grid_pos(struct Grid *grid); V2 grid_pos(struct Grid *grid);
V2 grid_vel(struct Grid *grid); V2 grid_vel(struct Grid *grid);
V2 grid_snapped_box_pos(struct Grid *grid, V2 world); // returns the snapped pos in world coords
float grid_rotation(struct Grid *grid); float grid_rotation(struct Grid *grid);
float grid_angular_velocity(struct Grid *grid); float grid_angular_velocity(struct Grid *grid);
void box_new(struct Box *to_modify, struct GameState *gs, struct Grid *grid, V2 pos); void box_new(struct Box *to_modify, struct GameState *gs, struct Grid *grid, V2 pos);

Loading…
Cancel
Save