put swing filtering back in, now that 6644 has been fixed
This commit is contained in:
parent
9d3c5cc012
commit
e476886059
9 changed files with 61 additions and 82 deletions
|
@ -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;
|
||||
|
|
25
src/unit.cpp
25
src/unit.cpp
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -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_;
|
||||
|
|
Loading…
Add table
Reference in a new issue