items on the floor
This commit is contained in:
parent
e87fa3b6ec
commit
bca71726db
|
@ -20,6 +20,7 @@ set(SOURCES
|
|||
src/enemies.c
|
||||
src/game.c
|
||||
src/geometry.c
|
||||
src/item.c
|
||||
src/main.c
|
||||
src/map.c
|
||||
src/menu.c
|
||||
|
@ -56,6 +57,9 @@ set(ASSETS
|
|||
assets-cg/hud_xp.ase
|
||||
assets-cg/skillicons.png
|
||||
assets-cg/font_hud.png
|
||||
# Items
|
||||
assets-cg/items/life.aseprite
|
||||
assets-cg/items/sword1.aseprite
|
||||
# Player animations
|
||||
assets-cg/player/player_up.aseprite
|
||||
assets-cg/player/player_right.aseprite
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
*.aseprite:
|
||||
custom-type: aseprite-anim
|
||||
name_regex: (.*)\.aseprite frames_item_\1
|
||||
next: Item=Item
|
||||
profile: p4
|
Binary file not shown.
Binary file not shown.
|
@ -75,6 +75,10 @@ ANIM1(hud_xp_Idle);
|
|||
ANIM1(hud_xp_Shine);
|
||||
ANIM1(hud_xp_Explode);
|
||||
|
||||
/* Items */
|
||||
ANIM1(item_life);
|
||||
ANIM1(item_sword1);
|
||||
|
||||
/* Animation functions. */
|
||||
|
||||
fixed_t (anim_duration)(anim_t const *anim)
|
||||
|
|
|
@ -106,3 +106,7 @@ extern anim_t anims_player_Hit;
|
|||
extern anim_t anims_hud_xp_Idle;
|
||||
extern anim_t anims_hud_xp_Shine;
|
||||
extern anim_t anims_hud_xp_Explode;
|
||||
|
||||
/* Items */
|
||||
extern anim_t anims_item_life;
|
||||
extern anim_t anims_item_sword1;
|
||||
|
|
|
@ -235,6 +235,14 @@ void aoe_apply(game_t *game, entity_t *entity, entity_t *e)
|
|||
bool was_hit = false;
|
||||
aoe_t *aoe = getcomp(entity, aoe);
|
||||
aoe_record_t *rec = aoe_record(aoe, e);
|
||||
fighter_t *e_f = getcomp(e, fighter);
|
||||
|
||||
if(aoe->type == AOE_ITEM && e_f && e_f->player) {
|
||||
item_pick_up(&aoe->data.item.data, e);
|
||||
aoe->lifetime = 0;
|
||||
/* Don't bother recording the hit since the item will disappear */
|
||||
was_hit = false;
|
||||
}
|
||||
|
||||
/* Don't hit entities that have been recently hit */
|
||||
if(rec && aoe->repeat_delay == 0) return;
|
||||
|
|
|
@ -6,9 +6,11 @@
|
|||
|
||||
#include "geometry.h"
|
||||
#include "anim.h"
|
||||
|
||||
#include "item.h"
|
||||
|
||||
enum {
|
||||
/* Item */
|
||||
AOE_ITEM,
|
||||
/* Bare-hand fist/close-contact attack */
|
||||
AOE_HIT,
|
||||
/* Simple ranged attack */
|
||||
|
@ -51,6 +53,8 @@ typedef struct
|
|||
uint16_t type;
|
||||
/* Effect data (type-dependent) */
|
||||
union {
|
||||
/* Item: item info */
|
||||
struct { item_data_t data; } item;
|
||||
/* Generic attacks: source and ATK strength */
|
||||
struct { int strength; int dir; } generic;
|
||||
/* AOE_PROJECTILE: speed and direction of movement */
|
||||
|
|
|
@ -189,7 +189,7 @@ void game_remove_dead_entities(game_t *g)
|
|||
|
||||
if(f && f->HP == 0 && f->enemy != NULL && anim_finished) {
|
||||
/* Give XP points to player */
|
||||
bool lvup = player_add_xp(g->player_data, f->enemy->id->xp);
|
||||
bool lvup = player_add_xp(g->player, f->enemy->id->xp);
|
||||
|
||||
if(lvup) {
|
||||
g->hud_xp_anim.frame = anims_hud_xp_Explode.start[0];
|
||||
|
|
|
@ -39,8 +39,6 @@ typedef struct game {
|
|||
int entity_count;
|
||||
/* Player; this must be one of the entities loaded in the game */
|
||||
entity_t *player;
|
||||
/* Associated player data */
|
||||
player_t *player_data;
|
||||
/* Field of movement to reach the player (used by most enemy AIs) */
|
||||
pfg_all2one_t paths_to_player;
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#include "item.h"
|
||||
#include "aoe.h"
|
||||
#include "comp/fighter.h"
|
||||
#include "comp/physical.h"
|
||||
#include "comp/visible.h"
|
||||
#include <gint/defs/util.h>
|
||||
|
||||
entity_t *item_make(item_data_t const *data, vec2 position)
|
||||
{
|
||||
entity_t *e = aoe_make(AOE_ITEM, position, fix(9999.0));
|
||||
|
||||
visible_t *v = getcomp(e, visible);
|
||||
v->sprite_plane = VERTICAL;
|
||||
v->shadow_size = 3;
|
||||
v->z = fix(0.35);
|
||||
|
||||
physical_t *p = getcomp(e, physical);
|
||||
p->hitbox = (rect){ -fix(4)/16, fix(3)/16, -fix(2)/16, fix(1)/16 };
|
||||
|
||||
aoe_t *aoe = getcomp(e, aoe);
|
||||
aoe->origin = NULL;
|
||||
aoe->repeat_delay = 0;
|
||||
aoe->data.item.data = *data;
|
||||
|
||||
if(data->type == ITEM_LIFE) {
|
||||
visible_set_anim(e, &anims_item_life, 1);
|
||||
}
|
||||
// else if(data->type == ITEM_X) {
|
||||
// visible_set_anim(e, &anims_item_x, 1);
|
||||
// }
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void item_pick_up(item_data_t const *data, entity_t *player)
|
||||
{
|
||||
fighter_t *f = getcomp(player, fighter);
|
||||
|
||||
if(data->type == ITEM_LIFE && f) {
|
||||
f->HP = min(f->HP + data->life.HP, f->HP_max);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
//---
|
||||
// items: Dropped objects that can be picked up from the ground
|
||||
//---
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "comp/entity.h"
|
||||
#include "geometry.h"
|
||||
|
||||
enum {
|
||||
ITEM_LIFE = 0,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
|
||||
union {
|
||||
/* ITEM_LIFE: Amount of HP restored */
|
||||
struct { int HP; } life;
|
||||
};
|
||||
|
||||
} item_data_t;
|
||||
|
||||
/* Create an item. This is just an AOE with a particular type. */
|
||||
entity_t *item_make(item_data_t const *data, vec2 position);
|
||||
|
||||
/* Give an item to a player entity. */
|
||||
void item_pick_up(item_data_t const *data, entity_t *player);
|
25
src/main.c
25
src/main.c
|
@ -10,6 +10,7 @@
|
|||
#include "enemies.h"
|
||||
#include "game.h"
|
||||
#include "geometry.h"
|
||||
#include "item.h"
|
||||
#include "level.h"
|
||||
#include "map.h"
|
||||
#include "menu.h"
|
||||
|
@ -86,7 +87,7 @@ int main(void)
|
|||
// Spawn player
|
||||
//---
|
||||
|
||||
player_t player_data = {
|
||||
player_data_t player_data = {
|
||||
.entity = NULL,
|
||||
.mechanical_limits = {
|
||||
.max_speed = fix(4.5),
|
||||
|
@ -105,7 +106,6 @@ int main(void)
|
|||
.xp_to_next_level = 0,
|
||||
.xp_current = 0,
|
||||
};
|
||||
game.player_data = &player_data;
|
||||
|
||||
entity_t *player = entity_make(physical, visible, mechanical, fighter);
|
||||
player_data.entity = player;
|
||||
|
@ -119,8 +119,7 @@ int main(void)
|
|||
player_f->combo_next = 0;
|
||||
player_f->combo_delay = fix(0);
|
||||
player_f->enemy = NULL;
|
||||
// TODO: Set link to player data in entity
|
||||
// player_f->player = &player_data;
|
||||
player_f->player = &player_data;
|
||||
player_f->skills[1] = SKILL_DASH;
|
||||
player_f->skills[2] = AOE_SHOCK;
|
||||
player_f->skills[3] = AOE_JUDGEMENT;
|
||||
|
@ -128,7 +127,7 @@ int main(void)
|
|||
for(int i = 0; i < 5; i++)
|
||||
player_f->actions_cooldown[i] = fix(0.0);
|
||||
/* Initialize stats. This will level up to level 1 */
|
||||
player_add_xp(&player_data, 0);
|
||||
player_add_xp(player, 0);
|
||||
player_f->HP = player_f->HP_max;
|
||||
|
||||
player_p->x = fix(game.level->player_spawn_x) + fix(0.5);
|
||||
|
@ -145,6 +144,22 @@ int main(void)
|
|||
game_add_entity(&game, player);
|
||||
game.player = player;
|
||||
|
||||
|
||||
int x=0, y=0;
|
||||
for(int i = 0; i < 100; i++) {
|
||||
y = rand() % game.map->height;
|
||||
x = rand() % game.map->width;
|
||||
map_cell_t const *cell = map_cell(game.map, x, y);
|
||||
__auto_type tiles = game.map->tileset->tiles;
|
||||
|
||||
if(!tiles[cell->base].solid &&
|
||||
(!cell->decor || !tiles[cell->decor].solid))
|
||||
break;
|
||||
}
|
||||
item_data_t data = { .type = ITEM_LIFE, .life.HP = 50 };
|
||||
entity_t *item = item_make(&data, (vec2){ fix(x)+fix(0.5), fix(y)+fix(0.5) });
|
||||
game_add_entity(&game, item);
|
||||
|
||||
//---
|
||||
// Main loop
|
||||
//---
|
||||
|
|
|
@ -6,8 +6,10 @@ static int xp_to_next_level(int level)
|
|||
return 3 * (level + 2) * (level + 2);
|
||||
}
|
||||
|
||||
bool player_add_xp(player_t *p, int points)
|
||||
bool player_add_xp(entity_t *e, int points)
|
||||
{
|
||||
player_data_t *p = getcomp(e, fighter)->player;
|
||||
|
||||
bool leveled_up = false;
|
||||
p->xp_current += max(points, 0);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "comp/fighter.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
typedef struct player_data {
|
||||
/* Associated entity */
|
||||
entity_t *entity;
|
||||
/* Mechanical limits (dynamically recomputed) */
|
||||
|
@ -21,7 +21,7 @@ typedef struct {
|
|||
int xp_to_next_level;
|
||||
int xp_current;
|
||||
|
||||
} player_t;
|
||||
} player_data_t;
|
||||
|
||||
/* Add XP points to a player. Returns true if levels up */
|
||||
bool player_add_xp(player_t *p, int points);
|
||||
bool player_add_xp(entity_t *p, int points);
|
||||
|
|
13
src/render.c
13
src/render.c
|
@ -434,16 +434,17 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
extern bopti_image_t img_hud;
|
||||
dimage(0, HUD_Y - img_hud.height, &img_hud);
|
||||
|
||||
fighter_t *player_f = getcomp(g->player, fighter);
|
||||
|
||||
extern font_t font_hud;
|
||||
player_data_t *player_data = player_f->player;
|
||||
dfont(&font_hud);
|
||||
dprint_opt(349, HUD_Y - 5, RGB24(0x15171a), C_NONE, DTEXT_CENTER,
|
||||
DTEXT_TOP, "%d", g->player_data->xp_level);
|
||||
DTEXT_TOP, "%d", player_data->xp_level);
|
||||
dprint_opt(349, HUD_Y - 6, RGB24(0xabb1ba), C_NONE, DTEXT_CENTER,
|
||||
DTEXT_TOP, "%d", g->player_data->xp_level);
|
||||
DTEXT_TOP, "%d", player_data->xp_level);
|
||||
dfont(&font_rogue);
|
||||
|
||||
fighter_t *player_f = getcomp(g->player, fighter);
|
||||
|
||||
/* Render life bar */
|
||||
extern bopti_image_t img_hud_life;
|
||||
int fill_height = (img_hud_life.height * player_f->HP) / player_f->HP_max;
|
||||
|
@ -458,8 +459,8 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
}
|
||||
else {
|
||||
static int const XP_FULL=22;
|
||||
int xp_current = g->player_data->xp_current;
|
||||
int xp_total = max(g->player_data->xp_to_next_level, 1);
|
||||
int xp_current = player_data->xp_current;
|
||||
int xp_total = max(player_data->xp_to_next_level, 1);
|
||||
int fill_height = XP_FULL * xp_current / xp_total;
|
||||
anim_frame_subrender(343, HUD_Y-32, g->hud_xp_anim.frame,
|
||||
0, XP_FULL - fill_height, -1, fill_height);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
enum {
|
||||
SKILL_DASH = 0x100,
|
||||
|
||||
/* Other skills: */
|
||||
/* Other skills in the AOE enumeration that are valid here: */
|
||||
// AOE_PROJECTILE,
|
||||
// AOE_SHOCK,
|
||||
// AOE_JUDGEMENT,
|
||||
|
|
Loading…
Reference in New Issue