new low level animation engine,
should ease the macroification and tuning of animations once they are converted (backward compatible).
This commit is contained in:
parent
a351011d26
commit
5d2f781f7b
17 changed files with 412 additions and 467 deletions
|
@ -1,5 +1,5 @@
|
|||
Version 1.3-svn:
|
||||
* editor
|
||||
* editor
|
||||
* allow maps to be loaded from scenario files and written back to them
|
||||
* campaigns
|
||||
* Heir to the Throne
|
||||
|
@ -60,6 +60,8 @@ Version 1.3-svn:
|
|||
* [event]s can now be written also inside [era]s (the [event]s are included
|
||||
in every scenario played using that era)
|
||||
* new operation for set_variable : divide
|
||||
* Animations now use duration= tag instead of begin= and end= (backward
|
||||
compatible)
|
||||
* multiplayer game management
|
||||
* client now tells the server if a game ended in victory or defeat
|
||||
* configurable castle size for random map generator (patch #598, FR #3232)
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
#define DEFENSE_ANIM FRAME BASEFRAME HITSOUND
|
||||
[defend]
|
||||
start_time=-126
|
||||
[frame]
|
||||
begin=-126
|
||||
end=-125
|
||||
duration=1
|
||||
image={BASEFRAME}
|
||||
[/frame]
|
||||
[frame]
|
||||
begin=-125
|
||||
end=-25
|
||||
duration=100
|
||||
image={FRAME}
|
||||
[/frame]
|
||||
[if]
|
||||
hits=hit
|
||||
[frame]
|
||||
begin=-25
|
||||
end=125
|
||||
duration=150
|
||||
image={FRAME}
|
||||
sound={HITSOUND}
|
||||
[/frame]
|
||||
|
@ -22,14 +20,12 @@
|
|||
[else]
|
||||
hits=miss,kill
|
||||
[frame]
|
||||
begin=-25
|
||||
end=125
|
||||
duration=150
|
||||
image={FRAME}
|
||||
[/frame]
|
||||
[/else]
|
||||
[frame]
|
||||
begin=125
|
||||
end=126
|
||||
duration=1
|
||||
image={BASEFRAME}
|
||||
[/frame]
|
||||
[/defend]
|
||||
|
@ -39,22 +35,20 @@
|
|||
|
||||
#define DEFENSE_ANIM_FILTERED FRAME BASEFRAME HITSOUND FILTER
|
||||
[defend]
|
||||
start_time=-126
|
||||
{FILTER}
|
||||
[frame]
|
||||
begin=-126
|
||||
end=-125
|
||||
duration=1
|
||||
image={BASEFRAME}
|
||||
[/frame]
|
||||
[frame]
|
||||
begin=-125
|
||||
end=-25
|
||||
duration=100
|
||||
image={FRAME}
|
||||
[/frame]
|
||||
[if]
|
||||
hits=hit
|
||||
[frame]
|
||||
begin=-25
|
||||
end=125
|
||||
duration=150
|
||||
image={FRAME}
|
||||
sound={HITSOUND}
|
||||
[/frame]
|
||||
|
@ -62,14 +56,12 @@
|
|||
[else]
|
||||
hits=miss,kill
|
||||
[frame]
|
||||
begin=-25
|
||||
end=125
|
||||
duration=150
|
||||
image={FRAME}
|
||||
[/frame]
|
||||
[/else]
|
||||
[frame]
|
||||
begin=125
|
||||
end=126
|
||||
duration=1
|
||||
image={BASEFRAME}
|
||||
[/frame]
|
||||
[/defend]
|
||||
|
|
|
@ -1427,29 +1427,24 @@ void calculate_healing(display& disp, const gamemap& map,
|
|||
|
||||
if (update_display){
|
||||
// This is all the pretty stuff.
|
||||
bool start_time_set = false;
|
||||
int start_time = 0;
|
||||
int start_time = INT_MAX;
|
||||
disp.scroll_to_tile(i->first.x, i->first.y, display::ONSCREEN);
|
||||
disp.select_hex(i->first);
|
||||
|
||||
for(std::vector<unit_map::iterator>::iterator heal_anim_it = healers.begin(); heal_anim_it != healers.end(); ++heal_anim_it) {
|
||||
(*heal_anim_it)->second.set_facing((*heal_anim_it)->first.get_relative_dir(i->first));
|
||||
(*heal_anim_it)->second.set_healing(disp,(*heal_anim_it)->first);
|
||||
if(start_time_set) {
|
||||
start_time = minimum<int>(start_time,(*heal_anim_it)->second.get_animation()->get_first_frame_time());
|
||||
} else {
|
||||
start_time = (*heal_anim_it)->second.get_animation()->get_first_frame_time();
|
||||
}
|
||||
start_time = (*heal_anim_it)->second.get_animation()->get_begin_time();
|
||||
}
|
||||
if (healing < 0) {
|
||||
i->second.set_poisoned(disp,i->first, -healing);
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_first_frame_time());
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_begin_time());
|
||||
// FIXME
|
||||
sound::play_sound("poison.ogg");
|
||||
disp.float_label(i->first, lexical_cast<std::string>(-healing), 255,0,0);
|
||||
} else {
|
||||
i->second.set_healed(disp,i->first, healing);
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_first_frame_time());
|
||||
start_time = minimum<int>(start_time, i->second.get_animation()->get_begin_time());
|
||||
sound::play_sound("heal.wav");
|
||||
disp.float_label(i->first, lexical_cast<std::string>(healing), 0,255,0);
|
||||
}
|
||||
|
|
305
src/animated.cpp
305
src/animated.cpp
|
@ -10,48 +10,46 @@
|
|||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
*/
|
||||
|
||||
#include "global.hpp"
|
||||
|
||||
//#include <string>
|
||||
//#include <vector>
|
||||
#include "SDL.h"
|
||||
#include "animated.hpp"
|
||||
#include "util.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T animated<T,T_void_value>::void_value_ = T_void_value()();
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
animated<T,T_void_value>::animated() :
|
||||
starting_frame_time_(INT_MAX),
|
||||
ending_frame_time_(INT_MIN),
|
||||
animated<T,T_void_value>::animated(int start_time) :
|
||||
starting_frame_time_(start_time),
|
||||
does_not_change_(true),
|
||||
started_(false),
|
||||
no_current_frame_(true),
|
||||
does_not_change_(false),
|
||||
real_start_ticks_(0),
|
||||
start_ticks_(0),
|
||||
start_tick_(0),
|
||||
cycles_(false),
|
||||
acceleration_(1),
|
||||
start_frame_(0)
|
||||
{}
|
||||
last_update_tick_(0),
|
||||
current_frame_key_(start_time)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
animated<T,T_void_value>::animated(const std::string &cfg, const string_initializer& init):
|
||||
starting_frame_time_(INT_MAX),
|
||||
animated<T,T_void_value>::animated(const std::string &cfg,int start_time, const string_initializer& init):
|
||||
starting_frame_time_(start_time),
|
||||
does_not_change_(true),
|
||||
started_(false),
|
||||
no_current_frame_(true),
|
||||
does_not_change_(false),
|
||||
real_start_ticks_(0),
|
||||
start_ticks_(0),
|
||||
start_tick_(0),
|
||||
cycles_(false),
|
||||
acceleration_(1),
|
||||
start_frame_(0)
|
||||
last_update_tick_(0),
|
||||
current_frame_key_(start_time)
|
||||
{
|
||||
std::vector<std::string> items = utils::split(cfg);
|
||||
|
||||
int current_time = 0;
|
||||
|
||||
std::vector<std::string>::const_iterator itor = items.begin();
|
||||
for(; itor != items.end(); ++itor) {
|
||||
const std::vector<std::string>& items = utils::split(*itor, ':');
|
||||
|
@ -66,159 +64,110 @@ animated<T,T_void_value>::animated(const std::string &cfg, const string_initiali
|
|||
time = 100;
|
||||
}
|
||||
|
||||
frames_.push_back(frame(current_time, init(str)));
|
||||
current_time += time;
|
||||
add_frame(time,init(str),false);
|
||||
}
|
||||
|
||||
starting_frame_time_ = 0;
|
||||
ending_frame_time_ = current_time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::add_frame()
|
||||
void animated<T,T_void_value>::add_frame(int duration, const T& value,bool force_change)
|
||||
{
|
||||
ending_frame_time_++;
|
||||
frames_.push_back(frame(ending_frame_time_));
|
||||
if(frames_.empty() ) {
|
||||
frames_[starting_frame_time_] =
|
||||
frame(duration,value);
|
||||
does_not_change_=!force_change;
|
||||
return;
|
||||
}
|
||||
typename std::map<int,frame>::const_reverse_iterator last_frame = frames_.rbegin();
|
||||
does_not_change_=false;
|
||||
frames_[last_frame->first +last_frame->second.duration_] =
|
||||
frame(duration,value);
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::add_frame(int start)
|
||||
{
|
||||
frames_.push_back(frame(start));
|
||||
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
|
||||
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::add_frame(int start, const T& value)
|
||||
{
|
||||
frames_.push_back(frame(start, value));
|
||||
starting_frame_time_ = minimum<int>(starting_frame_time_, start);
|
||||
ending_frame_time_ = maximum<int>(ending_frame_time_, start);
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::start_animation(int start_frame, int cycles, int acceleration)
|
||||
void animated<T,T_void_value>::start_animation(int start_time, bool cycles, double acceleration)
|
||||
{
|
||||
started_ = true;
|
||||
start_frame_ = start_frame;
|
||||
start_ticks_ = real_start_ticks_ = current_time_ = SDL_GetTicks() * acceleration;
|
||||
last_update_tick_ = SDL_GetTicks();
|
||||
start_tick_ = last_update_tick_ + ( starting_frame_time_ - start_time);
|
||||
cycles_ = cycles;
|
||||
current_cycle_ = 0;
|
||||
acceleration_ = acceleration;
|
||||
// current_frame_ = frames_.begin();
|
||||
current_frame_ = 0;
|
||||
no_current_frame_ = false;
|
||||
|
||||
if (ending_frame_time_ >= start_frame_) {
|
||||
duration_ = ending_frame_time_ - start_frame_;
|
||||
} else {
|
||||
duration_ = 0;
|
||||
}
|
||||
frame_changed_ = true;
|
||||
if(acceleration_ <=0) acceleration_ = 1;
|
||||
current_frame_key_= frames_.begin()->first;
|
||||
update_last_draw_time();
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
void animated<T,T_void_value>::update_current_frame()
|
||||
void animated<T,T_void_value>::update_last_draw_time()
|
||||
{
|
||||
// std::cerr << "--- updating frame ---\n";
|
||||
last_update_tick_ = SDL_GetTicks();
|
||||
if(does_not_change_)
|
||||
return;
|
||||
|
||||
frame_changed_ = false;
|
||||
// Always update current_time_, for the animation_time functions to work.
|
||||
current_time_ = SDL_GetTicks() * acceleration_;
|
||||
if(!started_)
|
||||
// Always update last_update_tick_, for the animation_time functions to work.
|
||||
if(!started_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(frames_.empty()) {
|
||||
no_current_frame_ = true;
|
||||
does_not_change_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(frames_.size() == 1 && cycles_ == INFINITE_CYCLES) {
|
||||
does_not_change_ = true;
|
||||
frame_changed_ = false;
|
||||
if(cycles_) {
|
||||
while(get_animation_time() > get_end_time()){ // cut extra time
|
||||
start_tick_ +=get_end_time()/acceleration_;
|
||||
current_frame_key_ =starting_frame_time_;
|
||||
}
|
||||
}
|
||||
|
||||
if (duration_ > 0) {
|
||||
// Ticks is the actual time since animation started.
|
||||
int ticks = current_time_ - start_ticks_;
|
||||
|
||||
// Handles cycle overflow
|
||||
if(ticks > duration_) {
|
||||
int ncycles = ticks/duration_;
|
||||
current_cycle_ = minimum<int>(cycles_, current_cycle_ + ncycles);
|
||||
start_ticks_ += ncycles * duration_;
|
||||
ticks -= ncycles * duration_;
|
||||
// current_frame_ = frames_.begin();
|
||||
current_frame_ = 0;
|
||||
frame_changed_ = true;
|
||||
}
|
||||
// Checks if the animation is finished
|
||||
if(cycles_ != INFINITE_CYCLES && current_cycle_ >= cycles_) {
|
||||
// If the animation is finished, the current frame is the last
|
||||
// one
|
||||
current_frame_ = frames_.size() - 1;
|
||||
frame_changed_ = true;
|
||||
// std::cerr << "Animation finished\n";
|
||||
no_current_frame_ = false;
|
||||
started_ = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(ticks < (frames_[current_frame_].milliseconds - start_frame_)) {
|
||||
// std::cerr << "Animation not yet started\n";
|
||||
frame_changed_ = true;
|
||||
no_current_frame_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Looks for the current frame
|
||||
typename std::vector<frame>::size_type i = current_frame_ + 1;
|
||||
for(; i != frames_.size(); ++i) {
|
||||
if(ticks < (frames_[i].milliseconds - start_frame_))
|
||||
break;
|
||||
current_frame_ = i;
|
||||
frame_changed_ = true;
|
||||
// std::cerr << "Skipping to next frame\n";
|
||||
}
|
||||
no_current_frame_ = false;
|
||||
|
||||
} else {
|
||||
// If the duration is void, the animation is automatically finished.
|
||||
// current_cycle_ = cycles_;
|
||||
if(cycles_ != -1) {
|
||||
started_ = false;
|
||||
} else {
|
||||
|
||||
does_not_change_ = true;
|
||||
}
|
||||
frame_changed_ = false;
|
||||
// current_frame_ = frames_.size() - 1;
|
||||
// frame_changed_ = false;
|
||||
// std::cerr << "Returning last frame\n";
|
||||
no_current_frame_ = false;
|
||||
typename std::map<int,frame>::iterator current_frame = frames_.find(current_frame_key_);
|
||||
while(get_current_frame_end_time() < get_animation_time() && // catch up
|
||||
get_current_frame_end_time() < get_end_time()) {// don't go after the end
|
||||
current_frame++;
|
||||
current_frame_key_ = current_frame->first;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
bool animated<T,T_void_value>::frame_changed() const
|
||||
bool animated<T,T_void_value>::need_update() const
|
||||
{
|
||||
return frame_changed_;
|
||||
if(does_not_change_) {
|
||||
return false;
|
||||
}
|
||||
if(frames_.empty()) {
|
||||
return false;
|
||||
}
|
||||
if(!started_) {
|
||||
return false;
|
||||
}
|
||||
if(SDL_GetTicks() > (unsigned int)(get_current_frame_end_time()/acceleration_+start_tick_)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
bool animated<T,T_void_value>::animation_would_finish() const
|
||||
{
|
||||
if(frames_.empty())
|
||||
return true;
|
||||
if(!started_)
|
||||
return true;
|
||||
if(!cycles_ && (SDL_GetTicks() > (unsigned int)(get_end_time()/acceleration_+start_tick_)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
template<typename T, typename T_void_value>
|
||||
bool animated<T,T_void_value>::animation_finished() const
|
||||
{
|
||||
if(frames_.empty())
|
||||
return true;
|
||||
if(!started_)
|
||||
return true;
|
||||
//if(current_cycle_ == cycles_)
|
||||
// return true;
|
||||
if(!cycles_ && (get_animation_time() > get_end_time()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -226,50 +175,66 @@ bool animated<T,T_void_value>::animation_finished() const
|
|||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_animation_time() const
|
||||
{
|
||||
if(!started_) return starting_frame_time_;
|
||||
if(does_not_change_)
|
||||
return SDL_GetTicks() * acceleration_ - real_start_ticks_ + start_frame_;
|
||||
if(!started_ ) return starting_frame_time_;
|
||||
|
||||
return current_time_ - real_start_ticks_ + start_frame_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_cycle_time() const
|
||||
{
|
||||
return current_time_ - start_ticks_ + start_frame_;
|
||||
return ((double)(last_update_tick_ - start_tick_)*acceleration_)+starting_frame_time_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_current_frame() const
|
||||
{
|
||||
if(no_current_frame_ == true)
|
||||
if(frames_.empty() )
|
||||
return void_value_;
|
||||
const frame& cur = frames_[current_frame_];
|
||||
if(!cur.has_value)
|
||||
return void_value_;
|
||||
return cur.value;
|
||||
return frames_.find(current_frame_key_)->second.value_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const int animated<T,T_void_value>::get_current_frame_begin_time() const
|
||||
{
|
||||
if(frames_.empty() )
|
||||
return starting_frame_time_;
|
||||
return frames_.find(current_frame_key_)->first;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const int animated<T,T_void_value>::get_current_frame_end_time() const
|
||||
{
|
||||
if(frames_.empty() )
|
||||
return starting_frame_time_;
|
||||
return get_current_frame_begin_time() +get_current_frame_duration();
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const int animated<T,T_void_value>::get_current_frame_duration() const
|
||||
{
|
||||
if(frames_.empty() )
|
||||
return 0;
|
||||
return frames_.find(current_frame_key_)->second.duration_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const int animated<T,T_void_value>::get_current_frame_time() const
|
||||
{
|
||||
if(frames_.empty() )
|
||||
return 0;
|
||||
return maximum<int>(get_current_frame_begin_time(),get_animation_time() - get_current_frame_begin_time());
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_first_frame() const
|
||||
{
|
||||
typename std::vector<frame>::const_iterator frame_;
|
||||
for(frame_ = frames_.begin() ; frame_ != frames_.end(); frame_++ ) {
|
||||
if(frame_->has_value)
|
||||
return frame_->value;
|
||||
}
|
||||
return void_value_;
|
||||
if(frames_.empty() )
|
||||
return void_value_;
|
||||
return frames_.begin()->second.value_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
const T& animated<T,T_void_value>::get_last_frame() const
|
||||
{
|
||||
typename std::vector<frame>::const_reverse_iterator frame_;
|
||||
for(frame_ = frames_.rbegin() ; frame_ != frames_.rend(); frame_++ ) {
|
||||
if(frame_->has_value)
|
||||
return frame_->value;
|
||||
}
|
||||
return void_value_;
|
||||
if(frames_.empty() )
|
||||
return void_value_;
|
||||
typename std::map<int,frame>::const_reverse_iterator last_frame = frames_.rbegin();
|
||||
return last_frame->second.value_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
|
@ -279,24 +244,20 @@ int animated<T,T_void_value>::get_frames_count() const
|
|||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_first_frame_time() const
|
||||
int animated<T,T_void_value>::get_begin_time() const
|
||||
{
|
||||
if (starting_frame_time_ != INT_MAX && starting_frame_time_ != INT_MIN)
|
||||
return starting_frame_time_;
|
||||
|
||||
return 0;
|
||||
return starting_frame_time_;
|
||||
}
|
||||
|
||||
template<typename T, typename T_void_value>
|
||||
int animated<T,T_void_value>::get_last_frame_time() const
|
||||
int animated<T,T_void_value>::get_end_time() const
|
||||
{
|
||||
if (ending_frame_time_ != INT_MAX && ending_frame_time_ != INT_MIN)
|
||||
return ending_frame_time_;
|
||||
|
||||
return 0;
|
||||
if(frames_.empty())
|
||||
return starting_frame_time_;
|
||||
typename std::map<int,frame>::const_reverse_iterator last_frame = frames_.rbegin();
|
||||
return (last_frame->first +last_frame->second.duration_);
|
||||
}
|
||||
|
||||
|
||||
// Force compilation of the following template instantiations
|
||||
|
||||
#include "unit_frame.hpp"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#define ANIMATED_IMAGE_H_INCLUDED
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
template<typename T>
|
||||
class void_value
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
virtual ~string_initializer(){};
|
||||
};
|
||||
|
||||
animated();
|
||||
animated(int start_time=0);
|
||||
virtual ~animated(){};
|
||||
|
||||
//if T can be constructed from a string, you may use this constructor
|
||||
|
@ -43,78 +43,69 @@ public:
|
|||
//if T cannot, you may provide a custom (subclassed) string_initializer
|
||||
//to do the job
|
||||
|
||||
animated(const std::string &cfg, const string_initializer& init=string_initializer());
|
||||
animated(const std::string &cfg, int start_time = 0, const string_initializer& init=string_initializer());
|
||||
|
||||
// Adds a void frame at the end
|
||||
void add_frame();
|
||||
// Adds a void frame
|
||||
void add_frame(int start);
|
||||
|
||||
// Adds a frame
|
||||
void add_frame(int start, const T& value);
|
||||
void add_frame(int duration, const T& value,bool force_change =false);
|
||||
|
||||
//Starts an animation cycle. The first frame of the animation to start
|
||||
//may be set to any value
|
||||
enum { INFINITE_CYCLES = -1 };
|
||||
void start_animation(int start_time=0, int cycles=1, int acceleration=1);
|
||||
void start_animation(int start_time=0, bool cycles=false, double acceleration=1);
|
||||
|
||||
int get_first_frame_time() const;
|
||||
int get_last_frame_time() const;
|
||||
int get_begin_time() const;
|
||||
int get_end_time() const;
|
||||
|
||||
//inlined for performance
|
||||
void update_current_frame();
|
||||
bool frame_changed() const;
|
||||
void update_last_draw_time();
|
||||
bool need_update() const;
|
||||
|
||||
//True if the current animation was finished
|
||||
bool animation_finished() const;
|
||||
bool animation_would_finish() const;
|
||||
int get_animation_time() const;
|
||||
int get_cycle_time() const;
|
||||
const T& get_current_frame() const;
|
||||
const int get_current_frame_begin_time() const;
|
||||
const int get_current_frame_end_time() const;
|
||||
const int get_current_frame_duration() const;
|
||||
const int get_current_frame_time() const;
|
||||
const T& get_first_frame() const;
|
||||
const T& get_last_frame() const;
|
||||
int get_frames_count() const;
|
||||
const bool does_not_change() const {return does_not_change_;}
|
||||
|
||||
|
||||
protected:
|
||||
int starting_frame_time_;
|
||||
|
||||
private:
|
||||
struct frame
|
||||
{
|
||||
frame(int milliseconds) :
|
||||
milliseconds(milliseconds), has_value(false)
|
||||
{};
|
||||
|
||||
frame(int milliseconds, const T& value) :
|
||||
milliseconds(milliseconds), has_value(true), value(value)
|
||||
frame(int duration , const T& value) :
|
||||
duration_(duration),value_(value)
|
||||
{};
|
||||
frame():
|
||||
duration_(0),value_(void_value_)
|
||||
{};
|
||||
|
||||
// Represents the timestamp of the frame start
|
||||
int milliseconds;
|
||||
bool has_value;
|
||||
T value;
|
||||
int duration_;
|
||||
T value_;
|
||||
};
|
||||
|
||||
static const T void_value_;
|
||||
|
||||
int starting_frame_time_;
|
||||
int ending_frame_time_;
|
||||
|
||||
bool started_;
|
||||
bool no_current_frame_;
|
||||
bool does_not_change_; // optimization for 1-frame permanent animations
|
||||
bool started_;
|
||||
std::map<int,frame> frames_;
|
||||
|
||||
int real_start_ticks_;
|
||||
int start_ticks_;
|
||||
int current_cycle_;
|
||||
int current_time_;
|
||||
int cycles_;
|
||||
int acceleration_;
|
||||
bool frame_changed_;
|
||||
int start_frame_;
|
||||
int duration_;
|
||||
typename std::vector<frame>::size_type current_frame_;
|
||||
//these are only valid when anim is started
|
||||
int start_tick_; // time at which we started
|
||||
bool cycles_;
|
||||
double acceleration_;
|
||||
int last_update_tick_;
|
||||
int current_frame_key_;
|
||||
|
||||
std::vector<frame> frames_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -189,16 +189,16 @@ bool terrain_builder::update_animation(const gamemap::location &loc)
|
|||
|
||||
imagelist::iterator itor = bg.begin();
|
||||
for(; itor != bg.end(); ++itor) {
|
||||
itor->update_current_frame();
|
||||
if(itor->frame_changed())
|
||||
if(itor->need_update())
|
||||
changed = true;
|
||||
itor->update_last_draw_time();
|
||||
}
|
||||
|
||||
itor = fg.begin();
|
||||
for(; itor != fg.end(); ++itor) {
|
||||
itor->update_current_frame();
|
||||
if(itor->frame_changed())
|
||||
if(itor->need_update())
|
||||
changed = true;
|
||||
itor->update_last_draw_time();
|
||||
}
|
||||
|
||||
return changed;
|
||||
|
@ -215,7 +215,7 @@ void terrain_builder::rebuild_terrain(const gamemap::location &loc)
|
|||
const std::string filename =
|
||||
map_.get_terrain_info(map_.get_terrain(loc)).symbol_image();
|
||||
animated<image::locator> img_loc("terrain/" + filename + ".png");
|
||||
img_loc.start_animation(0, animated<image::locator>::INFINITE_CYCLES);
|
||||
img_loc.start_animation(0, true);
|
||||
btile.images_background.push_back(img_loc);
|
||||
}
|
||||
}
|
||||
|
@ -280,12 +280,12 @@ bool terrain_builder::start_animation(building_rule &rule)
|
|||
initializer = locator_string_initializer(constraint->second.loc);
|
||||
}
|
||||
|
||||
animated<image::locator> th(variant->second.image_string,
|
||||
animated<image::locator> th(variant->second.image_string,0,
|
||||
initializer);
|
||||
|
||||
variant->second.image = th;
|
||||
variant->second.image.start_animation(0, animated<image::locator>::INFINITE_CYCLES);
|
||||
variant->second.image.update_current_frame();
|
||||
variant->second.image.start_animation(0, true);
|
||||
variant->second.image.update_last_draw_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,29 +120,26 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
|
|||
animated<image::locator> temp_anim;
|
||||
|
||||
std::vector<std::string> items = utils::split(flag);
|
||||
int current_time = 0;
|
||||
std::vector<std::string>::const_iterator itor = items.begin();
|
||||
for(; itor != items.end(); ++itor) {
|
||||
const std::vector<std::string>& items = utils::split(*itor, ':');
|
||||
std::string str;
|
||||
int time;
|
||||
const std::vector<std::string>& items = utils::split(*itor, ':');
|
||||
std::string str;
|
||||
int time;
|
||||
|
||||
if(items.size() > 1) {
|
||||
str = items.front();
|
||||
time = atoi(items.back().c_str());
|
||||
} else {
|
||||
str = *itor;
|
||||
time = 100;
|
||||
}
|
||||
if(items.size() > 1) {
|
||||
str = items.front();
|
||||
time = atoi(items.back().c_str());
|
||||
} else {
|
||||
str = *itor;
|
||||
time = 100;
|
||||
}
|
||||
|
||||
image::locator flag_image(str, new_rgb, old_rgb);
|
||||
temp_anim.add_frame(current_time, flag_image);
|
||||
current_time += time;
|
||||
image::locator flag_image(str, new_rgb, old_rgb);
|
||||
temp_anim.add_frame(time, flag_image);
|
||||
}
|
||||
temp_anim.add_frame(current_time);
|
||||
flags_.push_back(temp_anim);
|
||||
|
||||
flags_.back().start_animation(rand()%flags_.back().get_frames_count(), animated<image::locator>::INFINITE_CYCLES);
|
||||
flags_.back().start_animation(rand()%flags_.back().get_end_time(), true);
|
||||
}
|
||||
|
||||
//clear the screen contents
|
||||
|
@ -869,6 +866,9 @@ void display::draw(bool update,bool force)
|
|||
unit_invals.insert(*it);
|
||||
}
|
||||
draw_tile(*it, clip_rect);
|
||||
if(map_.is_village(*it) && player_teams::village_owner(*it) != -1) {
|
||||
flags_[player_teams::village_owner(*it)].update_last_draw_time();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2060,8 +2060,7 @@ void display::invalidate_animations()
|
|||
get_visible_hex_bounds(topleft, bottomright);
|
||||
|
||||
for(size_t i = 0; i < flags_.size(); ++i) {
|
||||
flags_[i].update_current_frame();
|
||||
if(flags_[i].frame_changed()) {
|
||||
if(flags_[i].need_update()) {
|
||||
animate_flags = true;
|
||||
}
|
||||
}
|
||||
|
@ -2076,14 +2075,14 @@ void display::invalidate_animations()
|
|||
}
|
||||
unit_map::iterator unit;
|
||||
for(unit=units_.begin() ; unit != units_.end() ; unit++) {
|
||||
unit->second.refresh(*this,unit->first);
|
||||
if (unit->second.get_animation() && !unit->second.get_animation()->does_not_change())
|
||||
if (unit->second.get_animation() && unit->second.get_animation()->need_update())
|
||||
invalidate(unit->first);
|
||||
unit->second.refresh(*this,unit->first);
|
||||
}
|
||||
if (temp_unit_ ) {
|
||||
temp_unit_->refresh(*this, temp_unit_loc_);
|
||||
if (temp_unit_->get_animation() && !temp_unit_->get_animation()->does_not_change())
|
||||
if (temp_unit_->get_animation() && temp_unit_->get_animation()->need_update())
|
||||
invalidate(temp_unit_loc_);
|
||||
temp_unit_->refresh(*this, temp_unit_loc_);
|
||||
}
|
||||
|
||||
|
||||
|
|
14
src/halo.cpp
14
src/halo.cpp
|
@ -35,7 +35,7 @@ display* disp = NULL;
|
|||
class effect
|
||||
{
|
||||
public:
|
||||
effect(int xpos, int ypos, const std::string& img, ORIENTATION orientation, int lifetime);
|
||||
effect(int xpos, int ypos, const std::string& img, ORIENTATION orientation,bool infinite);
|
||||
|
||||
void set_location(int x, int y);
|
||||
|
||||
|
@ -66,7 +66,7 @@ int halo_id = 1;
|
|||
bool hide_halo = false;
|
||||
|
||||
|
||||
effect::effect(int xpos, int ypos, const std::string& img, ORIENTATION orientation, int lifetime)
|
||||
effect::effect(int xpos, int ypos, const std::string& img, ORIENTATION orientation,bool infinite)
|
||||
: images_(img), orientation_(orientation), origx_(xpos), origy_(ypos), x_(xpos), y_(ypos),
|
||||
origzoom_(disp->zoom()), zoom_(disp->zoom()), surf_(NULL), buffer_(NULL), rect_(empty_rect)
|
||||
{
|
||||
|
@ -75,10 +75,10 @@ effect::effect(int xpos, int ypos, const std::string& img, ORIENTATION orientati
|
|||
|
||||
set_location(xpos,ypos);
|
||||
|
||||
images_.start_animation(0, lifetime);
|
||||
images_.start_animation(0,infinite);
|
||||
|
||||
if(!images_.animation_finished()) {
|
||||
images_.update_current_frame();
|
||||
images_.update_last_draw_time();
|
||||
}
|
||||
|
||||
current_image_ = "";
|
||||
|
@ -131,7 +131,7 @@ void effect::render()
|
|||
return;
|
||||
}
|
||||
|
||||
images_.update_current_frame();
|
||||
images_.update_last_draw_time();
|
||||
const std::string& img = current_image();
|
||||
if(surf_ == NULL || zoom_ != disp->zoom() || current_image_ != img) {
|
||||
current_image_ = img;
|
||||
|
@ -218,10 +218,10 @@ halo_hider::~halo_hider()
|
|||
unrender();
|
||||
}
|
||||
|
||||
int add(int x, int y, const std::string& image, ORIENTATION orientation, int lifetime_cycles)
|
||||
int add(int x, int y, const std::string& image, ORIENTATION orientation, bool infinite)
|
||||
{
|
||||
const int id = halo_id++;
|
||||
haloes.insert(std::pair<int,effect>(id,effect(x,y,image,orientation,lifetime_cycles)));
|
||||
haloes.insert(std::pair<int,effect>(id,effect(x,y,image,orientation,infinite)));
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ enum ORIENTATION { NORMAL, HREVERSE, VREVERSE, HVREVERSE };
|
|||
///centered on (x,y)
|
||||
///returns the handle to the halo object
|
||||
///0 is the invalid handle
|
||||
int add(int x, int y, const std::string& image, ORIENTATION orientation=NORMAL, int lifetime_cycles=-1);
|
||||
int add(int x, int y, const std::string& image, ORIENTATION orientation=NORMAL, bool infinite=true);
|
||||
|
||||
///function to set the position of an existing haloing
|
||||
///effect, according to its handle
|
||||
|
|
|
@ -445,8 +445,6 @@ Units cannot be killed by poison alone. The poison will not reduce it below 1 HP
|
|||
flag = current_team.flag();
|
||||
}
|
||||
|
||||
//must recolor flag image
|
||||
animated<image::locator> temp_anim;
|
||||
|
||||
// remove animation stuff we don't care about
|
||||
const std::vector<std::string> items = utils::split(flag);
|
||||
|
|
143
src/unit.cpp
143
src/unit.cpp
|
@ -1316,7 +1316,7 @@ void unit::read(const config& cfg)
|
|||
defensive_animations_.push_back(defensive_animation(**d));
|
||||
}
|
||||
if(defensive_animations_.empty()) {
|
||||
defensive_animations_.push_back(defensive_animation(unit_frame(absolute_image(),-150,150)));
|
||||
defensive_animations_.push_back(defensive_animation(-150,unit_frame(absolute_image(),300)));
|
||||
// always have a defensive animation
|
||||
}
|
||||
|
||||
|
@ -1324,7 +1324,7 @@ void unit::read(const config& cfg)
|
|||
teleport_animations_.push_back(unit_animation(**t));
|
||||
}
|
||||
if(teleport_animations_.empty()) {
|
||||
teleport_animations_.push_back(unit_animation(unit_frame(absolute_image(),-20,20)));
|
||||
teleport_animations_.push_back(unit_animation(-20,unit_frame(absolute_image(),40)));
|
||||
// always have a teleport animation
|
||||
}
|
||||
|
||||
|
@ -1336,7 +1336,7 @@ void unit::read(const config& cfg)
|
|||
death_animations_.push_back(death_animation(**death));
|
||||
}
|
||||
if(death_animations_.empty()) {
|
||||
death_animations_.push_back(death_animation(unit_frame(absolute_image(),0,10)));
|
||||
death_animations_.push_back(death_animation(0,unit_frame(absolute_image(),10)));
|
||||
// always have a death animation
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1344,7 @@ void unit::read(const config& cfg)
|
|||
movement_animations_.push_back(movement_animation(**movement_anim));
|
||||
}
|
||||
if(movement_animations_.empty()) {
|
||||
movement_animations_.push_back(movement_animation(unit_frame(absolute_image(),0,150)));
|
||||
movement_animations_.push_back(movement_animation(0,unit_frame(absolute_image(),150)));
|
||||
// always have a movement animation
|
||||
}
|
||||
|
||||
|
@ -1352,7 +1352,7 @@ void unit::read(const config& cfg)
|
|||
standing_animations_.push_back(standing_animation(**standing_anim));
|
||||
}
|
||||
if(standing_animations_.empty()) {
|
||||
standing_animations_.push_back(standing_animation(unit_frame(absolute_image(),0,0)));
|
||||
standing_animations_.push_back(standing_animation(0,unit_frame(absolute_image(),0)));
|
||||
// always have a standing animation
|
||||
}
|
||||
|
||||
|
@ -1360,7 +1360,7 @@ void unit::read(const config& cfg)
|
|||
leading_animations_.push_back(leading_animation(**leading_anim));
|
||||
}
|
||||
if(leading_animations_.empty()) {
|
||||
leading_animations_.push_back(leading_animation(unit_frame(absolute_image(),0,150)));
|
||||
leading_animations_.push_back(leading_animation(0,unit_frame(absolute_image(),150)));
|
||||
// always have a leading animation
|
||||
}
|
||||
|
||||
|
@ -1368,7 +1368,7 @@ void unit::read(const config& cfg)
|
|||
healing_animations_.push_back(healing_animation(**healing_anim));
|
||||
}
|
||||
if(healing_animations_.empty()) {
|
||||
healing_animations_.push_back(healing_animation(unit_frame(image_healing(),0,150,
|
||||
healing_animations_.push_back(healing_animation(0,unit_frame(image_healing(),150,
|
||||
"1.0","",0,"",image_halo_healing(),0,0)));
|
||||
// always have a healing animation
|
||||
}
|
||||
|
@ -1377,7 +1377,7 @@ void unit::read(const config& cfg)
|
|||
recruit_animations_.push_back(recruit_animation(**recruit_anim));
|
||||
}
|
||||
if(recruit_animations_.empty()) {
|
||||
recruit_animations_.push_back(recruit_animation(unit_frame(absolute_image(),0,600,"0~1:600")));
|
||||
recruit_animations_.push_back(recruit_animation(0,unit_frame(absolute_image(),600,"0~1:600")));
|
||||
// always have a recruit animation
|
||||
}
|
||||
|
||||
|
@ -1385,7 +1385,7 @@ void unit::read(const config& cfg)
|
|||
idle_animations_.push_back(idle_animation(**idle_anim));
|
||||
}
|
||||
if(idle_animations_.empty()) {
|
||||
idle_animations_.push_back(idle_animation(unit_frame(absolute_image(),0,1)));
|
||||
idle_animations_.push_back(idle_animation(0,unit_frame(absolute_image(),1)));
|
||||
// always have a idle animation
|
||||
}
|
||||
|
||||
|
@ -1393,7 +1393,7 @@ void unit::read(const config& cfg)
|
|||
levelin_animations_.push_back(levelin_animation(**levelin_anim));
|
||||
}
|
||||
if(levelin_animations_.empty()) {
|
||||
levelout_animations_.push_back(levelout_animation(unit_frame(absolute_image(),0,600,"1.0","",display::rgb(255,255,255),"1~0:600")));
|
||||
levelout_animations_.push_back(levelout_animation(0,unit_frame(absolute_image(),600,"1.0","",display::rgb(255,255,255),"1~0:600")));
|
||||
// always have a levelin animation
|
||||
}
|
||||
|
||||
|
@ -1401,7 +1401,7 @@ void unit::read(const config& cfg)
|
|||
levelout_animations_.push_back(levelout_animation(**levelout_anim));
|
||||
}
|
||||
if(levelout_animations_.empty()) {
|
||||
levelout_animations_.push_back(levelout_animation(unit_frame(absolute_image(),0,600,"1.0","",display::rgb(255,255,255),"0~1:600")));
|
||||
levelout_animations_.push_back(levelout_animation(0,unit_frame(absolute_image(),600,"1.0","",display::rgb(255,255,255),"0~1:600")));
|
||||
// always have a levelout animation
|
||||
}
|
||||
|
||||
|
@ -1582,7 +1582,6 @@ const surface unit::still_image() const
|
|||
void unit::refresh(const display& disp,const gamemap::location& loc)
|
||||
{
|
||||
if(state_ == STATE_IDLING && anim_ && anim_->animation_finished()) set_standing(disp, loc);
|
||||
if(anim_) anim_->update_current_frame();
|
||||
if(state_ != STATE_STANDING || SDL_GetTicks() < next_idling) return;
|
||||
set_idling(disp, loc);
|
||||
}
|
||||
|
@ -1598,9 +1597,8 @@ void unit::set_standing(const display &disp,const gamemap::location& loc, bool w
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new standing_animation(stand_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(),unit_animation::INFINITE_CYCLES,disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(),true,disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
next_idling= SDL_GetTicks() +30000 +rand()%10000;
|
||||
}
|
||||
void unit::set_defending(const display &disp,const gamemap::location& loc, int damage,const attack_type* attack,const attack_type* secondary_attack,int swing_num)
|
||||
|
@ -1622,16 +1620,12 @@ void unit::set_defending(const display &disp,const gamemap::location& loc, int d
|
|||
anim_ = new defensive_animation(defend_animation(disp,loc,hit_type,attack,secondary_attack,swing_num,damage));
|
||||
|
||||
// add a blink on damage effect
|
||||
int anim_time = anim_->get_last_frame_time();
|
||||
const image::locator my_image = anim_->get_last_frame().image();
|
||||
if(damage) {
|
||||
anim_->add_frame(anim_time,unit_frame(my_image,anim_time,anim_time+100,"1.0","",display::rgb(255,0,0),"0.5:50,0.0:50"));
|
||||
anim_time+=100;
|
||||
anim_->add_frame(100,unit_frame(my_image,100,"1.0","",display::rgb(255,0,0),"0.5:50,0.0:50"));
|
||||
}
|
||||
anim_->add_frame(anim_time);
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
void unit::set_extra_anim(const display &disp,const gamemap::location& loc, std::string flag)
|
||||
|
@ -1647,9 +1641,8 @@ void unit::set_extra_anim(const display &disp,const gamemap::location& loc, std:
|
|||
return;
|
||||
}
|
||||
anim_ = new unit_animation(*(extra_animation(disp,loc,flag)));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
const unit_animation & unit::set_attacking(const display &disp,const gamemap::location& loc,int damage,const attack_type& type,const attack_type* secondary_attack,int swing_num)
|
||||
|
@ -1669,9 +1662,8 @@ const unit_animation & unit::set_attacking(const display &disp,const gamemap::lo
|
|||
hit_type = fighting_animation::MISS;
|
||||
}
|
||||
anim_ = new attack_animation(type.animation(disp,loc,this,hit_type,secondary_attack,swing_num,damage));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
return ((attack_animation*)anim_)->get_missile_anim();
|
||||
}
|
||||
void unit::set_leading(const display &disp,const gamemap::location& loc)
|
||||
|
@ -1683,9 +1675,8 @@ void unit::set_leading(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new leading_animation(lead_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_leveling_in(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
|
@ -1696,9 +1687,8 @@ void unit::set_leveling_in(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new levelin_animation(levelingin_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_leveling_out(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
|
@ -1709,9 +1699,8 @@ void unit::set_leveling_out(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new levelout_animation(levelingout_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_recruited(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
|
@ -1723,9 +1712,8 @@ void unit::set_recruited(const display &disp,const gamemap::location& loc)
|
|||
}
|
||||
anim_ = new recruit_animation(recruiting_animation(disp,loc));
|
||||
// add a fade in effect
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_healed(const display &disp,const gamemap::location& /*loc*/, int /*healing*/)
|
||||
{
|
||||
|
@ -1735,10 +1723,9 @@ void unit::set_healed(const display &disp,const gamemap::location& /*loc*/, int
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new unit_animation(unit_frame(absolute_image(),0,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"));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_ = new unit_animation(0,unit_frame(absolute_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"));
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_poisoned(const display &disp,const gamemap::location& /*loc*/, int /*damage*/)
|
||||
{
|
||||
|
@ -1748,10 +1735,9 @@ void unit::set_poisoned(const display &disp,const gamemap::location& /*loc*/, in
|
|||
delete anim_;
|
||||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new unit_animation(unit_frame(absolute_image(),0,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"));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_ = new unit_animation(0,unit_frame(absolute_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"));
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
void unit::set_teleporting(const display &disp,const gamemap::location& loc)
|
||||
|
@ -1763,9 +1749,8 @@ void unit::set_teleporting(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new unit_animation(teleport_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(),1,disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(),false,disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
void unit::set_dying(const display &disp,const gamemap::location& loc,const attack_type* attack,const attack_type* secondary_attack)
|
||||
|
@ -1778,12 +1763,9 @@ void unit::set_dying(const display &disp,const gamemap::location& loc,const atta
|
|||
}
|
||||
anim_ = new death_animation(die_animation(disp,loc,fighting_animation::KILL,attack,secondary_attack));
|
||||
image::locator tmp_image = anim_->get_last_frame().image();
|
||||
int anim_time =anim_->get_last_frame_time();
|
||||
anim_->add_frame(0,unit_frame(tmp_image,anim_time,anim_time+600,"1~0:600"));
|
||||
anim_->add_frame(anim_time+600);
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->add_frame(600,unit_frame(tmp_image,600,"1~0:600"));
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
void unit::set_healing(const display &disp,const gamemap::location& loc)
|
||||
{
|
||||
|
@ -1794,9 +1776,8 @@ void unit::set_healing(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new healing_animation(heal_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
void unit::set_walking(const display &disp,const gamemap::location& loc)
|
||||
|
@ -1812,8 +1793,8 @@ void unit::set_walking(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new movement_animation(move_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1826,15 +1807,14 @@ void unit::set_idling(const display &disp,const gamemap::location& loc)
|
|||
anim_ = NULL;
|
||||
}
|
||||
anim_ = new idle_animation(idling_animation(disp,loc));
|
||||
anim_->start_animation(anim_->get_first_frame_time(), 1, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_first_frame_time() -1;
|
||||
anim_->update_current_frame();
|
||||
anim_->start_animation(anim_->get_begin_time(), false, disp.turbo_speed());
|
||||
frame_begin_time = anim_->get_begin_time() -1;
|
||||
}
|
||||
|
||||
|
||||
void unit::restart_animation(const display& disp,int start_time) {
|
||||
if(!anim_) return;
|
||||
anim_->start_animation(start_time,1,disp.turbo_speed());
|
||||
anim_->start_animation(start_time,false,disp.turbo_speed());
|
||||
frame_begin_time = start_time -1;
|
||||
}
|
||||
|
||||
|
@ -1869,17 +1849,17 @@ void unit::redraw_unit(display& disp,gamemap::location hex)
|
|||
|
||||
unit_frame current_frame;
|
||||
if(anim_->animation_finished()) current_frame = anim_->get_last_frame();
|
||||
else if(anim_->get_first_frame_time() > anim_->get_animation_time()) current_frame = anim_->get_first_frame();
|
||||
else if(anim_->get_begin_time() > anim_->get_animation_time()) current_frame = anim_->get_first_frame();
|
||||
else current_frame = anim_->get_current_frame();
|
||||
|
||||
image::locator loc;
|
||||
loc = current_frame.image();
|
||||
double tmp_offset = current_frame.offset(anim_->get_animation_time());
|
||||
double tmp_offset = current_frame.offset(anim_->get_current_frame_time());
|
||||
if(tmp_offset == -20.0) tmp_offset = offset_;
|
||||
const int x = int(tmp_offset*xdst + (1.0-tmp_offset)*xsrc);
|
||||
const int y = int(tmp_offset*ydst + (1.0-tmp_offset)*ysrc);
|
||||
if(frame_begin_time != current_frame.begin_time()) {
|
||||
frame_begin_time = current_frame.begin_time();
|
||||
if(frame_begin_time != anim_->get_current_frame_begin_time()) {
|
||||
frame_begin_time = anim_->get_current_frame_begin_time();
|
||||
if(!current_frame.sound().empty()) {
|
||||
sound::play_sound(current_frame.sound());
|
||||
}
|
||||
|
@ -1887,18 +1867,18 @@ void unit::redraw_unit(display& disp,gamemap::location hex)
|
|||
}
|
||||
if(unit_anim_halo_) halo::remove(unit_anim_halo_);
|
||||
unit_anim_halo_ = 0;
|
||||
if(!current_frame.halo(anim_->get_animation_time()).empty()) {
|
||||
if(!current_frame.halo(anim_->get_current_frame_time()).empty()) {
|
||||
|
||||
if(facing_ == gamemap::location::NORTH_WEST || facing_ == gamemap::location::SOUTH_WEST) {
|
||||
const int d = disp.hex_size() / 2;
|
||||
unit_anim_halo_ = halo::add(x+d-static_cast<int>(current_frame.halo_x(anim_->get_animation_time())*disp.zoom()),
|
||||
y+d+static_cast<int>(current_frame.halo_y(anim_->get_animation_time())*disp.zoom()),
|
||||
current_frame.halo(anim_->get_animation_time()));
|
||||
unit_anim_halo_ = halo::add(x+d-static_cast<int>(current_frame.halo_x(anim_->get_current_frame_time())*disp.zoom()),
|
||||
y+d+static_cast<int>(current_frame.halo_y(anim_->get_current_frame_time())*disp.zoom()),
|
||||
current_frame.halo(anim_->get_current_frame_time()));
|
||||
} else {
|
||||
const int d = disp.hex_size() / 2;
|
||||
unit_anim_halo_ = halo::add(x+d+static_cast<int>(current_frame.halo_x(anim_->get_animation_time())*disp.zoom()),
|
||||
y+d+static_cast<int>(current_frame.halo_y(anim_->get_animation_time())*disp.zoom()),
|
||||
current_frame.halo(anim_->get_animation_time()),
|
||||
unit_anim_halo_ = halo::add(x+d+static_cast<int>(current_frame.halo_x(anim_->get_current_frame_time())*disp.zoom()),
|
||||
y+d+static_cast<int>(current_frame.halo_y(anim_->get_current_frame_time())*disp.zoom()),
|
||||
current_frame.halo(anim_->get_current_frame_time()),
|
||||
halo::HREVERSE);
|
||||
}
|
||||
}
|
||||
|
@ -1922,9 +1902,9 @@ void unit::redraw_unit(display& disp,gamemap::location hex)
|
|||
}
|
||||
|
||||
Uint32 blend_with = current_frame.blend_with();
|
||||
double blend_ratio = current_frame.blend_ratio(anim_->get_animation_time());
|
||||
double blend_ratio = current_frame.blend_ratio(anim_->get_current_frame_time());
|
||||
if(blend_ratio == 0) { blend_with = disp.rgb(0,0,0); }
|
||||
fixed_t highlight_ratio = minimum<fixed_t>(alpha(),current_frame.highlight_ratio(anim_->get_animation_time()));
|
||||
fixed_t highlight_ratio = minimum<fixed_t>(alpha(),current_frame.highlight_ratio(anim_->get_current_frame_time()));
|
||||
if(invisible(hex,disp.get_units(),disp.get_teams()) &&
|
||||
highlight_ratio > ftofxp(0.5)) {
|
||||
highlight_ratio = ftofxp(0.5);
|
||||
|
@ -2029,6 +2009,7 @@ void unit::redraw_unit(display& disp,gamemap::location hex)
|
|||
}
|
||||
}
|
||||
refreshing_ = false;
|
||||
anim_->update_last_draw_time();
|
||||
}
|
||||
|
||||
gamemap::location::DIRECTION unit::facing() const
|
||||
|
@ -2063,8 +2044,8 @@ std::set<gamemap::location> unit::overlaps(const gamemap::location &loc) const
|
|||
break;
|
||||
}
|
||||
//very early calls, anim not initialized yet
|
||||
if(!anim_) return over;
|
||||
double tmp_offset = anim_->get_current_frame().offset(anim_->get_animation_time());
|
||||
double tmp_offset=offset_;
|
||||
if(anim_)tmp_offset= anim_->get_current_frame().offset(anim_->get_animation_time());
|
||||
if(tmp_offset == -20.0) tmp_offset = offset_;
|
||||
// invalidate adj neighbours
|
||||
if(tmp_offset > 0) {
|
||||
|
|
|
@ -90,22 +90,23 @@ config unit_animation::prepare_animation(const config &cfg,const std::string ani
|
|||
return expanded_animations;
|
||||
}
|
||||
|
||||
unit_animation::unit_animation(const unit_frame & frame )
|
||||
unit_animation::unit_animation(int start_time,const unit_frame & frame ):animated<unit_frame>(start_time)
|
||||
{
|
||||
add_frame(0,frame);
|
||||
if(frame.end_time() != frame.begin_time()) add_frame(frame.end_time());
|
||||
|
||||
add_frame(frame.duration(),frame,!frame.does_not_change());
|
||||
}
|
||||
|
||||
unit_animation::unit_animation(const config& cfg,const std::string frame_string ):terrain_types(utils::split(cfg["terrain"])){
|
||||
config::const_child_itors range = cfg.child_range(frame_string);
|
||||
|
||||
int last_end = INT_MIN;
|
||||
for(; range.first != range.second; ++range.first) {
|
||||
add_frame(atoi((**range.first)["begin"].c_str()), unit_frame(**range.first));
|
||||
last_end = maximum<int>(atoi((**range.first)["end"].c_str()), last_end);
|
||||
if(cfg["start_time"].empty() &&range.first != range.second) {
|
||||
starting_frame_time_ = atoi((**range.first)["begin"].c_str());
|
||||
} else {
|
||||
starting_frame_time_ = atoi(cfg["start_time"].c_str());
|
||||
}
|
||||
|
||||
for(; range.first != range.second; ++range.first) {
|
||||
unit_frame tmp_frame(**range.first);
|
||||
add_frame(tmp_frame.duration(),tmp_frame,!tmp_frame.does_not_change());
|
||||
}
|
||||
add_frame(last_end);
|
||||
|
||||
const std::vector<std::string>& my_directions = utils::split(cfg["direction"]);
|
||||
for(std::vector<std::string>::const_iterator i = my_directions.begin(); i != my_directions.end(); ++i) {
|
||||
|
|
|
@ -34,7 +34,7 @@ class unit_animation:public animated<unit_frame>
|
|||
|
||||
unit_animation(){};
|
||||
explicit unit_animation(const config& cfg,const std::string frame_string ="frame");
|
||||
explicit unit_animation(const unit_frame &frame);
|
||||
explicit unit_animation(int start_time,const unit_frame &frame);
|
||||
int matches(const display &disp,const gamemap::location& loc,const unit* my_unit) const;
|
||||
|
||||
private:
|
||||
|
@ -53,8 +53,8 @@ class fighting_animation:public unit_animation
|
|||
typedef enum { HIT, MISS, KILL} hit_type;
|
||||
|
||||
explicit fighting_animation(const config& cfg);
|
||||
explicit fighting_animation(const unit_frame &frame):
|
||||
unit_animation(frame) {};
|
||||
explicit fighting_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame) {};
|
||||
int matches(const display &disp,const gamemap::location& loc,const unit* my_unit,hit_type hit,const attack_type* attack,const attack_type* second_attack, int swing_num,int damage) const;
|
||||
|
||||
private:
|
||||
|
@ -69,7 +69,7 @@ class defensive_animation:public fighting_animation
|
|||
{
|
||||
public:
|
||||
explicit defensive_animation(const config& cfg):fighting_animation(cfg){};
|
||||
explicit defensive_animation(const unit_frame &frame):fighting_animation(frame){};
|
||||
explicit defensive_animation(int start_time,const unit_frame &frame):fighting_animation(start_time,frame){};
|
||||
};
|
||||
|
||||
|
||||
|
@ -77,7 +77,7 @@ class death_animation:public fighting_animation
|
|||
{
|
||||
public:
|
||||
explicit death_animation(const config& cfg):fighting_animation(cfg){};
|
||||
explicit death_animation(const unit_frame &frame):fighting_animation(frame) {};
|
||||
explicit death_animation(int start_time,const unit_frame &frame):fighting_animation(start_time,frame) {};
|
||||
private:
|
||||
};
|
||||
|
||||
|
@ -85,7 +85,7 @@ class attack_animation: public fighting_animation
|
|||
{
|
||||
public:
|
||||
explicit attack_animation(const config& cfg):fighting_animation(cfg),missile_anim(cfg,"missile_frame"){};
|
||||
explicit attack_animation(const unit_frame &frame):fighting_animation(frame) {};
|
||||
explicit attack_animation(int start_time,const unit_frame &frame):fighting_animation(start_time,frame) {};
|
||||
const unit_animation &get_missile_anim() {return missile_anim;}
|
||||
private:
|
||||
unit_animation missile_anim;
|
||||
|
@ -96,8 +96,8 @@ class movement_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit movement_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit movement_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit movement_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -106,8 +106,8 @@ class standing_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit standing_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit standing_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit standing_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -116,8 +116,8 @@ class leading_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit leading_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit leading_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit leading_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -126,8 +126,8 @@ class healing_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit healing_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit healing_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit healing_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -136,8 +136,8 @@ class recruit_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit recruit_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit recruit_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit recruit_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -146,8 +146,8 @@ class idle_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit idle_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit idle_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit idle_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -156,8 +156,8 @@ class levelin_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit levelin_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit levelin_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit levelin_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -166,8 +166,8 @@ class levelout_animation:public unit_animation
|
|||
{
|
||||
public:
|
||||
explicit levelout_animation(const config& cfg):unit_animation(cfg){};
|
||||
explicit levelout_animation(const unit_frame &frame):
|
||||
unit_animation(frame){};
|
||||
explicit levelout_animation(int start_time,const unit_frame &frame):
|
||||
unit_animation(start_time,frame){};
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -269,10 +269,10 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
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_first_frame_time());
|
||||
start_time = minimum<int>(start_time,missile_animation.get_first_frame_time());
|
||||
start_time = minimum<int>(start_time,attacker.get_animation()->get_first_frame_time());
|
||||
missile_animation.start_animation(start_time,1,acceleration);
|
||||
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();
|
||||
|
@ -286,14 +286,10 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
(leader_loc.valid() && leader->second.state() != unit::STATE_STANDING))
|
||||
){
|
||||
const unit_frame& missile_frame = missile_animation.get_current_frame();
|
||||
/* double pos = missile_frame.offset(missile_animation.get_animation_time());
|
||||
if(pos!=-20.0) pos = animation_time < missile_animation.get_first_frame_time()?1.0:
|
||||
double(animation_time)/double(missile_animation.get_first_frame_time());
|
||||
else pos= 1.0-pos;*/
|
||||
double pos = missile_frame.offset(animation_time);
|
||||
double pos = missile_frame.offset(missile_animation.get_current_frame_time());
|
||||
if(pos == -20.0) {
|
||||
pos = double(animation_time -missile_animation.get_first_frame_time())/
|
||||
double(missile_animation.get_last_frame_time()-missile_animation.get_first_frame_time());
|
||||
pos = 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);
|
||||
|
@ -302,8 +298,8 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
halo::remove(missile_frame_halo);
|
||||
missile_halo = 0;
|
||||
missile_frame_halo = 0;
|
||||
if(animation_time > missile_animation.get_first_frame_time() &&
|
||||
animation_time < missile_animation.get_last_frame_time() &&
|
||||
if(animation_time > missile_animation.get_begin_time() &&
|
||||
animation_time < missile_animation.get_end_time() &&
|
||||
(!disp.fogged(b.x,b.y) || !disp.fogged(a.x,a.y))) {
|
||||
const int posx = int(pos*xdst + (1.0-pos)*xsrc);
|
||||
const int posy = int(pos*ydst + (1.0-pos)*ysrc);
|
||||
|
@ -315,16 +311,16 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
} else {
|
||||
missile_image = missile_frame.image_diagonal();
|
||||
}
|
||||
if(!missile_frame.halo(animation_time).empty()) {
|
||||
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(animation_time),
|
||||
posy+d+missile_frame.halo_y(animation_time),
|
||||
missile_frame.halo(animation_time),
|
||||
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()),
|
||||
orientation);
|
||||
} else {
|
||||
missile_halo = halo::add(posx+d-missile_frame.halo_x(animation_time),
|
||||
posy+d+missile_frame.halo_y(animation_time),
|
||||
missile_frame.halo(animation_time),
|
||||
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()),
|
||||
orientation);
|
||||
}
|
||||
}
|
||||
|
@ -351,10 +347,10 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
|||
if(leader_loc.valid() && leader->second.get_animation()->animation_finished() ) {
|
||||
leader->second.set_standing(disp,leader_loc,true);
|
||||
}
|
||||
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();
|
||||
missile_animation.update_current_frame();
|
||||
}
|
||||
// make sure get hit sound is always played and labels always displayed
|
||||
if(damage > 0 && !hide && !sound_played) {
|
||||
|
@ -419,11 +415,11 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
|
||||
|
||||
attacker.set_attacking(disp,a,damage,attack,secondary_attack,swing);
|
||||
start_time=minimum<int>(start_time,attacker.get_animation()->get_first_frame_time());
|
||||
end_time=attacker.get_animation()->get_last_frame_time();
|
||||
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_first_frame_time());
|
||||
start_time=minimum<int>(start_time,defender.get_animation()->get_begin_time());
|
||||
|
||||
|
||||
const gamemap::location leader_loc = under_leadership(units,a);
|
||||
|
@ -434,7 +430,7 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
wassert(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_first_frame_time());
|
||||
start_time=minimum<int>(start_time,leader->second.get_animation()->get_begin_time());
|
||||
}
|
||||
|
||||
|
||||
|
@ -463,12 +459,12 @@ bool unit_attack(display& disp, unit_map& units,
|
|||
){
|
||||
|
||||
double pos = 0.0;
|
||||
if(animation_time < attacker.get_animation()->get_first_frame_time()) {
|
||||
if(animation_time < attacker.get_animation()->get_begin_time()) {
|
||||
pos = 0.0;
|
||||
} else if( animation_time > 0) {
|
||||
pos = (1.0-double(animation_time)/double(end_time));
|
||||
} else {
|
||||
pos = 1.0 - double(animation_time)/double(attacker.get_animation()->get_first_frame_time());
|
||||
pos = 1.0 - double(animation_time)/double(attacker.get_animation()->get_begin_time());
|
||||
}
|
||||
if(attacker.state() != unit::STATE_STANDING && pos > 0.0) {
|
||||
attacker.set_offset(pos*0.6);
|
||||
|
|
|
@ -56,6 +56,10 @@ const std::string& progressive_string::get_current_element( int current_time)con
|
|||
return data_[sub_halo].first;
|
||||
}
|
||||
|
||||
bool progressive_string::does_not_change() const
|
||||
{
|
||||
return data_.size() <= 1;
|
||||
}
|
||||
|
||||
|
||||
progressive_double::progressive_double(const std::string &data, int duration)
|
||||
|
@ -124,6 +128,11 @@ int progressive_double::duration() const
|
|||
}
|
||||
|
||||
|
||||
bool progressive_double::does_not_change() const
|
||||
{
|
||||
return data_.empty() ||
|
||||
( data_.size() == 1 && data_[0].first.first == data_[0].first.second);
|
||||
}
|
||||
|
||||
progressive_int::progressive_int(const std::string &data, int duration)
|
||||
{
|
||||
|
@ -187,38 +196,43 @@ int progressive_int::duration() const
|
|||
|
||||
}
|
||||
|
||||
bool progressive_int::does_not_change() const
|
||||
{
|
||||
return data_.empty() ||
|
||||
( data_.size() == 1 && data_[0].first.first == data_[0].first.second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unit_frame::unit_frame() :
|
||||
image_(), image_diagonal_(),halo_(), sound_(),
|
||||
halo_x_(), halo_y_(), begin_time_(0), end_time_(0),
|
||||
halo_x_(), halo_y_(), duration_(0),
|
||||
blend_with_(0),blend_ratio_(),
|
||||
highlight_ratio_("1.0"),offset_("-20")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
unit_frame::unit_frame(const image::locator& image, int begin,int end,
|
||||
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) :
|
||||
image_(image),image_diagonal_(diag),
|
||||
halo_(in_halo,end_time_ - begin_time_),
|
||||
halo_x_(halox,end_time_ - begin_time_),
|
||||
halo_y_(haloy,end_time_ - begin_time_),
|
||||
begin_time_(begin), end_time_(end),
|
||||
blend_with_(blend_color), blend_ratio_(blend_rate,end_time_ - begin_time_),
|
||||
highlight_ratio_(highlight,end_time_ - begin_time_)
|
||||
halo_(in_halo,duration),
|
||||
halo_x_(halox,duration),
|
||||
halo_y_(haloy,duration),
|
||||
duration_(duration),
|
||||
blend_with_(blend_color), blend_ratio_(blend_rate,duration),
|
||||
highlight_ratio_(highlight,duration)
|
||||
{
|
||||
// let's decide of duration ourselves
|
||||
if(offset.empty()) offset_=progressive_double("-20",end_time_-begin_time_);
|
||||
else offset_=progressive_double(offset,end_time_-begin_time_);
|
||||
end_time_ = end;
|
||||
end_time_ = maximum<int>(end_time_,begin + highlight_ratio_.duration());
|
||||
end_time_ = maximum<int>(end_time_,begin + blend_ratio_.duration());
|
||||
end_time_ = maximum<int>(end_time_,begin + halo_.duration());
|
||||
end_time_ = maximum<int>(end_time_,begin + offset_.duration());
|
||||
if(offset.empty()) offset_=progressive_double("-20",duration);
|
||||
else offset_=progressive_double(offset,duration);
|
||||
duration_ = maximum<int>(duration_, highlight_ratio_.duration());
|
||||
duration_ = maximum<int>(duration_, blend_ratio_.duration());
|
||||
duration_ = maximum<int>(duration_, halo_.duration());
|
||||
duration_ = maximum<int>(duration_, offset_.duration());
|
||||
}
|
||||
|
||||
|
||||
|
@ -228,47 +242,59 @@ unit_frame::unit_frame(const config& cfg)
|
|||
image_ = image::locator(cfg["image"]);
|
||||
image_diagonal_ = image::locator(cfg["image_diagonal"]);
|
||||
sound_ = cfg["sound"];
|
||||
begin_time_ = atoi(cfg["begin"].c_str());
|
||||
end_time_ = atoi(cfg["end"].c_str());
|
||||
halo_ = progressive_string(cfg["halo"],end_time_-begin_time_);
|
||||
halo_x_ = progressive_int(cfg["halo_x"],end_time_ -begin_time_);
|
||||
halo_y_ = progressive_int(cfg["halo_y"],end_time_ -begin_time_);
|
||||
if(!cfg["duration"].empty()) {
|
||||
duration_ = atoi(cfg["duration"].c_str());
|
||||
} else {
|
||||
duration_ = atoi(cfg["end"].c_str()) - atoi(cfg["begin"].c_str());
|
||||
}
|
||||
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()));
|
||||
blend_ratio_ = progressive_double(cfg["blend_ratio"],end_time_-begin_time_);
|
||||
highlight_ratio_ = progressive_double(cfg["alpha"].empty()?"1.0":cfg["alpha"],end_time_-begin_time_);
|
||||
offset_ = progressive_double(cfg["offset"].empty()?"-20":cfg["offset"],end_time_-begin_time_);
|
||||
blend_ratio_ = progressive_double(cfg["blend_ratio"],duration_);
|
||||
highlight_ratio_ = progressive_double(cfg["alpha"].empty()?"1.0":cfg["alpha"],duration_);
|
||||
offset_ = progressive_double(cfg["offset"].empty()?"-20":cfg["offset"],duration_);
|
||||
|
||||
}
|
||||
|
||||
|
||||
const std::string &unit_frame::halo(int current_time) const
|
||||
{
|
||||
return halo_.get_current_element(current_time - begin_time_);
|
||||
return halo_.get_current_element(current_time);
|
||||
}
|
||||
|
||||
double unit_frame::blend_ratio(int current_time) const
|
||||
{
|
||||
return blend_ratio_.get_current_element(current_time - begin_time_);
|
||||
return blend_ratio_.get_current_element(current_time);
|
||||
}
|
||||
|
||||
fixed_t unit_frame::highlight_ratio(int current_time) const
|
||||
{
|
||||
return ftofxp(highlight_ratio_.get_current_element(current_time - begin_time_));
|
||||
return ftofxp(highlight_ratio_.get_current_element(current_time));
|
||||
}
|
||||
|
||||
double unit_frame::offset(int current_time) const
|
||||
{
|
||||
return offset_.get_current_element(current_time - begin_time_);
|
||||
return offset_.get_current_element(current_time);
|
||||
}
|
||||
|
||||
int unit_frame::halo_x(int current_time) const
|
||||
{
|
||||
return halo_x_.get_current_element(current_time - begin_time_);
|
||||
return halo_x_.get_current_element(current_time);
|
||||
}
|
||||
|
||||
int unit_frame::halo_y(int current_time) const
|
||||
{
|
||||
return halo_y_.get_current_element(current_time - begin_time_);
|
||||
return halo_y_.get_current_element(current_time);
|
||||
}
|
||||
|
||||
bool unit_frame::does_not_change() const
|
||||
{
|
||||
return halo_.does_not_change() &&
|
||||
halo_x_.does_not_change() &&
|
||||
halo_y_.does_not_change() &&
|
||||
blend_ratio_.does_not_change() &&
|
||||
highlight_ratio_.does_not_change() &&
|
||||
offset_.does_not_change();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class progressive_string {
|
|||
progressive_string(const std::string& data = "",int duration = 0);
|
||||
int duration() const;
|
||||
const std::string & get_current_element(int time) const;
|
||||
bool does_not_change() const;
|
||||
private:
|
||||
std::vector<std::pair<std::string,int> > data_;
|
||||
};
|
||||
|
@ -38,6 +39,7 @@ class progressive_double {
|
|||
progressive_double(const std::string& data = "",int duration = 0);
|
||||
int duration() const;
|
||||
const double get_current_element(int time) const;
|
||||
bool does_not_change() const;
|
||||
private:
|
||||
std::vector<std::pair<std::pair<double,double>,int> > data_;
|
||||
};
|
||||
|
@ -48,6 +50,7 @@ class progressive_int {
|
|||
progressive_int(const std::string& data = "",int duration = 0);
|
||||
int duration() const;
|
||||
const int get_current_element(int time) const;
|
||||
bool does_not_change() const;
|
||||
private:
|
||||
std::vector<std::pair<std::pair<int,int>,int> > data_;
|
||||
};
|
||||
|
@ -58,7 +61,7 @@ class unit_frame {
|
|||
public:
|
||||
// constructors
|
||||
unit_frame();
|
||||
explicit unit_frame(const image::locator& image, int begin=0,int end=1,
|
||||
explicit unit_frame(const image::locator& image, int duration=0,
|
||||
const std::string& highlight="1.0",const std::string& offset="",
|
||||
Uint32 blend_color = 0, const std::string& blend_rate = "0",
|
||||
const std::string & in_halo = "",
|
||||
|
@ -72,12 +75,12 @@ class unit_frame {
|
|||
std::string sound() const { return sound_ ; };
|
||||
int halo_x(int current_time) const;
|
||||
int halo_y(int current_time) const;
|
||||
int begin_time() const { return begin_time_; }
|
||||
int end_time() const { return end_time_ ; }
|
||||
int duration() const { return duration_; }
|
||||
Uint32 blend_with() const { return blend_with_; }
|
||||
double blend_ratio(int current_time) const;
|
||||
fixed_t highlight_ratio(int current_time) const;
|
||||
double offset(int current_time) const;
|
||||
bool does_not_change() const;
|
||||
private:
|
||||
image::locator image_;
|
||||
image::locator image_diagonal_;
|
||||
|
@ -86,7 +89,7 @@ class unit_frame {
|
|||
std::string sound_;
|
||||
progressive_int halo_x_;
|
||||
progressive_int halo_y_;
|
||||
int begin_time_, end_time_;
|
||||
int duration_;
|
||||
Uint32 blend_with_;
|
||||
progressive_double blend_ratio_;
|
||||
progressive_double highlight_ratio_;
|
||||
|
|
|
@ -50,7 +50,7 @@ attack_type::attack_type(const config& cfg,const std::string& id, const std::str
|
|||
animation_.push_back(attack_animation(cfg));
|
||||
}
|
||||
if(animation_.empty()) {
|
||||
animation_.push_back(attack_animation(unit_frame(image_fighting,-200,100)));
|
||||
animation_.push_back(attack_animation(-200,unit_frame(image_fighting,300)));
|
||||
}
|
||||
assert(!animation_.empty());
|
||||
|
||||
|
@ -780,7 +780,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
defensive_animations_.push_back(defensive_animation(**d));
|
||||
}
|
||||
if(defensive_animations_.empty()) {
|
||||
defensive_animations_.push_back(defensive_animation(unit_frame(image(),-150,150)));
|
||||
defensive_animations_.push_back(defensive_animation(-150,unit_frame(image(),300)));
|
||||
// always have a defensive animation
|
||||
}
|
||||
|
||||
|
@ -792,7 +792,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
teleport_animations_.push_back(unit_animation(**t));
|
||||
}
|
||||
if(teleport_animations_.empty()) {
|
||||
teleport_animations_.push_back(unit_animation(unit_frame(image(),-20,20)));
|
||||
teleport_animations_.push_back(unit_animation(-20,unit_frame(image(),40)));
|
||||
// always have a defensive animation
|
||||
}
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"extra_anim");
|
||||
|
@ -809,7 +809,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
death_animations_.push_back(death_animation(**death));
|
||||
}
|
||||
if(death_animations_.empty()) {
|
||||
death_animations_.push_back(death_animation(unit_frame(image(),0,10)));
|
||||
death_animations_.push_back(death_animation(0,unit_frame(image(),10)));
|
||||
// always have a defensive animation
|
||||
}
|
||||
|
||||
|
@ -819,7 +819,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
movement_animations_.push_back(movement_animation(**movement_anim));
|
||||
}
|
||||
if(movement_animations_.empty()) {
|
||||
movement_animations_.push_back(movement_animation(unit_frame(image(),0,150)));
|
||||
movement_animations_.push_back(movement_animation(0,unit_frame(image(),150)));
|
||||
// always have a movement animation
|
||||
}
|
||||
|
||||
|
@ -829,7 +829,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
standing_animations_.push_back(standing_animation(**standing_anim));
|
||||
}
|
||||
if(standing_animations_.empty()) {
|
||||
standing_animations_.push_back(standing_animation(unit_frame(image(),0,1)));
|
||||
standing_animations_.push_back(standing_animation(0,unit_frame(image(),0)));
|
||||
// always have a standing animation
|
||||
}
|
||||
|
||||
|
@ -839,7 +839,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
leading_animations_.push_back(leading_animation(**leading_anim));
|
||||
}
|
||||
if(leading_animations_.empty()) {
|
||||
leading_animations_.push_back(leading_animation(unit_frame(image(),0,150)));
|
||||
leading_animations_.push_back(leading_animation(0,unit_frame(image(),150)));
|
||||
// always have a leading animation
|
||||
}
|
||||
|
||||
|
@ -849,7 +849,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
healing_animations_.push_back(healing_animation(**healing_anim));
|
||||
}
|
||||
if(healing_animations_.empty()) {
|
||||
healing_animations_.push_back(healing_animation(unit_frame(image::locator(cfg["image_healing"]),0,1,"1.0","",0,"",cfg["image_halo_healing"])));
|
||||
healing_animations_.push_back(healing_animation(0,unit_frame(image::locator(cfg["image_healing"]),1,"1.0","",0,"",cfg["image_halo_healing"])));
|
||||
// always have a healing animation
|
||||
}
|
||||
|
||||
|
@ -859,7 +859,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
recruit_animations_.push_back(recruit_animation(**recruit_anim));
|
||||
}
|
||||
if(recruit_animations_.empty()) {
|
||||
recruit_animations_.push_back(recruit_animation(unit_frame(image(),0,600,"0~1:600")));
|
||||
recruit_animations_.push_back(recruit_animation(0,unit_frame(image(),600,"0~1:600")));
|
||||
// always have a recruit animation
|
||||
}
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"idle_anim");
|
||||
|
@ -868,7 +868,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
idle_animations_.push_back(idle_animation(**idle_anim));
|
||||
}
|
||||
if(idle_animations_.empty()) {
|
||||
idle_animations_.push_back(idle_animation(unit_frame(image(),0,1)));
|
||||
idle_animations_.push_back(idle_animation(0,unit_frame(image(),1)));
|
||||
// always have a idle animation
|
||||
}
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"levelin_anim");
|
||||
|
@ -877,7 +877,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
levelin_animations_.push_back(levelin_animation(**levelin_anim));
|
||||
}
|
||||
if(levelin_animations_.empty()) {
|
||||
levelin_animations_.push_back(levelin_animation(unit_frame(image(),0,600,"1.0","",display::rgb(255,255,255),"1~0:600")));
|
||||
levelin_animations_.push_back(levelin_animation(0,unit_frame(image(),600,"1.0","",display::rgb(255,255,255),"1~0:600")));
|
||||
// always have a levelin animation
|
||||
}
|
||||
expanded_cfg = unit_animation::prepare_animation(cfg,"levelout_anim");
|
||||
|
@ -886,7 +886,7 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
|||
levelout_animations_.push_back(levelout_animation(**levelout_anim));
|
||||
}
|
||||
if(levelout_animations_.empty()) {
|
||||
levelout_animations_.push_back(levelout_animation(unit_frame(image(),0,600,"1.0","",display::rgb(255,255,255),"0~1:600")));
|
||||
levelout_animations_.push_back(levelout_animation(0,unit_frame(image(),600,"1.0","",display::rgb(255,255,255),"0~1:600")));
|
||||
// always have a levelout animation
|
||||
}
|
||||
flag_rgb_ = cfg["flag_rgb"];
|
||||
|
|
Loading…
Add table
Reference in a new issue