2010-10-12 10:55:23 +02:00
|
|
|
/*
|
2011-03-05 13:44:21 +01:00
|
|
|
* This software is licensed under the terms of the MIT-License
|
2017-02-11 02:24:47 +01:00
|
|
|
* See COPYING for further information.
|
2011-03-05 13:44:21 +01:00
|
|
|
* ---
|
2019-01-23 21:10:43 +01:00
|
|
|
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
|
2019-07-03 20:00:56 +02:00
|
|
|
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
2010-10-12 10:55:23 +02:00
|
|
|
*/
|
|
|
|
|
2019-01-23 21:10:43 +01:00
|
|
|
#ifndef IGUARD_player_h
|
|
|
|
#define IGUARD_player_h
|
|
|
|
|
2017-11-25 20:45:11 +01:00
|
|
|
#include "taisei.h"
|
2010-10-12 10:55:23 +02:00
|
|
|
|
2017-03-06 13:02:46 +01:00
|
|
|
#ifdef DEBUG
|
|
|
|
#define PLR_DPS_STATS
|
|
|
|
#endif
|
|
|
|
|
2017-03-06 01:25:59 +01:00
|
|
|
#include "util.h"
|
2011-04-26 12:04:45 +02:00
|
|
|
#include "enemy.h"
|
2012-08-15 16:36:39 +02:00
|
|
|
#include "gamepad.h"
|
2017-10-03 17:25:38 +02:00
|
|
|
#include "aniplayer.h"
|
2011-06-25 12:41:40 +02:00
|
|
|
#include "resource/animation.h"
|
2018-04-13 21:13:48 +02:00
|
|
|
#include "entity.h"
|
2011-06-13 18:48:36 +02:00
|
|
|
|
2017-03-21 11:09:32 +01:00
|
|
|
enum {
|
|
|
|
PLR_MAX_POWER = 400,
|
2019-02-22 00:56:03 +01:00
|
|
|
PLR_MAX_POWER_OVERFLOW = 200,
|
2019-01-04 23:59:39 +01:00
|
|
|
PLR_MAX_LIVES = 8,
|
|
|
|
PLR_MAX_BOMBS = 8,
|
2017-03-21 11:09:32 +01:00
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
// -Wpedantic doesn't like this
|
|
|
|
// PLR_MAX_PIV = UINT32_MAX,
|
|
|
|
#define PLR_MAX_PIV UINT32_MAX
|
|
|
|
#define PLR_MAX_GRAZE UINT32_MAX
|
|
|
|
#define PLR_MAX_VOLTAGE UINT16_MAX
|
|
|
|
|
2017-03-21 11:09:32 +01:00
|
|
|
PLR_MAX_LIFE_FRAGMENTS = 5,
|
2019-02-22 00:56:03 +01:00
|
|
|
PLR_MAX_BOMB_FRAGMENTS = 500,
|
2017-03-21 11:09:32 +01:00
|
|
|
|
|
|
|
PLR_START_LIVES = 2,
|
|
|
|
PLR_START_BOMBS = 3,
|
2019-02-22 00:56:03 +01:00
|
|
|
PLR_START_PIV = 10000,
|
2017-04-08 01:09:08 +02:00
|
|
|
|
2018-01-06 21:58:29 +01:00
|
|
|
PLR_STGPRACTICE_LIVES = PLR_MAX_LIVES,
|
|
|
|
PLR_STGPRACTICE_BOMBS = PLR_START_BOMBS,
|
2017-11-11 22:44:54 +01:00
|
|
|
|
|
|
|
PLR_MIN_BORDER_DIST = 16,
|
2019-02-22 00:56:03 +01:00
|
|
|
|
|
|
|
PLR_POWERSURGE_POWERCOST = 200,
|
2019-03-05 12:50:29 +01:00
|
|
|
|
|
|
|
PLR_RESPAWN_TIME = 60,
|
2017-03-21 11:09:32 +01:00
|
|
|
};
|
|
|
|
|
2019-03-05 12:50:29 +01:00
|
|
|
#define PLR_SPAWN_POS_X (VIEWPORT_W * 0.5)
|
|
|
|
#define PLR_SPAWN_POS_Y (VIEWPORT_H - 64.0)
|
|
|
|
#define PLR_SPAWN_POS CMPLX(PLR_SPAWN_POS_X, PLR_SPAWN_POS_Y)
|
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
static const float PLR_POWERSURGE_POSITIVE_DRAIN_MAX = (0.15 / 60.0);
|
|
|
|
static const float PLR_POWERSURGE_POSITIVE_DRAIN_MIN = (0.15 / 60.0);
|
2019-04-08 05:41:29 +02:00
|
|
|
static const float PLR_POWERSURGE_NEGATIVE_DRAIN_MAX = (0.15 / 60.0);
|
2019-02-22 00:56:03 +01:00
|
|
|
static const float PLR_POWERSURGE_NEGATIVE_DRAIN_MIN = (0.01 / 60.0);
|
|
|
|
static const float PLR_POWERSURGE_POSITIVE_GAIN = (1.50 / 60.0);
|
2019-03-28 16:56:06 +01:00
|
|
|
static const float PLR_POWERSURGE_NEGATIVE_GAIN = (0.40 / 60.0);
|
2019-02-22 00:56:03 +01:00
|
|
|
|
2017-03-06 15:24:57 +01:00
|
|
|
typedef enum {
|
|
|
|
// do not reorder these or you'll break replays
|
|
|
|
|
|
|
|
INFLAG_UP = 1,
|
|
|
|
INFLAG_DOWN = 2,
|
|
|
|
INFLAG_LEFT = 4,
|
|
|
|
INFLAG_RIGHT = 8,
|
|
|
|
INFLAG_FOCUS = 16,
|
|
|
|
INFLAG_SHOT = 32,
|
2017-09-19 20:46:28 +02:00
|
|
|
INFLAG_SKIP = 64,
|
2017-03-06 15:24:57 +01:00
|
|
|
} PlrInputFlag;
|
|
|
|
|
2010-10-12 10:55:23 +02:00
|
|
|
enum {
|
2017-03-06 15:24:57 +01:00
|
|
|
INFLAGS_MOVE = INFLAG_UP | INFLAG_DOWN | INFLAG_LEFT | INFLAG_RIGHT
|
2010-10-12 10:55:23 +02:00
|
|
|
};
|
|
|
|
|
2018-04-13 21:13:48 +02:00
|
|
|
typedef struct Player Player;
|
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
typedef struct PowerSurgeBonus {
|
|
|
|
uint baseline;
|
|
|
|
uint score;
|
|
|
|
uint gain_rate;
|
|
|
|
float discharge_power;
|
|
|
|
float discharge_range;
|
|
|
|
float discharge_damage;
|
|
|
|
} PowerSurgeBonus;
|
|
|
|
|
2018-04-13 21:13:48 +02:00
|
|
|
struct Player {
|
|
|
|
ENTITY_INTERFACE_NAMED(Player, ent);
|
|
|
|
|
2011-03-18 19:03:06 +01:00
|
|
|
complex pos;
|
2018-05-13 15:08:58 +02:00
|
|
|
complex velocity;
|
2017-10-29 23:45:24 +01:00
|
|
|
complex deathpos;
|
2019-02-22 00:56:03 +01:00
|
|
|
complex lastmovedir;
|
2017-02-11 02:24:47 +01:00
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
struct PlayerMode *mode;
|
|
|
|
AniPlayer ani;
|
|
|
|
EnemyList slaves;
|
|
|
|
EnemyList focus_circle;
|
2017-02-11 02:24:47 +01:00
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
struct {
|
|
|
|
float positive;
|
|
|
|
float negative;
|
|
|
|
struct {
|
|
|
|
int activated, expired;
|
|
|
|
} time;
|
|
|
|
int power;
|
|
|
|
double damage_done;
|
|
|
|
double damage_accum;
|
|
|
|
PowerSurgeBonus bonus;
|
|
|
|
} powersurge;
|
|
|
|
|
|
|
|
uint64_t points;
|
|
|
|
|
|
|
|
uint64_t extralife_threshold;
|
|
|
|
uint extralives_given;
|
|
|
|
|
|
|
|
uint point_item_value;
|
|
|
|
uint graze;
|
|
|
|
uint voltage;
|
2017-03-21 11:09:32 +01:00
|
|
|
int lives;
|
2011-03-23 12:26:30 +01:00
|
|
|
int bombs;
|
2017-03-21 11:09:32 +01:00
|
|
|
int life_fragments;
|
|
|
|
int bomb_fragments;
|
2017-10-29 23:45:24 +01:00
|
|
|
int continues_used;
|
2019-02-22 00:56:03 +01:00
|
|
|
int focus;
|
|
|
|
int power;
|
|
|
|
int power_overflow;
|
2017-03-21 11:09:32 +01:00
|
|
|
|
2017-10-29 23:45:24 +01:00
|
|
|
int continuetime;
|
2011-06-29 17:01:03 +02:00
|
|
|
int recovery;
|
2011-06-25 12:41:40 +02:00
|
|
|
int deathtime;
|
2012-08-11 14:03:41 +02:00
|
|
|
int respawntime;
|
2018-05-02 08:08:32 +02:00
|
|
|
int bombtotaltime;
|
2017-02-11 02:24:47 +01:00
|
|
|
|
2017-03-06 15:24:57 +01:00
|
|
|
int inputflags;
|
2018-04-12 16:08:48 +02:00
|
|
|
int lastmovesequence; // used for animation
|
2012-08-15 16:36:39 +02:00
|
|
|
int axis_ud;
|
|
|
|
int axis_lr;
|
2017-02-11 02:24:47 +01:00
|
|
|
|
2019-07-03 19:50:43 +02:00
|
|
|
float bomb_cutin_alpha;
|
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
bool gamepadmove;
|
2017-10-08 13:30:51 +02:00
|
|
|
bool iddqd;
|
2017-03-06 13:02:46 +01:00
|
|
|
|
|
|
|
#ifdef PLR_DPS_STATS
|
2018-05-03 19:51:10 +02:00
|
|
|
int dmglogframe;
|
|
|
|
int dmglog[240];
|
2017-03-06 13:02:46 +01:00
|
|
|
#endif
|
2018-04-13 21:13:48 +02:00
|
|
|
};
|
2010-10-12 10:55:23 +02:00
|
|
|
|
2017-03-06 01:25:59 +01:00
|
|
|
// this is used by both player and replay code
|
|
|
|
enum {
|
|
|
|
EV_PRESS,
|
|
|
|
EV_RELEASE,
|
|
|
|
EV_OVER, // replay-only
|
|
|
|
EV_AXIS_LR,
|
|
|
|
EV_AXIS_UD,
|
|
|
|
EV_CHECK_DESYNC, // replay-only
|
2017-03-21 03:28:35 +01:00
|
|
|
EV_FPS, // replay-only
|
2017-09-19 20:46:28 +02:00
|
|
|
EV_INFLAGS,
|
2017-10-29 23:45:24 +01:00
|
|
|
EV_CONTINUE,
|
2017-03-06 01:25:59 +01:00
|
|
|
};
|
|
|
|
|
2017-10-08 13:30:51 +02:00
|
|
|
// This is called first before we even enter stage_loop.
|
|
|
|
// It's also called right before syncing player state from a replay stage struct, if a replay is being watched or recorded, before every stage.
|
|
|
|
// The entire state is reset here, and defaults for story mode are set.
|
|
|
|
void player_init(Player *plr);
|
|
|
|
|
|
|
|
// This is called early in stage_loop, before creating or reading replay stage data.
|
|
|
|
// State that is not supposed to be preserved between stages is reset here, and any plrmode-specific resources are preloaded.
|
|
|
|
void player_stage_pre_init(Player *plr);
|
|
|
|
|
2018-10-23 05:26:22 +02:00
|
|
|
// This is called right after the stage's begin proc. After that, the actual game loop starts.
|
2017-10-08 13:30:51 +02:00
|
|
|
void player_stage_post_init(Player *plr);
|
|
|
|
|
|
|
|
// Yes, that's 3 different initialization functions right here.
|
2017-02-15 17:09:09 +01:00
|
|
|
|
2017-11-25 16:51:43 +01:00
|
|
|
void player_free(Player *plr);
|
|
|
|
|
2019-07-03 19:50:43 +02:00
|
|
|
void player_draw_overlay(Player *plr);
|
|
|
|
void player_logic(Player *plr);
|
2017-10-08 13:30:51 +02:00
|
|
|
bool player_should_shoot(Player *plr, bool extra);
|
2011-03-23 12:26:30 +01:00
|
|
|
|
2017-10-24 04:57:14 +02:00
|
|
|
bool player_set_power(Player *plr, short npow);
|
2019-02-22 00:56:03 +01:00
|
|
|
bool player_add_power(Player *plr, short pdelta);
|
2011-06-29 17:01:03 +02:00
|
|
|
|
2012-07-20 16:11:24 +02:00
|
|
|
void player_move(Player*, complex delta);
|
2011-07-05 15:20:19 +02:00
|
|
|
|
2012-07-20 16:11:24 +02:00
|
|
|
void player_realdeath(Player*);
|
|
|
|
void player_death(Player*);
|
2019-01-04 23:59:39 +01:00
|
|
|
void player_graze(Player *plr, complex pos, int pts, int effect_intensity, const Color *color);
|
2012-07-14 16:37:52 +02:00
|
|
|
|
2017-10-31 10:48:30 +01:00
|
|
|
void player_event(Player *plr, uint8_t type, uint16_t value, bool *out_useful, bool *out_cheat);
|
2017-09-19 20:46:28 +02:00
|
|
|
bool player_event_with_replay(Player *plr, uint8_t type, uint16_t value);
|
2012-07-14 16:37:52 +02:00
|
|
|
void player_applymovement(Player* plr);
|
2017-09-19 20:46:28 +02:00
|
|
|
void player_fix_input(Player *plr);
|
2012-07-14 16:37:52 +02:00
|
|
|
|
2017-03-21 11:09:32 +01:00
|
|
|
void player_add_life_fragments(Player *plr, int frags);
|
|
|
|
void player_add_bomb_fragments(Player *plr, int frags);
|
|
|
|
void player_add_lives(Player *plr, int lives);
|
|
|
|
void player_add_bombs(Player *plr, int bombs);
|
2019-04-07 00:55:13 +02:00
|
|
|
void player_add_points(Player *plr, uint points, complex location);
|
|
|
|
void player_add_piv(Player *plr, uint piv, complex location);
|
2019-02-22 00:56:03 +01:00
|
|
|
void player_add_voltage(Player *plr, uint voltage);
|
|
|
|
bool player_drain_voltage(Player *plr, uint voltage);
|
|
|
|
void player_extend_powersurge(Player *plr, float pos, float neg);
|
2017-03-21 11:09:32 +01:00
|
|
|
|
2018-07-30 09:04:09 +02:00
|
|
|
void player_register_damage(Player *plr, EntityInterface *target, const DamageInfo *damage);
|
2018-05-03 19:51:10 +02:00
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
void player_cancel_powersurge(Player *plr);
|
2018-07-30 15:14:27 +02:00
|
|
|
void player_placeholder_bomb_logic(Player *plr);
|
2017-11-26 14:06:35 +01:00
|
|
|
|
2018-07-31 09:07:34 +02:00
|
|
|
bool player_is_bomb_active(Player *plr);
|
2019-02-22 00:56:03 +01:00
|
|
|
bool player_is_powersurge_active(Player *plr);
|
2018-07-31 09:07:34 +02:00
|
|
|
bool player_is_vulnerable(Player *plr);
|
|
|
|
bool player_is_alive(Player *plr);
|
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
void player_powersurge_calc_bonus(Player *plr, PowerSurgeBonus *bonus);
|
|
|
|
|
|
|
|
uint64_t player_next_extralife_threshold(uint64_t step);
|
|
|
|
|
2017-11-26 14:06:35 +01:00
|
|
|
// Progress is normalized from 0: bomb start to 1: bomb end
|
2019-03-31 23:12:45 +02:00
|
|
|
double player_get_bomb_progress(Player *plr);
|
2017-10-17 22:27:35 +02:00
|
|
|
|
2019-02-22 00:56:03 +01:00
|
|
|
void player_damage_hook(Player *plr, EntityInterface *target, DamageInfo *dmg);
|
|
|
|
|
2017-03-11 04:41:57 +01:00
|
|
|
void player_preload(void);
|
2018-08-11 21:13:48 +02:00
|
|
|
|
|
|
|
// FIXME: where should this be?
|
|
|
|
complex plrutil_homing_target(complex org, complex fallback);
|
2019-01-23 21:10:43 +01:00
|
|
|
|
|
|
|
#endif // IGUARD_player_h
|