first go at the new animation API, still a WIP.
No regression expected. if anything changes, please tell me. Note that: * Fire and forget doesn't work yet, don't try using it * I will probably change how mvt anims work as discussed in IRC, but that's for a future commit
This commit is contained in:
parent
38bad0370e
commit
5aba45d829
12 changed files with 297 additions and 328 deletions
|
@ -26,6 +26,8 @@ Version 1.3.12+svn:
|
|||
full heal (+25% max xp)
|
||||
* gave the Necrophage a feeding ability, giving it +1 max HP for every living
|
||||
enemy killed
|
||||
* a floating text can now be specified within animation frames using the
|
||||
text= and text_color= keys
|
||||
* sound:
|
||||
* new or improved sounds: ogre hit and die
|
||||
* User interface
|
||||
|
|
|
@ -83,7 +83,11 @@ public:
|
|||
static const T void_value_; //MSVC: the frame constructor below requires this to be public
|
||||
|
||||
protected:
|
||||
friend class unit_animation;
|
||||
int starting_frame_time_;
|
||||
// backward compatibility for teleport anims
|
||||
void remove_frames_until(int starting_time);
|
||||
void remove_frames_after(int ending_time);
|
||||
|
||||
private:
|
||||
struct frame
|
||||
|
|
|
@ -284,4 +284,26 @@ int animated<T,T_void_value>::get_end_time() const
|
|||
return starting_frame_time_;
|
||||
return frames_.back().start_time_ + frames_.back().duration_;
|
||||
}
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::remove_frames_until(int new_starting_time)
|
||||
{
|
||||
while (starting_frame_time_ < new_starting_time && !frames_.empty() ) {
|
||||
starting_frame_time_ += frames_[0].duration_;
|
||||
frames_.erase(frames_.begin());
|
||||
}
|
||||
|
||||
}
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::remove_frames_after(int new_ending_time)
|
||||
{
|
||||
int last_start_time = starting_frame_time_;
|
||||
typename std::vector<frame>::iterator current_frame = frames_.begin();
|
||||
while (last_start_time < new_ending_time && current_frame != frames_.end()) {
|
||||
last_start_time += current_frame->duration_;
|
||||
current_frame++;
|
||||
}
|
||||
frames_.erase(current_frame,frames_.end());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -159,13 +159,10 @@ bool animate_unit_advancement(const game_data& info,unit_map& units, gamemap::lo
|
|||
// to the new unit, then fades back to the normal colour
|
||||
|
||||
if(!gui.video().update_locked()) {
|
||||
u->second.set_leveling_out(gui,u->first);
|
||||
while(!u->second.get_animation()->animation_would_finish()) {
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
events::pump();
|
||||
gui.delay(10);
|
||||
}
|
||||
unit_animator animator;
|
||||
animator.add_animation(&u->second,"levelout",u->first);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
}
|
||||
|
||||
if(choice < options.size()) {
|
||||
|
@ -189,13 +186,10 @@ bool animate_unit_advancement(const game_data& info,unit_map& units, gamemap::lo
|
|||
gui.invalidate_unit();
|
||||
|
||||
if(u != units.end() && !gui.video().update_locked()) {
|
||||
u->second.set_leveling_in(gui,u->first);
|
||||
while(!u->second.get_animation()->animation_would_finish()) {
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
events::pump();
|
||||
gui.delay(10);
|
||||
}
|
||||
unit_animator animator;
|
||||
animator.add_animation(&u->second,"levelin",u->first);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
u->second.set_standing(gui,u->first);
|
||||
gui.invalidate(loc);
|
||||
gui.draw();
|
||||
|
|
|
@ -2238,16 +2238,11 @@ bool event_handler::handle_event_command(const queued_event& event_info,
|
|||
|
||||
// We have found a unit that matches the filter
|
||||
if(u != units->end() && ! screen->fogged(u->first)) {
|
||||
screen->highlight_hex(u->first);
|
||||
screen->scroll_to_tile(u->first);
|
||||
|
||||
u->second.set_extra_anim(*screen,u->first,cfg["flag"]);
|
||||
while(!u->second.get_animation()->animation_would_finish()) {
|
||||
screen->invalidate(u->first);
|
||||
screen->draw();
|
||||
events::pump();
|
||||
screen->delay(10);
|
||||
}
|
||||
unit_animator animator;
|
||||
animator.add_animation(&u->second,cfg["flag"],u->first);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
u->second.set_standing(*screen,u->first);
|
||||
screen->invalidate(u->first);
|
||||
screen->draw();
|
||||
|
|
113
src/unit.cpp
113
src/unit.cpp
|
@ -1520,131 +1520,42 @@ const surface unit::still_image(bool scaled) const
|
|||
|
||||
void unit::set_standing(const game_display &disp,const gamemap::location& loc, bool with_bars)
|
||||
{
|
||||
state_ = STATE_STANDING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"standing"),with_bars,true);
|
||||
}
|
||||
void unit::set_defending(const game_display &disp,const gamemap::location& loc, int damage,const attack_type* attack,const attack_type* secondary_attack,int swing_num)
|
||||
{
|
||||
state_ = STATE_DEFENDING;
|
||||
|
||||
unit_animation::hit_type hit_type;
|
||||
if(damage >= hitpoints()) {
|
||||
hit_type = unit_animation::KILL;
|
||||
} else if(damage > 0) {
|
||||
hit_type = unit_animation::HIT;
|
||||
}else {
|
||||
hit_type = unit_animation::MISS;
|
||||
}
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"defend",damage,hit_type,attack,secondary_attack,swing_num),true);
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"standing"),with_bars,true,"",0,STATE_STANDING);
|
||||
}
|
||||
|
||||
void unit::set_extra_anim(const game_display &disp,const gamemap::location& loc, std::string flag)
|
||||
{
|
||||
state_ = STATE_EXTRA;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,flag),false);
|
||||
|
||||
}
|
||||
|
||||
void unit::set_attacking(const game_display &disp,const gamemap::location& loc,int damage,const attack_type& type,const attack_type* secondary_attack,int swing_num)
|
||||
{
|
||||
state_ = STATE_ATTACKING;
|
||||
unit_animation::hit_type hit_type;
|
||||
if(damage >= hitpoints()) {
|
||||
hit_type = unit_animation::KILL;
|
||||
} else if(damage > 0) {
|
||||
hit_type = unit_animation::HIT;
|
||||
}else {
|
||||
hit_type = unit_animation::MISS;
|
||||
}
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"attack",damage,hit_type,&type,secondary_attack,swing_num),true);
|
||||
|
||||
}
|
||||
void unit::set_leading(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEADING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"leading"),true);
|
||||
}
|
||||
void unit::set_leveling_in(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEVELIN;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"levelin"),false);
|
||||
}
|
||||
void unit::set_leveling_out(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_LEVELOUT;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"levelout"),false);
|
||||
}
|
||||
void unit::set_recruited(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_RECRUITED;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"recruited"),false);
|
||||
}
|
||||
void unit::set_healed(const game_display &disp,const gamemap::location& loc, int healing)
|
||||
{
|
||||
state_ = STATE_HEALED;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"healed",healing),true);
|
||||
}
|
||||
void unit::set_poisoned(const game_display &disp,const gamemap::location& loc, int damage)
|
||||
{
|
||||
state_ = STATE_POISONED;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"poisoned",damage),true);
|
||||
}
|
||||
|
||||
void unit::set_teleporting(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_TELEPORT;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"teleport"),false);
|
||||
}
|
||||
|
||||
void unit::set_dying(const game_display &disp,const gamemap::location& loc,const attack_type* attack,const attack_type* secondary_attack)
|
||||
{
|
||||
state_ = STATE_DYING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"death",0,unit_animation::KILL,attack,secondary_attack),false);
|
||||
}
|
||||
void unit::set_healing(const game_display &disp,const gamemap::location& loc,int healing)
|
||||
{
|
||||
state_ = STATE_HEALING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"healing",healing),true);
|
||||
}
|
||||
void unit::set_victorious(const game_display &disp,const gamemap::location& loc,const attack_type* attack,const attack_type* secondary_attack)
|
||||
{
|
||||
state_ = STATE_VICTORIOUS;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"victory",0,unit_animation::KILL,attack,secondary_attack),true);
|
||||
}
|
||||
|
||||
void unit::set_walking(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
if(state_ == STATE_WALKING && anim_ != NULL && anim_->matches(disp,loc,this,"movement") >unit_animation::MATCH_FAIL) {
|
||||
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
|
||||
}
|
||||
state_ = STATE_WALKING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"movement"),false);
|
||||
}
|
||||
|
||||
|
||||
void unit::set_idling(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_IDLING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"idling"),true);
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"idling"),true,true,"",0,STATE_FORGET);
|
||||
}
|
||||
|
||||
void unit::set_selecting(const game_display &disp,const gamemap::location& loc)
|
||||
{
|
||||
state_ = STATE_SELECTING;
|
||||
start_animation(disp,loc,choose_animation(disp,loc,"selected"),true);
|
||||
start_animation(disp,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)
|
||||
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)
|
||||
{
|
||||
if(!animation) {
|
||||
set_standing(disp,loc,with_bars);
|
||||
return ;
|
||||
}
|
||||
state_ =state;
|
||||
draw_bars_ = with_bars;
|
||||
offset_=0;
|
||||
if(anim_) delete anim_;
|
||||
anim_ = new unit_animation(*animation);
|
||||
anim_->start_animation(anim_->get_begin_time(),loc, loc.get_direction(facing_), cycles, disp.turbo_speed());
|
||||
anim_->start_animation(anim_->get_begin_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()) {
|
||||
next_idling_ = get_current_animation_tick()
|
||||
|
@ -1656,7 +1567,7 @@ void unit::start_animation(const game_display &disp, const gamemap::location &lo
|
|||
|
||||
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, disp.turbo_speed());
|
||||
anim_->start_animation(start_time,gamemap::location::null_location, gamemap::location::null_location, cycles, "",0,disp.turbo_speed());
|
||||
frame_begin_time_ = start_time -1;
|
||||
}
|
||||
|
||||
|
@ -1711,6 +1622,12 @@ void unit::redraw_unit(game_display& disp, const gamemap::location& loc)
|
|||
if(!anim_->sound().empty()) {
|
||||
sound::play_sound(anim_->sound());
|
||||
}
|
||||
if(!anim_->text().first.empty() ) {
|
||||
game_display::get_singleton()->float_label(loc,anim_->text().first,
|
||||
(anim_->text().second & 0x00FF0000) >> 16,
|
||||
(anim_->text().second & 0x0000FF00) >> 8,
|
||||
(anim_->text().second & 0x000000FF) >> 0);
|
||||
}
|
||||
}
|
||||
|
||||
double tmp_offset = anim_->offset(offset_);
|
||||
|
|
24
src/unit.hpp
24
src/unit.hpp
|
@ -124,7 +124,7 @@ public:
|
|||
void new_level();
|
||||
//! Called on every draw
|
||||
void refresh(const game_display& disp,const gamemap::location& loc) {
|
||||
if ((state_ == STATE_IDLING || state_ == STATE_SELECTING) && anim_ && anim_->animation_would_finish()) {
|
||||
if (state_ == STATE_FORGET && anim_ && anim_->animation_would_finish()) {
|
||||
set_standing(disp, loc);
|
||||
return;
|
||||
}
|
||||
|
@ -175,20 +175,7 @@ public:
|
|||
|
||||
|
||||
void set_standing(const game_display& disp,const gamemap::location& loc, bool with_bars = true);
|
||||
void set_defending(const game_display &disp,const gamemap::location& loc, int damage,const attack_type* attack,const attack_type* secondary_attack,int swing_num);
|
||||
void set_leading(const game_display& disp,const gamemap::location& loc);
|
||||
void set_healing(const game_display& disp,const gamemap::location& loc,int damage);
|
||||
void set_leveling_in(const game_display& disp,const gamemap::location& loc);
|
||||
void set_leveling_out(const game_display& disp,const gamemap::location& loc);
|
||||
void set_teleporting (const game_display& disp,const gamemap::location& loc);
|
||||
void set_extra_anim(const game_display& disp,const gamemap::location& loc, std::string flag);
|
||||
void set_dying(const game_display &disp,const gamemap::location& loc,const attack_type* attack,const attack_type* secondary_attack);
|
||||
void set_walking(const game_display& disp,const gamemap::location& loc);
|
||||
void set_attacking( const game_display &disp,const gamemap::location& loc,int damage,const attack_type& type,const attack_type* secondary_attack,int swing_num);
|
||||
void set_recruited(const game_display& disp,const gamemap::location& loc);
|
||||
void set_healed(const game_display& disp,const gamemap::location& loc,int healing);
|
||||
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 set_selecting(const game_display& disp,const gamemap::location& loc);
|
||||
void restart_animation(const game_display& disp,int start_time, bool cycles = false);
|
||||
|
@ -244,13 +231,8 @@ public:
|
|||
void set_interrupted_move(const gamemap::location& interrupted_move) { interrupted_move_ = interrupted_move; }
|
||||
|
||||
//! States for animation.
|
||||
enum STATE { STATE_STANDING, STATE_ATTACKING, STATE_DEFENDING,
|
||||
STATE_LEADING, STATE_HEALING, STATE_WALKING,
|
||||
STATE_LEVELIN, STATE_LEVELOUT,
|
||||
STATE_DYING, STATE_EXTRA, STATE_TELEPORT,
|
||||
STATE_RECRUITED, STATE_HEALED, STATE_POISONED,
|
||||
STATE_IDLING, STATE_SELECTING, STATE_VICTORIOUS};
|
||||
void start_animation(const game_display &disp, const gamemap::location &loc,const unit_animation* animation, bool with_bars,bool cycles=false);
|
||||
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);
|
||||
|
||||
//! The name of the file to game_display (used in menus).
|
||||
const std::string& absolute_image() const { return cfg_["image"]; }
|
||||
|
|
|
@ -369,21 +369,25 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
|
|||
(**anim_itor)["apply_to"] ="healed";
|
||||
(**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(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";
|
||||
}
|
||||
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),240,"1.0","",display::rgb(255,255,255),"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30"),"healed",unit_animation::DEFAULT_ANIM));
|
||||
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),240,"1.0","",display::rgb(255,255,255),"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30","","","","","heal.wav"),"healed",unit_animation::DEFAULT_ANIM));
|
||||
// Always have a healed animation
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"poison_anim");
|
||||
const config::child_list& poison_anims = expanded_cfg.get_children("poison_anim");
|
||||
for(anim_itor = poison_anims.begin(); anim_itor != poison_anims.end(); ++anim_itor) {
|
||||
(**anim_itor)["apply_to"] ="poison";
|
||||
(**anim_itor)["apply_to"] ="poisoned";
|
||||
(**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(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";
|
||||
}
|
||||
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),240,"1.0","",display::rgb(0,255,0),"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30"),"poison",unit_animation::DEFAULT_ANIM));
|
||||
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),240,"1.0","",display::rgb(0,255,0),"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30","","","","","poison.ogg"),"poisoned",unit_animation::DEFAULT_ANIM));
|
||||
// Always have a poison animation
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"movement_anim");
|
||||
const config::child_list& movement_anims = expanded_cfg.get_children("movement_anim");
|
||||
|
@ -479,12 +483,17 @@ void unit_animation::initialize_anims( std::vector<unit_animation> & animations,
|
|||
expanded_cfg = unit_animation::prepare_animation(cfg,"teleport_anim");
|
||||
const config::child_list& teleports = expanded_cfg.get_children("teleport_anim");
|
||||
for(anim_itor = teleports.begin(); anim_itor != teleports.end(); ++anim_itor) {
|
||||
(**anim_itor)["apply_to"] ="teleport";
|
||||
(**anim_itor)["apply_to"] ="pre_teleport";
|
||||
animations.push_back(unit_animation(**anim_itor));
|
||||
animations.back().unit_anim_.remove_frames_after(0);
|
||||
(**anim_itor)["apply_to"] ="post_teleport";
|
||||
animations.push_back(unit_animation(**anim_itor));
|
||||
animations.back().unit_anim_.remove_frames_until(0);
|
||||
//lg::wml_error<<"teleport 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=teleport flag\n";
|
||||
}
|
||||
if(with_default) animations.push_back(unit_animation(-20,unit_frame(image::locator(cfg["image"]),40),"teleport",unit_animation::DEFAULT_ANIM));
|
||||
if(with_default) animations.push_back(unit_animation(-150,unit_frame(image::locator(cfg["image"]),150,"1~0"),"pre_teleport",unit_animation::DEFAULT_ANIM));
|
||||
if(with_default) animations.push_back(unit_animation(0,unit_frame(image::locator(cfg["image"]),150,"0~1"),"post_teleport",unit_animation::DEFAULT_ANIM));
|
||||
// Always have a defensive animation
|
||||
|
||||
}
|
||||
|
@ -519,6 +528,11 @@ double unit_animation::crude_animation::offset(double default_val) const
|
|||
return get_current_frame().offset(get_current_frame_time(),offset_.get_current_element(get_animation_time() - get_begin_time(),default_val)) ;
|
||||
}
|
||||
|
||||
std::pair<std::string,Uint32> unit_animation::crude_animation::text() const
|
||||
{
|
||||
return get_current_frame().text();
|
||||
}
|
||||
|
||||
bool unit_animation::crude_animation::need_update() const
|
||||
{
|
||||
if(animated<unit_frame>::need_update()) return true;
|
||||
|
@ -568,7 +582,6 @@ unit_animation::crude_animation::crude_animation(
|
|||
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(!halo_.does_not_change() ||
|
||||
!halo_x_.does_not_change() ||
|
||||
!halo_y_.does_not_change() ||
|
||||
|
@ -638,9 +651,14 @@ int unit_animation::get_begin_time() const
|
|||
return result;
|
||||
}
|
||||
|
||||
void unit_animation::start_animation(int start_time,const gamemap::location &src, const gamemap::location &dst, bool cycles, double acceleration)
|
||||
void unit_animation::start_animation(int start_time,const gamemap::location &src, const gamemap::location &dst, bool cycles, const std::string text, const Uint32 text_color, double acceleration)
|
||||
{
|
||||
unit_anim_.start_animation(start_time, src, dst, cycles, acceleration);
|
||||
unit_anim_.start_animation(start_time, src, dst, cycles,acceleration);
|
||||
if(!text.empty()) {
|
||||
crude_animation crude_build;
|
||||
crude_build.add_frame(1,unit_frame(image::locator(),1,"","",0,"","","","","","",text,text_color),true);
|
||||
sub_anims_["_add_text"] = crude_build;
|
||||
}
|
||||
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);
|
||||
|
@ -648,6 +666,7 @@ void unit_animation::start_animation(int start_time,const gamemap::location &src
|
|||
}
|
||||
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();
|
||||
|
@ -666,8 +685,17 @@ void unit_animation::crude_animation::redraw()
|
|||
|
||||
update_last_draw_time();
|
||||
const unit_frame& current_frame= get_current_frame();
|
||||
if(!current_frame.sound().empty() && get_current_frame_begin_time() != last_frame_begin_time_ ) {
|
||||
if(get_current_frame_begin_time() != last_frame_begin_time_ ) {
|
||||
// stuff sthat should be done only once per frame
|
||||
if(!current_frame.sound().empty() ) {
|
||||
sound::play_sound(current_frame.sound());
|
||||
}
|
||||
if(!current_frame.text().first.empty() ) {
|
||||
game_display::get_singleton()->float_label(src_,current_frame.text().first,
|
||||
(current_frame.text().second & 0x00FF0000) >> 16,
|
||||
(current_frame.text().second & 0x0000FF00) >> 8,
|
||||
(current_frame.text().second & 0x000000FF) >> 0);
|
||||
}
|
||||
}
|
||||
last_frame_begin_time_ = get_current_frame_begin_time();
|
||||
image::locator image_loc;
|
||||
|
@ -752,4 +780,87 @@ void unit_animation::crude_animation::start_animation(int start_time,
|
|||
src_ = src;
|
||||
dst_ = dst;
|
||||
}
|
||||
};
|
||||
|
||||
void unit_animator::add_animation(unit* animated_unit,const std::string& event,
|
||||
const gamemap::location &src , const int value,bool with_bars,bool cycles,
|
||||
const std::string text,const Uint32 text_color,
|
||||
const unit_animation::hit_type hit_type,
|
||||
const attack_type* attack, const attack_type* second_attack, int swing_num)
|
||||
{
|
||||
if(!animated_unit) return;
|
||||
anim_elem tmp;
|
||||
game_display*disp = game_display::get_singleton();
|
||||
tmp.my_unit = animated_unit;
|
||||
tmp.text = text;
|
||||
tmp.text_color = text_color;
|
||||
tmp.src = src;
|
||||
tmp.with_bars= with_bars;
|
||||
tmp.cycles = cycles;
|
||||
tmp.animation = animated_unit->choose_animation(*disp,src,event,value,hit_type,attack,second_attack,swing_num);
|
||||
if(!tmp.animation) return;
|
||||
|
||||
|
||||
|
||||
start_time_ = maximum<int>(start_time_,tmp.animation->get_begin_time());
|
||||
animated_units_.push_back(tmp);
|
||||
}
|
||||
void unit_animator::replace_anim_if_invalid(unit* animated_unit,const std::string& event,
|
||||
const gamemap::location &src , const int value,bool with_bars,bool cycles,
|
||||
const std::string text,const Uint32 text_color,
|
||||
const unit_animation::hit_type hit_type,
|
||||
const attack_type* attack, const attack_type* second_attack, int swing_num)
|
||||
{
|
||||
if(!animated_unit) return;
|
||||
game_display*disp = game_display::get_singleton();
|
||||
if(animated_unit->get_animation() &&
|
||||
!animated_unit->get_animation()->animation_would_finish() &&
|
||||
animated_unit->get_animation()->matches(*disp,src,animated_unit,event,value,hit_type,attack,second_attack,swing_num) >unit_animation::MATCH_FAIL) {
|
||||
anim_elem tmp;
|
||||
tmp.my_unit = animated_unit;
|
||||
tmp.text = text;
|
||||
tmp.text_color = text_color;
|
||||
tmp.src = src;
|
||||
tmp.with_bars= with_bars;
|
||||
tmp.cycles = cycles;
|
||||
tmp.animation = NULL;
|
||||
animated_units_.push_back(tmp);
|
||||
}else {
|
||||
add_animation(animated_unit,event,src,value,with_bars,cycles,text,text_color,hit_type,attack,second_attack,swing_num);
|
||||
}
|
||||
}
|
||||
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->animation = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool unit_animator::would_end() const
|
||||
{
|
||||
bool finished = true;
|
||||
for(std::vector<anim_elem>::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();anim++) {
|
||||
finished &= anim->my_unit->get_animation()->animation_would_finish();
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
void unit_animator::wait_for_end() const
|
||||
{
|
||||
bool finished = false;
|
||||
game_display*disp = game_display::get_singleton();
|
||||
while(!finished) {
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
finished = true;
|
||||
for(std::vector<anim_elem>::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();anim++) {
|
||||
finished &= anim->my_unit->get_animation()->animation_would_finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ class unit_animation
|
|||
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);
|
||||
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, const std::string text="", const Uint32 text_color=0, double acceleration=1);
|
||||
const int get_current_frame_begin_time() const{ return unit_anim_.get_current_frame_begin_time() ; };
|
||||
void redraw();
|
||||
|
||||
|
@ -68,10 +68,11 @@ 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); };
|
||||
std::pair<std::string,Uint32> text() const { return unit_anim_.text() ; };
|
||||
private:
|
||||
static config prepare_animation(const config &cfg,const std::string animation_tag);
|
||||
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);
|
||||
explicit unit_animation(int start_time,const unit_frame &frame,const std::string& event="",const int variation=DEFAULT_ANIM);
|
||||
class crude_animation:public animated<unit_frame>
|
||||
{
|
||||
public:
|
||||
|
@ -98,6 +99,7 @@ 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;
|
||||
std::pair<std::string,Uint32> text() const ;
|
||||
void redraw( );
|
||||
void start_animation(int start_time,const gamemap::location& src,const gamemap::location& dst, bool cycles=false, double acceleration=1);
|
||||
private:
|
||||
|
@ -132,5 +134,41 @@ class unit_animation
|
|||
crude_animation unit_anim_;
|
||||
};
|
||||
|
||||
class unit_animator
|
||||
{
|
||||
public:
|
||||
unit_animator():start_time_(INT_MIN){};
|
||||
void add_animation(unit* animated_unit,const std::string& event,
|
||||
const gamemap::location &src = gamemap::location::null_location,
|
||||
const int value=0,bool with_bars = false,bool cycles = false,
|
||||
const std::string text="",const Uint32 text_color=0,
|
||||
const unit_animation::hit_type hit_type = unit_animation::INVALID,
|
||||
const attack_type* attack=NULL, const attack_type* second_attack = NULL,
|
||||
int swing_num =0);
|
||||
void replace_anim_if_invalid(unit* animated_unit,const std::string& event,
|
||||
const gamemap::location &src = gamemap::location::null_location,
|
||||
const int value=0,bool with_bars = false,bool cycles = false,
|
||||
const std::string text="",const Uint32 text_color=0,
|
||||
const unit_animation::hit_type hit_type = unit_animation::INVALID,
|
||||
const attack_type* attack=NULL, const attack_type* second_attack = NULL,
|
||||
int swing_num =0);
|
||||
void start_animations();
|
||||
void empty(){start_time_ = INT_MIN ; animated_units_.clear();};
|
||||
|
||||
|
||||
bool would_end() const;
|
||||
void wait_for_end() const;
|
||||
private:
|
||||
typedef struct {
|
||||
unit *my_unit;
|
||||
const unit_animation * animation;
|
||||
std::string text;
|
||||
Uint32 text_color;
|
||||
gamemap::location src;
|
||||
bool with_bars;
|
||||
bool cycles;
|
||||
} anim_elem;
|
||||
std::vector<anim_elem> animated_units_;
|
||||
int start_time_;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -42,28 +42,22 @@ static void teleport_unit_between( const gamemap::location& a, const gamemap::lo
|
|||
if(!disp || disp->video().update_locked() || disp->fogged(a) && disp->fogged(b)) {
|
||||
return;
|
||||
}
|
||||
disp->scroll_to_tiles(a,b,game_display::ONSCREEN,true);
|
||||
|
||||
temp_unit.set_teleporting(*disp,a);
|
||||
if (!disp->fogged(a)) { // teleport
|
||||
disp->scroll_to_tile(a,game_display::ONSCREEN);
|
||||
while(!temp_unit.get_animation()->animation_finished() && temp_unit.get_animation()->get_animation_time() < 0) {
|
||||
disp->invalidate(a);
|
||||
disp->place_temporary_unit(temp_unit, a);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
}
|
||||
disp->place_temporary_unit(temp_unit,a);
|
||||
unit_animator animator;
|
||||
animator.add_animation(&temp_unit,"pre_teleport",a);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
}
|
||||
if (!disp->fogged(b)) { // teleport
|
||||
temp_unit.restart_animation(*disp,0);
|
||||
disp->scroll_to_tile(b,game_display::ONSCREEN);
|
||||
while(!temp_unit.get_animation()->animation_finished()) {
|
||||
disp->invalidate(b);
|
||||
disp->place_temporary_unit(temp_unit, b);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
}
|
||||
disp->place_temporary_unit(temp_unit,b);
|
||||
disp->scroll_to_tiles(b,a,game_display::ONSCREEN,true);
|
||||
unit_animator animator;
|
||||
animator.add_animation(&temp_unit,"post_teleport",b);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
}
|
||||
temp_unit.set_standing(*disp,b);
|
||||
disp->update_display();
|
||||
|
@ -72,6 +66,9 @@ static void teleport_unit_between( const gamemap::location& a, const gamemap::lo
|
|||
|
||||
static void move_unit_between( const gamemap& map, const gamemap::location& a, const gamemap::location& b, unit& temp_unit)
|
||||
{
|
||||
//NOTES TO SELF (boucman)
|
||||
// get rid of speed dependant gliding
|
||||
// add some sort of auto slide anyway
|
||||
game_display* disp = game_display::get_singleton();
|
||||
if(!disp || disp->video().update_locked() || disp->fogged(a) && disp->fogged(b)) {
|
||||
return;
|
||||
|
@ -91,13 +88,15 @@ static void move_unit_between( const gamemap& map, const gamemap::location& a, c
|
|||
int mvt_time = 1;
|
||||
|
||||
while(mvt_time < total_mvt_time-1) { // One draw in each hex at least
|
||||
unit_animator animator;
|
||||
disp->delay(10);
|
||||
mvt_time = SDL_GetTicks() -start_time;
|
||||
if(mvt_time >=total_mvt_time) mvt_time = total_mvt_time -1;
|
||||
double pos =double(mvt_time)/total_mvt_time;
|
||||
const gamemap::location& ref_loc =pos<0.5?a:b;
|
||||
if(pos >= 0.5) pos = pos -1;
|
||||
temp_unit.set_walking(*disp,ref_loc);
|
||||
animator.replace_anim_if_invalid(&temp_unit,"movement",ref_loc);
|
||||
animator.start_animations();
|
||||
temp_unit.set_offset(pos);
|
||||
disp->place_temporary_unit(temp_unit,ref_loc);
|
||||
disp->draw();
|
||||
|
@ -181,32 +180,13 @@ void unit_die(const gamemap::location& loc, unit& loser,
|
|||
if(!disp ||disp->video().update_locked() || disp->fogged(loc) || preferences::show_combat() == false) {
|
||||
return;
|
||||
}
|
||||
unit_animator animator;
|
||||
animator.add_animation(&loser,"death",loc,0,false,false,"",0,unit_animation::KILL,attack,secondary_attack,0);
|
||||
animator.add_animation(winner,"victory",loc.get_direction(loser.facing()),0,false,false,"",0,
|
||||
unit_animation::KILL,secondary_attack,attack,0);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
|
||||
loser.set_dying(*disp,loc,attack,secondary_attack);
|
||||
if(winner == NULL) { // Test to see if there is no victor.
|
||||
|
||||
while(!loser.get_animation()->animation_finished()) {
|
||||
|
||||
disp->invalidate(loc);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
}
|
||||
return;
|
||||
}
|
||||
winner->set_victorious(*disp,loc,attack,secondary_attack);
|
||||
int start_time = minimum<int>(loser.get_animation()->get_begin_time(),winner->get_animation()->get_begin_time());
|
||||
|
||||
winner->restart_animation(*disp,start_time);
|
||||
loser.restart_animation(*disp,start_time);
|
||||
|
||||
while((!loser.get_animation()->animation_would_finish()) || ((!winner->get_animation()->animation_would_finish()))) {
|
||||
|
||||
disp->invalidate(loc);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,91 +214,53 @@ void unit_attack(
|
|||
|
||||
const unit_map::iterator def = units.find(b);
|
||||
assert(def != units.end());
|
||||
unit& defender = def->second;
|
||||
|
||||
att->second.set_facing(a.get_relative_dir(b));
|
||||
def->second.set_facing(b.get_relative_dir(a));
|
||||
|
||||
int start_time = 500;
|
||||
int end_time = 0;
|
||||
|
||||
bool def_was_hidden = def->second.get_hidden();
|
||||
def->second.set_hidden(true);
|
||||
unit defender = def->second;
|
||||
disp->place_temporary_unit(defender,b);
|
||||
defender.set_hidden(false);
|
||||
|
||||
|
||||
attacker.set_attacking(*disp,a,damage,attack,secondary_attack,swing);
|
||||
start_time=minimum<int>(start_time,attacker.get_animation()->get_begin_time());
|
||||
end_time=attacker.get_animation()->get_end_time();
|
||||
|
||||
defender.set_defending(*disp,b,damage,&attack, secondary_attack, swing);
|
||||
start_time=minimum<int>(start_time,defender.get_animation()->get_begin_time());
|
||||
|
||||
|
||||
unit_animator animator;
|
||||
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);
|
||||
assert(leader != units.end());
|
||||
leader->second.set_facing(leader_loc.get_relative_dir(a));
|
||||
leader->second.set_leading(*disp,leader_loc);
|
||||
start_time=minimum<int>(start_time,leader->second.get_animation()->get_begin_time());
|
||||
|
||||
{
|
||||
std::string text ;
|
||||
if(damage) text = lexical_cast<std::string>(damage);
|
||||
if(!hit_text.empty()) {
|
||||
text.insert(text.begin(),hit_text.size()/2,' ');
|
||||
text = text + "\n" + hit_text;
|
||||
}
|
||||
|
||||
unit_animation::hit_type hit_type;
|
||||
if(damage >= defender.hitpoints()) {
|
||||
hit_type = unit_animation::KILL;
|
||||
} else if(damage > 0) {
|
||||
hit_type = unit_animation::HIT;
|
||||
}else {
|
||||
hit_type = unit_animation::MISS;
|
||||
}
|
||||
animator.add_animation(&attacker,"attack",att->first,damage,true,false,"",0,hit_type,&attack,secondary_attack,swing);
|
||||
animator.add_animation(&defender,"defend",def->first,damage,true,false,text,display::rgb(255,0,0),hit_type,&attack,secondary_attack,swing);
|
||||
|
||||
if(leader_loc.valid()){
|
||||
leader = units.find(leader_loc);
|
||||
leader->second.set_facing(leader_loc.get_relative_dir(a));
|
||||
assert(leader != units.end());
|
||||
animator.add_animation(&leader->second,"leading",leader_loc,damage,true,false,"",0,hit_type,&attack,secondary_attack,swing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gamemap::location update_tiles[6];
|
||||
get_adjacent_tiles(b,update_tiles);
|
||||
|
||||
|
||||
attacker.restart_animation(*disp,start_time);
|
||||
defender.restart_animation(*disp,start_time);
|
||||
if(leader_loc.valid()) leader->second.restart_animation(*disp,start_time);
|
||||
|
||||
int animation_time = start_time;
|
||||
bool sound_played = false;
|
||||
while(!hide && (
|
||||
!attacker.get_animation()->animation_would_finish() ||
|
||||
!defender.get_animation()->animation_would_finish() ||
|
||||
(leader_loc.valid() && !leader->second.get_animation()->animation_would_finish() ) ||
|
||||
damage > 0)
|
||||
){
|
||||
|
||||
if(!sound_played && animation_time > 0) {
|
||||
sound_played = true;
|
||||
std::string text ;
|
||||
if(damage) text = lexical_cast<std::string>(damage);
|
||||
if(!hit_text.empty()) {
|
||||
text.insert(text.begin(),hit_text.size()/2,' ');
|
||||
text = text + "\n" + hit_text;
|
||||
}
|
||||
sound::play_sound(defender.get_hit_sound());
|
||||
disp->float_label(b,text,255,0,0);
|
||||
disp->invalidate_unit();
|
||||
}
|
||||
if(damage > 0 && animation_time > 0) {
|
||||
defender.take_hit(1);
|
||||
damage--;
|
||||
disp->invalidate_unit();
|
||||
}
|
||||
disp->invalidate(b);
|
||||
disp->invalidate(a);
|
||||
if(leader_loc.valid()) disp->invalidate(leader_loc);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
if(attacker.get_animation()->animation_finished()) {
|
||||
attacker.set_offset(0.0);
|
||||
}
|
||||
disp->delay(10);
|
||||
animation_time = attacker.get_animation()->get_animation_time();
|
||||
}
|
||||
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);
|
||||
def->second.set_hidden(def_was_hidden);
|
||||
disp->remove_temporary_unit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -332,89 +274,42 @@ void unit_recruited(gamemap::location& loc)
|
|||
u->second.set_hidden(true);
|
||||
disp->scroll_to_tile(loc,game_display::ONSCREEN);
|
||||
disp->draw();
|
||||
u->second.set_recruited(*disp,loc);
|
||||
u->second.set_hidden(false);
|
||||
while(!u->second.get_animation()->animation_finished()) {
|
||||
|
||||
disp->invalidate(loc);
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
}
|
||||
unit_animator animator;
|
||||
animator.add_animation(&u->second,"recruited",loc);
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
u->second.set_standing(*disp,loc);
|
||||
if (loc==disp->mouseover_hex()) disp->invalidate_unit();
|
||||
}
|
||||
|
||||
void unit_healing(unit& healed_p,gamemap::location& healed_loc, std::vector<unit_map::iterator> healers, int healing)
|
||||
void unit_healing(unit& healed,gamemap::location& healed_loc, std::vector<unit_map::iterator> healers, int healing)
|
||||
{
|
||||
game_display* disp = game_display::get_singleton();
|
||||
if(!disp || disp->video().update_locked() || disp->fogged(healed_loc)) return;
|
||||
if(healing==0) return;
|
||||
// This is all the pretty stuff.
|
||||
int start_time = INT_MAX;
|
||||
disp->scroll_to_tile(healed_loc, game_display::ONSCREEN);
|
||||
disp->select_hex(healed_loc);
|
||||
unit healed = healed_p;
|
||||
bool was_hidden = healed.get_hidden();
|
||||
healed_p.set_hidden(true);
|
||||
disp->place_temporary_unit(healed,healed_loc);
|
||||
healed.set_hidden(false);
|
||||
unit_animator animator;
|
||||
|
||||
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_facing((*heal_anim_it)->first.get_relative_dir(healed_loc));
|
||||
(*heal_anim_it)->second.set_healing(*disp,(*heal_anim_it)->first,healing);
|
||||
start_time = minimum<int>((*heal_anim_it)->second.get_animation()->get_begin_time(),start_time);
|
||||
animator.add_animation(&(*heal_anim_it)->second,"healing",(*heal_anim_it)->first,healing);
|
||||
}
|
||||
if (healing < 0) {
|
||||
healed.set_poisoned(*disp,healed_loc, -healing);
|
||||
start_time = minimum<int>(start_time, healed.get_animation()->get_begin_time());
|
||||
//! @todo FIXME
|
||||
sound::play_sound("poison.ogg");
|
||||
disp->float_label(healed_loc, lexical_cast<std::string>(-healing), 255,0,0);
|
||||
animator.add_animation(&healed,"poisoned",healed_loc,-healing,false,false,lexical_cast<std::string>(-healing), display::rgb(255,0,0));
|
||||
} else {
|
||||
healed.set_healed(*disp,healed_loc, healing);
|
||||
start_time = minimum<int>(start_time, healed.get_animation()->get_begin_time());
|
||||
sound::play_sound("heal.wav");
|
||||
disp->float_label(healed_loc, lexical_cast<std::string>(healing), 0,255,0);
|
||||
}
|
||||
disp->draw();
|
||||
events::pump();
|
||||
// Restart all anims in a synchronized way
|
||||
healed.restart_animation(*disp, start_time);
|
||||
for(std::vector<unit_map::iterator>::iterator heal_reanim_it = healers.begin(); heal_reanim_it != healers.end(); ++heal_reanim_it) {
|
||||
(*heal_reanim_it)->second.restart_animation(*disp, start_time);
|
||||
animator.add_animation(&healed,"healed",healed_loc,healing,false,false,lexical_cast<std::string>(healing), display::rgb(0,255,0));
|
||||
}
|
||||
animator.start_animations();
|
||||
animator.wait_for_end();
|
||||
|
||||
bool finished;
|
||||
do {
|
||||
finished = (healed.get_animation()->animation_finished() && healing==0);
|
||||
disp->invalidate(healed_loc);
|
||||
for(std::vector<unit_map::iterator>::iterator heal_fanim_it = healers.begin(); heal_fanim_it != healers.end(); ++heal_fanim_it) {
|
||||
finished &= (*heal_fanim_it)->second.get_animation()->animation_finished();
|
||||
disp->invalidate((*heal_fanim_it)->first);
|
||||
}
|
||||
//! @todo TODO : Adapt HP change speed to turbo_speed
|
||||
if(healing > 0) {
|
||||
healed.heal(1);
|
||||
healing--;
|
||||
} else if (healing < 0) {
|
||||
healed.take_hit(1);
|
||||
healing++;
|
||||
}
|
||||
disp->draw();
|
||||
events::pump();
|
||||
disp->delay(10);
|
||||
} while (!finished);
|
||||
|
||||
healed_p.set_standing(*disp,healed_loc);
|
||||
healed_p.set_hidden(was_hidden);
|
||||
disp->remove_temporary_unit();
|
||||
healed.set_standing(*disp,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);
|
||||
}
|
||||
|
||||
disp->update_display();
|
||||
events::pump();
|
||||
}
|
||||
|
||||
} // end unit_display namespace
|
||||
|
|
|
@ -151,6 +151,7 @@ template class progressive_<double>;
|
|||
|
||||
unit_frame::unit_frame() :
|
||||
image_(), image_diagonal_(),halo_(), sound_(),
|
||||
text_(""),text_color_(0),
|
||||
halo_x_(), halo_y_(), duration_(0),
|
||||
blend_with_(0),blend_ratio_(),
|
||||
highlight_ratio_(""), offset_()
|
||||
|
@ -161,10 +162,12 @@ unit_frame::unit_frame(const image::locator& image, int duration,
|
|||
const std::string& highlight, const std::string& offset,
|
||||
Uint32 blend_color, const std::string& blend_rate,
|
||||
const std::string& in_halo, const std::string& halox, const std::string& haloy,
|
||||
const image::locator & diag,const std::string & sound) :
|
||||
const image::locator & diag,const std::string & sound,
|
||||
const std::string & text, const Uint32 text_color) :
|
||||
image_(image),image_diagonal_(diag),
|
||||
halo_(in_halo,duration),
|
||||
sound_(sound),
|
||||
text_(text), text_color_(text_color),
|
||||
halo_x_(halox,duration),
|
||||
halo_y_(haloy,duration),
|
||||
duration_(duration),
|
||||
|
@ -183,6 +186,9 @@ unit_frame::unit_frame(const config& cfg)
|
|||
image_ = image::locator(cfg["image"]);
|
||||
image_diagonal_ = image::locator(cfg["image_diagonal"]);
|
||||
sound_ = cfg["sound"];
|
||||
text_ = cfg["text"];
|
||||
std::vector<std::string> tmp_string_vect=utils::split(cfg["text_color"]);
|
||||
if(tmp_string_vect.size() ==3) text_color_ = display::rgb(atoi(tmp_string_vect[0].c_str()),atoi(tmp_string_vect[1].c_str()),atoi(tmp_string_vect[2].c_str()));
|
||||
if(!cfg["duration"].empty()) {
|
||||
duration_ = atoi(cfg["duration"].c_str());
|
||||
} else {
|
||||
|
@ -191,8 +197,8 @@ unit_frame::unit_frame(const config& cfg)
|
|||
halo_ = progressive_string(cfg["halo"],duration_);
|
||||
halo_x_ = progressive_int(cfg["halo_x"],duration_);
|
||||
halo_y_ = progressive_int(cfg["halo_y"],duration_);
|
||||
std::vector<std::string> tmp_blend=utils::split(cfg["blend_color"]);
|
||||
if(tmp_blend.size() ==3) blend_with_= display::rgb(atoi(tmp_blend[0].c_str()),atoi(tmp_blend[1].c_str()),atoi(tmp_blend[2].c_str()));
|
||||
tmp_string_vect=utils::split(cfg["blend_color"]);
|
||||
if(tmp_string_vect.size() ==3) blend_with_= display::rgb(atoi(tmp_string_vect[0].c_str()),atoi(tmp_string_vect[1].c_str()),atoi(tmp_string_vect[2].c_str()));
|
||||
blend_ratio_ = progressive_double(cfg["blend_ratio"],duration_);
|
||||
highlight_ratio_ = progressive_double(cfg["alpha"],duration_);
|
||||
offset_ = progressive_double(cfg["offset"],duration_);
|
||||
|
|
|
@ -68,7 +68,7 @@ class unit_frame {
|
|||
Uint32 blend_color = 0, const std::string& blend_rate = "",
|
||||
const std::string & in_halo = "",
|
||||
const std::string & halox = "",const std::string & haloy = "",
|
||||
const image::locator & diag ="",const std::string & sound = "");
|
||||
const image::locator & diag ="",const std::string & sound = "",const std::string & text = "", const Uint32 text_color=0);
|
||||
explicit unit_frame(const config& cfg);
|
||||
image::locator image() const { return image_ ;}
|
||||
image::locator image_diagonal() const { return image_diagonal_ ; }
|
||||
|
@ -76,6 +76,7 @@ class unit_frame {
|
|||
{ return halo_.get_current_element(current_time,default_val); }
|
||||
|
||||
std::string sound() const { return sound_ ; };
|
||||
std::pair<std::string,Uint32> text() const { return std::pair<std::string,Uint32>(text_,text_color_) ; };
|
||||
int halo_x(int current_time,const int default_val=0) const { return halo_x_.get_current_element(current_time,default_val); }
|
||||
int halo_y(int current_time,const int default_val=0) const { return halo_y_.get_current_element(current_time,default_val); }
|
||||
int duration() const { return duration_; }
|
||||
|
@ -97,6 +98,8 @@ class unit_frame {
|
|||
progressive_string halo_;
|
||||
|
||||
std::string sound_;
|
||||
std::string text_;
|
||||
Uint32 text_color_;
|
||||
progressive_int halo_x_;
|
||||
progressive_int halo_y_;
|
||||
int duration_;
|
||||
|
|
Loading…
Add table
Reference in a new issue