added ability to customize attack animations...

...based on direction attack takes place from
This commit is contained in:
Dave White 2005-02-07 03:44:37 +00:00
parent 19b2f8caf5
commit f1dc8ab736
7 changed files with 64 additions and 8 deletions

View file

@ -84,6 +84,25 @@ bool gamemap::is_keep(const gamemap::location& loc) const
return on_board(loc) && is_keep(get_terrain(loc));
}
gamemap::location::DIRECTION gamemap::location::parse_direction(const std::string& str)
{
if(str == "n") {
return NORTH;
} else if(str == "ne") {
return NORTH_EAST;
} else if(str == "se") {
return SOUTH_EAST;
} else if(str == "s") {
return SOUTH;
} else if(str == "sw") {
return SOUTH_WEST;
} else if(str == "nw") {
return NORTH_WEST;
} else {
return NDIRECTIONS;
}
}
gamemap::location::location(const config& cfg) : x(-1), y(-1)
{
const std::string& xstr = cfg["x"];

View file

@ -52,7 +52,9 @@ public:
struct location {
//any valid direction which can be moved in in our hexagonal world.
enum DIRECTION { NORTH, NORTH_EAST, SOUTH_EAST, SOUTH,
SOUTH_WEST, NORTH_WEST };
SOUTH_WEST, NORTH_WEST, NDIRECTIONS };
static DIRECTION parse_direction(const std::string& str);
location() : x(-1), y(-1) {}
location(int x, int y) : x(x), y(y) {}

View file

@ -36,6 +36,19 @@ void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res)
res->y = a.y - (is_even(a.x) ? 1:0);
}
gamemap::location::DIRECTION get_adjacent_direction(const gamemap::location& from, const gamemap::location& to)
{
gamemap::location adj[6];
get_adjacent_tiles(from,adj);
for(size_t n = 0; n != 6; ++n) {
if(adj[n] == to) {
return static_cast<gamemap::location::DIRECTION>(n);
}
}
return gamemap::location::NDIRECTIONS;
}
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
{
//two tiles are adjacent if y is different by 1, and x by 0, or if

View file

@ -24,6 +24,10 @@ bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b);
//res. res must point to an array of 6 location objects.
void get_adjacent_tiles(const gamemap::location& a, gamemap::location* res);
//function which returns the direction from 'from' to 'to'. If 'from' and 'to' are not adjacent, then
//the function will return 'NDIRECTIONS'.
gamemap::location::DIRECTION get_adjacent_direction(const gamemap::location& from, const gamemap::location& to);
//function which gives the number of hexes between two tiles (i.e. the minimum
//number of hexes that have to be traversed to get from one hex to the other)
size_t distance_between(const gamemap::location& a, const gamemap::location& b);

View file

@ -317,7 +317,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
leader->second.set_leading(true);
}
unit_animation attack_anim = attack.animation();
unit_animation attack_anim = attack.animation(get_adjacent_direction(a,b));
//the missile frames are based around the time when the missile impacts.
//the 'real' frames are based around the time when the missile launches.
@ -641,7 +641,7 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
return unit_attack_ranged(disp, units, a, b, damage, attack);
}
unit_animation attack_anim = attack.animation();
unit_animation attack_anim = attack.animation(get_adjacent_direction(a,b));
const bool hits = damage > 0;
const std::vector<unit_animation::sfx>& sounds = attack_anim.sound_effects();

View file

@ -142,7 +142,18 @@ attack_type::attack_type(const config& cfg)
{
const config::child_list& animations = cfg.get_children("animation");
for(config::child_list::const_iterator an = animations.begin(); an != animations.end(); ++an) {
animation_.push_back(unit_animation(**an));
const std::string& dir = (**an)["direction"];
if(dir == "") {
animation_.push_back(unit_animation(**an));
} else {
const std::vector<std::string>& directions = config::split(dir);
for(std::vector<std::string>::const_iterator i = directions.begin(); i != directions.end(); ++i) {
const gamemap::location::DIRECTION d = gamemap::location::parse_direction(*i);
if(d != gamemap::location::NDIRECTIONS) {
direction_animation_[d].push_back(unit_animation(**an));
}
}
}
}
if(animation_.empty()) {
@ -225,10 +236,16 @@ bool attack_type::slow() const
return slow_;
}
const unit_animation& attack_type::animation() const
const unit_animation& attack_type::animation(const gamemap::location::DIRECTION dir) const
{
wassert(animation_.empty() == false);
return animation_[rand()%animation_.size()];
const std::vector<unit_animation>* animation = &animation_;
if(dir < sizeof(direction_animation_)/sizeof(*direction_animation_) &&
direction_animation_[dir].empty() == false) {
animation = &direction_animation_[dir];
}
wassert(animation->empty() == false);
return (*animation)[rand()%animation->size()];
}
bool attack_type::matches_filter(const config& cfg) const

View file

@ -94,12 +94,13 @@ public:
//this function returns a random animation out of the possible
//animations for this attack. It will not return the same attack
//each time.
const unit_animation& animation() const;
const unit_animation& animation(gamemap::location::DIRECTION dir=gamemap::location::NDIRECTIONS) const;
bool matches_filter(const config& cfg) const;
bool apply_modification(const config& cfg,std::string* description);
private:
std::vector<unit_animation> animation_;
std::vector<unit_animation> direction_animation_[6];
std::string name_;
std::string type_;
std::string special_;