wesnoth/src/unit.hpp
2004-05-10 20:47:03 +00:00

270 lines
7.2 KiB
C++

/* $Id$ */
/*
Copyright (C) 2003 by David White <davidnwhite@optusnet.com.au>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
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 "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(game_data& data, const config& cfg);
unit(const unit_type* t, int side, bool use_traits=false, bool dummy_unit=false);
//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 advances() const;
int side() const;
double alpha() const;
void make_recruiter();
bool can_recruit() const;
int total_movement() const;
int movement_left() const;
bool can_attack() const;
void set_movement(int moves);
void set_attacked();
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 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;
void read(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 longest_range() const;
std::vector<attack_type> attacks_at_range(int range) 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_defending(bool newval,
attack_type::RANGE range=attack_type::LONG_RANGE);
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 std::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;
void add_modification(const std::string& type, const config& modification,
bool no_add=false);
const std::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);
private:
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_;
int hitpoints_;
int maxHitpoints_, backupMaxHitpoints_;
int experience_;
int maxExperience_, backupMaxExperience_;
int side_;
//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 };
int moves_;
bool facingLeft_;
int maxMovement_, backupMaxMovement_;
bool resting_;
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_;
std::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_;
void apply_modifications();
void remove_temporary_modifications();
void generate_traits();
};
//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_;
};
struct compare_unit_values
{
bool operator()(const unit& a, const unit& b) const;
};
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