2021-12-25 11:47:22 +01:00
|
|
|
#include "comp/entity.h"
|
|
|
|
#include "comp/physical.h"
|
|
|
|
#include "comp/visible.h"
|
|
|
|
#include "comp/mechanical.h"
|
|
|
|
#include "comp/fighter.h"
|
2021-12-27 21:54:55 +01:00
|
|
|
#include "comp/particle.h"
|
2021-12-25 11:47:22 +01:00
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "anim.h"
|
2021-12-25 11:47:22 +01:00
|
|
|
#include "aoe.h"
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "enemies.h"
|
2021-06-04 15:14:12 +02:00
|
|
|
#include "game.h"
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "geometry.h"
|
2022-02-16 17:42:05 +01:00
|
|
|
#include "item.h"
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "level.h"
|
|
|
|
#include "map.h"
|
2022-02-13 10:03:14 +01:00
|
|
|
#include "menu.h"
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "pathfinding.h"
|
2022-01-17 18:29:05 +01:00
|
|
|
#include "player.h"
|
2021-06-15 17:27:30 +02:00
|
|
|
#include "render.h"
|
2022-02-05 14:38:26 +01:00
|
|
|
#include "skills.h"
|
2021-05-30 21:59:09 +02:00
|
|
|
|
|
|
|
#include <gint/display.h>
|
|
|
|
#include <gint/keyboard.h>
|
|
|
|
#include <gint/usb.h>
|
|
|
|
#include <gint/usb-ff-bulk.h>
|
|
|
|
#include <gint/cpu.h>
|
|
|
|
#include <gint/timer.h>
|
2021-12-25 11:47:22 +01:00
|
|
|
#include <gint/kmalloc.h>
|
2022-02-02 10:16:59 +01:00
|
|
|
#include <gint/defs/util.h>
|
2022-03-18 23:36:32 +01:00
|
|
|
#include <gint/rtc.h>
|
2021-06-09 12:18:51 +02:00
|
|
|
|
2021-05-30 21:59:09 +02:00
|
|
|
#include <stdlib.h>
|
2021-06-25 11:44:29 +02:00
|
|
|
#include <string.h>
|
|
|
|
#include <fxlibc/printf.h>
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
#include <libprof.h>
|
2021-06-09 20:47:39 +02:00
|
|
|
|
2022-05-04 20:15:41 +02:00
|
|
|
/* Record USB frames (used by main menu and game loop) */
|
|
|
|
bool rogue_life_video_capture = false;
|
|
|
|
|
2023-01-02 11:50:25 +01:00
|
|
|
static int menu_select_play_repeat(void)
|
2021-05-30 21:59:09 +02:00
|
|
|
{
|
2022-02-13 10:03:14 +01:00
|
|
|
int lv = menu_level_select(0);
|
2021-12-29 12:02:51 +01:00
|
|
|
if(lv == -1) return 1;
|
|
|
|
|
2021-06-04 15:14:12 +02:00
|
|
|
game_t game = { 0 };
|
|
|
|
camera_t *c = &game.camera;
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2022-05-21 19:54:22 +02:00
|
|
|
game_load(&game, level_all[lv]);
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
struct {
|
2022-05-21 19:54:22 +02:00
|
|
|
/* Developer menu is open */
|
|
|
|
bool dev_menu;
|
|
|
|
/* Show developer submenus */
|
|
|
|
bool dev_menu_view;
|
|
|
|
bool dev_menu_spawn;
|
2021-06-25 11:44:29 +02:00
|
|
|
/* Show variables */
|
|
|
|
bool show_vars;
|
|
|
|
/* Show hitboxes */
|
|
|
|
bool show_hitboxes;
|
|
|
|
/* Show BFS field around player */
|
|
|
|
bool show_bfs_field;
|
|
|
|
pfg_all2one_t bfs_field;
|
|
|
|
/* Show path to some fixed cell */
|
|
|
|
bool show_path;
|
|
|
|
pfg_path_t grid_path;
|
|
|
|
pfc_path_t continuous_path;
|
|
|
|
/* Show performance metrics */
|
|
|
|
bool show_perf;
|
2022-01-17 18:29:05 +01:00
|
|
|
/* Coordinates of a point of interest */
|
|
|
|
int some_x, some_y;
|
|
|
|
/* Game is paused */
|
|
|
|
bool paused;
|
2021-06-25 11:44:29 +02:00
|
|
|
|
|
|
|
} debug;
|
|
|
|
memset(&debug, 0, sizeof debug);
|
2021-06-15 17:27:30 +02:00
|
|
|
|
2021-06-01 17:49:29 +02:00
|
|
|
//---
|
2021-07-16 15:51:32 +02:00
|
|
|
// Spawn player
|
2021-06-01 17:49:29 +02:00
|
|
|
//---
|
|
|
|
|
2022-02-16 17:42:05 +01:00
|
|
|
player_data_t player_data = {
|
2022-01-17 18:29:05 +01:00
|
|
|
.entity = NULL,
|
|
|
|
.mechanical_limits = {
|
|
|
|
.max_speed = fix(4.5),
|
|
|
|
.friction = fix(0.7),
|
|
|
|
.dash_speed = fix(20),
|
|
|
|
.dash_duration = fix(1) / 8,
|
2022-02-13 16:02:36 +01:00
|
|
|
.max_disruption_speed = fix(3.0),
|
2022-01-17 18:29:05 +01:00
|
|
|
},
|
2022-05-31 21:42:43 +02:00
|
|
|
.stats = { .HP=60, .ATK=13, .MAG=10, .DEF=6 },
|
|
|
|
.stats_growth = { .HP=25, .ATK=1, .MAG=1, .DEF=1 },
|
|
|
|
|
2022-01-17 18:29:05 +01:00
|
|
|
.xp_level = 0,
|
|
|
|
.xp_to_next_level = 0,
|
|
|
|
.xp_current = 0,
|
2023-01-23 21:56:55 +01:00
|
|
|
.inventory = { ITEM_POTION_HP, ITEM_POTION_FRZ, -1, -1,
|
2022-06-05 23:11:06 +02:00
|
|
|
-1, -1, -1, -1 },
|
2022-03-18 22:21:30 +01:00
|
|
|
.equipment = { -1, -1, -1 },
|
2021-12-29 12:02:51 +01:00
|
|
|
};
|
2021-06-04 15:14:12 +02:00
|
|
|
|
2021-12-29 12:02:51 +01:00
|
|
|
entity_t *player = entity_make(physical, visible, mechanical, fighter);
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.entity = player;
|
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
physical_t *player_p = getcomp(player, physical);
|
|
|
|
visible_t *player_v = getcomp(player, visible);
|
|
|
|
mechanical_t *player_m = getcomp(player, mechanical);
|
|
|
|
fighter_t *player_f = getcomp(player, fighter);
|
2021-06-01 17:49:29 +02:00
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
player_f->combo_length = 2;
|
|
|
|
player_f->combo_next = 0;
|
|
|
|
player_f->combo_delay = fix(0);
|
2022-02-08 22:48:08 +01:00
|
|
|
player_f->enemy = NULL;
|
2022-02-16 17:42:05 +01:00
|
|
|
player_f->player = &player_data;
|
2022-03-19 18:14:00 +01:00
|
|
|
for(int i = 0; i < 6; i++)
|
|
|
|
player_f->skills[i] = -1;
|
2022-06-25 18:04:07 +02:00
|
|
|
player_f->skills[0] = AOE_SLASH;
|
2022-03-18 20:36:29 +01:00
|
|
|
for(int i = 0; i < 6; i++)
|
2022-02-05 14:38:26 +01:00
|
|
|
player_f->actions_cooldown[i] = fix(0.0);
|
2022-01-17 18:29:05 +01:00
|
|
|
/* Initialize stats. This will level up to level 1 */
|
2022-05-31 21:42:43 +02:00
|
|
|
player_f->HP_max = player_data.stats.HP;
|
|
|
|
player_f->ATK = player_data.stats.ATK;
|
|
|
|
player_f->MAG = player_data.stats.MAG;
|
|
|
|
player_f->DEF = player_data.stats.DEF;
|
2022-02-16 17:42:05 +01:00
|
|
|
player_add_xp(player, 0);
|
2022-01-17 18:29:05 +01:00
|
|
|
player_f->HP = player_f->HP_max;
|
2021-06-01 17:49:29 +02:00
|
|
|
|
2021-12-28 22:23:09 +01:00
|
|
|
player_p->x = fix(game.level->player_spawn_x) + fix(0.5);
|
|
|
|
player_p->y = fix(game.level->player_spawn_y) + fix(0.5);
|
|
|
|
player_p->facing = DOWN;
|
2021-12-25 11:47:22 +01:00
|
|
|
player_p->hitbox = (rect){ -fix(5)/16, fix(5)/16, -fix(2)/16, fix(4)/16 };
|
2021-06-01 17:49:29 +02:00
|
|
|
|
2022-01-17 18:29:05 +01:00
|
|
|
player_m->limits = &player_data.mechanical_limits;
|
2021-12-25 11:47:22 +01:00
|
|
|
|
2021-12-29 12:02:51 +01:00
|
|
|
player_v->sprite_plane = VERTICAL;
|
2021-12-25 11:47:22 +01:00
|
|
|
player_v->shadow_size = 4;
|
|
|
|
visible_set_anim(player, &anims_player_Idle, 1);
|
2021-06-01 22:06:58 +02:00
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
game_add_entity(&game, player);
|
|
|
|
game.player = player;
|
2021-06-09 20:47:39 +02:00
|
|
|
|
2021-05-30 21:59:09 +02:00
|
|
|
//---
|
|
|
|
// Main loop
|
|
|
|
//---
|
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
/* Start a timer at the FRAME_RATE setting to schedule new frames */
|
2021-05-30 21:59:09 +02:00
|
|
|
volatile int frame_tick = 1;
|
|
|
|
int timer_id = timer_configure(TIMER_ANY, 1000000 / FRAME_RATE,
|
|
|
|
GINT_CALL_SET(&frame_tick));
|
|
|
|
if(timer_id >= 0)
|
|
|
|
timer_start(timer_id);
|
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
bool stop = false;
|
2021-06-02 15:40:32 +02:00
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
prof_t perf_render, perf_simul;
|
|
|
|
uint32_t time_render=0, time_simul=0;
|
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
while(!stop) {
|
2021-05-30 21:59:09 +02:00
|
|
|
while(!frame_tick) sleep();
|
2021-08-30 17:48:44 +02:00
|
|
|
frame_tick = 0;
|
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
bool attack = false;
|
2022-03-18 20:36:29 +01:00
|
|
|
bool bullet_time = game.menu_open;
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
/* This assumes the frame is not late; can do better with libprof */
|
2021-05-30 21:59:09 +02:00
|
|
|
fixed_t dt = fix(1) / FRAME_RATE;
|
2022-03-18 20:36:29 +01:00
|
|
|
fixed_t dt_rt = dt;
|
2022-01-18 09:45:23 +01:00
|
|
|
if(bullet_time)
|
2022-03-18 20:36:29 +01:00
|
|
|
dt >>= 2;
|
2022-05-21 19:54:22 +02:00
|
|
|
if(debug.paused || debug.dev_menu)
|
2022-03-18 20:36:29 +01:00
|
|
|
dt = dt_rt = 0;
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
perf_render = prof_make();
|
|
|
|
prof_enter(perf_render);
|
2021-06-04 16:24:47 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
render_game(&game, debug.show_hitboxes);
|
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
/* kmalloc_arena_t *_uram = kmalloc_get_arena("_uram");
|
|
|
|
kmalloc_gint_stats_t *_uram_stats = kmalloc_get_gint_stats(_uram);
|
2022-01-17 18:29:05 +01:00
|
|
|
dprint(1, 15, C_WHITE, "Memory: %d", _uram_stats->used_memory); */
|
2021-12-25 11:47:22 +01:00
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
/* Developer/tweaking menu */
|
2021-06-25 11:44:29 +02:00
|
|
|
if(debug.show_vars) {
|
2021-06-29 19:35:06 +02:00
|
|
|
uint32_t *vram = (void *)gint_vram;
|
2022-12-31 18:26:57 +01:00
|
|
|
for(int i = 0; i < 396 * 224 / 2; i++) {
|
|
|
|
vram[i] = (vram[i] & 0xf7def7de) >> 1;
|
2021-06-15 17:27:30 +02:00
|
|
|
}
|
|
|
|
uint16_t gray = C_RGB(16, 16, 16);
|
|
|
|
|
2021-06-29 19:35:06 +02:00
|
|
|
dprint(3, 40, C_WHITE, "Player speed: %g tiles/s",
|
2022-01-17 18:29:05 +01:00
|
|
|
f2double(player_data.mechanical_limits.max_speed));
|
2021-06-29 19:35:06 +02:00
|
|
|
dprint(15, 55, gray, "[frac] -/+ [X,0,T]");
|
2021-06-15 17:27:30 +02:00
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
dprint(3, 70, C_WHITE, "Friction: %g",
|
2022-01-17 18:29:05 +01:00
|
|
|
f2double(player_data.mechanical_limits.friction));
|
2021-06-29 19:35:06 +02:00
|
|
|
dprint(15, 85, gray, "[F<>D] -/+ [log]");
|
2021-06-15 17:27:30 +02:00
|
|
|
|
|
|
|
dprint(3, 115, C_WHITE, "Dash speed: %g tiles/s",
|
2022-01-17 18:29:05 +01:00
|
|
|
f2double(player_data.mechanical_limits.dash_speed));
|
2021-06-29 19:35:06 +02:00
|
|
|
dprint(15, 130, gray, "[(] -/+ [ln]");
|
2021-06-15 17:27:30 +02:00
|
|
|
|
|
|
|
dprint(3, 145, C_WHITE, "Dash duration: %g s",
|
2022-01-17 18:29:05 +01:00
|
|
|
f2double(player_data.mechanical_limits.dash_duration));
|
2021-06-29 19:35:06 +02:00
|
|
|
dprint(15, 160, gray, "[)] -/+ [sin]");
|
2022-12-31 18:26:57 +01:00
|
|
|
|
|
|
|
dprint(DWIDTH/2, 40, C_WHITE, "Score: %d",
|
|
|
|
game_compute_score(&game));
|
|
|
|
dprint(DWIDTH/2, 55, C_WHITE, "kill_number: %d",
|
|
|
|
game.score.kill_number);
|
|
|
|
dprint(DWIDTH/2, 70, C_WHITE, "longest_combo_chain: %d",
|
|
|
|
game.score.longest_combo_chain);
|
|
|
|
dprint(DWIDTH/2, 85, C_WHITE, "combo_chains: %d",
|
|
|
|
game.score.combo_chains);
|
|
|
|
dprint(DWIDTH/2, 100, C_WHITE, "largest_simult_kill: %d",
|
|
|
|
game.score.largest_simult_kill);
|
|
|
|
dprint(DWIDTH/2, 115, C_WHITE, "simult_kills: %d",
|
|
|
|
game.score.simult_kills);
|
|
|
|
dprint(DWIDTH/2, 130, C_WHITE, "one_shot_kills: %d",
|
|
|
|
game.score.one_shot_kills);
|
|
|
|
dprint(DWIDTH/2, 145, C_WHITE, "waves_survived: %d",
|
|
|
|
game.score.waves_survived);
|
|
|
|
dprint(DWIDTH/2, 160, C_WHITE, "current_simult_kills: %d",
|
|
|
|
game.score.current_simult_kills);
|
|
|
|
dprint(DWIDTH/2, 175, C_WHITE, "*_timer: %f",
|
|
|
|
f2double(game.score.current_simult_kill_timer));
|
2021-06-15 17:27:30 +02:00
|
|
|
}
|
|
|
|
|
2022-05-21 19:54:22 +02:00
|
|
|
if(debug.dev_menu_view) {
|
|
|
|
uint32_t *vram = (void *)gint_vram;
|
|
|
|
for(int i = 0; i < DWIDTH * DHEIGHT / 2; i++)
|
|
|
|
vram[i] = (vram[i] & 0xf7def7de) >> 1;
|
|
|
|
|
|
|
|
int fg = C_RGB(31, 31, 0);
|
|
|
|
dprint(3, 25, debug.show_hitboxes ? fg : C_WHITE,
|
|
|
|
"[1] Show hitboxes");
|
|
|
|
dprint(3, 40, debug.show_bfs_field ? fg : C_WHITE,
|
|
|
|
"[2] Show BFS field");
|
|
|
|
dprint(3, 55, debug.show_path ? fg : C_WHITE,
|
|
|
|
"[3] Show pathfinding to spawner");
|
|
|
|
}
|
|
|
|
|
|
|
|
if(debug.dev_menu_spawn) {
|
|
|
|
uint32_t *vram = (void *)gint_vram;
|
|
|
|
for(int i = 0; i < DWIDTH * DHEIGHT / 2; i++)
|
|
|
|
vram[i] = (vram[i] & 0xf7def7de) >> 1;
|
|
|
|
|
|
|
|
dprint(3, 25, C_WHITE, "Spawn an enemy");
|
|
|
|
|
2022-05-22 15:56:30 +02:00
|
|
|
for(int i = 0; i < 16; i++) {
|
|
|
|
int x=12+186*(i/8), y=40+18*(i%8);
|
2022-05-21 19:54:22 +02:00
|
|
|
enemy_t const *enemy = enemy_data(i+1);
|
|
|
|
if(!enemy)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
anim_frame_t *frame = enemy->anim_idle->start[0];
|
|
|
|
dprint(x, y, C_WHITE, "[%d]", i+1);
|
2022-05-22 15:56:30 +02:00
|
|
|
dsubimage(x+(20+44)/2 - frame->w / 2, y+4 - frame->h / 2,
|
|
|
|
frame->sheet, frame->x, frame->y, frame->w, frame->h,
|
|
|
|
DIMAGE_NONE);
|
|
|
|
dprint(x+44, y, C_WHITE, "%s (lv. %d)", enemy->name,
|
2022-05-21 19:54:22 +02:00
|
|
|
enemy->level);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
if(debug.show_path) {
|
|
|
|
if(debug.grid_path.points)
|
|
|
|
for(int i = 0; i < debug.grid_path.length; i++) {
|
2021-10-24 21:54:37 +02:00
|
|
|
ivec2 j = camera_map2screen(c,
|
|
|
|
vec_i2f_center(debug.grid_path.points[i]));
|
|
|
|
ivec2 k = camera_map2screen(c,
|
|
|
|
vec_i2f_center(debug.grid_path.points[i+1]));
|
2021-06-25 11:44:29 +02:00
|
|
|
dline(j.x, j.y, k.x, k.y, C_RGB(31, 0, 31));
|
|
|
|
}
|
|
|
|
if(debug.continuous_path.points)
|
|
|
|
for(int i = 0; i < debug.continuous_path.length; i++) {
|
2021-10-24 21:54:37 +02:00
|
|
|
ivec2 j = camera_map2screen(c,
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.continuous_path.points[i]);
|
2021-10-24 21:54:37 +02:00
|
|
|
ivec2 k = camera_map2screen(c,
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.continuous_path.points[i+1]);
|
|
|
|
dline(j.x, j.y, k.x, k.y, C_RGB(0, 31, 31));
|
2021-06-15 17:27:30 +02:00
|
|
|
}
|
2021-06-04 16:24:47 +02:00
|
|
|
|
2022-01-17 18:29:05 +01:00
|
|
|
debug.some_x = game.level->spawner_count > 0 ?
|
|
|
|
game.level->spawner_x[0] : game.map->width / 2;
|
|
|
|
debug.some_y = game.level->spawner_count > 0 ?
|
|
|
|
game.level->spawner_y[0] : game.map->height / 2;
|
|
|
|
|
2021-12-25 11:47:22 +01:00
|
|
|
vec2 p = physical_pos(player);
|
2022-01-17 18:29:05 +01:00
|
|
|
vec2 q = vec_i2f_center((ivec2){ debug.some_x, debug.some_y });
|
2021-12-27 21:54:55 +01:00
|
|
|
bool clear = raycast_clear_hitbox(game.map,p,q,player_p->hitbox);
|
2021-06-05 11:38:51 +02:00
|
|
|
|
2021-10-24 21:54:37 +02:00
|
|
|
ivec2 j = camera_map2screen(c, p);
|
|
|
|
ivec2 k = camera_map2screen(c, q);
|
2021-06-25 11:44:29 +02:00
|
|
|
dline(j.x, j.y, k.x, k.y, clear ? C_GREEN : C_RED);
|
2021-06-15 17:27:30 +02:00
|
|
|
}
|
2021-06-04 16:24:47 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
if(debug.show_bfs_field && game.paths_to_player.direction) {
|
2022-02-06 09:32:54 +01:00
|
|
|
render_pfg_all2one(&game.paths_to_player, c, game.occupation);
|
2021-06-25 11:44:29 +02:00
|
|
|
}
|
2021-06-15 17:27:30 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
if(debug.show_perf) {
|
2022-02-08 22:48:08 +01:00
|
|
|
extern uint32_t time_render_map, time_render_hud;
|
|
|
|
dprint(1, 15, C_WHITE, "Render: map %.3D, hud %.3D, total %.3D ms",
|
|
|
|
time_render_map, time_render_hud, time_render);
|
2021-06-25 11:44:29 +02:00
|
|
|
dprint(1, 29, C_WHITE, "Simul: %.3D ms", time_simul);
|
|
|
|
}
|
|
|
|
|
2022-05-21 19:54:22 +02:00
|
|
|
if(debug.dev_menu) {
|
2021-06-25 11:44:29 +02:00
|
|
|
int fg = C_RGB(31, 31, 0);
|
|
|
|
fkey_button(1, "PARAMS", debug.show_vars ? fg : C_WHITE);
|
2022-05-21 19:54:22 +02:00
|
|
|
fkey_button(2, "VIEW", debug.dev_menu_view ? fg : C_WHITE);
|
|
|
|
fkey_button(3, "SPAWN", debug.dev_menu_spawn ? fg : C_WHITE);
|
|
|
|
fkey_button(4, "GOD", C_WHITE);
|
2021-06-25 11:44:29 +02:00
|
|
|
fkey_button(5, "PERF", debug.show_perf ? fg : C_WHITE);
|
2022-01-17 18:29:05 +01:00
|
|
|
fkey_button(6, "PAUSE", debug.paused ? fg : C_WHITE);
|
2021-06-25 11:44:29 +02:00
|
|
|
}
|
|
|
|
|
2022-05-21 19:54:22 +02:00
|
|
|
if(keydown(KEY_F6) && keydown(KEY_ALPHA) && debug.dev_menu
|
2022-01-17 18:29:05 +01:00
|
|
|
&& usb_is_open()) {
|
2022-05-04 20:15:41 +02:00
|
|
|
rogue_life_video_capture = !rogue_life_video_capture;
|
2021-08-16 13:31:28 +02:00
|
|
|
}
|
2022-05-04 20:15:41 +02:00
|
|
|
if(rogue_life_video_capture) {
|
2021-08-16 13:31:28 +02:00
|
|
|
usb_fxlink_videocapture(false);
|
|
|
|
}
|
2021-06-15 17:27:30 +02:00
|
|
|
|
|
|
|
/* Instead of dupdate(); for accurate performance measurements. Leaving
|
|
|
|
the DMA running during the simulation affects the results in extreme
|
|
|
|
proportions (can turn 1 ms of simulation into 11 ms measured) */
|
2022-05-17 21:12:39 +02:00
|
|
|
dupdate();
|
2021-06-15 17:27:30 +02:00
|
|
|
|
|
|
|
prof_leave(perf_render);
|
|
|
|
time_render = prof_time(perf_render);
|
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
//---
|
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
perf_simul = prof_make();
|
|
|
|
prof_enter(perf_simul);
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-07-16 15:51:32 +02:00
|
|
|
game_spawn_enemies(&game);
|
2021-08-15 11:05:04 +02:00
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
key_event_t ev;
|
2021-06-05 11:38:51 +02:00
|
|
|
while((ev = pollevent()).type != KEYEV_NONE) {
|
2023-01-15 19:45:44 +01:00
|
|
|
if(ev.type != KEYEV_DOWN) continue;
|
2021-06-05 11:38:51 +02:00
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_MENU)
|
|
|
|
gint_osmenu();
|
2023-01-02 11:50:25 +01:00
|
|
|
if(ev.key == KEY_EXIT && game.finish_time > 0 &&
|
|
|
|
game.time_total >= game.finish_time + fix(2.0))
|
2021-06-04 16:24:47 +02:00
|
|
|
stop = true;
|
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
/* Debug settings */
|
2022-05-21 19:54:22 +02:00
|
|
|
if(ev.key == KEY_OPTN) {
|
|
|
|
debug.dev_menu ^= 1;
|
|
|
|
if(!debug.dev_menu) {
|
|
|
|
debug.dev_menu_view = 0;
|
|
|
|
debug.dev_menu_spawn = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Main debug menu entries */
|
|
|
|
if(ev.key == KEY_F1 && debug.dev_menu)
|
|
|
|
debug.show_vars ^= 1;
|
|
|
|
if(ev.key == KEY_F2 && debug.dev_menu) {
|
|
|
|
debug.dev_menu_view ^= 1;
|
|
|
|
if(debug.dev_menu_view)
|
|
|
|
debug.dev_menu_spawn = 0;
|
|
|
|
}
|
|
|
|
if(ev.key == KEY_F3 && debug.dev_menu) {
|
|
|
|
debug.dev_menu_spawn ^= 1;
|
|
|
|
if(debug.dev_menu_spawn)
|
|
|
|
debug.dev_menu_view = 0;
|
|
|
|
}
|
|
|
|
if(ev.key == KEY_F4 && debug.dev_menu) {
|
|
|
|
player_add_xp(game.player, 1000);
|
2022-05-22 15:56:30 +02:00
|
|
|
// fighter_effect_invulnerability(game.player, fix(999.0));
|
2022-05-21 19:54:22 +02:00
|
|
|
player_f->skills[1] = AOE_SHOCK;
|
|
|
|
player_f->skills[2] = AOE_JUDGEMENT;
|
|
|
|
player_f->skills[3] = SKILL_DASH;
|
|
|
|
player_f->skills[4] = AOE_BULLET;
|
2022-06-25 18:04:07 +02:00
|
|
|
|
|
|
|
player_data.inventory[4] = ITEM_SWORD1;
|
|
|
|
player_data.inventory[5] = ITEM_SWORD2;
|
|
|
|
player_data.inventory[6] = ITEM_SCEPTER1;
|
|
|
|
player_data.inventory[7] = ITEM_SCEPTER2;
|
2022-05-21 19:54:22 +02:00
|
|
|
}
|
|
|
|
if(ev.key == KEY_F5 && debug.dev_menu)
|
|
|
|
debug.show_perf ^= 1;
|
|
|
|
if(ev.key == KEY_F6 && debug.dev_menu)
|
|
|
|
debug.paused ^= 1;
|
|
|
|
if(ev.key == KEY_F2 && debug.dev_menu) {
|
|
|
|
}
|
|
|
|
/* Debug menu: View */
|
|
|
|
if(ev.key == KEY_1 && debug.dev_menu_view)
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.show_hitboxes ^= 1;
|
2022-05-21 19:54:22 +02:00
|
|
|
if(ev.key == KEY_2 && debug.dev_menu_view)
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.show_bfs_field ^= 1;
|
2022-05-21 19:54:22 +02:00
|
|
|
if(ev.key == KEY_3 && debug.dev_menu_view)
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.show_path ^= 1;
|
2022-05-21 19:54:22 +02:00
|
|
|
/* Debug menu: Spawn */
|
|
|
|
if(keycode_digit(ev.key) >= 0 && debug.dev_menu_spawn) {
|
|
|
|
int id = keycode_digit(ev.key);
|
|
|
|
game_spawn_enemy(&game, id, -1);
|
|
|
|
}
|
2021-06-05 11:38:51 +02:00
|
|
|
|
2022-03-18 22:21:30 +01:00
|
|
|
#if 0
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_XOT)
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.max_speed += fix(1)/8;
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_FRAC) {
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.max_speed -= fix(1)/8;
|
|
|
|
if(player_data.mechanical_limits.max_speed < 0)
|
|
|
|
player_data.mechanical_limits.max_speed = 0;
|
2021-06-05 11:38:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(ev.key == KEY_LOG) {
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.friction += fix(1) / 32;
|
|
|
|
if(player_data.mechanical_limits.friction > 1)
|
|
|
|
player_data.mechanical_limits.friction = 1;
|
2021-06-04 16:24:47 +02:00
|
|
|
}
|
|
|
|
if(ev.key == KEY_FD) {
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.friction -= fix(1) / 32;
|
|
|
|
if(player_data.mechanical_limits.friction <= 0)
|
|
|
|
player_data.mechanical_limits.friction = 0;
|
2021-06-04 16:24:47 +02:00
|
|
|
}
|
2021-06-05 11:38:51 +02:00
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_LN)
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.dash_speed += fix(0.5);
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_LEFTP) {
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.dash_speed -= fix(0.5);
|
|
|
|
if(player_data.mechanical_limits.dash_speed <= 0)
|
|
|
|
player_data.mechanical_limits.dash_speed = 0;
|
2021-06-04 16:24:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(ev.key == KEY_SIN)
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.dash_duration += fix(1) / 64;
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_RIGHTP) {
|
2022-01-17 18:29:05 +01:00
|
|
|
player_data.mechanical_limits.dash_duration -= fix(1) / 64;
|
|
|
|
if(player_data.mechanical_limits.dash_duration <= 0)
|
|
|
|
player_data.mechanical_limits.dash_duration = 0;
|
2021-06-04 16:24:47 +02:00
|
|
|
}
|
2021-06-05 11:38:51 +02:00
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
if(ev.key == KEY_PLUS)
|
|
|
|
camera_zoom(c, c->zoom + 1);
|
|
|
|
if(ev.key == KEY_MINUS)
|
|
|
|
camera_zoom(c, c->zoom - 1);
|
2022-01-17 18:29:05 +01:00
|
|
|
#endif
|
2022-01-18 09:45:23 +01:00
|
|
|
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && !game.menu_open && !(game.finish_time > 0)
|
|
|
|
&& ev.key == KEY_SHIFT && !debug.dev_menu)
|
2021-06-04 16:24:47 +02:00
|
|
|
attack = true;
|
2022-01-18 09:45:23 +01:00
|
|
|
|
|
|
|
/* Menus */
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && !debug.dev_menu && !(game.finish_time > 0)
|
|
|
|
&& ev.key == KEY_F6 && !keydown(KEY_ALPHA)) {
|
2022-12-28 11:27:05 +01:00
|
|
|
if(game.menu_open)
|
|
|
|
game_hud_anim_backpack_close(&game);
|
|
|
|
else
|
|
|
|
game_hud_anim_backpack_open(&game);
|
2022-03-18 20:36:29 +01:00
|
|
|
game.menu_open = !game.menu_open;
|
2022-12-28 11:27:05 +01:00
|
|
|
}
|
2022-03-18 22:21:30 +01:00
|
|
|
|
|
|
|
/* Inventory movement */
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && game.menu_open && !(game.finish_time > 0)) {
|
2022-05-31 21:42:43 +02:00
|
|
|
int y = game.menu_cursor / 4, x = game.menu_cursor % 4;
|
2022-03-18 22:21:30 +01:00
|
|
|
y = y + (ev.key == KEY_DOWN) - (ev.key == KEY_UP);
|
|
|
|
x = x + (ev.key == KEY_RIGHT) - (ev.key == KEY_LEFT);
|
2022-05-31 21:42:43 +02:00
|
|
|
y = max(0, min(y, 1));
|
|
|
|
x = max(0, min(x, 3));
|
|
|
|
game.menu_cursor = 4 * y + x;
|
2022-03-18 22:21:30 +01:00
|
|
|
}
|
|
|
|
|
2022-06-05 23:11:06 +02:00
|
|
|
/* Using and equipping items */
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && game.menu_open && !(game.finish_time > 0)
|
|
|
|
&& ev.key == KEY_SHIFT) {
|
2022-03-18 22:21:30 +01:00
|
|
|
int item = player_data.inventory[game.menu_cursor];
|
|
|
|
int slot = item_equipment_slot(item);
|
|
|
|
|
|
|
|
if(item >= 0 && slot >= 0) {
|
2022-05-31 21:42:43 +02:00
|
|
|
if(player_data.equipment[slot] == game.menu_cursor)
|
|
|
|
player_data.equipment[slot] = -1;
|
|
|
|
else
|
|
|
|
player_data.equipment[slot] = game.menu_cursor;
|
|
|
|
|
2022-03-19 18:14:00 +01:00
|
|
|
/* Update skills */
|
2022-05-31 21:45:48 +02:00
|
|
|
int sk[6];
|
|
|
|
player_compute_skills(player, player_data.equipment, sk);
|
|
|
|
/* Reet the cooldown for all skills that changed */
|
|
|
|
for(int i = 0; i < 6; i++) {
|
|
|
|
if(sk[i] < 0)
|
|
|
|
player_f->actions_cooldown[i] = 0;
|
|
|
|
else if(sk[i] != player_f->skills[i])
|
|
|
|
player_f->actions_cooldown[i] =
|
|
|
|
skill_cooldown(sk[i]);
|
|
|
|
player_f->skills[i] = sk[i];
|
|
|
|
}
|
2022-03-18 22:21:30 +01:00
|
|
|
}
|
2023-01-23 21:56:55 +01:00
|
|
|
else if(item >= 0 && item_use(item, &game, player)) {
|
2022-06-05 23:11:06 +02:00
|
|
|
player_data.inventory[game.menu_cursor] = -1;
|
2023-01-15 17:17:45 +01:00
|
|
|
|
|
|
|
int color = item_buff_color(item);
|
|
|
|
if(color > 0) {
|
|
|
|
entity_t *part = particle_make_buff(player, color);
|
|
|
|
game_add_entity(&game, part);
|
|
|
|
}
|
2022-06-05 23:11:06 +02:00
|
|
|
}
|
2022-03-18 22:21:30 +01:00
|
|
|
}
|
2021-06-04 16:24:47 +02:00
|
|
|
}
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2021-06-04 16:24:47 +02:00
|
|
|
/* Camera movement */
|
2021-08-30 17:48:44 +02:00
|
|
|
#if 0
|
2021-05-30 21:59:09 +02:00
|
|
|
fixed_t vx = CAMERA_SPEED_X;
|
|
|
|
fixed_t vy = CAMERA_SPEED_Y;
|
|
|
|
|
2021-06-01 17:49:29 +02:00
|
|
|
if(keydown(KEY_4) || keydown(KEY_7) || keydown(KEY_1))
|
2021-05-30 21:59:09 +02:00
|
|
|
camera_move(c, -fmul(dt, vx), 0);
|
2021-06-01 17:49:29 +02:00
|
|
|
if(keydown(KEY_6) || keydown(KEY_9) || keydown(KEY_3))
|
2021-05-30 21:59:09 +02:00
|
|
|
camera_move(c, fmul(dt, vx), 0);
|
2021-06-01 17:49:29 +02:00
|
|
|
if(keydown(KEY_8) || keydown(KEY_7) || keydown(KEY_9))
|
2021-05-30 21:59:09 +02:00
|
|
|
camera_move(c, 0, -fmul(dt, vy));
|
2021-06-01 17:49:29 +02:00
|
|
|
if(keydown(KEY_2) || keydown(KEY_1) || keydown(KEY_3))
|
2021-05-30 21:59:09 +02:00
|
|
|
camera_move(c, 0, fmul(dt, vy));
|
2021-08-30 17:48:44 +02:00
|
|
|
#endif
|
2021-05-30 21:59:09 +02:00
|
|
|
|
2022-03-19 18:14:00 +01:00
|
|
|
/* Player movement input */
|
|
|
|
int input_dir = -1, next_dir = -1;
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && !game.menu_open && !(game.finish_time > 0)
|
|
|
|
&& player_f->HP > 0) {
|
2022-03-19 18:14:00 +01:00
|
|
|
if(keydown(KEY_UP)) input_dir = UP;
|
|
|
|
if(keydown(KEY_DOWN)) input_dir = DOWN;
|
|
|
|
if(keydown(KEY_LEFT)) input_dir = LEFT;
|
|
|
|
if(keydown(KEY_RIGHT)) input_dir = RIGHT;
|
|
|
|
}
|
2023-01-02 11:50:25 +01:00
|
|
|
if(game.finish_time > 0)
|
|
|
|
next_dir = -1;
|
|
|
|
else if(input_dir >= 0)
|
|
|
|
next_dir = input_dir;
|
|
|
|
else
|
|
|
|
next_dir = player_p->facing;
|
2022-03-19 18:14:00 +01:00
|
|
|
|
|
|
|
/* Player skills (including movement skills) */
|
|
|
|
bool can_use_skill = !debug.paused && !game.menu_open
|
2023-01-02 11:50:25 +01:00
|
|
|
&& !(game.finish_time > 0) && player_f->HP > 0 && !debug.dev_menu;
|
2022-03-19 18:14:00 +01:00
|
|
|
|
|
|
|
if(can_use_skill && keydown(KEY_F1))
|
|
|
|
skill_use(&game, player, 1, fdir(next_dir));
|
|
|
|
if(can_use_skill && keydown(KEY_F2))
|
|
|
|
skill_use(&game, player, 2, fdir(next_dir));
|
|
|
|
if(can_use_skill && keydown(KEY_F3))
|
|
|
|
skill_use(&game, player, 3, fdir(next_dir));
|
|
|
|
if(can_use_skill && keydown(KEY_F4))
|
|
|
|
skill_use(&game, player, 4, fdir(next_dir));
|
|
|
|
|
2021-06-01 22:06:58 +02:00
|
|
|
/* Player movement */
|
2022-03-18 22:21:30 +01:00
|
|
|
if(!debug.paused && !game.menu_open && player_f->HP > 0) {
|
2022-03-19 18:14:00 +01:00
|
|
|
mechanical_move4(player, input_dir, dt, game.map);
|
2021-08-29 09:44:38 +02:00
|
|
|
|
2022-03-19 18:14:00 +01:00
|
|
|
if(input_dir >= 0)
|
2021-12-25 11:47:22 +01:00
|
|
|
visible_set_anim(player, &anims_player_Walking, 1);
|
|
|
|
else
|
|
|
|
visible_set_anim(player, &anims_player_Idle, 1);
|
2021-06-04 15:14:12 +02:00
|
|
|
}
|
2021-06-10 22:48:27 +02:00
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
/* Directions to reach the player from anywhere on the grid */
|
2022-02-06 09:32:54 +01:00
|
|
|
game_compute_occupation(&game);
|
2021-06-25 11:44:29 +02:00
|
|
|
pfg_all2one_free(&game.paths_to_player);
|
2022-02-06 09:32:54 +01:00
|
|
|
game.paths_to_player = pfg_dijkstra(game.map,
|
|
|
|
vec_f2i(physical_pos(player)), game.occupation);
|
2021-06-25 11:44:29 +02:00
|
|
|
|
2021-06-30 13:56:58 +02:00
|
|
|
/* Enemy AI */
|
2023-01-23 21:56:55 +01:00
|
|
|
if(player_f->HP > 0 && game.freeze_time == 0)
|
2021-12-25 11:47:22 +01:00
|
|
|
for(int i = 0; i < game.entity_count; i++) {
|
2021-06-10 00:07:01 +02:00
|
|
|
entity_t *e = game.entities[i];
|
2021-12-25 11:47:22 +01:00
|
|
|
fighter_t *f = getcomp(e, fighter);
|
|
|
|
mechanical_t *m = getcomp(e, mechanical);
|
2022-02-08 22:48:08 +01:00
|
|
|
if(!f || !m || !f->enemy || f->HP == 0)
|
2021-12-25 11:47:22 +01:00
|
|
|
continue;
|
2021-06-10 00:07:01 +02:00
|
|
|
|
2022-02-03 17:39:57 +01:00
|
|
|
enemy_ai(&game, e, dt);
|
2021-12-25 11:47:22 +01:00
|
|
|
|
|
|
|
if(mechanical_moving(e))
|
2022-02-08 22:48:08 +01:00
|
|
|
visible_set_anim(e, f->enemy->id->anim_walking, 1);
|
2021-12-25 11:47:22 +01:00
|
|
|
else
|
2022-02-08 22:48:08 +01:00
|
|
|
visible_set_anim(e, f->enemy->id->anim_idle, 1);
|
2021-06-10 00:07:01 +02:00
|
|
|
}
|
|
|
|
|
2021-06-30 13:56:58 +02:00
|
|
|
/* Player attack */
|
2023-01-02 11:50:25 +01:00
|
|
|
if(!debug.paused && !game.menu_open && !(game.finish_time > 0)
|
|
|
|
&& player_f->HP > 0 && attack && !player_f->current_attack) {
|
2022-06-25 18:04:07 +02:00
|
|
|
if(player_f->skills[0] == AOE_SLASH) {
|
|
|
|
int hit_number=0, effect=AOE_SLASH;
|
|
|
|
|
|
|
|
/* If hitting within .25s of the previous hit ending, combo! */
|
|
|
|
if(abs(player_f->combo_delay) < fix(0.25))
|
|
|
|
hit_number = player_f->combo_next;
|
|
|
|
player_f->combo_next = (hit_number+1) % player_f->combo_length;
|
|
|
|
|
|
|
|
if(hit_number == 0) effect = AOE_SLASH;
|
|
|
|
if(hit_number == 1) effect = AOE_IMPALE;
|
|
|
|
entity_t *aoe = aoe_make_attack_4(effect, player,
|
|
|
|
player_p->facing);
|
|
|
|
getcomp(aoe, visible)->z = fix(0.25);
|
|
|
|
game_add_entity(&game, aoe);
|
|
|
|
|
|
|
|
visible_set_anim(player, &anims_player_Attack, 2);
|
|
|
|
player_f->current_attack = aoe;
|
|
|
|
player_f->attack_follows_movement = true;
|
|
|
|
player_f->combo_delay = getcomp(aoe, aoe)->lifetime;
|
|
|
|
}
|
|
|
|
else if(player_f->skills[0] == AOE_PROJECTILE_FAST) {
|
|
|
|
vec2 dir = pathfinding_autoaim(&game, player, game.map);
|
|
|
|
if(dir.x == 0 && dir.y == 0)
|
|
|
|
dir = fdir(player_p->facing);
|
|
|
|
skill_use(&game, player, 0, dir);
|
|
|
|
}
|
2021-12-25 11:47:22 +01:00
|
|
|
}
|
2021-08-16 13:53:53 +02:00
|
|
|
|
2021-10-23 15:10:20 +02:00
|
|
|
/* Ideas for additional skills:
|
|
|
|
- Freeze enemies
|
|
|
|
- Barrier around player
|
|
|
|
- Teleport
|
|
|
|
- Time manipulation
|
2022-02-04 10:32:10 +01:00
|
|
|
- Player buffs (short but strong) or wide area debuffs
|
2021-10-23 15:10:20 +02:00
|
|
|
Ideas for items:
|
|
|
|
- Healing potion
|
|
|
|
- Equipment
|
|
|
|
- XP boosts
|
|
|
|
- Weaker but longer-lasting buffs */
|
2021-06-10 22:48:27 +02:00
|
|
|
|
2022-12-28 11:27:05 +01:00
|
|
|
game_update_animations(&game, dt, dt_rt);
|
2022-02-07 20:41:39 +01:00
|
|
|
game_update_effects(&game, dt);
|
2021-12-25 11:47:22 +01:00
|
|
|
game_update_aoes(&game, dt);
|
2021-06-25 11:44:29 +02:00
|
|
|
game_update_particles(&game, dt);
|
2021-12-30 10:16:15 +01:00
|
|
|
// TODO: Kill out-of-bounds entities
|
2021-12-25 11:47:22 +01:00
|
|
|
game_remove_dead_entities(&game);
|
2022-02-04 10:12:00 +01:00
|
|
|
|
|
|
|
/* Update combo and action cooldowns */
|
2021-12-25 11:47:22 +01:00
|
|
|
player_f->combo_delay -= dt;
|
2022-02-05 14:38:26 +01:00
|
|
|
game_run_cooldowns(&game, dt);
|
2021-12-25 11:47:22 +01:00
|
|
|
|
|
|
|
/* Reset default anims */
|
|
|
|
if(!player_v->anim.frame)
|
|
|
|
visible_set_anim(player, &anims_player_Idle, 1);
|
2021-12-25 18:21:31 +01:00
|
|
|
for(int i = 0; i < game.entity_count; i++) {
|
|
|
|
entity_t *e = game.entities[i];
|
|
|
|
fighter_t *f = getcomp(e, fighter);
|
|
|
|
visible_t *v = getcomp(e, visible);
|
2022-02-08 22:48:08 +01:00
|
|
|
if(f && f->enemy && v && !v->anim.frame) {
|
|
|
|
visible_set_anim(e, f->enemy->id->anim_idle, 1);
|
2021-12-25 18:21:31 +01:00
|
|
|
}
|
|
|
|
}
|
2021-06-25 11:44:29 +02:00
|
|
|
|
2022-02-02 10:16:59 +01:00
|
|
|
/* Reduce screenshake time */
|
|
|
|
game.screenshake_duration -= dt;
|
|
|
|
if(game.screenshake_duration < 0) {
|
|
|
|
game.screenshake_duration = 0;
|
|
|
|
game.screenshake_amplitude = 0;
|
|
|
|
}
|
|
|
|
|
2022-03-18 20:36:29 +01:00
|
|
|
/* Menu animation */
|
|
|
|
if(game.menu_open && game.menu_time < fix(1)) {
|
|
|
|
game.menu_time = min(game.menu_time + 2 * dt_rt, fix(1));
|
|
|
|
}
|
|
|
|
else if(!game.menu_open && game.menu_time > fix(0)) {
|
|
|
|
game.menu_time = max(game.menu_time - 2 * dt_rt, fix(0));
|
|
|
|
}
|
|
|
|
|
2022-06-05 23:11:06 +02:00
|
|
|
/* Reduce message time */
|
|
|
|
if(game.message && game.message_time > 0) {
|
|
|
|
game.message_time -= dt_rt;
|
|
|
|
if(game.message_time <= 0) {
|
|
|
|
game.message_time = 0;
|
|
|
|
game.message = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-25 11:44:29 +02:00
|
|
|
game.time_total += dt;
|
2023-01-23 21:56:55 +01:00
|
|
|
if(game.freeze_time >= 0) {
|
|
|
|
game.freeze_time -= dt;
|
|
|
|
if(game.freeze_time < 0) {
|
|
|
|
game.event_time += -game.freeze_time;
|
|
|
|
game.freeze_time = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
game.event_time += dt;
|
|
|
|
}
|
2021-06-15 17:27:30 +02:00
|
|
|
|
2021-07-16 15:51:32 +02:00
|
|
|
/* Next wave */
|
2022-03-14 22:50:24 +01:00
|
|
|
if(player_f->HP > 0 && game_current_event_finished(&game))
|
|
|
|
game_next_event(&game);
|
2021-07-16 15:51:32 +02:00
|
|
|
|
2023-01-02 11:50:25 +01:00
|
|
|
/* Victory or game over */
|
|
|
|
if(!game.finish_time && game_defeated(&game)) {
|
|
|
|
game.finish_time = game.time_total;
|
|
|
|
game.victory = false;
|
|
|
|
game.menu_open = false;
|
|
|
|
}
|
|
|
|
else if(!game.finish_time && game_victory_achieved(&game)) {
|
|
|
|
game.finish_time = game.time_total;
|
|
|
|
game.victory = true;
|
|
|
|
game.menu_open = false;
|
|
|
|
}
|
|
|
|
/* Start the final screen when everything has settled */
|
|
|
|
if(game.finish_time > 0 && !game.menu_time
|
|
|
|
&& game.final_screen_time < 0) {
|
|
|
|
game.final_screen_time = fix(0);
|
|
|
|
}
|
|
|
|
|
2021-06-15 17:27:30 +02:00
|
|
|
/* Visual pathfinding debug */
|
2021-06-25 11:44:29 +02:00
|
|
|
if(debug.show_path) {
|
|
|
|
pfg_path_free(&debug.grid_path);
|
|
|
|
pfc_path_free(&debug.continuous_path);
|
|
|
|
|
2022-01-17 18:29:05 +01:00
|
|
|
vec2 target = vec_i2f_center((ivec2){ debug.some_x,debug.some_y });
|
2022-02-06 09:32:54 +01:00
|
|
|
debug.grid_path = pfg_outwards(&game.paths_to_player,
|
2021-10-24 21:54:37 +02:00
|
|
|
vec_f2i(target));
|
2021-06-25 11:44:29 +02:00
|
|
|
debug.continuous_path = pfc_shortcut_full(&debug.grid_path,
|
2021-12-25 11:47:22 +01:00
|
|
|
physical_pos(player), target, player_p->hitbox);
|
2021-06-25 11:44:29 +02:00
|
|
|
}
|
2021-06-15 17:27:30 +02:00
|
|
|
|
|
|
|
prof_leave(perf_simul);
|
|
|
|
time_simul = prof_time(perf_simul);
|
|
|
|
}
|
2021-05-30 21:59:09 +02:00
|
|
|
|
|
|
|
timer_stop(timer_id);
|
2023-01-02 11:50:25 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
|
|
|
/* Enable %f etc. in printf()-like functions */
|
|
|
|
__printf_enable_fp();
|
|
|
|
/* Enable %D for decimal fixed-point in printf()-like functions */
|
|
|
|
__printf_enable_fixed();
|
|
|
|
/* Initialize the PRNG */
|
|
|
|
srand(rtc_ticks());
|
|
|
|
/* Initialize the benchmarking/profiling library */
|
|
|
|
prof_init();
|
|
|
|
/* Open the USB connection (for screenshots with fxlink) */
|
|
|
|
usb_interface_t const *interfaces[] = { &usb_ff_bulk, NULL };
|
|
|
|
usb_open(interfaces, GINT_CALL_NULL);
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
menu_select_play_repeat();
|
|
|
|
}
|
|
|
|
|
2021-06-02 15:40:32 +02:00
|
|
|
prof_quit();
|
2021-05-30 21:59:09 +02:00
|
|
|
usb_close();
|
2021-06-02 10:06:10 +02:00
|
|
|
return 1;
|
2021-05-30 21:59:09 +02:00
|
|
|
}
|