Some new UI and orbs

main
Cameron Murphy Reikes 2 years ago
parent 34a2406200
commit 54992b9043

@ -23,7 +23,7 @@
#define DEBUG_TOOLS
#define CHIPMUNK_INTEGRITY_CHECK
// #define FAT_THRUSTERS
#define NO_GRAVITY
// #define NO_GRAVITY
// #define NO_SUNS
#else

Binary file not shown.

@ -352,7 +352,7 @@ LauncherTarget missile_launcher_target(GameState *gs, Entity *launcher)
{
cpShape *cur_shape = res->shape;
Entity *other = cp_shape_entity(cur_shape);
flight_assert(other->is_box || other->is_player || other->is_missile);
flight_assert(other->is_box || other->is_player || other->is_missile || other->is_orb);
cpVect to = cpvsub(entity_pos(other), entity_pos(launcher));
bool should_attack = true;
@ -360,6 +360,8 @@ LauncherTarget missile_launcher_target(GameState *gs, Entity *launcher)
should_attack = false;
if (other->owning_squad == launcher->owning_squad)
should_attack = false;
if (other->is_orb)
should_attack = true;
if (should_attack && cpvlength(to) < nearest_dist)
{
@ -532,14 +534,18 @@ void entity_set_rotation(Entity *e, double rot)
void entity_set_pos(Entity *e, cpVect pos)
{
flight_assert(e->is_grid);
flight_assert(e->body != NULL);
cpBodySetPosition(e->body, (pos));
}
static const cpShapeFilter BOXES_FILTER = {CP_NO_GROUP, BOXES, CP_ALL_CATEGORIES};
static const cpShapeFilter NOT_BOXES_FILTER = {CP_NO_GROUP, CP_ALL_CATEGORIES & (~BOXES), CP_ALL_CATEGORIES};
#define PLAYER_SHAPE_FILTER cpShapeFilterNew(CP_NO_GROUP, PLAYERS, CP_ALL_CATEGORIES)
// size is (1/2 the width, 1/2 the height)
void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, cpVect pos, cpVect size, double mass)
{
// @Robust remove this garbage
if (e->shape != NULL)
{
cpSpaceRemoveShape(gs->space, e->shape);
@ -561,9 +567,18 @@ void create_rectangle_shape(GameState *gs, Entity *e, Entity *parent, cpVect pos
cpShapeSetUserData(e->shape, (void *)e);
cpShapeSetMass(e->shape, mass);
cpSpaceAddShape(gs->space, e->shape);
cpShapeSetFilter(e->shape, NOT_BOXES_FILTER);
}
void create_circle_shape(GameState *gs, Entity *e, double radius)
{
e->shape = cpCircleShapeNew(e->body, ORB_RADIUS, cpv(0, 0));
e->shape_parent_entity = get_id(gs, e);
e->shape_radius = radius;
cpShapeSetMass(e->shape, ORB_MASS);
cpShapeSetUserData(e->shape, (void *)e);
cpSpaceAddShape(gs->space, e->shape);
cpShapeSetFilter(e->shape, NOT_BOXES_FILTER);
}
#define PLAYER_SHAPE_FILTER cpShapeFilterNew(CP_NO_GROUP, PLAYERS, CP_ALL_CATEGORIES)
void create_player(Player *player)
{
@ -583,6 +598,14 @@ void create_player(Player *player)
#endif
}
void create_orb(GameState *gs, Entity *e)
{
create_body(gs, e);
create_circle_shape(gs, e, ORB_RADIUS);
e->is_circle_shape = true;
e->is_orb = true;
}
void create_missile(GameState *gs, Entity *e)
{
create_body(gs, e);
@ -623,7 +646,7 @@ void box_create(GameState *gs, Entity *new_box, Entity *grid, cpVect pos)
create_rectangle_shape(gs, new_box, grid, pos, (cpVect){halfbox, halfbox}, 1.0);
cpShapeSetFilter(new_box->shape, cpShapeFilterNew(CP_NO_GROUP, BOXES, CP_ALL_CATEGORIES));
cpShapeSetFilter(new_box->shape, BOXES_FILTER);
box_add_to_boxes(gs, grid, new_box);
}
@ -970,9 +993,11 @@ Entity *box_grid(Entity *box)
return (Entity *)cpBodyGetUserData(cpShapeGetBody(box->shape));
}
// in local space
cpVect entity_shape_pos(Entity *box)
cpVect entity_shape_pos(Entity *e)
{
return (cpShapeGetCenterOfGravity(box->shape));
flight_assert(e != NULL);
flight_assert(e->shape != NULL);
return (cpShapeGetCenterOfGravity(e->shape));
}
double entity_shape_mass(Entity *box)
{
@ -1316,10 +1341,18 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
bool has_shape = ser->serializing && e->shape != NULL;
SER_VAR(&has_shape);
if (has_shape)
{
SER_VAR(&e->is_circle_shape);
if (e->is_circle_shape)
{
SER_MAYBE_RETURN(ser_f(ser, &e->shape_radius));
}
else
{
SER_MAYBE_RETURN(ser_fV2(ser, &e->shape_size));
}
SER_MAYBE_RETURN(ser_entityid(ser, &e->shape_parent_entity));
Entity *parent = get_entity(gs, e->shape_parent_entity);
SER_ASSERT(parent != NULL);
@ -1344,11 +1377,18 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_VAR(&filter.group);
SER_VAR(&filter.mask);
if (!ser->serializing)
{
if (e->is_circle_shape)
{
create_circle_shape(gs, e, e->shape_radius);
}
else
{
create_rectangle_shape(gs, e, parent, shape_pos, e->shape_size, shape_mass);
cpShapeSetFilter(e->shape, filter);
}
}
}
if (!ser->save_or_load_from_disk)
{
@ -1393,12 +1433,17 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
SER_MAYBE_RETURN(ser_entityid(ser, &e->boxes));
}
SER_VAR(&e->is_missile)
SER_VAR(&e->is_missile);
if (e->is_missile)
{
SER_MAYBE_RETURN(ser_f(ser, &e->time_burned_for));
}
SER_VAR(&e->is_orb);
if (e->is_orb)
{
}
SER_VAR(&e->is_box);
if (e->is_box)
{
@ -1920,7 +1965,6 @@ static bool scanner_filter(Entity *e)
static void do_explosion(GameState *gs, Entity *explosion, double dt)
{
double cur_explosion_damage = dt * EXPLOSION_DAMAGE_PER_SEC;
cpVect explosion_origin = explosion->explosion_pos;
double explosion_push_strength = explosion->explosion_push_strength;
@ -2255,6 +2299,16 @@ void create_initial_world(GameState *gs)
}
#ifndef DEBUG_WORLD
Log("Creating release world\n");
#define ORB_AT(pos) \
{ \
Entity *orb = new_entity(gs); \
create_orb(gs, orb); \
entity_set_pos(orb, pos); \
}
ORB_AT(cpv(-5.0, 0.0));
ORB_AT(cpv(-50.0, 100.0));
ORB_AT(cpv(-50.0, -100.0));
create_bomb_station(gs, (cpVect){800.0, 800.0}, BoxExplosive);
// create_hard_shell_station(gs, (cpVect){800.0, 400.0}, BoxGyroscope);
create_bomb_station(gs, (cpVect){800.0, -800.0}, BoxCloaking);
@ -2464,7 +2518,7 @@ void process(struct GameState *gs, double dt)
if (seat_maybe_in == NULL) // not in any seat
{
cpPointQueryInfo query_info = {0};
cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &query_info);
cpShape *result = cpSpacePointQueryNearest(gs->space, (world_hand_pos), 0.1, BOXES_FILTER, &query_info);
if (result != NULL)
{
Entity *potential_seat = cp_shape_entity(result);
@ -2594,7 +2648,7 @@ void process(struct GameState *gs, double dt)
cpVect world_build = world_hand_pos;
Entity *target_grid = grid_to_build_on(gs, world_hand_pos);
cpShape *maybe_box_to_destroy = cpSpacePointQueryNearest(gs->space, (world_build), 0.01, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, BOXES), &info);
cpShape *maybe_box_to_destroy = cpSpacePointQueryNearest(gs->space, (world_build), 0.01, cpShapeFilterNew(CP_NO_GROUP, BOXES, BOXES), &info);
if (maybe_box_to_destroy != NULL)
{
Entity *cur_box = cp_shape_entity(maybe_box_to_destroy);
@ -2684,6 +2738,7 @@ void process(struct GameState *gs, double dt)
else
{
entity_destroy(gs, e);
continue;
}
continue;
}
@ -2734,10 +2789,37 @@ void process(struct GameState *gs, double dt)
if (e->explosion_progress >= EXPLOSION_TIME)
{
entity_destroy(gs, e);
continue;
}
}
}
if (e->is_orb)
{
PROFILE_SCOPE("Orb")
{
circle_query(gs->space, entity_pos(e), ORB_HEAT_MAX_DETECTION_DIST);
cpVect final_force = cpv(0, 0);
QUEUE_ITER(&query_result, QueryResult, res)
{
Entity *potential_aggravation = cp_shape_entity(res->shape);
if (potential_aggravation->is_box && potential_aggravation->box_type == BoxThruster && fabs(potential_aggravation->thrust) > 0.1)
{
final_force = cpvadd(final_force, cpvmult(cpvsub(entity_pos(potential_aggravation), entity_pos(e)), ORB_HEAT_FORCE_MULTIPLIER));
}
}
if (cpvlength(final_force) > ORB_MAX_FORCE)
{
final_force = cpvmult(cpvnormalize(final_force), ORB_MAX_FORCE);
}
// add drag
final_force = cpvadd(final_force, cpvmult(entity_vel(gs, e), -1.0 * lerp(ORB_DRAG_CONSTANT, ORB_FROZEN_DRAG_CONSTANT, e->damage)));
cpBodyApplyForceAtWorldPoint(e->body, final_force, entity_pos(e));
e->damage -= dt * ORB_HEAL_RATE;
e->damage = clamp01(e->damage);
}
}
if (e->is_missile)
{
PROFILE_SCOPE("Missile")
@ -2752,10 +2834,11 @@ void process(struct GameState *gs, double dt)
Entity *explosion = new_entity(gs);
explosion->is_explosion = true;
explosion->explosion_pos = entity_pos(e);
explosion->explosion_vel = (cpBodyGetVelocity(e->body));
explosion->explosion_vel = cpBodyGetVelocity(e->body);
explosion->explosion_push_strength = MISSILE_EXPLOSION_PUSH;
explosion->explosion_radius = MISSILE_EXPLOSION_RADIUS;
entity_destroy(gs, e);
continue;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 798 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 B

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 618 B

@ -43,7 +43,6 @@ static sg_pipeline goodpixel_pipeline;
static struct GameState gs = {0};
static int my_player_index = -1;
static bool right_mouse_down = false;
#define MAX_KEYDOWN SAPP_KEYCODE_MENU
static bool keydown[MAX_KEYDOWN] = {0};
static bool piloting_rotation_capable_ship = false;
@ -126,6 +125,8 @@ static sg_image image_rothelp;
static sg_image image_zoomeasyhelp;
static sg_image image_gyrospin;
static sg_image image_noenergy;
static sg_image image_orb;
static sg_image image_orb_frozen;
static enum BoxType toolbar[TOOLBAR_SLOTS] = {
BoxHullpiece,
@ -654,6 +655,8 @@ static void init(void)
image_gyrospin = load_image("loaded/gyroscope_spinner.png");
image_zoomeasyhelp = load_image("loaded/zoomeasyhelp.png");
image_noenergy = load_image("loaded/no_energy.png");
image_orb = load_image("loaded/orb.png");
image_orb_frozen = load_image("loaded/orb_frozen.png");
}
// socket initialization
@ -1236,25 +1239,6 @@ static void ui(bool draw, double dt, double width, double height)
}
#undef FLAG_ITER
// draw spice bar
if (draw)
{
static double damage = 0.5;
if (myentity() != NULL)
{
damage = myentity()->damage;
}
set_color_values(0.5, 0.5, 0.5, cur_opacity);
double margin = width * 0.2;
double bar_width = width - margin * 2.0;
double y = height - 150.0;
draw_filled_rect(margin, y, bar_width, 30.0);
set_color_values(1.0, 1.0, 1.0, cur_opacity);
draw_filled_rect(margin, y, bar_width * (1.0 - damage), 30.0);
}
// draw muted
static double toggle_mute_opacity = 0.2;
const double size = 150.0;
@ -1289,18 +1273,19 @@ static void ui(bool draw, double dt, double width, double height)
}
// draw item toolbar
double itembar_width = 0.0;
{
double itemframe_width =
(float)sg_query_image_info(image_itemframe).width * 2.0;
double itemframe_height =
(float)sg_query_image_info(image_itemframe).height * 2.0;
double total_width = itemframe_width * (float)TOOLBAR_SLOTS;
itembar_width = itemframe_width * (float)TOOLBAR_SLOTS;
double item_width = itemframe_width * 0.75;
double item_height = itemframe_height * 0.75;
double item_offset_x = (itemframe_width - item_width) / 2.0;
double item_offset_y = (itemframe_height - item_height) / 2.0;
double x = width / 2.0 - total_width / 2.0;
double x = width / 2.0 - itembar_width / 2.0;
double y = height - itemframe_height * 1.5;
for (int i = 0; i < TOOLBAR_SLOTS; i++)
{
@ -1394,6 +1379,24 @@ static void ui(bool draw, double dt, double width, double height)
x += itemframe_width;
}
}
// draw spice bar
if (draw)
{
static double damage = 0.5;
if (myentity() != NULL)
{
damage = myentity()->damage;
}
set_color_values(0.5, 0.5, 0.5, cur_opacity);
double bar_width = itembar_width * 1.1;
double margin = (width - bar_width)/2.0;
double y = height - 150.0;
draw_filled_rect(margin, y, bar_width, 30.0);
set_color_values(1.0, 1.0, 1.0, cur_opacity);
draw_filled_rect(margin, y, bar_width * (1.0 - damage), 30.0);
}
if (draw)
sgp_pop_transform();
@ -1671,7 +1674,9 @@ static void frame(void)
PROFILE_SCOPE("gameplay and prediction")
{
// interpolate zoom
zoom = lerp(zoom, zoom_target, dt * 12.0);
zoom = lerp(zoom, zoom_target, dt * 16.0);
// zoom = lerp(log(zoom), log(zoom_target), dt * 20.0);
// zoom = exp(zoom);
// calculate build preview stuff
cpVect local_hand_pos = {0};
@ -2250,13 +2255,31 @@ static void frame(void)
}
}
// draw orb
if (e->is_orb)
{
set_color(WHITE);
double effective_radius = ORB_RADIUS * 2.2;
set_color_values(1.0, 1.0, 1.0, 1.0 - e->damage);
sgp_set_image(0, image_orb);
pipeline_scope(goodpixel_pipeline)
draw_texture_centered(entity_pos(e), effective_radius);
sgp_reset_image(0);
set_color_values(1.0, 1.0, 1.0, e->damage);
sgp_set_image(0, image_orb_frozen);
pipeline_scope(goodpixel_pipeline)
draw_texture_centered(entity_pos(e), effective_radius);
sgp_reset_image(0);
}
// draw missile
if (e->is_missile)
{
transform_scope
{
rotate_at(entity_rotation(e), entity_pos(e).x, entity_pos(e).y);
set_color_values(1.0, 1.0, 1.0, 1.0);
set_color(WHITE);
if (is_burning(e))
{

@ -33,6 +33,16 @@
#define PLAYER_JETPACK_ROTATION_ENERGY_PER_SECOND 0.2f
#define PLAYER_JETPACK_SPICE_PER_SECOND 0.08f
#define PLAYER_BIG_SCALING 300.0
#define ORB_MASS 4.0
#define ORB_RADIUS 1.0
#define ORB_HEAT_FORCE_MULTIPLIER 5.0
#define ORB_DRAG_CONSTANT 1.0
#define ORB_FROZEN_DRAG_CONSTANT 10.0
#define ORB_HEAT_MAX_DETECTION_DIST 80.0
#define ORB_HEAL_RATE 0.2
#define ORB_MAX_FORCE 160.0
#define SCANNER_ENERGY_USE 0.05f
#define MAX_HAND_REACH 1.0f
#define SCANNER_SCAN_RATE 0.5f
@ -62,6 +72,7 @@
#define EXPLOSION_DAMAGE_PER_SEC 10.0f
#define EXPLOSION_DAMAGE_THRESHOLD 0.2f // how much damage until it explodes
#define GOLD_UNLOCK_RADIUS 1.0f
#ifndef TIME_BETWEEN_WORLD_SAVE
#define TIME_BETWEEN_WORLD_SAVE 30.0f
#endif
@ -115,12 +126,7 @@
#define flight_assert(condition) __flight_assert(condition, __FILE__, __LINE__, #condition)
// including headers from headers bad
#ifndef CHIPMUNK_H
typedef void cpSpace;
typedef void cpBody;
typedef void cpShape;
#endif
#include <chipmunk.h> // unfortunate but needs cpSpace, cpBody, cpShape etc
#include "queue.h"
#include <stdbool.h>
@ -247,7 +253,7 @@ typedef struct Entity
bool no_save_to_disk; // stuff generated later on, like player's bodies or space stations that respawn.
double damage; // used by box and player
double damage; // used by box, player, and orb
cpBody *body; // used by grid, player, and box
cpShape *shape; // must be a box so shape_size can be set appropriately, and serialized
@ -259,8 +265,10 @@ typedef struct Entity
// 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
bool is_circle_shape;
EntityID shape_parent_entity; // can't be zero if shape is nonzero
cpVect shape_size;
double shape_radius; // only when circle shape
cpVect shape_size; // only when rect shape
// player
bool is_player;
@ -288,6 +296,9 @@ typedef struct Entity
bool is_missile;
double time_burned_for; // until MISSILE_BURN_TIME. Before MISSILE_ARM_TIME cannot explode
// orb
bool is_orb;
// grids
bool is_grid;
double total_energy_capacity;

Loading…
Cancel
Save