mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-10 20:17:59 +00:00
301 lines
9.0 KiB
C++
301 lines
9.0 KiB
C++
/* $Id: unit_frame.cpp 9735 2006-01-18 18:31:24Z boucman $ */
|
|
/*
|
|
Copyright (C) 2006 by Jeremy Rosen <jeremy.rosen@enst-bretagne.fr>
|
|
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
|
|
#include <global.hpp>
|
|
#include <unit_frame.hpp>
|
|
#include <display.hpp>
|
|
progressive_string::progressive_string(const std::string & data,int duration)
|
|
{
|
|
const std::vector<std::string> first_pass = utils::split(data);
|
|
const int time_chunk = maximum<int>(duration / (first_pass.size()?first_pass.size():1),1);
|
|
|
|
std::vector<std::string>::const_iterator tmp;
|
|
for(tmp=first_pass.begin();tmp != first_pass.end() ; tmp++) {
|
|
std::vector<std::string> second_pass = utils::split(*tmp,':');
|
|
if(second_pass.size() > 1) {
|
|
data_.push_back(std::pair<std::string,int>(second_pass[0],atoi(second_pass[1].c_str())));
|
|
} else {
|
|
data_.push_back(std::pair<std::string,int>(second_pass[0],time_chunk));
|
|
}
|
|
}
|
|
}
|
|
int progressive_string::duration() const
|
|
{
|
|
int total =0;
|
|
std::vector<std::pair<std::string,int> >::const_iterator cur_halo;
|
|
for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) {
|
|
total += cur_halo->second;
|
|
}
|
|
return total;
|
|
|
|
}
|
|
const std::string grr;
|
|
|
|
const std::string& progressive_string::get_current_element( int current_time)const
|
|
{
|
|
int time = 0;
|
|
unsigned int sub_halo = 0;
|
|
if(data_.empty()) return grr;
|
|
while(time < current_time&& sub_halo < data_.size()) {
|
|
time += data_[sub_halo].second;
|
|
sub_halo++;
|
|
|
|
}
|
|
if(sub_halo > 0) sub_halo --;
|
|
if(sub_halo >= data_.size()) sub_halo = data_.size();
|
|
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)
|
|
{
|
|
const std::vector<std::string> first_split = utils::split(data);
|
|
const int time_chunk = maximum<int>(duration / (first_split.size()?first_split.size():1),1);
|
|
|
|
std::vector<std::string>::const_iterator tmp;
|
|
std::vector<std::pair<std::string,int> > first_pass;
|
|
for(tmp=first_split.begin();tmp != first_split.end() ; tmp++) {
|
|
std::vector<std::string> second_pass = utils::split(*tmp,':');
|
|
if(second_pass.size() > 1) {
|
|
first_pass.push_back(std::pair<std::string,int>(second_pass[0],atoi(second_pass[1].c_str())));
|
|
} else {
|
|
first_pass.push_back(std::pair<std::string,int>(second_pass[0],time_chunk));
|
|
}
|
|
}
|
|
std::vector<std::pair<std::string,int> >::const_iterator tmp2;
|
|
for(tmp2=first_pass.begin();tmp2 != first_pass.end() ; tmp2++) {
|
|
std::vector<std::string> range = utils::split(tmp2->first,'~');
|
|
data_.push_back(std::pair<std::pair<double,double>,int> (
|
|
std::pair<double,double>(
|
|
atof(range[0].c_str()),
|
|
atof(range.size()>1?range[1].c_str():range[0].c_str())),
|
|
tmp2->second));
|
|
}
|
|
|
|
}
|
|
const double progressive_double::get_current_element(int current_time)const
|
|
{
|
|
int time = 0;
|
|
unsigned int sub_halo = 0;
|
|
if(data_.empty()) return 0;
|
|
while(time < current_time&& sub_halo < data_.size()) {
|
|
time += data_[sub_halo].second;
|
|
sub_halo++;
|
|
|
|
}
|
|
if(sub_halo > 0) {
|
|
sub_halo--;
|
|
time -= data_[sub_halo].second;
|
|
}
|
|
if(sub_halo >= data_.size()) {
|
|
sub_halo = data_.size();
|
|
time = current_time; // never more than max allowed
|
|
}
|
|
|
|
const double first = data_[sub_halo].first.first;
|
|
const double second = data_[sub_halo].first.second;
|
|
|
|
return ( double(current_time - time)/(double)(data_[sub_halo].second))*(second - first)+ first;
|
|
|
|
}
|
|
|
|
|
|
|
|
int progressive_double::duration() const
|
|
{
|
|
int total =0;
|
|
std::vector<std::pair<std::pair<double,double>,int> >::const_iterator cur_halo;
|
|
for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) {
|
|
total += cur_halo->second;
|
|
}
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
const std::vector<std::string> first_split = utils::split(data);
|
|
const int time_chunk = maximum<int>(duration / (first_split.size()?first_split.size():1),1);
|
|
|
|
std::vector<std::string>::const_iterator tmp;
|
|
std::vector<std::pair<std::string,int> > first_pass;
|
|
for(tmp=first_split.begin();tmp != first_split.end() ; tmp++) {
|
|
std::vector<std::string> second_pass = utils::split(*tmp,':');
|
|
if(second_pass.size() > 1) {
|
|
first_pass.push_back(std::pair<std::string,int>(second_pass[0],atoi(second_pass[1].c_str())));
|
|
} else {
|
|
first_pass.push_back(std::pair<std::string,int>(second_pass[0],time_chunk));
|
|
}
|
|
}
|
|
std::vector<std::pair<std::string,int> >::const_iterator tmp2;
|
|
for(tmp2=first_pass.begin();tmp2 != first_pass.end() ; tmp2++) {
|
|
std::vector<std::string> range = utils::split(tmp2->first,'~');
|
|
data_.push_back(std::pair<std::pair<int,int>,int> (
|
|
std::pair<int,int>(
|
|
atoi(range[0].c_str()),
|
|
atoi(range.size()>1?range[1].c_str():range[0].c_str())),
|
|
tmp2->second));
|
|
}
|
|
|
|
}
|
|
const int progressive_int::get_current_element(int current_time)const
|
|
{
|
|
int time = 0;
|
|
unsigned int sub_halo = 0;
|
|
if(data_.empty()) return 0;
|
|
while(time < current_time&& sub_halo < data_.size()) {
|
|
time += data_[sub_halo].second;
|
|
sub_halo++;
|
|
|
|
}
|
|
if(sub_halo > 0) {
|
|
sub_halo--;
|
|
time -= data_[sub_halo].second;
|
|
}
|
|
if(sub_halo >= data_.size()) {
|
|
sub_halo = data_.size();
|
|
time = current_time; // never more than max allowed
|
|
}
|
|
|
|
const int first = data_[sub_halo].first.first;
|
|
const int second = data_[sub_halo].first.second;
|
|
|
|
return int(( double(current_time - time)/(double)(data_[sub_halo].second))*(second - first)+ first);
|
|
|
|
}
|
|
int progressive_int::duration() const
|
|
{
|
|
int total =0;
|
|
std::vector<std::pair<std::pair<int,int>,int> >::const_iterator cur_halo;
|
|
for(cur_halo = data_.begin() ; cur_halo != data_.end() ; cur_halo++) {
|
|
total += cur_halo->second;
|
|
}
|
|
return total;
|
|
|
|
}
|
|
|
|
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_(), duration_(0),
|
|
blend_with_(0),blend_ratio_(),
|
|
highlight_ratio_("1.0"),offset_("-20")
|
|
{
|
|
}
|
|
|
|
|
|
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,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",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());
|
|
}
|
|
|
|
|
|
|
|
unit_frame::unit_frame(const config& cfg)
|
|
{
|
|
image_ = image::locator(cfg["image"]);
|
|
image_diagonal_ = image::locator(cfg["image_diagonal"]);
|
|
sound_ = cfg["sound"];
|
|
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"],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);
|
|
}
|
|
|
|
double unit_frame::blend_ratio(int current_time) const
|
|
{
|
|
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));
|
|
}
|
|
|
|
double unit_frame::offset(int current_time) const
|
|
{
|
|
return offset_.get_current_element(current_time);
|
|
}
|
|
|
|
int unit_frame::halo_x(int current_time) const
|
|
{
|
|
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);
|
|
}
|
|
|
|
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();
|
|
}
|