#include "../common.hpp" namespace game { enum { ET_UNIT, ET_EFFECT }; enum { TILE_NONE, TILE_DIRT, TILE_STONE, TILE_WATER }; 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::tile_t *tile, world::tile_index_t x, procgen::perlin_noise_t *perlin); namespace assets { typedef struct { render::oriented_sprite_4M_t head_idle, body_idle; render::oriented_sprite_4M_t body_aiming, body_firing; render::oriented_sprite_4M2_t legs_idle, legs_walking; render::animated_texture_t dead; } human_assets_t; typedef struct { render::oriented_sprite_4M_t idle, walking; render::animated_texture_t dead; } alien_assets_t; typedef struct { render::animated_texture_t blood; } fx_assets_t; extern human_assets_t human; extern alien_assets_t alien; extern fx_assets_t fx; void load(void); } class unit_t : public world::entity_t { protected: game::state_t *game; world::world_t *world; world::cmodel_t make_cmodel(v2f_t at); void compute_bounds(); double next_targetting = -INFINITY; double last_attack = -INFINITY; public: v2f_t x; rectf_t size, render_size; world::cflags_t cflags; size_t selected = 0; typedef enum { UNIT_HUMAN, UNIT_ALIEN } type_t; type_t type; std::string name; unit_t(game::state_t *game_, type_t type_); virtual void think(void) = 0; struct { bool moving = false; v2f_t dst; float angle = 0.0f; std::list path; bool blocked; size_t attempts_left; float next_attempt; } move; void place(world::world_t *world_, v2f_t x_); bool keep_moving(double speed); bool start_moving(v2f_t dst, world::cflags_t cflags); bool awake = false; double wake_time = -INFINITY; virtual void wake(unit_t *by_whom) = 0; virtual void sleep(void) = 0; struct { size_t armor_class; roll_params_t hit_roll; roll_params_t damage_roll; } cs; 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); virtual void die() = 0; std::string say_text; double say_time = -INFINITY; void say(std::string str); void render_to(render::state_t *render); }; class human_t : public unit_t { double last_target_time = -INFINITY; v2f_t last_target_x; public: human_t(game::state_t *game_); void render_to(render::state_t *render); void wake(unit_t *by_whom); void sleep(void); void think(void); void die(void); }; class alien_t : public unit_t { double next_targetting = -INFINITY; public: alien_t(game::state_t *game_); void render_to(render::state_t *render); void wake(unit_t *by_whom); void sleep(void); void think(void); void die(void); }; class effect_t : public world::entity_t { public: game::state_t *game; double ttl = +INFINITY; effect_t(game::state_t *game_); virtual ~effect_t() {}; }; 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) = default; 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) = default; void render_to(render::state_t *render); }; };