put swing filtering back in, now that 6644 has been fixed

This commit is contained in:
Jérémy Rosen 2006-09-03 13:33:55 +00:00
parent 9d3c5cc012
commit e476886059
9 changed files with 61 additions and 82 deletions

View file

@ -769,6 +769,8 @@ attack::attack(display& gui, const gamemap& map,
bool defender_strikes_first = (d_stats_->firststrike && ! a_stats_->firststrike);
unsigned int rounds = maximum<unsigned int>(a_stats_->rounds, d_stats_->rounds) - 1;
int abs_n_attack_ = 0;
int abs_n_defend_ = 0;
static const std::string poison_string("poison");
@ -776,6 +778,7 @@ attack::attack(display& gui, const gamemap& map,
while(n_attacks_ > 0 || n_defends_ > 0) {
LOG_NG << "start of attack loop...\n";
abs_n_attack_++;
if(n_attacks_ > 0 && defender_strikes_first == false) {
const int ran_num = get_random();
@ -829,7 +832,7 @@ attack::attack(display& gui, const gamemap& map,
bool dies = unit_display::unit_attack(gui_,units_,attacker_,defender_,
damage_defender_takes,
*a_stats_->weapon,
update_display_);
update_display_,abs_n_attack_);
LOG_NG << "defender took " << damage_defender_takes << (dies ? " and died" : "") << "\n";
attack_stats.attack_result(hits ? (dies ? statistics::attack_context::KILLS : statistics::attack_context::HITS)
: statistics::attack_context::MISSES, attacker_damage_);
@ -976,6 +979,7 @@ attack::attack(display& gui, const gamemap& map,
//if the defender got to strike first, they use it up here.
defender_strikes_first = false;
abs_n_defend_++;
if(n_defends_ > 0) {
LOG_NG << "doing defender attack...\n";
@ -1031,7 +1035,7 @@ attack::attack(display& gui, const gamemap& map,
bool dies = unit_display::unit_attack(gui_,units_,defender_,attacker_,
damage_attacker_takes,
*d_stats_->weapon,
update_display_);
update_display_,abs_n_defend_);
LOG_NG << "attacker took " << damage_attacker_takes << (dies ? " and died" : "") << "\n";
if(ran_results == NULL) {
config cfg;

View file

@ -1518,7 +1518,7 @@ void unit::set_standing(const display &disp,const gamemap::location& loc, bool w
frame_begin_time = anim_->get_first_frame_time() -1;
anim_->update_current_frame();
}
void unit::set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack)
void unit::set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack,int swing_num)
{
state_ = STATE_DEFENDING;
draw_bars_ = false;
@ -1534,7 +1534,7 @@ void unit::set_defending(const display &disp,const gamemap::location& loc, int d
}else {
hit_type = fighting_animation::MISS;
}
anim_ = new defensive_animation(defend_animation(disp.get_map().underlying_union_terrain(loc),hit_type,attack));
anim_ = new defensive_animation(defend_animation(disp.get_map().underlying_union_terrain(loc),hit_type,attack,swing_num));
// add a blink on damage effect
int anim_time = anim_->get_last_frame_time();
@ -1567,7 +1567,7 @@ void unit::set_extra_anim(const display &disp,const gamemap::location& loc, std:
anim_->update_current_frame();
}
const unit_animation & unit::set_attacking(const display &disp,const gamemap::location& /*loc*/,bool hit,const attack_type& type)
const unit_animation & unit::set_attacking(const display &disp,const gamemap::location& loc,int damage,const attack_type& type,int swing_num)
{
state_ = STATE_ATTACKING;
draw_bars_ = false;
@ -1575,12 +1575,19 @@ const unit_animation & unit::set_attacking(const display &disp,const gamemap::lo
delete anim_;
anim_ = NULL;
}
const attack_type::attack_animation &attack_anim = type.animation(hit,facing_) ;
anim_ = new unit_animation(attack_anim.animation);
fighting_animation::hit_type hit_type;
if(damage >= hitpoints()) {
hit_type = fighting_animation::KILL;
} else if(damage > 0) {
hit_type = fighting_animation::HIT;
}else {
hit_type = fighting_animation::MISS;
}
anim_ = new attack_animation(type.animation(disp.get_map().underlying_union_terrain(loc),hit_type,facing_,swing_num));
anim_->start_animation(anim_->get_first_frame_time(),1,disp.turbo()?5:1);
frame_begin_time = anim_->get_first_frame_time() -1;
anim_->update_current_frame();
return attack_anim.missile_animation;
return ((attack_animation*)anim_)->get_missile_anim();
}
void unit::set_leading(const display &disp,const gamemap::location& loc)
{
@ -2696,13 +2703,13 @@ const std::string& unit::race() const
}
const defensive_animation& unit::defend_animation(const std::string &terrain,
fighting_animation::hit_type hits, const attack_type* attack) const
fighting_animation::hit_type hits, const attack_type* attack,int swing_num) const
{
//select one of the matching animations at random
std::vector<const defensive_animation*> options;
int max_val = -1;
for(std::vector<defensive_animation>::const_iterator i = defensive_animations_.begin(); i != defensive_animations_.end(); ++i) {
int matching = i->matches(terrain,facing_,hits,attack);
int matching = i->matches(terrain,facing_,hits,attack,swing_num);
if(matching == max_val) {
options.push_back(&*i);
} else if(matching > max_val) {
@ -2746,7 +2753,7 @@ const death_animation& unit::die_animation(const std::string &terrain,
std::vector<const death_animation*> options;
int max_val = -1;
for(std::vector<death_animation>::const_iterator i = death_animations_.begin(); i != death_animations_.end(); ++i) {
int matching = i->matches(terrain,facing_,hits,attack);
int matching = i->matches(terrain,facing_,hits,attack,0);
if(matching == max_val) {
options.push_back(&*i);
} else if(matching > max_val) {

View file

@ -158,7 +158,7 @@ class unit
void redraw_unit(display& disp,gamemap::location hex);
void set_standing(const display& disp,const gamemap::location& loc, bool with_bars = true);
void set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack);
void set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack,int swing_num);
void set_leading(const display& disp,const gamemap::location& loc);
void set_healing(const display& disp,const gamemap::location& loc);
void set_leveling_in(const display& disp,const gamemap::location& loc);
@ -167,7 +167,7 @@ class unit
void set_extra_anim(const display& disp,const gamemap::location& loc, std::string flag);
void set_dying(const display &disp,const gamemap::location& loc,const attack_type* attack);
void set_walking(const display& disp,const gamemap::location& loc);
const unit_animation & set_attacking(const display& disp,const gamemap::location& loc,bool hit,const attack_type& type);
const unit_animation & set_attacking( const display &disp,const gamemap::location& loc,int damage,const attack_type& type,int swing_num);
void set_recruited(const display& disp,const gamemap::location& loc);
void set_healed(const display& disp,const gamemap::location& loc,int healing);
void set_poisoned(const display& disp,const gamemap::location& loc,int damage);
@ -237,7 +237,7 @@ class unit
const std::string& race() const;
const defensive_animation& defend_animation(const std::string &terrain,
fighting_animation::hit_type hits,const attack_type* attack) const;
fighting_animation::hit_type hits,const attack_type* attack,int swing_num) const;
const unit_animation& teleport_animation() const;
const unit_animation* extra_animation(const std::string &terrain,const std::string &flag) const;
const death_animation& die_animation(const std::string &terrain,

View file

@ -170,10 +170,15 @@ fighting_animation::fighting_animation(const config& cfg) :unit_animation(cfg),
hits.push_back(KILL);
}
}
std::vector<std::string> swing_str = utils::split(cfg["swing"]);
std::vector<std::string>::iterator swing;
for(swing=swing_str.begin() ; swing != swing_str.end() ; swing++) {
swing_num.push_back(atoi(swing->c_str()));
}
}
int fighting_animation::matches(const std::string &terrain,gamemap::location::DIRECTION dir,hit_type hit,const attack_type* attack) const
int fighting_animation::matches(const std::string &terrain,gamemap::location::DIRECTION dir,hit_type hit,const attack_type* attack, int swing) const
{
int result = unit_animation::matches(terrain,dir);
if(!attack) {
@ -189,6 +194,13 @@ int fighting_animation::matches(const std::string &terrain,gamemap::location::DI
result ++;
}
}
if(swing_num.empty() == false ) {
if (std::find(swing_num.begin(),swing_num.end(),swing)== swing_num.end()) {
return -1;
} else {
result ++;
}
}
if(range.empty()== false) {
if (std::find(range.begin(),range.end(),attack->range())== range.end()) {
return -1;

View file

@ -57,10 +57,11 @@ class fighting_animation:public unit_animation
explicit fighting_animation(const config& cfg);
explicit fighting_animation(const std::string &image, const std::string &range="",int begin_at = -150, int end_at = 150):
unit_animation(image,begin_at,end_at),range(utils::split(range)) {};
int matches(const std::string &terrain,gamemap::location::DIRECTION dir,hit_type hit,const attack_type* attack) const;
int matches(const std::string &terrain,gamemap::location::DIRECTION dir,hit_type hit,const attack_type* attack,int swing_num) const;
private:
std::vector<hit_type> hits;
std::vector<int> swing_num;
std::vector<std::string> range;
std::vector<std::string> damage_type, special;
};
@ -81,6 +82,16 @@ class death_animation:public fighting_animation
private:
};
class attack_animation: public fighting_animation
{
public:
explicit attack_animation(const config& cfg):fighting_animation(cfg),missile_anim(cfg,"missile_frame"){};
explicit attack_animation(const std::string &image):fighting_animation(image,"",-200,100) {};
const unit_animation &get_missile_anim() {return missile_anim;}
private:
unit_animation missile_anim;
};
class movement_animation:public unit_animation
{

View file

@ -196,7 +196,7 @@ namespace {
bool unit_attack_ranged(display& disp, unit_map& units,
const gamemap::location& a, const gamemap::location& b,
int damage, const attack_type& attack, bool update_display)
int damage, const attack_type& attack, bool update_display, int swing)
{
const bool hide = disp.update_locked() || disp.fogged(a.x,a.y) && disp.fogged(b.x,b.y)
@ -212,7 +212,6 @@ bool unit_attack_ranged(display& disp, unit_map& units,
wassert(def != units.end());
unit& defender = def->second;
const bool hits = damage > 0;
const int acceleration = disp.turbo() ? 5 : 1;
@ -230,7 +229,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
// start leader and attacker animation, wait for attacker animation to end
unit_animation missile_animation = attacker.set_attacking(disp,a,hits,attack);
unit_animation missile_animation = attacker.set_attacking(disp,a,damage,attack,swing);
const gamemap::location leader_loc = under_leadership(units,a);
unit_map::iterator leader = units.end();
if(leader_loc.valid()){
@ -268,7 +267,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
}
const unit_animation::FRAME_DIRECTION dir = (a.x == b.x) ? unit_animation::VERTICAL:unit_animation::DIAGONAL;
defender.set_defending(disp,b,damage,&attack);
defender.set_defending(disp,b,damage,&attack,swing);
// min of attacker, defender, missile and -200
const int start_time = minimum<int>(
minimum<int>(
@ -384,7 +383,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
bool unit_attack(display& disp, unit_map& units,
const gamemap::location& a, const gamemap::location& b, int damage,
const attack_type& attack, bool update_display)
const attack_type& attack, bool update_display, int swing)
{
const bool hide = disp.update_locked() || disp.fogged(a.x,a.y) && disp.fogged(b.x,b.y)
|| preferences::show_combat() == false || (!update_display);
@ -406,19 +405,18 @@ bool unit_attack(display& disp, unit_map& units,
att->second.set_facing(a.get_relative_dir(b));
def->second.set_facing(b.get_relative_dir(a));
if(attack.range_type() == attack_type::LONG_RANGE) {
return unit_attack_ranged(disp, units, a, b, damage, attack, update_display);
return unit_attack_ranged(disp, units, a, b, damage, attack, update_display, swing);
}
const bool hits = damage > 0;
int start_time = 500;
int end_time = 0;
attacker.set_attacking(disp,a,hits,attack);
attacker.set_attacking(disp,a,damage,attack,swing);
start_time=minimum<int>(start_time,attacker.get_animation()->get_first_frame_time());
end_time=attacker.get_animation()->get_last_frame_time();
defender.set_defending(disp,b,damage,&attack);
defender.set_defending(disp,b,damage,&attack, swing);
start_time=minimum<int>(start_time,defender.get_animation()->get_first_frame_time());

View file

@ -39,7 +39,7 @@ void unit_die(display& disp, const gamemap::location& loc, unit& u, const attack
///playing field.
bool unit_attack(display& disp, unit_map& units,
const gamemap::location& a, const gamemap::location& b, int damage,
const attack_type& attack, bool update_display);
const attack_type& attack, bool update_display, int swing);
}

View file

@ -153,13 +153,13 @@ int attack_type::movement_used() const
return cfg_["movement_used"] == "" ? 100000 : lexical_cast_default<int>(cfg_["movement_used"]);
}
const attack_type::attack_animation& attack_type::animation(bool hit,const gamemap::location::DIRECTION dir) const
const attack_animation& attack_type::animation(const std::string &terrain,const fighting_animation::hit_type hit,const gamemap::location::DIRECTION dir,int swing_num) const
{
//select one of the matching animations at random
std::vector<const attack_animation*> options;
int max_val = -1;
for(std::vector<attack_animation>::const_iterator i = animation_.begin(); i != animation_.end(); ++i) {
int matching = i->matches(hit,dir);
int matching = i->matches(terrain,dir,hit,this,swing_num);
if(matching == max_val) {
options.push_back(&*i);
} else if(matching > max_val) {
@ -173,45 +173,6 @@ const attack_type::attack_animation& attack_type::animation(bool hit,const gamem
return *options[rand()%options.size()];
}
attack_type::attack_animation::attack_animation(const config& cfg):animation(cfg),missile_animation(cfg,"missile_frame"),hits(HIT_OR_MISS)
{
const std::vector<std::string>& my_directions = utils::split(cfg["direction"]);
for(std::vector<std::string>::const_iterator i = my_directions.begin(); i != my_directions.end(); ++i) {
const gamemap::location::DIRECTION d = gamemap::location::parse_direction(*i);
directions.push_back(d);
}
if(missile_animation.get_first_frame_time() == 0 && missile_animation.get_last_frame_time() == 0) {
// create animation ourself
missile_animation = unit_animation(game_config::missile_n_image,0,0,game_config::missile_ne_image);
}
const std::string& hits_str = cfg["hits"];
if(hits_str.empty() == false) {
hits = (hits_str == "yes") ? HIT : MISS;
}
}
int attack_type::attack_animation::matches(bool hit,gamemap::location::DIRECTION dir) const
{
int result = 0;
if(directions.empty()== false) {
if (std::find(directions.begin(),directions.end(),dir)== directions.end()) {
return -1;
} else {
result ++;
}
}
if(hits != HIT_OR_MISS ) {
if(hit && (hits == HIT)) {
result++;
} else if(!hit && (hits == MISS)) {
result++;
} else {
return -1;
}
}
return result;
}
bool attack_type::matches_filter(const config& cfg,bool self) const
{
const std::string& filter_range = cfg["range"];

View file

@ -85,22 +85,8 @@ public:
bool special_affects_opponent(const config& cfg) const;
bool special_affects_self(const config& cfg) const;
struct attack_animation
{
typedef enum { HIT, MISS, HIT_OR_MISS } hit_type;
explicit attack_animation(const config& cfg);
explicit attack_animation(const std::string &image,const hit_type for_hit= HIT_OR_MISS):animation(image,-200,100),hits(for_hit) {};
int matches(bool hit,gamemap::location::DIRECTION dir=gamemap::location::NDIRECTIONS) const;
std::vector<gamemap::location::DIRECTION> directions;
unit_animation animation;
unit_animation missile_animation;
hit_type hits;
};
config cfg_;
const attack_animation& animation(bool hit,gamemap::location::DIRECTION dir=gamemap::location::NDIRECTIONS) const;
const attack_animation& animation(const std::string &terrain,const fighting_animation::hit_type hit,const gamemap::location::DIRECTION dir,int swing_num) const;
private:
std::vector<attack_animation> animation_;
t_string description_;