/*
This file is part of Minitrem.
Minitrem is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Minitrem is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Minitrem. If not, see .
*/
#include "../common.hpp"
namespace game {
enum {
ET_UNIT,
ET_EFFECT,
ET_DECO
};
enum {
TILE_NONE,
TILE_DIRT,
TILE_DIRT_RED,
TILE_STONE,
TILE_STONE_RED,
TILE_WATER,
TILE_GRAVEL
};
enum {
CF_BACKGROUND = 1,
CF_SOLID = 2,
CF_BODY = 4,
CF_BODY_SMALL = 8,
CF_WATER = 16
};
extern size_t selection_cookie;
void worldgen(world::world_t *world, world::sector_index_t index, world::sector_t *sector,
bool gen_tiles, bool gen_decos, void *data);
namespace assets {
typedef struct {
render::oriented_sprite_4M_t head_idle, body_idle;
render::oriented_sprite_4M_t body_aiming, body_firing;
render::animated_texture_t body_panic;
render::oriented_sprite_4M2_t legs_idle, legs_walking;
render::animated_texture_t dead;
audio::sound_t fire;
} soldier_assets_t;
typedef struct {
render::oriented_sprite_4M_t idle, walking;
render::animated_texture_t dead;
} spider_assets_t;
typedef struct {
render::animated_texture_t idle, dead;
} nest_assets_t;
typedef struct {
render::animated_texture_t blood;
} fx_assets_t;
typedef struct {
render::animated_texture_t stone, eyething;
render::animated_texture_t spike, spike_small;
render::animated_texture_t wart;
} deco_assets_t;
extern soldier_assets_t soldier;
extern spider_assets_t spider;
extern nest_assets_t nest;
extern fx_assets_t fx;
extern deco_assets_t deco;
extern render::animated_texture_t unit_selected;
extern render::animated_texture_t unit_selected_halo;
extern render::animated_texture_t move_marker;
void load(void);
}
namespace text {
typedef enum {
LANG_ENGLISH,
LANG_POLISH
} language_t;
extern language_t language;
typedef enum {
PAUSED,
UNPAUSED,
FOLLOWING_ON,
FOLLOWING_OFF,
SAY_GROUP,
SAY_NO_PATH,
SAY_READY,
SAY_READY_GROUP,
SAY_MOVING,
SAY_MOVING_GROUP,
SAY_PANIC,
UNIT_NAME_SPIDER,
UNIT_NAME_SOLDIER,
UNIT_NAME_NEST,
UNIT_DEATH,
UNIT_ATTACK,
UNIT_MISS,
UNIT_CRITICAL_MISS,
UNIT_CRITICAL_HIT,
UNIT_DAMAGE,
UNIT_SAVING_THROW_WILLPOWER,
UNIT_SAVING_THROW_SUCCESS,
UNIT_SAVING_THROW_FAILURE
} index_t;
std::string get(index_t index);
}
class entity_t : public world::entity_t {
public:
game::state_t *game = 0;
v2f_t x;
rectf_t size, render_size;
entity_t(game::state_t *game, int type_);
virtual ~entity_t(void) = 0;
void destroy(void);
void place(world::world_t *world);
void place(world::world_t *world, v2f_t x_);
bool ignore_waking = true; // Most entities won't need this mechanism.
bool awake = false;
double wake_time = -INFINITY;
void wake(void);
void sleep(void);
virtual void on_think(void) = 0;
virtual void on_spawn(void) = 0;
virtual void on_wake(void) = 0;
};
class fx_move_marker_t;
class unit_t : public entity_t {
protected:
double next_targetting = -INFINITY;
double last_attack = -INFINITY;
public:
size_t selected = 0;
typedef enum {
UNIT_SOLDIER,
UNIT_SPIDER,
UNIT_NEST
} type_t;
type_t type;
std::string name;
unit_t(game::state_t *game_, type_t type_);
bool friendly = false;
bool controllable = false;
struct {
world::cflags_t cflags;
bool moving = false;
v2f_t dst;
float angle = 0.0f;
std::list path;
bool blocked;
size_t attempts_left;
float next_attempt;
} move;
bool keep_moving(double speed);
bool start_moving(v2f_t dst);
struct {
size_t armor_class;
die_t hit_die;
} cs;
struct {
audio::sound_t *attack = NULL;
} sounds;
bool dead = false;
double death_time = -INFINITY;
int health = 1, max_health = 1;
void damage(int points, unit_t *attacker);
void try_attack(unit_t *target);
void die(unit_t *killer);
virtual void on_death() = 0;
std::string say_text;
double say_time = -INFINITY;
void say(std::string str);
void render_to(render::state_t *render);
};
class unit_soldier_t : public unit_t {
friend state_t;
protected:
double last_target_time = -INFINITY;
v2f_t last_target_x;
std::unique_ptr move_marker;
sf::Color selection_color;
double next_fear_test = -INFINITY;
size_t willpower_bonus;
size_t fear_dc;
bool panic = false;
double panic_end;
double panic_turn;
void check_area(void);
void target_and_attack(void);
public:
unit_soldier_t(game::state_t *game_);
~unit_soldier_t(void) {};
void render_to(render::state_t *render);
void render_late_to(render::state_t *render);
void on_think(void);
void on_spawn(void) {};
void on_wake(void) {};
void on_death(void);
};
class unit_spider_t : public unit_t {
public:
unit_spider_t(game::state_t *game_);
~unit_spider_t(void) {};
void render_to(render::state_t *render);
void render_late_to(render::state_t *render) {};
void target_and_attack(void);
void on_think(void);
void on_spawn(void) {};
void on_wake(void);
void on_death(void);
};
class unit_nest_t : public unit_t {
double next_spawning = -INFINITY;
public:
unit_nest_t(game::state_t *game_);
~unit_nest_t(void) {};
void render_to(render::state_t *render);
void render_late_to(render::state_t *render) {};
void on_think(void);
void on_spawn(void);
void on_death(void);
void on_wake(void) {};
};
class effect_t : public game::entity_t {
public:
double ttl = +INFINITY;
effect_t(game::state_t *game_);
virtual ~effect_t() {};
void on_think(void);
void on_spawn(void) {};
void on_wake(void) {};
void render_late_to(render::state_t *render) {};
};
class fx_tracer_t : public effect_t {
v2f_t x0, x1;
public:
fx_tracer_t(game::state_t *game_, v2f_t x0_, v2f_t x1_);
~fx_tracer_t(void) {};
void render_to(render::state_t *render);
};
class fx_blood_t : public effect_t {
bool alien;
v2f_t x;
public:
fx_blood_t(game::state_t *game_, v2f_t x_, bool alien_);
~fx_blood_t(void) {};
void render_to(render::state_t *render);
};
class fx_move_marker_t : public effect_t {
v2f_t x;
public:
fx_move_marker_t(game::state_t *game_, v2f_t x_);
~fx_move_marker_t(void);
void render_to(render::state_t *render);
};
typedef enum {
DECO_STONE,
DECO_STONE_SMALL,
DECO_EYETHING,
DECO_SPIKE,
DECO_SPIKE_SMALL,
DECO_WART
} deco_type_t;
class deco_t : public game::entity_t {
deco_type_t type;
public:
double phase_shift;
deco_t(game::state_t *game, deco_type_t type_);
void render_to(render::state_t *render);
void render_late_to(render::state_t *render) {};
void on_think(void) {};
void on_spawn(void) {};
void on_wake(void) {};
};
};