quick fix for the animation glitch

(sub frames not being synchronised) proper fix to come later...
This commit is contained in:
Jérémy Rosen 2007-12-31 12:46:49 +00:00
parent ef2cc5dacf
commit 9ff5682180
11 changed files with 53 additions and 48 deletions

View File

@ -1383,13 +1383,13 @@ attack::attack(game_display& gui, const gamemap& map,
}
if(a_ != units.end()) {
a_->second.set_standing(gui_,a_->first);
a_->second.set_standing(a_->first);
if(attackerxp_)
a_->second.get_experience(attackerxp_);
}
if(d_ != units.end()) {
d_->second.set_standing(gui_,d_->first);
d_->second.set_standing(d_->first);
if(defenderxp_)
d_->second.get_experience(defenderxp_);
}

View File

@ -532,7 +532,7 @@ gamemap::location ai_interface::move_unit_partial(location from, location to,
p->first = to;
info_.units.add(p);
p->second.set_standing(info_.disp,p->first);
p->second.set_standing(p->first);
if(info_.map.is_village(to)) {
// If a new village is captured, disallow any future movement.
if (!info_.teams[info_.team_num-1].owns_village(to))

View File

@ -191,7 +191,7 @@ bool animate_unit_advancement(const game_data& info,unit_map& units, gamemap::lo
animator.add_animation(&u->second,"levelin",u->first);
animator.start_animations();
animator.wait_for_end();
u->second.set_standing(gui,u->first);
u->second.set_standing(u->first);
gui.invalidate(loc);
gui.draw();
events::pump();

View File

@ -2358,7 +2358,7 @@ bool event_handler::handle_event_command(const queued_event& event_info,
animator.add_animation(&u->second,cfg["flag"],u->first);
animator.start_animations();
animator.wait_for_end();
u->second.set_standing(*screen,u->first);
u->second.set_standing(u->first);
screen->invalidate(u->first);
screen->draw();
events::pump();

View File

@ -1291,7 +1291,7 @@ private:
up->second.set_movement(starting_moves);
up->first = route.back();
units_.add(up);
up->second.set_standing(*gui_,up->first);
up->second.set_standing(up->first);
gui_->invalidate(route.back());
gui_->draw();
}
@ -1414,7 +1414,7 @@ private:
up->second.set_movement(starting_moves);
up->first = route.back();
units_.add(up);
up->second.set_standing(*gui_,up->first);
up->second.set_standing(up->first);
if(map_.is_village(route.back())) {
get_village(route.back(),*gui_,teams_,up->second.side()-1,units_);

View File

@ -997,7 +997,7 @@ bool do_replay(game_display& disp, const gamemap& map, const game_data& gameinfo
//if unit has arrived to destination, goto variable is cleaned
up->second.set_goto(gamemap::location());
}
up->second.set_standing(disp,up->first);
up->second.set_standing(up->first);
u = units.find(dst);
check_checksums(disp,units,*cfg);
// Get side now, in case game events change the unit.

View File

@ -1531,36 +1531,30 @@ const surface unit::still_image(bool scaled) const
return unit_image;
}
void unit::set_standing(const game_display &disp,const gamemap::location& loc, bool with_bars)
void unit::set_standing(const gamemap::location& loc, bool with_bars)
{
start_animation(disp,loc,choose_animation(disp,loc,"standing"),with_bars,true,"",0,STATE_STANDING);
const game_display * disp = game_display::get_singleton();
start_animation(INT_MAX,loc,choose_animation(*disp,loc,"standing"),with_bars,true,"",0,STATE_STANDING);
}
void unit::set_walking(const game_display &disp,const gamemap::location& loc)
{
if(state_ == STATE_ANIM && anim_ != NULL && anim_->matches(disp,loc,this,"movement") >unit_animation::MATCH_FAIL) {
return; // finish current animation, don't start a new one
// is this the right behaviour ? we might not want that anymore
}
start_animation(disp,loc,choose_animation(disp,loc,"movement"),false);
}
void unit::set_idling(const game_display &disp,const gamemap::location& loc)
{
start_animation(disp,loc,choose_animation(disp,loc,"idling"),true,true,"",0,STATE_FORGET);
start_animation(INT_MAX,loc,choose_animation(disp,loc,"idling"),true,true,"",0,STATE_FORGET);
}
void unit::set_selecting(const game_display &disp,const gamemap::location& loc)
{
start_animation(disp,loc,choose_animation(disp,loc,"selected"),true,true,"",0,STATE_FORGET);
start_animation(INT_MAX,loc,choose_animation(disp,loc,"selected"),true,true,"",0,STATE_FORGET);
}
void unit::start_animation(const game_display &disp, const gamemap::location &loc,const unit_animation * animation,bool with_bars,bool cycles,const std::string text, const Uint32 text_color,STATE state)
void unit::start_animation(const int start_time, const gamemap::location &loc,const unit_animation * animation,bool with_bars,bool cycles,const std::string text, const Uint32 text_color,STATE state)
{
const game_display * disp = game_display::get_singleton();
if(!animation) {
set_standing(disp,loc,with_bars);
set_standing(loc,with_bars);
return ;
}
state_ =state;
@ -1568,21 +1562,17 @@ 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(),loc, loc.get_direction(facing_), cycles,text,text_color, disp.turbo_speed());
const int real_start_time = start_time == INT_MAX ? anim_->get_begin_time() : start_time;
anim_->start_animation(real_start_time,loc, loc.get_direction(facing_), cycles,text,text_color, disp->turbo_speed());
frame_begin_time_ = anim_->get_begin_time() -1;
if (disp.idle_anim()) {
if (disp->idle_anim()) {
next_idling_ = get_current_animation_tick()
+ static_cast<int>((20000 + rand() % 20000) * disp.idle_anim_rate());
+ static_cast<int>((20000 + rand() % 20000) * disp->idle_anim_rate());
} else {
next_idling_ = INT_MAX;
}
}
void unit::restart_animation(const game_display& disp,int start_time, bool cycles) {
if(!anim_) return;
anim_->start_animation(start_time,gamemap::location::null_location, gamemap::location::null_location, cycles, "",0,disp.turbo_speed());
frame_begin_time_ = start_time -1;
}
void unit::set_facing(gamemap::location::DIRECTION dir) {
if(dir != gamemap::location::NDIRECTIONS) {
@ -1626,7 +1616,7 @@ void unit::redraw_unit(game_display& disp, const gamemap::location& loc)
const int ysrc_adjusted = ysrc - height_adjust;
if(!anim_) {
set_standing(disp,loc);
set_standing(loc);
}
anim_->update_last_draw_time();

View File

@ -128,12 +128,12 @@ public:
//! Called on every draw
void refresh(const game_display& disp,const gamemap::location& loc) {
if (state_ == STATE_FORGET && anim_ && anim_->animation_would_finish()) {
set_standing(disp, loc);
set_standing( loc);
return;
}
if (state_ != STATE_STANDING || incapacitated() || (get_current_animation_tick() < next_idling_)) return;
if (get_current_animation_tick() > next_idling_ + 1000) { // prevent all units animating at the same
set_standing(disp,loc);
set_standing(loc);
} else {
set_idling(disp, loc);
}
@ -177,11 +177,9 @@ public:
void clear_haloes();
void set_standing(const game_display& disp,const gamemap::location& loc, bool with_bars = true);
void set_walking(const game_display& disp,const gamemap::location& loc);
void set_standing(const gamemap::location& loc, bool with_bars = true);
void set_idling(const game_display& disp,const gamemap::location& loc);
void set_selecting(const game_display& disp,const gamemap::location& loc);
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);
@ -234,7 +232,7 @@ public:
//! States for animation.
enum STATE { STATE_STANDING, STATE_FORGET, STATE_ANIM};
void start_animation(const game_display &disp, const gamemap::location &loc,const unit_animation* animation, bool with_bars,bool cycles=false,const std::string text = "", const Uint32 text_color =0,STATE state = STATE_ANIM);
void start_animation(const int start_time , const gamemap::location &loc,const unit_animation* animation, bool with_bars,bool cycles=false,const std::string text = "", const Uint32 text_color =0,STATE state = STATE_ANIM);
//! The name of the file to game_display (used in menus).
const std::string& absolute_image() const { return cfg_["image"]; }

View File

@ -370,6 +370,7 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
(**anim_itor)["value"]=(**anim_itor)["healing"];
animations.push_back(unit_animation(**anim_itor));
animations.back().sub_anims_["_healed_sound"] = crude_animation();
animations.back().sub_anims_["_healed_sound"].add_frame(1,unit_frame());
animations.back().sub_anims_["_healed_sound"].add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","","heal.wav"),true);
//lg::wml_error<<"healed animations are deprecate, support will be removed in 1.3.11 (in unit "<<cfg["name"]<<")\n";
//lg::wml_error<<"please put it with an [animation] tag and apply_to=healed flag\n";
@ -383,6 +384,7 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
(**anim_itor)["value"]=(**anim_itor)["damage"];
animations.push_back(unit_animation(**anim_itor));
animations.back().sub_anims_["_poison_sound"] = crude_animation();
animations.back().sub_anims_["_poison_sound"].add_frame(1,unit_frame());
animations.back().sub_anims_["_poison_sound"].add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","","poison.ogg"),true);
//lg::wml_error<<"poison animations are deprecate, support will be removed in 1.3.11 (in unit "<<cfg["name"]<<")\n";
//lg::wml_error<<"please put it with an [animation] tag and apply_to=poison flag\n";
@ -455,6 +457,7 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
animations.back().add_frame(600,unit_frame(image_loc,600,"1~0:600"));
if(!cfg["die_sound"].empty()) {
animations.back().sub_anims_["_death_sound"] = crude_animation();
animations.back().sub_anims_["_death_sound"].add_frame(1,unit_frame());
animations.back().sub_anims_["_death_sound"].add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","",cfg["die_sound"]),true);
}
//lg::wml_error<<"death animations are deprecate, support will be removed in 1.3.11 (in unit "<<cfg["name"]<<")\n";
@ -463,6 +466,7 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),600,"1~0:600"),"death",unit_animation::DEFAULT_ANIM));
if(!cfg["die_sound"].empty()) {
animations.back().sub_anims_["_death_sound"] = crude_animation();
animations.back().sub_anims_["_death_sound"].add_frame(1,unit_frame());
animations.back().sub_anims_["_death_sound"].add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","",cfg["die_sound"]),true);
}
// Always have a defensive animation
@ -660,6 +664,7 @@ void unit_animation::start_animation(int start_time,const gamemap::location &src
unit_anim_.start_animation(start_time, src, dst, cycles,acceleration);
if(!text.empty()) {
crude_animation crude_build;
crude_build.add_frame(1,unit_frame());
crude_build.add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","","",text,text_color),true);
sub_anims_["_add_text"] = crude_build;
}
@ -700,8 +705,8 @@ void unit_animation::crude_animation::redraw()
(current_frame.text().second & 0x0000FF00) >> 8,
(current_frame.text().second & 0x000000FF) >> 0);
}
last_frame_begin_time_ = get_current_frame_begin_time();
}
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();
@ -835,10 +840,9 @@ void unit_animator::replace_anim_if_invalid(unit* animated_unit,const std::strin
}
void unit_animator::start_animations()
{
game_display*disp = game_display::get_singleton();
for(std::vector<anim_elem>::iterator anim = animated_units_.begin(); anim != animated_units_.end();anim++) {
if(anim->animation) {
anim->my_unit->start_animation(*disp,anim->src, anim->animation,anim->with_bars, anim->cycles,anim->text,anim->text_color);
anim->my_unit->start_animation(get_begin_time(),anim->src, anim->animation,anim->with_bars, anim->cycles,anim->text,anim->text_color);
anim->animation = NULL;
}
@ -886,7 +890,19 @@ int unit_animator::get_end_time() const
{
int end_time = INT_MIN;
for(std::vector<anim_elem>::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();anim++) {
if(anim->my_unit->get_animation()) {
end_time = maximum<int>(end_time,anim->my_unit->get_animation()->get_end_time());
}
}
return end_time;
}
int unit_animator::get_begin_time() const
{
int begin_time = INT_MAX;
for(std::vector<anim_elem>::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();anim++) {
if(anim->my_unit->get_animation()) {
begin_time = minimum<int>(begin_time,anim->my_unit->get_animation()->get_begin_time());
}
}
return begin_time;
}

View File

@ -157,6 +157,7 @@ class unit_animator
bool would_end() const;
int get_animation_time() const;
int get_end_time() const;
int get_begin_time() const;
void wait_for_end() const;
void wait_until( int animation_time) const;
private:

View File

@ -59,7 +59,7 @@ static void teleport_unit_between( const gamemap::location& a, const gamemap::lo
animator.start_animations();
animator.wait_for_end();
}
temp_unit.set_standing(*disp,b);
temp_unit.set_standing(b);
disp->update_display();
events::pump();
}
@ -145,7 +145,7 @@ void move_unit(const std::vector<gamemap::location>& path, unit& u, const std::v
}
disp->remove_temporary_unit();
u.set_facing(path[path.size()-2].get_relative_dir(path[path.size()-1]));
u.set_standing(*disp,path[path.size()-1]);
u.set_standing(path[path.size()-1]);
// Clean the footsteps path, its hexes will be invalidated if needed
disp->set_route(NULL);
@ -239,9 +239,9 @@ void unit_attack(
animator.start_animations();
animator.wait_for_end();
if(leader_loc.valid()) leader->second.set_standing(*disp,leader_loc);
att->second.set_standing(*disp,a);
def->second.set_standing(*disp,b);
if(leader_loc.valid()) leader->second.set_standing(leader_loc);
att->second.set_standing(a);
def->second.set_standing(b);
}
@ -260,7 +260,7 @@ void unit_recruited(gamemap::location& loc)
animator.add_animation(&u->second,"recruited",loc);
animator.start_animations();
animator.wait_for_end();
u->second.set_standing(*disp,loc);
u->second.set_standing(loc);
if (loc==disp->mouseover_hex()) disp->invalidate_unit();
}
@ -286,9 +286,9 @@ void unit_healing(unit& healed,gamemap::location& healed_loc, std::vector<unit_m
animator.start_animations();
animator.wait_for_end();
healed.set_standing(*disp,healed_loc);
healed.set_standing(healed_loc);
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)->first);
(*heal_sanim_it)->second.set_standing((*heal_sanim_it)->first);
}
}