mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-19 03:20:26 +00:00
305 lines
8.2 KiB
C++
305 lines
8.2 KiB
C++
/* $Id$ */
|
|
/*
|
|
Copyright (C) 2003 by David White <davidnwhite@verizon.net>
|
|
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
#ifndef UNIT_H_INCLUDED
|
|
#define UNIT_H_INCLUDED
|
|
|
|
#include "config.hpp"
|
|
#include "map.hpp"
|
|
#include "race.hpp"
|
|
#include "team.hpp"
|
|
#include "unit_types.hpp"
|
|
|
|
#include <set>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
class unit;
|
|
|
|
typedef std::map<gamemap::location,unit> unit_map;
|
|
|
|
class unit
|
|
{
|
|
public:
|
|
friend struct unit_movement_resetter;
|
|
|
|
unit(const game_data& data, const config& cfg);
|
|
unit(const unit_type* t, int side, bool use_traits=false, bool dummy_unit=false, unit_race::GENDER gender=unit_race::MALE);
|
|
|
|
//a constructor used when advancing a unit
|
|
unit(const unit_type* t, const unit& u);
|
|
const unit_type& type() const;
|
|
std::string name() const;
|
|
const std::string& description() const;
|
|
const std::string& underlying_description() const;
|
|
|
|
//information about the unit -- a detailed description of it
|
|
const std::string& unit_description() const;
|
|
|
|
void rename(const std::string& new_description);
|
|
|
|
int hitpoints() const;
|
|
int max_hitpoints() const;
|
|
int experience() const;
|
|
int max_experience() const;
|
|
bool get_experience(int xp);
|
|
bool unrenamable() const; /** < Set to true for some scenario-specific units which should not be renamed */
|
|
bool advances() const;
|
|
int side() const;
|
|
unit_race::GENDER gender() const;
|
|
void set_side(int new_side);
|
|
fixed_t alpha() const;
|
|
void make_recruiter();
|
|
bool can_recruit() const;
|
|
int total_movement() const;
|
|
int movement_left() const;
|
|
void set_hold_position(bool value);
|
|
bool hold_position() const;
|
|
void set_user_end_turn(bool value=true);
|
|
bool user_end_turn() const;
|
|
bool can_attack() const;
|
|
void set_movement(int moves);
|
|
void set_attacked();
|
|
void unit_hold_position();
|
|
void end_unit_turn();
|
|
void new_turn();
|
|
void end_turn();
|
|
void new_level();
|
|
|
|
void set_resting(bool resting);
|
|
bool is_resting() const;
|
|
|
|
bool gets_hit(int damage);
|
|
void heal();
|
|
void heal(int amount);
|
|
void heal_all();
|
|
|
|
bool invisible(const std::string& terrain, int lawful_bonus,
|
|
const gamemap::location& loc,
|
|
const unit_map& units,const std::vector<team>& teams) const;
|
|
bool poisoned() const;
|
|
bool stone() const;
|
|
|
|
bool incapacitated() const;
|
|
bool has_moved() const;
|
|
bool has_goto() const;
|
|
|
|
bool emits_zoc() const;
|
|
|
|
bool matches_filter(const config& cfg) const;
|
|
|
|
void set_flag(const std::string& flag);
|
|
void remove_flag(const std::string& flag);
|
|
bool has_flag(const std::string& flag) const;
|
|
|
|
void add_overlay(const std::string& overlay);
|
|
void remove_overlay(const std::string& overlay);
|
|
const std::vector<std::string>& overlays() const;
|
|
|
|
/**
|
|
* Initializes this unit from a cfg object.
|
|
*
|
|
* \param data The global game_data object
|
|
* \param cfg Configuration object from which to read the unit
|
|
*/
|
|
void read(const game_data& data, const config& cfg);
|
|
|
|
void write(config& cfg) const;
|
|
|
|
void assign_role(const std::string& role);
|
|
|
|
const std::vector<attack_type>& attacks() const;
|
|
|
|
int movement_cost(const gamemap& map, gamemap::TERRAIN terrain) const;
|
|
int defense_modifier(const gamemap& map, gamemap::TERRAIN terrain) const;
|
|
int damage_against(const attack_type& attack) const;
|
|
|
|
//gets the unit image that should currently be displayed
|
|
//(could be in the middle of an attack etc)
|
|
const std::string& image() const;
|
|
|
|
void set_standing();
|
|
void set_defending(bool hits, attack_type::RANGE range, int start_frame, int acceleration);
|
|
void update_defending_frame();
|
|
void set_attacking(bool newval, const attack_type* type=NULL, int ms=0);
|
|
|
|
void set_leading(bool newval);
|
|
void set_healing(bool newval);
|
|
|
|
bool facing_left() const;
|
|
void set_facing_left(bool newval);
|
|
|
|
const t_string& traits_description() const;
|
|
|
|
int value() const;
|
|
bool is_guardian() const;
|
|
|
|
const gamemap::location& get_goto() const;
|
|
void set_goto(const gamemap::location& new_goto);
|
|
|
|
int upkeep() const;
|
|
|
|
bool is_flying() const;
|
|
|
|
bool can_advance() const;
|
|
config::child_list get_modification_advances() const;
|
|
|
|
size_t modification_count(const std::string& type, const std::string& id) const;
|
|
|
|
void add_modification(const std::string& type, const config& modification,
|
|
bool no_add=false);
|
|
|
|
const t_string& modification_description(const std::string& type) const;
|
|
|
|
bool move_interrupted() const;
|
|
const gamemap::location& get_interrupted_move() const;
|
|
void set_interrupted_move(const gamemap::location& interrupted_move);
|
|
//is set to the number of moves left, ATTACKED if attacked,
|
|
// MOVED if moved and then pressed "end turn"
|
|
// NOT_MOVED if not moved and pressed "end turn"
|
|
enum MOVES { ATTACKED=-1, MOVED=-2, NOT_MOVED=-3 };
|
|
private:
|
|
unit_race::GENDER generate_gender(const unit_type& type, bool use_genders);
|
|
unit_race::GENDER gender_;
|
|
std::string variation_;
|
|
|
|
const unit_type* type_;
|
|
|
|
enum STATE { STATE_NORMAL, STATE_ATTACKING,
|
|
STATE_DEFENDING_LONG, STATE_DEFENDING_SHORT, STATE_LEADING, STATE_HEALING};
|
|
STATE state_;
|
|
const attack_type* attackType_;
|
|
int attackingMilliseconds_;
|
|
bool getsHit_;
|
|
|
|
int hitpoints_;
|
|
int maxHitpoints_, backupMaxHitpoints_;
|
|
int experience_;
|
|
int maxExperience_, backupMaxExperience_;
|
|
|
|
int side_;
|
|
|
|
int moves_;
|
|
bool user_end_turn_;
|
|
bool facingLeft_;
|
|
int maxMovement_, backupMaxMovement_;
|
|
bool resting_;
|
|
bool hold_position_;
|
|
|
|
std::string underlying_description_, description_;
|
|
|
|
//this field is used if the scenario creator places a custom unit description
|
|
//with a certain unit. If this field is empty, then the more general unit description
|
|
//from the unit's base type will be used
|
|
std::string custom_unit_description_;
|
|
|
|
bool recruit_;
|
|
|
|
std::string role_;
|
|
|
|
std::set<std::string> statusFlags_;
|
|
std::vector<std::string> overlays_;
|
|
|
|
//this field stores user-variables associated with the unit
|
|
config variables_;
|
|
|
|
std::vector<attack_type> attacks_;
|
|
std::vector<attack_type> backupAttacks_;
|
|
|
|
config modifications_;
|
|
|
|
t_string traitsDescription_;
|
|
|
|
string_map modificationDescriptions_;
|
|
|
|
bool guardian_;
|
|
|
|
gamemap::location goto_, interrupted_move_;
|
|
|
|
enum UPKEEP_COST { UPKEEP_FREE, UPKEEP_LOYAL, UPKEEP_FULL_PRICE };
|
|
|
|
UPKEEP_COST upkeep_;
|
|
|
|
bool unrenamable_;
|
|
|
|
unit_animation anim_;
|
|
const unit_animation* get_animation() const;
|
|
|
|
void reset_modifications();
|
|
void apply_modifications();
|
|
void remove_temporary_modifications();
|
|
void generate_traits();
|
|
void generate_traits_description();
|
|
};
|
|
|
|
//object which temporarily resets a unit's movement
|
|
struct unit_movement_resetter
|
|
{
|
|
unit_movement_resetter(unit& u, bool operate=true) : u_(u), moves_(u.moves_)
|
|
{
|
|
if(operate) {
|
|
u.moves_ = u.total_movement();
|
|
}
|
|
}
|
|
|
|
~unit_movement_resetter()
|
|
{
|
|
u_.moves_ = moves_;
|
|
}
|
|
|
|
private:
|
|
unit& u_;
|
|
int moves_;
|
|
};
|
|
|
|
void sort_units(std::vector< unit > &);
|
|
|
|
int team_units(const unit_map& units, int team_num);
|
|
int team_upkeep(const unit_map& units, int team_num);
|
|
unit_map::const_iterator team_leader(int side, const unit_map& units);
|
|
std::string team_name(int side, const unit_map& units);
|
|
unit_map::iterator find_visible_unit(unit_map& units,
|
|
const gamemap::location loc,
|
|
const gamemap& map, int lawful_bonus,
|
|
const std::vector<team>& teams, const team& current_team);
|
|
unit_map::const_iterator find_visible_unit(const unit_map& units,
|
|
const gamemap::location loc,
|
|
const gamemap& map, int lawful_bonus,
|
|
const std::vector<team>& teams, const team& current_team);
|
|
|
|
struct team_data
|
|
{
|
|
int units, upkeep, villages, expenses, net_income, gold;
|
|
};
|
|
|
|
team_data calculate_team_data(const class team& tm, int side, const unit_map& units);
|
|
|
|
std::string get_team_name(int side, const unit_map& units);
|
|
|
|
const std::set<gamemap::location> vacant_villages(const std::set<gamemap::location>& villages, const unit_map& units);
|
|
|
|
//this object is used to temporary place a unit in the unit map, swapping out any unit
|
|
//that is already there. On destruction, it restores the unit map to its original state.
|
|
struct temporary_unit_placer
|
|
{
|
|
temporary_unit_placer(unit_map& m, const gamemap::location& loc, const unit& u);
|
|
~temporary_unit_placer();
|
|
|
|
private:
|
|
unit_map& m_;
|
|
const gamemap::location& loc_;
|
|
const unit temp_;
|
|
bool use_temp_;
|
|
};
|
|
|
|
#endif
|