From dd48d3d8dbc2ec2edb0cd08dcb42161ff11a06cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Rosen?= Date: Sun, 28 Oct 2007 10:17:53 +0000 Subject: [PATCH] allow multiple sub-animations, in all animations (not just missile in fight) --- changelog | 3 + src/animated.hpp | 1 + src/animated.i | 10 ++- src/display.cpp | 9 +- src/display.hpp | 4 +- src/unit.cpp | 22 ++--- src/unit.hpp | 2 +- src/unit_animation.cpp | 195 ++++++++++++++++++++++++++++++++++++++++- src/unit_animation.hpp | 56 +++++++----- src/unit_display.cpp | 60 +------------ src/unit_types.cpp | 9 +- 11 files changed, 257 insertions(+), 114 deletions(-) diff --git a/changelog b/changelog index e1b64769b4d..30d0cad8485 100644 --- a/changelog +++ b/changelog @@ -41,6 +41,9 @@ Version 1.3.9+svn: are now deleted (rather than just autosaves as formerly). This is done before replay saving, if that is enabled. The preference name has changed from delete_autosaves to delete_saves. + * Animation engine allow multiple type of frames (a la "missile frames") + for all types of anims, you can have multiple such anims using different + frame names * miscellaneous and bug fixes: Version 1.3.9: diff --git a/src/animated.hpp b/src/animated.hpp index 8ca511a1d5f..9069ccaaf82 100644 --- a/src/animated.hpp +++ b/src/animated.hpp @@ -112,6 +112,7 @@ private: double acceleration_; int last_update_tick_; int current_frame_key_; + int last_frame_key_; }; diff --git a/src/animated.i b/src/animated.i index e051e2e560a..b8aae52574d 100644 --- a/src/animated.i +++ b/src/animated.i @@ -51,7 +51,8 @@ animated::animated(int start_time) : cycles_(false), acceleration_(1), last_update_tick_(0), - current_frame_key_(0) + current_frame_key_(0), + last_frame_key_(-1) { } @@ -64,7 +65,8 @@ animated::animated(const std::vector > &cfg, in cycles_(false), acceleration_(1), last_update_tick_(0), - current_frame_key_(0) + current_frame_key_(0), + last_frame_key_(-1) { typename std::vector< std::pair >::const_iterator itor = cfg.begin(); @@ -101,6 +103,8 @@ void animated::start_animation(int start_time, bool cycles, doub if(acceleration_ <=0) acceleration_ = 1; current_frame_key_= 0; update_last_draw_time(); + // need to force last frame key in the case of starting anim... + last_frame_key_ = -1; } @@ -108,6 +112,7 @@ template void animated::update_last_draw_time() { last_update_tick_ = current_ticks; + last_frame_key_ = current_frame_key_; if(does_not_change_) return; @@ -124,6 +129,7 @@ void animated::update_last_draw_time() while(get_animation_time() > get_end_time()){ // cut extra time start_tick_ += static_cast(get_end_time()/acceleration_); current_frame_key_ = 0; + last_frame_key_ = -1; } } if(get_current_frame_end_time() < get_animation_time() && // catch up diff --git a/src/display.cpp b/src/display.cpp index 13539118e93..c2c4e3ec466 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -829,8 +829,8 @@ void display::clear_hex_overlay(const gamemap::location& loc) } void display::render_unit_image(int x, int y, surface image, - bool reverse, bool greyscale, fixed_t alpha, - Uint32 blendto, double blend_ratio, double submerged) + bool hreverse, bool greyscale, fixed_t alpha, + Uint32 blendto, double blend_ratio, double submerged,bool vreverse) { if (image==NULL) @@ -843,9 +843,12 @@ void display::render_unit_image(int x, int y, surface image, surface surf(image); - if(reverse) { + if(hreverse) { surf = image::reverse_image(surf); } + if(vreverse) { + surf = flop_surface(surf); + } if(greyscale) { surf = greyscale_image(surf); diff --git a/src/display.hpp b/src/display.hpp index c8f15c472ad..d5045a26f8e 100644 --- a/src/display.hpp +++ b/src/display.hpp @@ -234,9 +234,9 @@ public: //! submerged: the amount of the unit out of 1.0 that is submerged //! (presumably under water) and thus shouldn't be drawn void render_unit_image(int x, int y, surface image, - bool reverse=false, bool greyscale=false, + bool hreverse=false, bool greyscale=false, fixed_t alpha=ftofxp(1.0), Uint32 blendto=0, - double blend_ratio=0, double submerged=0.0); + double blend_ratio=0, double submerged=0.0,bool vreverse =false); const theme::menu* menu_pressed(); diff --git a/src/unit.cpp b/src/unit.cpp index 6d4b33c220a..8d62fb9593c 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -1320,12 +1320,7 @@ void unit::read(const config& cfg, bool use_traits) animations_ = ut->animations_; cfg_.clear_children("animation"); } else { - const config::child_list& animations = cfg_.get_children("animation"); - config::child_list::const_iterator d; - for(d = animations.begin(); d != animations.end(); ++d) { - animations_.push_back(unit_animation(**d)); - } - unit_animation::back_compat_initialize_anims(animations_,cfg_,type()->attacks(true)); + unit_animation::initialize_anims(animations_,cfg_,type()->attacks(true)); } } else { // Remove animations from private cfg, since they're not needed there now @@ -1614,7 +1609,7 @@ void unit::start_animation(const game_display &disp, const gamemap::location &lo offset_=0; if(anim_) delete anim_; anim_ = new unit_animation(*animation); - anim_->start_animation(anim_->get_begin_time(), cycles, disp.turbo_speed()); + anim_->start_animation(anim_->get_begin_time(),loc, loc.get_direction(facing_), cycles, disp.turbo_speed()); frame_begin_time_ = anim_->get_begin_time() -1; if (disp.idle_anim()) { next_idling_ = get_current_animation_tick() @@ -1624,9 +1619,9 @@ void unit::start_animation(const game_display &disp, const gamemap::location &lo } } -void unit::restart_animation(const game_display& disp,int start_time) { +void unit::restart_animation(const game_display& disp,int start_time, bool cycles) { if(!anim_) return; - anim_->start_animation(start_time,false,disp.turbo_speed()); + anim_->start_animation(start_time,gamemap::location::null_location, gamemap::location::null_location, cycles, disp.turbo_speed()); frame_begin_time_ = start_time -1; } @@ -1868,6 +1863,7 @@ void unit::redraw_unit(game_display& disp, const gamemap::location& loc) } } + anim_->redraw(); refreshing_ = false; anim_->update_last_draw_time(); } @@ -2590,13 +2586,7 @@ void unit::add_modification(const std::string& type, const config& mod, bool no_ game_config::add_color_info(**i.first); LOG_UT << "applying image_mod \n"; } else if (apply_to == "new_animation") { - // TODO most of this is to keep backward compatibility, to be removed in due time... - const config::child_list& animations = (**i.first).get_children("animation"); - config::child_list::const_iterator d; - for(d = animations.begin(); d != animations.end(); ++d) { - animations_.push_back(unit_animation(**d)); - } - unit_animation::back_compat_initialize_anims(animations_,**i.first,std::vector()); + unit_animation::initialize_anims(animations_,**i.first,std::vector()); } } // end while } else { // for times = per level & level = 0 we still need to rebuild the descriptions diff --git a/src/unit.hpp b/src/unit.hpp index 1e6fe3072b9..996adc04db3 100644 --- a/src/unit.hpp +++ b/src/unit.hpp @@ -190,7 +190,7 @@ public: void set_victorious(const game_display &disp,const gamemap::location& loc,const attack_type* attack,const attack_type* secondary_attack); void set_poisoned(const game_display& disp,const gamemap::location& loc,int damage); void set_idling(const game_display& disp,const gamemap::location& loc); - void restart_animation(const game_display& disp,int start_time); + void restart_animation(const game_display& disp,int start_time, bool cycles = false); const unit_animation* get_animation() const { return anim_;}; void set_offset(double offset){offset_ = offset;} void set_facing(gamemap::location::DIRECTION dir); diff --git a/src/unit_animation.cpp b/src/unit_animation.cpp index 2a5cd860254..cdf124a2da7 100644 --- a/src/unit_animation.cpp +++ b/src/unit_animation.cpp @@ -19,12 +19,14 @@ #include "game_config.hpp" #include "gettext.hpp" #include "log.hpp" +#include "halo.hpp" #include "pathutils.hpp" #include "unit.hpp" #include "unit_animation.hpp" #include "unit_types.hpp" #include "util.hpp" #include "variable.hpp" +#include "sound.hpp" #include "wassert.hpp" #include "serialization/string_utils.hpp" @@ -104,8 +106,14 @@ unit_animation::unit_animation(int start_time,const unit_frame & frame , const s unit_animation::unit_animation(const config& cfg,const std::string frame_string ) : terrain_types_(t_translation::read_list(cfg["terrain"])),base_score_(0), - missile_anim_(cfg,"missile_"),unit_anim_(cfg,frame_string) + unit_anim_(cfg,frame_string) { + config::child_map::const_iterator frame_itor =cfg.all_children().begin(); + for( /*null*/; frame_itor != cfg.all_children().end() ; frame_itor++) { + if(frame_itor->first == frame_string) continue; + if(frame_itor->first.find("_frame",frame_itor->first.size() -6 ) == std::string::npos) continue; + sub_anims_[frame_itor->first] = crude_animation(cfg,frame_itor->first.substr(0,frame_itor->first.size() -5)); + } event_ =utils::split(cfg["apply_to"]); const std::vector& my_directions = utils::split(cfg["direction"]); @@ -266,10 +274,18 @@ void unit_animation::back_compat_add_name(const std::string name,const std::stri } -void unit_animation::back_compat_initialize_anims( std::vector & animations, const config & cfg, std::vector tmp_attacks) +void unit_animation::initialize_anims( std::vector & animations, const config & cfg, std::vector tmp_attacks) { config expanded_cfg; config::child_list::const_iterator anim_itor; + + expanded_cfg = unit_animation::prepare_animation(cfg,"animation"); + const config::child_list& parsed_animations = expanded_cfg.get_children("animation"); + for(anim_itor = parsed_animations.begin(); anim_itor != parsed_animations.end(); ++anim_itor) { + animations.push_back(unit_animation(**anim_itor)); + } + + expanded_cfg = unit_animation::prepare_animation(cfg,"leading_anim"); const config::child_list& leading_anims = expanded_cfg.get_children("leading_anim"); for(anim_itor = leading_anims.begin(); anim_itor != leading_anims.end(); ++anim_itor) { @@ -513,6 +529,10 @@ unit_animation::crude_animation::crude_animation(const config& cfg,const std::st } else { starting_frame_time_ = atoi(cfg[frame_string+"start_time"].c_str()); } + if(frame_string == "missile_") { + // lg::wml_error To be deprecated eventually + add_frame(1,unit_frame("",1),true); + } for(; range.first != range.second; ++range.first) { unit_frame tmp_frame(**range.first); @@ -526,6 +546,14 @@ unit_animation::crude_animation::crude_animation(const config& cfg,const std::st blend_ratio_ = progressive_double(cfg[frame_string+"blend_ratio"],get_animation_duration()); highlight_ratio_ = progressive_double(cfg[frame_string+"alpha"],get_animation_duration()); offset_ = progressive_double(cfg[frame_string+"offset"],get_animation_duration()); + if(offset_.does_not_change() && frame_string == "missile_") { + // lg::wml_error To be deprecated eventually + offset_=progressive_double("0~0.8",get_animation_duration()); + } + if( frame_string == "missile_") { + // lg::wml_error To be deprecated eventually + add_frame(1,unit_frame("",1),true); + } if(!halo_.does_not_change() || !halo_x_.does_not_change() || @@ -539,3 +567,166 @@ unit_animation::crude_animation::crude_animation(const config& cfg,const std::st +bool unit_animation::need_update() const +{ + if(unit_anim_.need_update()) return true; + std::map::const_iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + if(anim_itor->second.need_update()) return true; + } + return false; +}; +bool unit_animation::animation_finished() const +{ + if(!unit_anim_.animation_finished()) return false; + std::map::const_iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + if(!anim_itor->second.animation_finished()) return false; + } + return true; +}; +bool unit_animation::animation_would_finish() const +{ + if(!unit_anim_.animation_would_finish()) return false; + std::map::const_iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + if(!anim_itor->second.animation_would_finish()) return false; + } + return true; +}; +void unit_animation::update_last_draw_time() +{ + unit_anim_.update_last_draw_time(); + std::map::iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + anim_itor->second.update_last_draw_time(); + } +}; +int unit_animation::get_end_time() const +{ + int result = unit_anim_.get_end_time(); + std::map::const_iterator anim_itor =sub_anims_.end(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + result= minimum(result,anim_itor->second.get_end_time()); + } + return result; +}; +int unit_animation::get_begin_time() const +{ + int result = unit_anim_.get_begin_time(); + std::map::const_iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + result= minimum(result,anim_itor->second.get_begin_time()); + } + return result; +}; +void unit_animation::start_animation(int start_time,const gamemap::location &src, const gamemap::location &dst, bool cycles, double acceleration) +{ + unit_anim_.start_animation(start_time, src, dst, cycles, acceleration); + std::map::iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + anim_itor->second.start_animation(start_time,src,dst,cycles,acceleration); + } +} +void unit_animation::redraw() +{ + std::map::iterator anim_itor =sub_anims_.begin(); + for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) { + anim_itor->second.redraw(); + } +} +void unit_animation::crude_animation::redraw() +{ + const int xsrc = game_display::get_singleton()->get_location_x(src_); + const int ysrc = game_display::get_singleton()->get_location_y(src_); + const int xdst = game_display::get_singleton()->get_location_x(dst_); + const int ydst = game_display::get_singleton()->get_location_y(dst_); + const gamemap::location::DIRECTION direction = src_.get_relative_dir(dst_); + + double tmp_offset = offset(); + int d2 = game_display::get_singleton()->hex_size() / 2; + const unit_frame& current_frame= get_current_frame(); + if(!current_frame.sound().empty() && get_current_frame_begin_time() != last_frame_begin_time_ ) { + sound::play_sound(current_frame.sound()); + } + last_frame_begin_time_ = get_current_frame_begin_time(); + image::locator image_loc; + if(direction != gamemap::location::NORTH && direction != gamemap::location::SOUTH) { + image_loc = current_frame.image_diagonal(); + } + if(image_loc.is_void()) { // invalid diag image, or not diagonal + image_loc = current_frame.image(); + } + + surface image; + if(!image_loc.is_void() && image_loc.get_filename() != "") { // invalid diag image, or not diagonal + image=image::get_image(image_loc, + image::SCALED_TO_ZOOM, + false + ); + } + const int x = static_cast(tmp_offset * xdst + (1.0-tmp_offset) * xsrc) + d2 ; + const int y = static_cast(tmp_offset * ydst + (1.0-tmp_offset) * ysrc) + d2; + if (image != NULL) { + bool facing_west = direction == gamemap::location::NORTH_WEST || direction == gamemap::location::SOUTH_WEST; + bool facing_north = direction == gamemap::location::NORTH_WEST || direction == gamemap::location::NORTH || direction == gamemap::location::NORTH_EAST; + game_display::get_singleton()->render_unit_image(x- image->w/2, y - image->h/2, image, facing_west, false, + highlight_ratio(), blend_with_, blend_ratio(),0,!facing_north); + } + halo::remove(halo_id_); + halo_id_ = halo::NO_HALO; + if(!halo().empty()) { + halo::ORIENTATION orientation; + switch(direction) + { + case gamemap::location::NORTH: + case gamemap::location::NORTH_EAST: + orientation = halo::NORMAL; + break; + case gamemap::location::SOUTH_EAST: + case gamemap::location::SOUTH: + orientation = halo::VREVERSE; + break; + case gamemap::location::SOUTH_WEST: + orientation = halo::HVREVERSE; + break; + case gamemap::location::NORTH_WEST: + orientation = halo::HREVERSE; + break; + case gamemap::location::NDIRECTIONS: + default: + orientation = halo::NORMAL; + break; + } + if(direction != gamemap::location::SOUTH_WEST && direction != gamemap::location::NORTH_WEST) { + halo_id_ = halo::add(x+halo_x(), + y+halo_y(), + halo(), + gamemap::location(-1, -1), + orientation); + } else { + halo_id_ = halo::add(x-halo_x(), + y+halo_y(), + halo(), + gamemap::location(-1, -1), + orientation); + } + } + update_last_draw_time(); +} +unit_animation::crude_animation::~crude_animation() +{ + halo::remove(halo_id_); + halo_id_ = halo::NO_HALO; +} +void unit_animation::crude_animation::start_animation(int start_time,const gamemap::location &src,const gamemap::location &dst, bool cycles, double acceleration) +{ + halo::remove(halo_id_); + halo_id_ = halo::NO_HALO; + animated::start_animation(start_time,cycles,acceleration); + last_frame_begin_time_ = get_begin_time() -1; + if(src != gamemap::location::null_location || dst != gamemap::location::null_location) { + src_ = src; + dst_ = dst; + } +}; diff --git a/src/unit_animation.hpp b/src/unit_animation.hpp index 81055afe4a0..5a293ca157b 100644 --- a/src/unit_animation.hpp +++ b/src/unit_animation.hpp @@ -34,13 +34,33 @@ class unit_animation public: typedef enum { MATCH_FAIL=-2 , DEFAULT_ANIM=-1}; typedef enum { HIT, MISS, KILL, INVALID} hit_type; - static config prepare_animation(const config &cfg,const std::string animation_tag); + static void initialize_anims( std::vector & animations, const config & cfg, std::vector tmp_attacks); - unit_animation(){}; - explicit unit_animation(const config& cfg,const std::string frame_string =""); - explicit unit_animation(int start_time,const unit_frame &frame,const std::string& even="",const int variation=0); int matches(const game_display &disp,const gamemap::location& loc,const unit* my_unit,const std::string & event="",const int value=0,hit_type hit=INVALID,const attack_type* attack=NULL,const attack_type* second_attack = NULL, int swing_num =0) const; + + const unit_frame& get_last_frame() const{ return unit_anim_.get_last_frame() ; }; + void add_frame(int duration, const unit_frame& value,bool force_change =false){ unit_anim_.add_frame(duration,value,force_change) ; }; + + bool need_update() const; + bool animation_finished() const; + bool animation_would_finish() const; + void update_last_draw_time(); + int get_begin_time() const; + int get_end_time() const; + int get_animation_time() const{ return unit_anim_.get_animation_time() ; }; + void start_animation(int start_time,const gamemap::location &src = gamemap::location::null_location, const gamemap::location &dst = gamemap::location::null_location , bool cycles=false, double acceleration=1); + const int get_current_frame_begin_time() const{ return unit_anim_.get_current_frame_begin_time() ; }; + void redraw(); + + // only to support all [attack_anim] format, to remove at 1.3.10 time + void back_compat_add_name(const std::string name="",const std::string range =""); + // to be privatized post 1.3.10 + static config prepare_animation(const config &cfg,const std::string animation_tag); + explicit unit_animation(const config& cfg,const std::string frame_string =""); + friend class unit; + protected: + // reserved to class unit, for the special case of redrawing the unit base frame image::locator image() const { return unit_anim_.get_current_frame().image() ; } image::locator image_diagonal() const { return unit_anim_.get_current_frame().image_diagonal() ; } std::string sound() const { return unit_anim_.get_current_frame().sound() ; }; @@ -51,29 +71,15 @@ class unit_animation double blend_ratio(const double default_val = 0) const{ return unit_anim_.blend_ratio(default_val); }; fixed_t highlight_ratio(const float default_val = 1.0) const{ return unit_anim_.highlight_ratio(default_val); }; double offset(double default_val =0.0) const{ return unit_anim_.offset(default_val); }; - - bool need_update() const{return unit_anim_.need_update();}; - bool animation_finished() const{ return unit_anim_.animation_finished() ; }; - bool animation_would_finish() const{ return unit_anim_.animation_would_finish() ; }; - const unit_frame& get_last_frame() const{ return unit_anim_.get_last_frame() ; }; - void add_frame(int duration, const unit_frame& value,bool force_change =false){ unit_anim_.add_frame(duration,value,force_change) ; }; - void start_animation(int start_time, bool cycles=false, double acceleration=1){ unit_anim_.start_animation(start_time, cycles, acceleration);}; - int get_begin_time() const{ return unit_anim_.get_begin_time() ; }; - void update_last_draw_time(){unit_anim_.update_last_draw_time();}; - const int get_current_frame_begin_time() const{ return unit_anim_.get_current_frame_begin_time() ; }; - int get_animation_time() const{ return unit_anim_.get_animation_time() ; }; - int get_end_time() const{ return unit_anim_.get_end_time() ; }; - - // only to support all [attack_anim] format, to remove at 1.3.10 time - void back_compat_add_name(const std::string name="",const std::string range =""); - const animated &get_missile_anim() const {return missile_anim_;} - static void back_compat_initialize_anims( std::vector & animations, const config & cfg, std::vector tmp_attacks); private: + unit_animation(){}; + explicit unit_animation(int start_time,const unit_frame &frame,const std::string& even="",const int variation=0); class crude_animation:public animated { public: explicit crude_animation(int start_time=0):animated(start_time){}; explicit crude_animation(const config& cfg,const std::string frame_string ="frame"); + virtual ~crude_animation(); bool need_update() const; const std::string &halo(const std::string&default_val ="") const; int halo_x(const int default_val = 0) const; @@ -81,6 +87,8 @@ class unit_animation double blend_ratio(const double default_val = 0) const; fixed_t highlight_ratio(const float default_val = 1.0) const; double offset(double default_val =0.0) const; + void redraw( ); + void start_animation(int start_time,const gamemap::location& src,const gamemap::location& dst, bool cycles=false, double acceleration=1); private: //animation params that can be locally overridden by frames @@ -91,6 +99,10 @@ class unit_animation Uint32 blend_with_; progressive_double blend_ratio_; progressive_double highlight_ratio_; + gamemap::location src_; + gamemap::location dst_; + int halo_id_; + int last_frame_begin_time_; }; t_translation::t_list terrain_types_; @@ -105,7 +117,7 @@ class unit_animation std::vector secondary_attack_filter_; std::vector hits_; std::vector swing_num_; - crude_animation missile_anim_; + std::map sub_anims_; crude_animation unit_anim_; }; diff --git a/src/unit_display.cpp b/src/unit_display.cpp index a01e5bf96c0..9eacecbf188 100644 --- a/src/unit_display.cpp +++ b/src/unit_display.cpp @@ -236,14 +236,8 @@ static void unit_attack_ranged( disp->place_temporary_unit(defender,b); defender.set_hidden(false); - const double acceleration = disp->turbo_speed(); - // More damage shown for longer, but 1s at most for this factor - const double xsrc = disp->get_location_x(a); - const double ysrc = disp->get_location_y(a) - (attacker.is_flying() ? 0 : disp->get_map().get_terrain_info(disp->get_map().get_terrain(a)).unit_height_adjust()); - const double xdst = disp->get_location_x(b); - const double ydst = disp->get_location_y(b) -( defender.is_flying() ? 0 : disp->get_map().get_terrain_info(disp->get_map().get_terrain(b)).unit_height_adjust()); gamemap::location update_tiles[6]; get_adjacent_tiles(b,update_tiles); @@ -253,7 +247,6 @@ static void unit_attack_ranged( // Start leader and attacker animation, wait for attacker animation to end attacker.set_attacking(*disp,a,damage,attack,secondary_attack,swing); - animated missile_animation = attacker.get_animation()->get_missile_anim(); const gamemap::location leader_loc = under_leadership(units,a); unit_map::iterator leader = units.end(); if(leader_loc.valid()){ @@ -289,15 +282,12 @@ static void unit_attack_ranged( orientation = halo::NORMAL; break; } - const bool vertical_dir = (a.x == b.x) ? true:false; defender.set_defending(*disp,b,damage,&attack,secondary_attack,swing); // Min of attacker, defender, missile and -200 int start_time = -200; start_time = minimum(start_time,defender.get_animation()->get_begin_time()); - start_time = minimum(start_time,missile_animation.get_begin_time()); start_time = minimum(start_time,attacker.get_animation()->get_begin_time()); - missile_animation.start_animation(start_time,false,acceleration); defender.restart_animation(*disp,start_time); attacker.restart_animation(*disp,start_time); animation_time = defender.get_animation()->get_animation_time(); @@ -307,56 +297,9 @@ static void unit_attack_ranged( while(!hide && ( !attacker.get_animation()->animation_would_finish() || !defender.get_animation()->animation_would_finish() || - !missile_animation.animation_finished() || (leader_loc.valid() && !leader->second.get_animation()->animation_finished()) || damage >0) ){ - const unit_frame& missile_frame = missile_animation.get_current_frame(); - double pos = missile_frame.offset(missile_animation.get_current_frame_time(), - double(animation_time -missile_animation.get_begin_time())/ - double(missile_animation.get_end_time()-missile_animation.get_begin_time())); - disp->invalidate(b); - disp->invalidate(a); - if(leader_loc.valid()) disp->invalidate(leader_loc); - halo::remove(missile_halo); - halo::remove(missile_frame_halo); - missile_halo = halo::NO_HALO; - missile_frame_halo = halo::NO_HALO; - if(animation_time > missile_animation.get_begin_time() && - animation_time < missile_animation.get_end_time() && - (!disp->fogged(b) || !disp->fogged(a))) { - const int posx = int(pos*xdst + (1.0-pos)*xsrc); - const int posy = int(pos*ydst + (1.0-pos)*ysrc); - - image::locator missile_image= missile_frame.image(); - const int d = disp->hex_size() / 2; - if(vertical_dir) { - missile_image = missile_frame.image(); - } else { - missile_image = missile_frame.image_diagonal(); - } - if(!missile_frame.halo(missile_animation.get_current_frame_time()).empty()) { - if(attack_ori != gamemap::location::SOUTH_WEST && attack_ori != gamemap::location::NORTH_WEST) { - missile_halo = halo::add(posx+d+missile_frame.halo_x(missile_animation.get_current_frame_time()), - posy+d+missile_frame.halo_y(missile_animation.get_current_frame_time()), - missile_frame.halo(missile_animation.get_current_frame_time()), - gamemap::location(-1, -1), - orientation); - } else { - missile_halo = halo::add(posx+d-missile_frame.halo_x(missile_animation.get_current_frame_time()), - posy+d+missile_frame.halo_y(missile_animation.get_current_frame_time()), - missile_frame.halo(missile_animation.get_current_frame_time()), - gamemap::location(-1, -1), - orientation); - } - } - missile_frame_halo = halo::add(posx+d, - posy+d, - missile_image.get_filename(), - gamemap::location(-1, -1), - orientation); - - } if(!sound_played && animation_time > 0) { sound_played = true; std::string text ; @@ -376,11 +319,10 @@ static void unit_attack_ranged( } disp->draw(); events::pump(); - missile_animation.update_last_draw_time(); disp->delay(10); // We use missile animation because it's the only one // not reseted in the middle to go to standing - animation_time = missile_animation.get_animation_time(); + animation_time = attacker.get_animation()->get_animation_time(); } halo::remove(missile_halo); diff --git a/src/unit_types.cpp b/src/unit_types.cpp index 62c56a059cd..2bfaa828386 100644 --- a/src/unit_types.cpp +++ b/src/unit_types.cpp @@ -44,6 +44,7 @@ attack_type::attack_type(const config& cfg,const std::string& id, bool with_anim } if (with_animations) { const config expanded_cfg = unit_animation::prepare_animation(cfg,"animation"); + // TODO: prepare animation should be privatized once the code is removed const config::child_list& animations = expanded_cfg.get_children("animation"); for(config::child_list::const_iterator d = animations.begin(); d != animations.end(); ++d) { lg::wml_error<<"attack animation directly in attack is deprecated, support will be removed in 1.3.10 (in unit "<(cfg_["experience"],500); - config expanded_cfg = unit_animation::prepare_animation(cfg,"animation"); - const config::child_list& animations = expanded_cfg.get_children("animation"); - config::child_list::const_iterator anim_itor; - for(anim_itor = animations.begin(); anim_itor != animations.end(); ++anim_itor) { - animations_.push_back(unit_animation(**anim_itor)); - } - unit_animation::back_compat_initialize_anims(animations_,cfg,attacks(true)); + unit_animation::initialize_anims(animations_,cfg,attacks(true)); flag_rgb_ = cfg["flag_rgb"]; game_config::add_color_info(cfg); // Deprecation messages, only seen when unit is parsed for the first time.