allow multiple sub-animations, in all animations (not just missile in fight)

This commit is contained in:
Jérémy Rosen 2007-10-28 10:17:53 +00:00
parent bdab825b22
commit dd48d3d8db
11 changed files with 257 additions and 114 deletions

View file

@ -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:

View file

@ -112,6 +112,7 @@ private:
double acceleration_;
int last_update_tick_;
int current_frame_key_;
int last_frame_key_;
};

View file

@ -51,7 +51,8 @@ animated<T,T_void_value>::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<T,T_void_value>::animated(const std::vector<std::pair<int,T> > &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<int,T> >::const_iterator itor = cfg.begin();
@ -101,6 +103,8 @@ void animated<T,T_void_value>::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<typename T, typename T_void_value>
void animated<T,T_void_value>::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<T,T_void_value>::update_last_draw_time()
while(get_animation_time() > get_end_time()){ // cut extra time
start_tick_ += static_cast<int>(get_end_time()/acceleration_);
current_frame_key_ = 0;
last_frame_key_ = -1;
}
}
if(get_current_frame_end_time() < get_animation_time() && // catch up

View file

@ -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);

View file

@ -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();

View file

@ -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<attack_type>());
unit_animation::initialize_anims(animations_,**i.first,std::vector<attack_type>());
}
} // end while
} else { // for times = per level & level = 0 we still need to rebuild the descriptions

View file

@ -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);

View file

@ -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<std::string>& 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<unit_animation> & animations, const config & cfg, std::vector<attack_type> tmp_attacks)
void unit_animation::initialize_anims( std::vector<unit_animation> & animations, const config & cfg, std::vector<attack_type> 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<std::string,crude_animation>::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<std::string,crude_animation>::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<std::string,crude_animation>::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<std::string,crude_animation>::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<std::string,crude_animation>::const_iterator anim_itor =sub_anims_.end();
for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) {
result= minimum<int>(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<std::string,crude_animation>::const_iterator anim_itor =sub_anims_.begin();
for( /*null*/; anim_itor != sub_anims_.end() ; anim_itor++) {
result= minimum<int>(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<std::string,crude_animation>::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<std::string,crude_animation>::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<int>(tmp_offset * xdst + (1.0-tmp_offset) * xsrc) + d2 ;
const int y = static_cast<int>(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<unit_frame>::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;
}
};

View file

@ -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<unit_animation> & animations, const config & cfg, std::vector<attack_type> 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<unit_frame> &get_missile_anim() const {return missile_anim_;}
static void back_compat_initialize_anims( std::vector<unit_animation> & animations, const config & cfg, std::vector<attack_type> 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<unit_frame>
{
public:
explicit crude_animation(int start_time=0):animated<unit_frame>(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<config> secondary_attack_filter_;
std::vector<hit_type> hits_;
std::vector<int> swing_num_;
crude_animation missile_anim_;
std::map<std::string,crude_animation> sub_anims_;
crude_animation unit_anim_;
};

View file

@ -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<unit_frame> 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<int>(start_time,defender.get_animation()->get_begin_time());
start_time = minimum<int>(start_time,missile_animation.get_begin_time());
start_time = minimum<int>(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);

View file

@ -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 "<<id<<")\n";
@ -627,13 +628,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
experience_needed_=lexical_cast_default<int>(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.