better animation filtering criterias
This commit is contained in:
parent
f53ce2d54d
commit
ebe9c01ab2
10 changed files with 205 additions and 189 deletions
|
@ -76,6 +76,7 @@ SVN trunk (1.1.2+svn):
|
|||
* floating damage/heal or status can be printed over a modified unit using
|
||||
the 'text', 'red', 'blue', and 'green' keys in [unstore_unit]
|
||||
* store_locations now stores terrain as well as x,y
|
||||
* more filtering criterias for animations
|
||||
* multiplayer settings:
|
||||
* two additional MP timer settings, time reservoir limit and action bonus:
|
||||
* Reservoir prevents the turn timer from exceeding an upper limit.
|
||||
|
|
|
@ -159,7 +159,7 @@ std::string recruit_unit(const gamemap& map, int side,
|
|||
un->second.set_hidden(true);
|
||||
disp->scroll_to_tile(recruit_location.x,recruit_location.y,display::ONSCREEN);
|
||||
un->second.set_hidden(false);
|
||||
un->second.set_recruited(*disp);
|
||||
un->second.set_recruited(*disp,recruit_location);
|
||||
while(!un->second.get_animation()->animation_finished()) {
|
||||
disp->invalidate(recruit_location);
|
||||
disp->draw();
|
||||
|
@ -167,7 +167,7 @@ std::string recruit_unit(const gamemap& map, int side,
|
|||
if(!disp->turbo()) SDL_Delay(10);
|
||||
|
||||
}
|
||||
un->second.set_standing(*disp);
|
||||
un->second.set_standing(*disp,recruit_location);
|
||||
}
|
||||
}
|
||||
LOG_NG << "firing recruit event\n";
|
||||
|
@ -1781,7 +1781,7 @@ void calculate_healing(display& disp, const gamemap& map,
|
|||
disp.select_hex(i->first);
|
||||
|
||||
for(std::vector<unit_map::iterator>::iterator heal_anim_it = healers.begin(); heal_anim_it != healers.end(); ++heal_anim_it) {
|
||||
(*heal_anim_it)->second.set_healing(disp);
|
||||
(*heal_anim_it)->second.set_healing(disp,(*heal_anim_it)->first);
|
||||
if(start_time_set) {
|
||||
start_time = minimum<int>(start_time,(*heal_anim_it)->second.get_animation()->get_first_frame_time());
|
||||
} else {
|
||||
|
@ -1789,13 +1789,13 @@ void calculate_healing(display& disp, const gamemap& map,
|
|||
}
|
||||
}
|
||||
if (healing < 0) {
|
||||
i->second.set_poisoned(disp, -healing);
|
||||
i->second.set_poisoned(disp,i->first, -healing);
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_first_frame_time());
|
||||
// FIXME
|
||||
sound::play_sound("groan.wav");
|
||||
disp.float_label(i->first, lexical_cast<std::string>(-healing), 255,0,0);
|
||||
} else {
|
||||
i->second.set_healed(disp, healing);
|
||||
i->second.set_healed(disp,i->first, healing);
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_first_frame_time());
|
||||
sound::play_sound("heal.wav");
|
||||
disp.float_label(i->first, lexical_cast<std::string>(healing), 0,255,0);
|
||||
|
@ -1827,9 +1827,9 @@ void calculate_healing(display& disp, const gamemap& map,
|
|||
SDL_Delay(10);
|
||||
} while (!finished);
|
||||
|
||||
i->second.set_standing(disp);
|
||||
i->second.set_standing(disp,i->first);
|
||||
for(std::vector<unit_map::iterator>::iterator heal_sanim_it = healers.begin(); heal_sanim_it != healers.end(); ++heal_sanim_it) {
|
||||
(*heal_sanim_it)->second.set_standing(disp);
|
||||
(*heal_sanim_it)->second.set_standing(disp,(*heal_sanim_it)->first);
|
||||
}
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
|
|
|
@ -133,7 +133,7 @@ bool animate_unit_advancement(const game_data& info,unit_map& units, gamemap::lo
|
|||
//new unit, then fades back to the normal colour
|
||||
|
||||
if(!gui.update_locked()) {
|
||||
u->second.set_leveling_out(gui);
|
||||
u->second.set_leveling_out(gui,u->first);
|
||||
while(!u->second.get_animation()->animation_finished()) {
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
|
@ -156,14 +156,14 @@ bool animate_unit_advancement(const game_data& info,unit_map& units, gamemap::lo
|
|||
gui.invalidate_unit();
|
||||
|
||||
if(!gui.update_locked()) {
|
||||
u->second.set_leveling_in(gui);
|
||||
u->second.set_leveling_in(gui,u->first);
|
||||
while(!u->second.get_animation()->animation_finished()) {
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
events::pump();
|
||||
if(!gui.turbo()) SDL_Delay(10);
|
||||
}
|
||||
u->second.set_standing(gui);
|
||||
u->second.set_standing(gui,u->first);
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
events::pump();
|
||||
|
|
|
@ -195,7 +195,7 @@ public:
|
|||
void float_label(const gamemap::location& loc, const std::string& text,
|
||||
int red, int green, int blue);
|
||||
|
||||
const gamemap& get_map() { return map_;}
|
||||
const gamemap& get_map()const { return map_;}
|
||||
private:
|
||||
enum ADJACENT_TERRAIN_TYPE { ADJACENT_BACKGROUND, ADJACENT_FOREGROUND, ADJACENT_FOGSHROUD };
|
||||
|
||||
|
|
|
@ -1123,7 +1123,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
|
|||
un->second.set_hidden(true);
|
||||
screen->scroll_to_tile(loc.x,loc.y,display::ONSCREEN);
|
||||
un->second.set_hidden(false);
|
||||
un->second.set_recruited(*screen);
|
||||
un->second.set_recruited(*screen,un->first);
|
||||
while(!un->second.get_animation()->animation_finished()) {
|
||||
screen->invalidate(loc);
|
||||
screen->draw();
|
||||
|
@ -1131,7 +1131,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
|
|||
if(!screen->turbo()) SDL_Delay(10);
|
||||
|
||||
}
|
||||
un->second.set_standing(*screen);
|
||||
un->second.set_standing(*screen,un->first);
|
||||
}
|
||||
} else {
|
||||
player_info* const player = state_of_game->get_player((*teams)[new_unit.side()-1].save_id());
|
||||
|
@ -1666,7 +1666,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
|
|||
screen->highlight_hex(u->first);
|
||||
screen->scroll_to_tile(u->first.x,u->first.y);
|
||||
|
||||
u->second.set_extra_anim(*screen,cfg["flag"]);
|
||||
u->second.set_extra_anim(*screen,u->first,cfg["flag"]);
|
||||
while(!u->second.get_animation()->animation_finished()) {
|
||||
screen->invalidate(u->first);
|
||||
screen->draw();
|
||||
|
@ -1674,7 +1674,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
|
|||
if(!screen->turbo()) SDL_Delay(10);
|
||||
|
||||
}
|
||||
u->second.set_standing(*screen);
|
||||
u->second.set_standing(*screen,u->first);
|
||||
screen->invalidate(u->first);
|
||||
screen->draw();
|
||||
events::pump();
|
||||
|
|
86
src/unit.cpp
86
src/unit.cpp
|
@ -1229,7 +1229,7 @@ const surface unit::still_image() const
|
|||
surface unit_image(image::get_image(loc,image::UNSCALED));
|
||||
return unit_image;
|
||||
}
|
||||
void unit::set_standing(const display &disp)
|
||||
void unit::set_standing(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_STANDING;
|
||||
draw_bars_ = true;
|
||||
|
@ -1243,7 +1243,7 @@ void unit::set_standing(const display &disp)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_defending(const display &disp, int damage, std::string range)
|
||||
void unit::set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack)
|
||||
{
|
||||
state_ = STATE_DEFENDING;
|
||||
draw_bars_ = true;
|
||||
|
@ -1251,7 +1251,15 @@ void unit::set_defending(const display &disp, int damage, std::string range)
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new defensive_animation(defend_animation(damage > 0?true:false,range));
|
||||
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 defensive_animation(defend_animation(disp.get_map().underlying_union_terrain(loc),hit_type,attack));
|
||||
|
||||
// add a blink on damage effect
|
||||
int anim_time = anim_->get_last_frame_time();
|
||||
|
@ -1270,7 +1278,7 @@ void unit::set_defending(const display &disp, int damage, std::string range)
|
|||
anim_->update_current_frame();
|
||||
}
|
||||
|
||||
void unit::set_extra_anim(const display &disp, std::string flag)
|
||||
void unit::set_extra_anim(const display &disp,const gamemap::location& loc, std::string flag)
|
||||
{
|
||||
state_ = STATE_EXTRA;
|
||||
draw_bars_ = false;
|
||||
|
@ -1278,17 +1286,17 @@ void unit::set_extra_anim(const display &disp, std::string flag)
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
if(!extra_animation(flag)) {
|
||||
set_standing(disp);
|
||||
if(!extra_animation(disp.get_map().underlying_union_terrain(loc),flag)) {
|
||||
set_standing(disp,loc);
|
||||
return;
|
||||
}
|
||||
anim_ = new unit_animation(*(extra_animation(flag)));
|
||||
anim_ = new unit_animation(*(extra_animation(disp.get_map().underlying_union_terrain(loc),flag)));
|
||||
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();
|
||||
}
|
||||
|
||||
const unit_animation & unit::set_attacking(const display &disp,bool hit,const attack_type& type)
|
||||
const unit_animation & unit::set_attacking(const display &disp,const gamemap::location& loc,bool hit,const attack_type& type)
|
||||
{
|
||||
state_ = STATE_ATTACKING;
|
||||
draw_bars_ = false;
|
||||
|
@ -1303,7 +1311,7 @@ const unit_animation & unit::set_attacking(const display &disp,bool hit,const at
|
|||
anim_->update_current_frame();
|
||||
return attack_anim.missile_animation;
|
||||
}
|
||||
void unit::set_leading(const display &disp)
|
||||
void unit::set_leading(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEADING;
|
||||
draw_bars_ = false;
|
||||
|
@ -1316,7 +1324,7 @@ void unit::set_leading(const display &disp)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_leveling_in(const display &disp)
|
||||
void unit::set_leveling_in(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEVELIN;
|
||||
draw_bars_ = false;
|
||||
|
@ -1340,7 +1348,7 @@ void unit::set_leveling_in(const display &disp)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_leveling_out(const display &disp)
|
||||
void unit::set_leveling_out(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEVELOUT;
|
||||
draw_bars_ = false;
|
||||
|
@ -1364,7 +1372,7 @@ void unit::set_leveling_out(const display &disp)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_recruited(const display &disp)
|
||||
void unit::set_recruited(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_RECRUITED;
|
||||
draw_bars_ = false;
|
||||
|
@ -1385,7 +1393,7 @@ void unit::set_recruited(const display &disp)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_healed(const display &disp, int healing)
|
||||
void unit::set_healed(const display &disp,const gamemap::location& loc, int healing)
|
||||
{
|
||||
state_ = STATE_HEALED;
|
||||
draw_bars_ = true;
|
||||
|
@ -1410,7 +1418,7 @@ void unit::set_healed(const display &disp, int healing)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_poisoned(const display &disp, int damage)
|
||||
void unit::set_poisoned(const display &disp,const gamemap::location& loc, int damage)
|
||||
{
|
||||
state_ = STATE_POISONED;
|
||||
draw_bars_ = true;
|
||||
|
@ -1436,7 +1444,7 @@ void unit::set_poisoned(const display &disp, int damage)
|
|||
anim_->update_current_frame();
|
||||
}
|
||||
|
||||
void unit::set_teleporting(const display &disp)
|
||||
void unit::set_teleporting(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_TELEPORT;
|
||||
draw_bars_ = false;
|
||||
|
@ -1450,7 +1458,7 @@ void unit::set_teleporting(const display &disp)
|
|||
anim_->update_current_frame();
|
||||
}
|
||||
|
||||
void unit::set_dying(const display &disp, const attack_type* attack)
|
||||
void unit::set_dying(const display &disp,const gamemap::location& loc,const attack_type* attack)
|
||||
{
|
||||
state_ = STATE_DYING;
|
||||
draw_bars_ = false;
|
||||
|
@ -1458,7 +1466,7 @@ void unit::set_dying(const display &disp, const attack_type* attack)
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new death_animation(die_animation(attack));
|
||||
anim_ = new death_animation(die_animation(disp.get_map().underlying_union_terrain(loc),fighting_animation::KILL,attack));
|
||||
double blend_ratio = 1.0;
|
||||
std::string tmp_image = anim_->get_last_frame().image;
|
||||
int anim_time =anim_->get_last_frame_time();
|
||||
|
@ -1471,7 +1479,7 @@ void unit::set_dying(const display &disp, const attack_type* attack)
|
|||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
}
|
||||
void unit::set_healing(const display &disp)
|
||||
void unit::set_healing(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_HEALING;
|
||||
draw_bars_ = true;
|
||||
|
@ -1492,10 +1500,10 @@ void unit::set_healing(const display &disp)
|
|||
anim_->update_current_frame();
|
||||
}
|
||||
|
||||
void unit::set_walking(const display &disp, const std::string terrain)
|
||||
void unit::set_walking(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
movement_animation* const anim = dynamic_cast<movement_animation*>(anim_);
|
||||
if(state_ == STATE_WALKING && anim != NULL && anim->matches(terrain,facing_) >=0) {
|
||||
if(state_ == STATE_WALKING && anim != NULL && anim->matches(disp.get_map().underlying_union_terrain(loc),facing_) >=0) {
|
||||
return; // finish current animation, don't start a new one
|
||||
}
|
||||
state_ = STATE_WALKING;
|
||||
|
@ -1504,7 +1512,7 @@ void unit::set_walking(const display &disp, const std::string terrain)
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new movement_animation(move_animation(terrain,facing_));
|
||||
anim_ = new movement_animation(move_animation(disp.get_map().underlying_union_terrain(loc),facing_));
|
||||
anim_->start_animation(anim_->get_first_frame_time(),1,disp.turbo()?5:1);
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
}
|
||||
|
@ -1544,7 +1552,7 @@ void unit::redraw_unit(display& disp,gamemap::location hex)
|
|||
const int x = int(offset_*xdst + (1.0-offset_)*xsrc);
|
||||
const int y = int(offset_*ydst + (1.0-offset_)*ysrc);
|
||||
|
||||
if(!anim_) set_standing(disp);
|
||||
if(!anim_) set_standing(disp,hex);
|
||||
const gamemap::TERRAIN terrain = map.get_terrain(hex);
|
||||
const double submerge = is_flying() ? 0.0 : map.get_terrain_info(terrain).unit_submerge() * disp.zoom();
|
||||
const int height_adjust = is_flying() ? 0 : int(map.get_terrain_info(terrain).unit_height_adjust() * disp.zoom());
|
||||
|
@ -2362,13 +2370,14 @@ const std::string& unit::race() const
|
|||
return race_->name();
|
||||
}
|
||||
|
||||
const defensive_animation& unit::defend_animation(bool hits, std::string range) const
|
||||
const defensive_animation& unit::defend_animation(const std::string &terrain,
|
||||
fighting_animation::hit_type hits, const attack_type* attack) 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(hits,range);
|
||||
int matching = i->matches(terrain,facing_,hits,attack);
|
||||
if(matching == max_val) {
|
||||
options.push_back(&*i);
|
||||
} else if(matching > max_val) {
|
||||
|
@ -2385,23 +2394,34 @@ const unit_animation& unit::teleport_animation() const
|
|||
{
|
||||
return teleport_animations_[rand() % teleport_animations_.size()];
|
||||
}
|
||||
const unit_animation* unit::extra_animation(std::string flag) const
|
||||
const unit_animation* unit::extra_animation(const std::string &terrain,const std::string &flag) const
|
||||
{
|
||||
if (extra_animations_.count(flag) == 0) return NULL;
|
||||
std::multimap<std::string,unit_animation>::const_iterator index = extra_animations_.lower_bound(flag);
|
||||
int i = (rand()% extra_animations_.count(flag));
|
||||
for(int j = 0 ; j < i ; j++) {
|
||||
index++;
|
||||
//select one of the matching animations at random
|
||||
std::vector<const unit_animation*> options;
|
||||
int max_val = -1;
|
||||
std::multimap<std::string,unit_animation>::const_iterator i;
|
||||
for(i = extra_animations_.lower_bound(flag); i != extra_animations_.upper_bound(flag); ++i) {
|
||||
int matching = i->second.matches(terrain,facing_);
|
||||
if(matching == max_val) {
|
||||
options.push_back(&i->second);
|
||||
} else if(matching > max_val) {
|
||||
max_val = matching;
|
||||
options.erase(options.begin(),options.end());
|
||||
options.push_back(&i->second);
|
||||
}
|
||||
}
|
||||
return &index->second;
|
||||
if(extra_animations_.lower_bound(flag) == extra_animations_.end()) { return NULL;}
|
||||
|
||||
return options[rand()%options.size()];
|
||||
}
|
||||
const death_animation& unit::die_animation(const attack_type* attack) const
|
||||
const death_animation& unit::die_animation(const std::string &terrain,
|
||||
fighting_animation::hit_type hits,const attack_type* attack) const
|
||||
{
|
||||
//select one of the matching animations at random
|
||||
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(attack);
|
||||
int matching = i->matches(terrain,facing_,hits,attack);
|
||||
if(matching == max_val) {
|
||||
options.push_back(&*i);
|
||||
} else if(matching > max_val) {
|
||||
|
|
36
src/unit.hpp
36
src/unit.hpp
|
@ -160,20 +160,20 @@ class unit
|
|||
const surface still_image() const;
|
||||
void redraw_unit(display& disp,gamemap::location hex);
|
||||
|
||||
void set_standing(const display& disp);
|
||||
void set_defending(const display& disp, int damage, std::string range);
|
||||
void set_leading(const display& disp);
|
||||
void set_healing(const display& disp);
|
||||
void set_leveling_in(const display& disp);
|
||||
void set_leveling_out(const display& disp);
|
||||
void set_teleporting (const display& disp);
|
||||
void set_extra_anim(const display& disp, std::string flag);
|
||||
void set_dying( const display& disp,const attack_type *attack);
|
||||
void set_walking(const display& disp,const std::string terrain);
|
||||
const unit_animation & set_attacking(const display& disp,bool hit,const attack_type& type);
|
||||
void set_recruited(const display& disp);
|
||||
void set_healed(const display& disp,int healing);
|
||||
void set_poisoned(const display& disp,int damage);
|
||||
void set_standing(const display& disp,const gamemap::location& loc);
|
||||
void set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack);
|
||||
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);
|
||||
void set_leveling_out(const display& disp,const gamemap::location& loc);
|
||||
void set_teleporting (const display& disp,const gamemap::location& loc);
|
||||
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);
|
||||
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);
|
||||
void restart_animation(const display& disp,int start_time);
|
||||
const unit_animation* get_animation() const { return anim_;};
|
||||
void set_offset(double offset){offset_ = offset;}
|
||||
|
@ -239,10 +239,12 @@ class unit
|
|||
unit_type::ALIGNMENT alignment() const;
|
||||
const std::string& race() const;
|
||||
|
||||
const defensive_animation& defend_animation(bool hits, std::string range) const;
|
||||
const defensive_animation& defend_animation(const std::string &terrain,
|
||||
fighting_animation::hit_type hits,const attack_type* attack) const;
|
||||
const unit_animation& teleport_animation() const;
|
||||
const unit_animation* extra_animation(std::string flag) const;
|
||||
const death_animation& die_animation(const attack_type* attack) const;
|
||||
const unit_animation* extra_animation(const std::string &terrain,const std::string &flag) const;
|
||||
const death_animation& die_animation(const std::string &terrain,
|
||||
fighting_animation::hit_type hits,const attack_type* attack) const;
|
||||
const movement_animation& move_animation(const std::string terrain,gamemap::location::DIRECTION) const;
|
||||
|
||||
bool get_ability_bool(const std::string& ability, const gamemap::location& loc) const;
|
||||
|
|
|
@ -69,8 +69,8 @@ unit_animation::unit_animation(const std::string image )
|
|||
{
|
||||
add_frame(0,unit_frame(image));
|
||||
}
|
||||
unit_animation::unit_animation(const config& cfg,const std::string frame_string )
|
||||
{
|
||||
|
||||
unit_animation::unit_animation(const config& cfg,const std::string frame_string ):terrain_types(utils::split(cfg["terrain"])){
|
||||
config::const_child_itors range = cfg.child_range(frame_string);
|
||||
|
||||
int last_end = INT_MIN;
|
||||
|
@ -80,6 +80,12 @@ unit_animation::unit_animation(const config& cfg,const std::string frame_string
|
|||
}
|
||||
add_frame(last_end);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* warn on deprecated WML */
|
||||
if(cfg.child("sound")) {
|
||||
LOG_STREAM(err, config) << "an animation uses the deprecated [sound] tag, please include sound in the [frame] tag\n";
|
||||
|
@ -93,29 +99,19 @@ unit_animation::unit_animation(const std::string image, int begin_at, int end_at
|
|||
add_frame(end_at);
|
||||
}
|
||||
|
||||
defensive_animation::defensive_animation(const config& cfg) :unit_animation(cfg), hits(HIT_OR_MISS), range(utils::split(cfg["range"]))
|
||||
{
|
||||
const std::string& hits_str = cfg["hits"];
|
||||
if(hits_str.empty() == false) {
|
||||
hits = (hits_str == "yes") ? HIT : MISS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int defensive_animation::matches(bool h, std::string r) const
|
||||
int unit_animation::matches(const std::string &terrain,const gamemap::location::DIRECTION dir) const
|
||||
{
|
||||
int result = 0;
|
||||
if(hits != HIT_OR_MISS ) {
|
||||
if(h && (hits == HIT)) {
|
||||
result++;
|
||||
} else if(!h && (hits == MISS)) {
|
||||
result++;
|
||||
} else {
|
||||
if(terrain_types.empty()== false) {
|
||||
if (std::find(terrain_types.begin(),terrain_types.end(),terrain)== terrain_types.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
if(range.empty()== false) {
|
||||
if (std::find(range.begin(),range.end(),r)== range.end()) {
|
||||
|
||||
if(directions.empty()== false) {
|
||||
if (std::find(directions.begin(),directions.end(),dir)== directions.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
|
@ -125,20 +121,48 @@ int defensive_animation::matches(bool h, std::string r) const
|
|||
return result;
|
||||
}
|
||||
|
||||
death_animation::death_animation(const config& cfg):unit_animation(cfg),
|
||||
damage_type(utils::split(cfg["damage_type"])), special(utils::split(cfg["attack_special"]))
|
||||
fighting_animation::fighting_animation(const config& cfg) :unit_animation(cfg), range(utils::split(cfg["range"])),
|
||||
damage_type(utils::split(cfg["damage_type"])), special(utils::split(cfg["attack_special"]))
|
||||
{
|
||||
std::vector<std::string> hits_str = utils::split(cfg["hits"]);
|
||||
std::vector<std::string>::iterator hit;
|
||||
for(hit=hits_str.begin() ; hit != hits_str.end() ; hit++) {
|
||||
if(*hit == "yes" || *hit == "hit") {
|
||||
hits.push_back(HIT);
|
||||
}
|
||||
if(*hit == "no" || *hit == "miss") {
|
||||
hits.push_back(MISS);
|
||||
}
|
||||
if(*hit == "kill" ) {
|
||||
hits.push_back(KILL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int death_animation::matches(const attack_type* attack) const
|
||||
|
||||
int fighting_animation::matches(const std::string &terrain,gamemap::location::DIRECTION dir,hit_type hit,const attack_type* attack) const
|
||||
{
|
||||
int result = 0;
|
||||
if(attack == NULL) {
|
||||
int result = unit_animation::matches(terrain,dir);
|
||||
if(!attack) {
|
||||
if(damage_type.empty() && special.empty())
|
||||
return 0;
|
||||
return result;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
if(hits.empty() == false ) {
|
||||
if (std::find(hits.begin(),hits.end(),hit)== hits.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
if(range.empty()== false) {
|
||||
if (std::find(range.begin(),range.end(),attack->range())== range.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
|
||||
if(damage_type.empty()== false) {
|
||||
if (std::find(damage_type.begin(),damage_type.end(),attack->type())== damage_type.end()) {
|
||||
|
@ -161,45 +185,7 @@ int death_animation::matches(const attack_type* attack) const
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
movement_animation::movement_animation(const config& cfg)
|
||||
:unit_animation(cfg), terrain_types(utils::split(cfg["terrain"]))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
movement_animation::movement_animation(const std::string& image,const std::string& terrain,gamemap::location::DIRECTION dir):unit_animation(image,0,150),terrain_types(utils::split(terrain))
|
||||
{
|
||||
if(dir !=gamemap::location::NDIRECTIONS) {
|
||||
directions.push_back(dir);
|
||||
}
|
||||
}
|
||||
int movement_animation::matches(const std::string &terrain,gamemap::location::DIRECTION dir) const
|
||||
{
|
||||
int result = 0;
|
||||
if(terrain_types.empty()== false) {
|
||||
if (std::find(terrain_types.begin(),terrain_types.end(),terrain)== terrain_types.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
|
||||
if(directions.empty()== false) {
|
||||
if (std::find(directions.begin(),directions.end(),dir)== directions.end()) {
|
||||
return -1;
|
||||
} else {
|
||||
result ++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,54 +30,63 @@ class unit_animation:public animated<unit_frame>
|
|||
|
||||
unit_animation(){};
|
||||
explicit unit_animation(const config& cfg,const std::string frame_string ="frame");
|
||||
explicit unit_animation(const std::string image, int begin_at, int end_at, const std::string image_diagonal = "",const std::string halo="",int halo_x=0,int halo_y=0);
|
||||
explicit unit_animation(const std::string image, int begin_at, int end_at,
|
||||
const std::string image_diagonal = "",const std::string halo="",int halo_x=0,int halo_y=0);
|
||||
explicit unit_animation(const std::string image);
|
||||
int matches(const std::string &terrain,const gamemap::location::DIRECTION dir) const;
|
||||
|
||||
enum FRAME_DIRECTION { VERTICAL, DIAGONAL };
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class defensive_animation:public unit_animation
|
||||
{
|
||||
public:
|
||||
typedef enum { HIT, MISS, HIT_OR_MISS } hit_type;
|
||||
|
||||
explicit defensive_animation(const config& cfg);
|
||||
explicit defensive_animation(const std::string &image, const std::string &range="",const hit_type for_hit= HIT_OR_MISS): unit_animation(image,-150,150),hits(for_hit),range(utils::split(range)) {};
|
||||
int matches(bool hits, std::string range) const;
|
||||
|
||||
private:
|
||||
hit_type hits;
|
||||
std::vector<std::string> range;
|
||||
};
|
||||
|
||||
|
||||
class attack_type;
|
||||
class death_animation:public unit_animation
|
||||
{
|
||||
public:
|
||||
explicit death_animation(const config& cfg);
|
||||
explicit death_animation(const std::string &image):unit_animation(image,0,10) {};
|
||||
int matches(const attack_type* attack) const;
|
||||
private:
|
||||
std::vector<std::string> damage_type, special;
|
||||
};
|
||||
|
||||
|
||||
class movement_animation:public unit_animation
|
||||
{
|
||||
public:
|
||||
explicit movement_animation(const config& cfg);
|
||||
explicit movement_animation(const std::string& image,const std::string& terrain="",gamemap::location::DIRECTION dir=gamemap::location::NDIRECTIONS);
|
||||
int matches(const std::string &terrain,gamemap::location::DIRECTION dir=gamemap::location::NDIRECTIONS) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> terrain_types;
|
||||
std::vector<gamemap::location::DIRECTION> directions;
|
||||
};
|
||||
|
||||
class attack_type;
|
||||
|
||||
|
||||
class fighting_animation:public unit_animation
|
||||
{
|
||||
public:
|
||||
typedef enum { HIT, MISS, KILL} hit_type;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
std::vector<hit_type> hits;
|
||||
std::vector<std::string> range;
|
||||
std::vector<std::string> damage_type, special;
|
||||
};
|
||||
|
||||
class defensive_animation:public fighting_animation
|
||||
{
|
||||
public:
|
||||
explicit defensive_animation(const config& cfg):fighting_animation(cfg){};
|
||||
explicit defensive_animation(const std::string &image, const std::string &range="",int begin_at = -150, int end_at = 150):fighting_animation(image,range,begin_at,end_at){};
|
||||
};
|
||||
|
||||
|
||||
class death_animation:public fighting_animation
|
||||
{
|
||||
public:
|
||||
explicit death_animation(const config& cfg):fighting_animation(cfg){};
|
||||
explicit death_animation(const std::string &image):fighting_animation(image,"",0,10) {};
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
class movement_animation:public unit_animation
|
||||
{
|
||||
public:
|
||||
explicit movement_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit movement_animation(const std::string& image):
|
||||
unit_animation(image,0,150){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ void teleport_unit_between(display& disp, const gamemap::location& a, const game
|
|||
|
||||
|
||||
|
||||
u.set_teleporting(disp);
|
||||
u.set_teleporting(disp,a);
|
||||
if (!disp.fogged(a.x, a.y)) { // teleport
|
||||
disp.scroll_to_tile(a.x,a.y,display::ONSCREEN);
|
||||
while(!u.get_animation()->animation_finished() && u.get_animation()->get_animation_time() < 0) {
|
||||
|
@ -64,7 +64,7 @@ void teleport_unit_between(display& disp, const gamemap::location& a, const game
|
|||
if(!disp.turbo()) SDL_Delay(10);
|
||||
}
|
||||
}
|
||||
u.set_standing(disp);
|
||||
u.set_standing(disp,b);
|
||||
disp.remove_temporary_unit();
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
|
@ -78,7 +78,6 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
|
|||
return;
|
||||
}
|
||||
|
||||
const gamemap::TERRAIN src_terrain = map.get_terrain(a);
|
||||
const gamemap::TERRAIN dst_terrain = map.get_terrain(b);
|
||||
|
||||
const int acceleration = disp.turbo() ? 5:1;
|
||||
|
@ -94,7 +93,7 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
|
|||
int mvt_time = SDL_GetTicks() -start_time;
|
||||
disp.scroll_to_tiles(a.x,a.y,b.x,b.y,display::ONSCREEN);
|
||||
while(mvt_time < total_mvt_time) {
|
||||
u.set_walking(disp,map.underlying_mvt_terrain(src_terrain));
|
||||
u.set_walking(disp,a);
|
||||
const double pos =double(mvt_time)/total_mvt_time;
|
||||
disp.invalidate(a);
|
||||
disp.place_temporary_unit(u,a);
|
||||
|
@ -157,7 +156,7 @@ void move_unit(display& disp, const gamemap& map, const std::vector<gamemap::loc
|
|||
disp.draw();
|
||||
}
|
||||
}
|
||||
u.set_standing(disp);
|
||||
u.set_standing(disp,path[path.size()-1]);
|
||||
|
||||
//make sure the entire path is cleaned properly
|
||||
for(std::vector<gamemap::location>::const_iterator it = path.begin(); it != path.end(); ++it) {
|
||||
|
@ -175,7 +174,7 @@ void unit_die(display& disp,const gamemap::location& loc, unit& u, const attack_
|
|||
if(die_sound != "" && die_sound != "null") {
|
||||
sound::play_sound(die_sound);
|
||||
}
|
||||
u.set_dying(disp,attack);
|
||||
u.set_dying(disp,loc,attack);
|
||||
|
||||
|
||||
while(!u.get_animation()->animation_finished()) {
|
||||
|
@ -185,10 +184,9 @@ void unit_die(display& disp,const gamemap::location& loc, unit& u, const attack_
|
|||
events::pump();
|
||||
if(!disp.turbo()) SDL_Delay(10);
|
||||
}
|
||||
u.set_standing(disp);
|
||||
u.set_standing(disp,loc);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -229,14 +227,14 @@ 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,hits,attack);
|
||||
unit_animation missile_animation = attacker.set_attacking(disp,a,hits,attack);
|
||||
const gamemap::location leader_loc = under_leadership(units,a);
|
||||
unit_map::iterator leader = units.end();
|
||||
if(leader_loc.valid()){
|
||||
LOG_DP << "found leader at " << leader_loc << '\n';
|
||||
leader = units.find(leader_loc);
|
||||
wassert(leader != units.end());
|
||||
leader->second.set_leading(disp);
|
||||
leader->second.set_leading(disp,leader_loc);
|
||||
}
|
||||
while(!attacker.get_animation()->animation_finished() ) {
|
||||
disp.invalidate(a);
|
||||
|
@ -254,7 +252,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
const bool hflip = b.x < a.x;
|
||||
const unit_animation::FRAME_DIRECTION dir = (a.x == b.x) ? unit_animation::VERTICAL:unit_animation::DIAGONAL;
|
||||
|
||||
defender.set_defending(disp,damage,attack.range());
|
||||
defender.set_defending(disp,b,damage,&attack);
|
||||
const int start_time = minimum<int>(minimum<int>(defender.get_animation()->get_first_frame_time(),
|
||||
missile_animation.get_first_frame_time()),-200);
|
||||
missile_animation.start_animation(start_time,acceleration);
|
||||
|
@ -331,10 +329,10 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
if(dead) {
|
||||
unit_display::unit_die(disp,def->first,def->second,&attack);
|
||||
} else {
|
||||
def->second.set_standing(disp);
|
||||
def->second.set_standing(disp,b);
|
||||
}
|
||||
if(leader_loc.valid()) leader->second.set_standing(disp);
|
||||
att->second.set_standing(disp);
|
||||
if(leader_loc.valid()) leader->second.set_standing(disp,leader_loc);
|
||||
att->second.set_standing(disp,a);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
|
||||
|
@ -379,11 +377,11 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
int end_time = 0;
|
||||
|
||||
|
||||
attacker.set_attacking(disp,hits,attack);
|
||||
attacker.set_attacking(disp,a,hits,attack);
|
||||
start_time=minimum<int>(start_time,attacker.get_animation()->get_first_frame_time());
|
||||
end_time=maximum<int>(end_time,attacker.get_animation()->get_last_frame_time());
|
||||
|
||||
defender.set_defending(disp,damage,attack.range());
|
||||
defender.set_defending(disp,b,damage,&attack);
|
||||
start_time=minimum<int>(start_time,defender.get_animation()->get_first_frame_time());
|
||||
end_time=maximum<int>(end_time,defender.get_animation()->get_last_frame_time());
|
||||
|
||||
|
@ -394,7 +392,7 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
LOG_DP << "found leader at " << leader_loc << '\n';
|
||||
leader = units.find(leader_loc);
|
||||
wassert(leader != units.end());
|
||||
leader->second.set_leading(disp);
|
||||
leader->second.set_leading(disp,leader_loc);
|
||||
start_time=minimum<int>(start_time,leader->second.get_animation()->get_first_frame_time());
|
||||
end_time=maximum<int>(end_time,leader->second.get_animation()->get_last_frame_time());
|
||||
}
|
||||
|
@ -453,10 +451,10 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
if(dead) {
|
||||
unit_display::unit_die(disp,def->first,def->second,&attack);
|
||||
} else {
|
||||
def->second.set_standing(disp);
|
||||
def->second.set_standing(disp,b);
|
||||
}
|
||||
if(leader_loc.valid()) leader->second.set_standing(disp);
|
||||
att->second.set_standing(disp);
|
||||
if(leader_loc.valid()) leader->second.set_standing(disp,leader_loc);
|
||||
att->second.set_standing(disp,a);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue