00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "global.hpp"
00019
00020 #include "game_display.hpp"
00021 #include "halo.hpp"
00022 #include "sound.hpp"
00023 #include "unit_frame.hpp"
00024
00025
00026 progressive_string::progressive_string(const std::string & data,int duration) :
00027 data_(),
00028 input_(data)
00029 {
00030 const std::vector<std::string> first_pass = utils::split(data);
00031 const int time_chunk = std::max<int>(duration / (first_pass.size()?first_pass.size():1),1);
00032
00033 std::vector<std::string>::const_iterator tmp;
00034 for(tmp=first_pass.begin();tmp != first_pass.end() ; ++tmp) {
00035 std::vector<std::string> second_pass = utils::split(*tmp,':');
00036 if(second_pass.size() > 1) {
00037 data_.push_back(std::pair<std::string,int>(second_pass[0],atoi(second_pass[1].c_str())));
00038 } else {
00039 data_.push_back(std::pair<std::string,int>(second_pass[0],time_chunk));
00040 }
00041 }
00042 }
00043 int progressive_string::duration() const
00044 {
00045 int total =0;
00046 std::vector<std::pair<std::string,int> >::const_iterator cur_halo;
00047 for(cur_halo = data_.begin() ; cur_halo != data_.end() ; ++cur_halo) {
00048 total += cur_halo->second;
00049 }
00050 return total;
00051
00052 }
00053
00054 static const std::string empty_string;
00055
00056 const std::string& progressive_string::get_current_element(int current_time)const
00057 {
00058 int time = 0;
00059 unsigned int sub_halo = 0;
00060 if(data_.empty()) return empty_string;
00061 while(time < current_time&& sub_halo < data_.size()) {
00062 time += data_[sub_halo].second;
00063 ++sub_halo;
00064
00065 }
00066 if(sub_halo) sub_halo--;
00067 return data_[sub_halo].first;
00068 }
00069
00070 template <class T>
00071 progressive_<T>::progressive_(const std::string &data, int duration) :
00072 data_(),
00073 input_(data)
00074 {
00075 int split_flag = utils::REMOVE_EMPTY;
00076 const std::vector<std::string> comma_split = utils::split(data,',',split_flag);
00077 const int time_chunk = std::max<int>(1, duration / std::max<int>(comma_split.size(),1));
00078
00079 std::vector<std::string>::const_iterator com_it = comma_split.begin();
00080 for(; com_it != comma_split.end(); ++com_it) {
00081 std::vector<std::string> colon_split = utils::split(*com_it,':',split_flag);
00082 int time = (colon_split.size() > 1) ? atoi(colon_split[1].c_str()) : time_chunk;
00083
00084 std::vector<std::string> range = utils::split(colon_split[0],'~',split_flag);
00085 T range0 = lexical_cast<T>(range[0]);
00086 T range1 = (range.size() > 1) ? lexical_cast<T>(range[1]) : range0;
00087 typedef std::pair<T,T> range_pair;
00088 data_.push_back(std::pair<range_pair,int>(range_pair(range0, range1), time));
00089 }
00090 }
00091
00092 template <class T>
00093 const T progressive_<T>::get_current_element(int current_time, T default_val) const
00094 {
00095 int time = 0;
00096 unsigned int sub_halo = 0;
00097 int searched_time = current_time;
00098 if(searched_time < 0) searched_time = 0;
00099 if(searched_time > duration()) searched_time = duration();
00100 if(data_.empty()) return default_val;
00101 while(time < searched_time&& sub_halo < data_.size()) {
00102 time += data_[sub_halo].second;
00103 ++sub_halo;
00104
00105 }
00106 if(sub_halo != 0) {
00107 sub_halo--;
00108 time -= data_[sub_halo].second;
00109 }
00110
00111 const T first = data_[sub_halo].first.first;
00112 const T second = data_[sub_halo].first.second;
00113
00114 return T((static_cast<double>(searched_time - time) /
00115 static_cast<double>(data_[sub_halo].second)) *
00116 (second - first) + first);
00117 }
00118
00119 template<class T>
00120 int progressive_<T>::duration() const
00121 {
00122 int total = 0;
00123 typename std::vector<std::pair<std::pair<T, T>, int> >::const_iterator cur_halo;
00124 for(cur_halo = data_.begin() ; cur_halo != data_.end() ; ++cur_halo) {
00125 total += cur_halo->second;
00126 }
00127 return total;
00128
00129 }
00130
00131 template <class T>
00132 bool progressive_<T>::does_not_change() const
00133 {
00134 return data_.empty() ||
00135 ( data_.size() == 1 && data_[0].first.first == data_[0].first.second);
00136 }
00137
00138
00139 template class progressive_<int>;
00140 template class progressive_<double>;
00141
00142 frame_parameters::frame_parameters() :
00143 duration(0),
00144 image(),
00145 image_diagonal(),
00146 image_mod(""),
00147 halo(""),
00148 halo_x(0),
00149 halo_y(0),
00150 halo_mod(""),
00151 sound(""),
00152 text(""),
00153 text_color(0),
00154 blend_with(0),
00155 blend_ratio(0.0),
00156 highlight_ratio(1.0),
00157 offset(0),
00158 submerge(0.0),
00159 x(0),
00160 y(0),
00161 directional_x(0),
00162 directional_y(0),
00163 auto_vflip(t_unset),
00164 auto_hflip(t_unset),
00165 primary_frame(t_unset),
00166 drawing_layer(display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST)
00167 {}
00168
00169 frame_builder::frame_builder() :
00170 duration_(1),
00171 image_(),
00172 image_diagonal_(),
00173 image_mod_(""),
00174 halo_(""),
00175 halo_x_(""),
00176 halo_y_(""),
00177 halo_mod_(""),
00178 sound_(""),
00179 text_(""),
00180 text_color_(0),
00181 blend_with_(0),
00182 blend_ratio_(""),
00183 highlight_ratio_(""),
00184 offset_(""),
00185 submerge_(""),
00186 x_(""),
00187 y_(""),
00188 directional_x_(""),
00189 directional_y_(""),
00190 auto_vflip_(t_unset),
00191 auto_hflip_(t_unset),
00192 primary_frame_(t_unset),
00193 drawing_layer_(str_cast(display::LAYER_UNIT_DEFAULT - display::LAYER_UNIT_FIRST))
00194 {}
00195
00196 frame_builder::frame_builder(const config& cfg,const std::string& frame_string) :
00197 duration_(1),
00198 image_(cfg[frame_string + "image"]),
00199 image_diagonal_(cfg[frame_string + "image_diagonal"]),
00200 image_mod_(cfg[frame_string + "image_mod"]),
00201 halo_(cfg[frame_string + "halo"]),
00202 halo_x_(cfg[frame_string + "halo_x"]),
00203 halo_y_(cfg[frame_string + "halo_y"]),
00204 halo_mod_(cfg[frame_string + "halo_mod"]),
00205 sound_(cfg[frame_string + "sound"]),
00206 text_(cfg[frame_string + "text"]),
00207 text_color_(0),
00208 blend_with_(0),
00209 blend_ratio_(cfg[frame_string + "blend_ratio"]),
00210 highlight_ratio_(cfg[frame_string + "alpha"]),
00211 offset_(cfg[frame_string + "offset"]),
00212 submerge_(cfg[frame_string + "submerge"]),
00213 x_(cfg[frame_string + "x"]),
00214 y_(cfg[frame_string + "y"]),
00215 directional_x_(cfg[frame_string + "directional_x"]),
00216 directional_y_(cfg[frame_string + "directional_y"]),
00217 auto_vflip_(t_unset),
00218 auto_hflip_(t_unset),
00219 primary_frame_(t_unset),
00220 drawing_layer_(cfg[frame_string + "layer"])
00221 {
00222 if(!cfg.has_attribute(frame_string + "auto_vflip")) {
00223 auto_vflip_ = t_unset;
00224 } else if(cfg[frame_string + "auto_vflip"].to_bool()) {
00225 auto_vflip_ = t_true;
00226 } else {
00227 auto_vflip_ = t_false;
00228 }
00229 if(!cfg.has_attribute(frame_string + "auto_hflip")) {
00230 auto_hflip_ = t_unset;
00231 } else if(cfg[frame_string + "auto_hflip"].to_bool()) {
00232 auto_hflip_ = t_true;
00233 } else {
00234 auto_hflip_ = t_false;
00235 }
00236 if(!cfg.has_attribute(frame_string + "primary")) {
00237 primary_frame_ = t_unset;
00238 } else if(cfg[frame_string + "primary"].to_bool()) {
00239 primary_frame_ = t_true;
00240 } else {
00241 primary_frame_ = t_false;
00242 }
00243 std::vector<std::string> color = utils::split(cfg[frame_string + "text_color"]);
00244 if (color.size() == 3) {
00245 text_color_ = display::rgb(atoi(color[0].c_str()),
00246 atoi(color[1].c_str()), atoi(color[2].c_str()));
00247 }
00248
00249 if (const config::attribute_value *v = cfg.get(frame_string + "duration")) {
00250 duration(*v);
00251 } else {
00252 duration(cfg[frame_string + "end"].to_int() - cfg[frame_string + "begin"].to_int());
00253 }
00254
00255 color = utils::split(cfg[frame_string + "blend_color"]);
00256 if (color.size() == 3) {
00257 blend_with_ = display::rgb(atoi(color[0].c_str()),
00258 atoi(color[1].c_str()), atoi(color[2].c_str()));
00259 }
00260 }
00261
00262 frame_builder & frame_builder::image(const image::locator& image ,const std::string & image_mod)
00263 {
00264 image_ = image;
00265 image_mod_ = image_mod;
00266 return *this;
00267 }
00268 frame_builder & frame_builder::image_diagonal(const image::locator& image_diagonal,const std::string& image_mod)
00269 {
00270 image_diagonal_ = image_diagonal;
00271 image_mod_ = image_mod;
00272 return *this;
00273 }
00274 frame_builder & frame_builder::sound(const std::string& sound)
00275 {
00276 sound_=sound;
00277 return *this;
00278 }
00279 frame_builder & frame_builder::text(const std::string& text,const Uint32 text_color)
00280 {
00281 text_=text;
00282 text_color_=text_color;
00283 return *this;
00284 }
00285 frame_builder & frame_builder::halo(const std::string &halo, const std::string &halo_x, const std::string& halo_y,const std::string & halo_mod)
00286 {
00287 halo_ = halo;
00288 halo_x_ = halo_x;
00289 halo_y_ = halo_y;
00290 halo_mod_= halo_mod;
00291 return *this;
00292 }
00293 frame_builder & frame_builder::duration(const int duration)
00294 {
00295 duration_= duration;
00296 return *this;
00297 }
00298 frame_builder & frame_builder::blend(const std::string& blend_ratio,const Uint32 blend_color)
00299 {
00300 blend_with_=blend_color;
00301 blend_ratio_=blend_ratio;
00302 return *this;
00303 }
00304 frame_builder & frame_builder::highlight(const std::string& highlight)
00305 {
00306 highlight_ratio_=highlight;
00307 return *this;
00308 }
00309 frame_builder & frame_builder::offset(const std::string& offset)
00310 {
00311 offset_=offset;
00312 return *this;
00313 }
00314 frame_builder & frame_builder::submerge(const std::string& submerge)
00315 {
00316 submerge_=submerge;
00317 return *this;
00318 }
00319 frame_builder & frame_builder::x(const std::string& x)
00320 {
00321 x_=x;
00322 return *this;
00323 }
00324 frame_builder & frame_builder::y(const std::string& y)
00325 {
00326 y_=y;
00327 return *this;
00328 }
00329 frame_builder & frame_builder::directional_x(const std::string& directional_x)
00330 {
00331 directional_x_=directional_x;
00332 return *this;
00333 }
00334 frame_builder & frame_builder::directional_y(const std::string& directional_y)
00335 {
00336 directional_y_=directional_y;
00337 return *this;
00338 }
00339 frame_builder & frame_builder::auto_vflip(const bool auto_vflip)
00340 {
00341 if(auto_vflip) auto_vflip_ = t_true;
00342 else auto_vflip_ = t_false;
00343 return *this;
00344 }
00345 frame_builder & frame_builder::auto_hflip(const bool auto_hflip)
00346 {
00347 if(auto_hflip) auto_hflip_ = t_true;
00348 else auto_hflip_ = t_false;
00349 return *this;
00350 }
00351 frame_builder & frame_builder::primary_frame(const bool primary_frame)
00352 {
00353 if(primary_frame) primary_frame_ = t_true;
00354 else primary_frame_ = t_false;
00355 return *this;
00356 }
00357 frame_builder & frame_builder::drawing_layer(const std::string& drawing_layer)
00358 {
00359 drawing_layer_=drawing_layer;
00360 return *this;
00361 }
00362
00363
00364 frame_parsed_parameters::frame_parsed_parameters(const frame_builder & builder, int duration) :
00365 duration_(duration ? duration :builder.duration_),
00366 image_(builder.image_),
00367 image_diagonal_(builder.image_diagonal_),
00368 image_mod_(builder.image_mod_),
00369 halo_(builder.halo_,duration_),
00370 halo_x_(builder.halo_x_,duration_),
00371 halo_y_(builder.halo_y_,duration_),
00372 halo_mod_(builder.halo_mod_),
00373 sound_(builder.sound_),
00374 text_(builder.text_),
00375 text_color_(builder.text_color_),
00376 blend_with_(builder.blend_with_),
00377 blend_ratio_(builder.blend_ratio_,duration_),
00378 highlight_ratio_(builder.highlight_ratio_,duration_),
00379 offset_(builder.offset_,duration_),
00380 submerge_(builder.submerge_,duration_),
00381 x_(builder.x_,duration_),
00382 y_(builder.y_,duration_),
00383 directional_x_(builder.directional_x_,duration_),
00384 directional_y_(builder.directional_y_,duration_),
00385 auto_vflip_(builder.auto_vflip_),
00386 auto_hflip_(builder.auto_hflip_),
00387 primary_frame_(builder.primary_frame_),
00388 drawing_layer_(builder.drawing_layer_,duration_)
00389 {}
00390
00391
00392 bool frame_parsed_parameters::does_not_change() const
00393 {
00394 return halo_.does_not_change() &&
00395 halo_x_.does_not_change() &&
00396 halo_y_.does_not_change() &&
00397 blend_ratio_.does_not_change() &&
00398 highlight_ratio_.does_not_change() &&
00399 offset_.does_not_change() &&
00400 submerge_.does_not_change() &&
00401 x_.does_not_change() &&
00402 y_.does_not_change() &&
00403 directional_x_.does_not_change() &&
00404 directional_y_.does_not_change() &&
00405 drawing_layer_.does_not_change();
00406 }
00407 bool frame_parsed_parameters::need_update() const
00408 {
00409 if(!halo_.does_not_change() ||
00410 !halo_x_.does_not_change() ||
00411 !halo_y_.does_not_change() ||
00412 !blend_ratio_.does_not_change() ||
00413 !highlight_ratio_.does_not_change() ||
00414 !offset_.does_not_change() ||
00415 !submerge_.does_not_change() ||
00416 !x_.does_not_change() ||
00417 !y_.does_not_change() ||
00418 !directional_x_.does_not_change() ||
00419 !directional_y_.does_not_change() ||
00420 !drawing_layer_.does_not_change() ) {
00421 return true;
00422 }
00423 return false;
00424 }
00425
00426 const frame_parameters frame_parsed_parameters::parameters(int current_time) const
00427 {
00428 frame_parameters result;
00429 result.duration = duration_;
00430 result.image = image_;
00431 result.image_diagonal = image_diagonal_;
00432 result.image_mod = image_mod_;
00433 result.halo = halo_.get_current_element(current_time);
00434 result.halo_x = halo_x_.get_current_element(current_time);
00435 result.halo_y = halo_y_.get_current_element(current_time);
00436 result.halo_mod = halo_mod_;
00437 result.sound = sound_;
00438 result.text = text_;
00439 result.text_color = text_color_;
00440 result.blend_with = blend_with_;
00441 result.blend_ratio = blend_ratio_.get_current_element(current_time);
00442 result.highlight_ratio = highlight_ratio_.get_current_element(current_time,1.0);
00443 result.offset = offset_.get_current_element(current_time,-1000);
00444 result.submerge = submerge_.get_current_element(current_time);
00445 result.x = x_.get_current_element(current_time);
00446 result.y = y_.get_current_element(current_time);
00447 result.directional_x = directional_x_.get_current_element(current_time);
00448 result.directional_y = directional_y_.get_current_element(current_time);
00449 result.auto_vflip = auto_vflip_;
00450 result.auto_hflip = auto_hflip_;
00451 result.primary_frame = primary_frame_;
00452 result.drawing_layer = drawing_layer_.get_current_element(current_time,display::LAYER_UNIT_DEFAULT-display::LAYER_UNIT_FIRST);
00453 return result;
00454 }
00455
00456 void frame_parsed_parameters::override( int duration
00457 , const std::string& highlight
00458 , const std::string& blend_ratio
00459 , Uint32 blend_color
00460 , const std::string& offset
00461 , const std::string& layer
00462 , const std::string& modifiers)
00463 {
00464
00465 if(!highlight.empty()) {
00466 highlight_ratio_ = progressive_double(highlight,duration);
00467 } else if(duration != duration_){
00468 highlight_ratio_=progressive_double(highlight_ratio_.get_original(),duration);
00469 }
00470 if(!offset.empty()) {
00471 offset_= progressive_double(offset,duration);
00472 } else if(duration != duration_){
00473 offset_=progressive_double(offset_.get_original(),duration);
00474 }
00475 if(!blend_ratio.empty()) {
00476 blend_ratio_ = progressive_double(blend_ratio,duration);
00477 blend_with_ = blend_color;
00478 } else if(duration != duration_){
00479 blend_ratio_=progressive_double(blend_ratio_.get_original(),duration);
00480 }
00481 if(!layer.empty()) {
00482 drawing_layer_ = progressive_int(layer,duration);
00483 } else if(duration != duration_){
00484 drawing_layer_=progressive_int(drawing_layer_.get_original(),duration);
00485 }
00486 if(!modifiers.empty()) {
00487 image_mod_+=modifiers;
00488 }
00489
00490 if(duration != duration_) {
00491 halo_ = progressive_string(halo_.get_original(),duration);
00492 halo_x_ = progressive_int(halo_x_.get_original(),duration);
00493 halo_y_ = progressive_int(halo_y_.get_original(),duration);
00494 submerge_=progressive_double(submerge_.get_original(),duration);
00495 x_=progressive_int(x_.get_original(),duration);
00496 y_=progressive_int(y_.get_original(),duration);
00497 directional_x_=progressive_int(directional_x_.get_original(),duration);
00498 directional_y_=progressive_int(directional_y_.get_original(),duration);
00499 duration_ = duration;
00500 }
00501 }
00502
00503
00504 void unit_frame::redraw(const int frame_time,bool first_time,const map_location & src,const map_location & dst,int*halo_id,const frame_parameters & animation_val,const frame_parameters & engine_val)const
00505 {
00506 const int xsrc = game_display::get_singleton()->get_location_x(src);
00507 const int ysrc = game_display::get_singleton()->get_location_y(src);
00508 const int xdst = game_display::get_singleton()->get_location_x(dst);
00509 const int ydst = game_display::get_singleton()->get_location_y(dst);
00510 const map_location::DIRECTION direction = src.get_relative_dir(dst);
00511
00512 const frame_parameters current_data = merge_parameters(frame_time,animation_val,engine_val);
00513 double tmp_offset = current_data.offset;
00514
00515
00516
00517
00518
00519 int d2 = display::get_singleton()->hex_size() / 2;
00520 if(first_time ) {
00521
00522 if(!current_data.sound.empty() ) {
00523 sound::play_sound(current_data.sound);
00524 }
00525 if(!current_data.text.empty() ) {
00526 game_display::get_singleton()->float_label(src,current_data.text,
00527 (current_data.text_color & 0x00FF0000) >> 16,
00528 (current_data.text_color & 0x0000FF00) >> 8,
00529 (current_data.text_color & 0x000000FF) >> 0);
00530 }
00531 }
00532 image::locator image_loc;
00533 if(direction != map_location::NORTH && direction != map_location::SOUTH) {
00534 image_loc = image::locator(current_data.image_diagonal,current_data.image_mod);
00535 }
00536 if(image_loc.is_void() || image_loc.get_filename() == "") {
00537 image_loc = image::locator(current_data.image,current_data.image_mod);
00538 }
00539
00540 surface image;
00541 if(!image_loc.is_void() && image_loc.get_filename() != "") {
00542 image=image::get_image(image_loc, image::SCALED_TO_ZOOM);
00543 }
00544 const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * xsrc) + d2;
00545 const int y = static_cast<int>(tmp_offset * ydst + (1.0-tmp_offset) * ysrc) + d2;
00546 if (image != NULL) {
00547 #ifdef LOW_MEM
00548 bool facing_west = false;
00549 #else
00550 bool facing_west = direction == map_location::NORTH_WEST || direction == map_location::SOUTH_WEST;
00551 #endif
00552 bool facing_north = direction == map_location::NORTH_WEST || direction == map_location::NORTH || direction == map_location::NORTH_EAST;
00553 if(!current_data.auto_hflip) facing_west = false;
00554 if(!current_data.auto_vflip) facing_north = true;
00555 int my_x = x + current_data.x- image->w/2;
00556 int my_y = y + current_data.y- image->h/2;
00557 if(facing_west) {
00558 my_x -= current_data.directional_x;
00559 } else {
00560 my_x += current_data.directional_x;
00561 }
00562 if(facing_north) {
00563 my_y += current_data.directional_y;
00564 } else {
00565 my_y -= current_data.directional_y;
00566 }
00567
00568 game_display::get_singleton()->render_image( my_x,my_y,
00569 static_cast<display::tdrawing_layer>(display::LAYER_UNIT_FIRST+current_data.drawing_layer),
00570 src, image, facing_west, false,
00571 ftofxp(current_data.highlight_ratio), current_data.blend_with,
00572 current_data.blend_ratio,current_data.submerge,!facing_north);
00573 }
00574 halo::remove(*halo_id);
00575 *halo_id = halo::NO_HALO;
00576 if(!current_data.halo.empty()) {
00577 halo::ORIENTATION orientation;
00578 switch(direction)
00579 {
00580 case map_location::NORTH:
00581 case map_location::NORTH_EAST:
00582 orientation = halo::NORMAL;
00583 break;
00584 case map_location::SOUTH_EAST:
00585 case map_location::SOUTH:
00586 if(!current_data.auto_vflip) {
00587 orientation = halo::NORMAL;
00588 } else {
00589 orientation = halo::VREVERSE;
00590 }
00591 break;
00592 case map_location::SOUTH_WEST:
00593 if(!current_data.auto_vflip) {
00594 orientation = halo::HREVERSE;
00595 } else {
00596 orientation = halo::HVREVERSE;
00597 }
00598 break;
00599 case map_location::NORTH_WEST:
00600 orientation = halo::HREVERSE;
00601 break;
00602 case map_location::NDIRECTIONS:
00603 default:
00604 orientation = halo::NORMAL;
00605 break;
00606 }
00607 if(direction != map_location::SOUTH_WEST && direction != map_location::NORTH_WEST) {
00608 *halo_id = halo::add(static_cast<int>(x+current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
00609 static_cast<int>(y+current_data.halo_y* game_display::get_singleton()->get_zoom_factor()),
00610 current_data.halo + current_data.halo_mod,
00611 map_location(-1, -1),
00612 orientation);
00613 } else {
00614 *halo_id = halo::add(static_cast<int>(x-current_data.halo_x* game_display::get_singleton()->get_zoom_factor()),
00615 static_cast<int>(y+current_data.halo_y* game_display::get_singleton()->get_zoom_factor()),
00616 current_data.halo + current_data.halo_mod,
00617 map_location(-1, -1),
00618 orientation);
00619 }
00620 }
00621 }
00622 std::set<map_location> unit_frame::get_overlaped_hex(const int frame_time,const map_location & src,const map_location & dst,const frame_parameters & animation_val,const frame_parameters & engine_val) const
00623 {
00624 display* disp = display::get_singleton();
00625 const int xsrc = disp->get_location_x(src);
00626 const int ysrc = disp->get_location_y(src);
00627 const int xdst = disp->get_location_x(dst);
00628 const int ydst = disp->get_location_y(dst);
00629 const map_location::DIRECTION direction = src.get_relative_dir(dst);
00630
00631 const frame_parameters current_data = merge_parameters(frame_time,animation_val,engine_val);
00632 double tmp_offset = current_data.offset;
00633 int d2 = game_display::get_singleton()->hex_size() / 2;
00634
00635 image::locator image_loc;
00636 if(direction != map_location::NORTH && direction != map_location::SOUTH) {
00637 image_loc = image::locator(current_data.image_diagonal,current_data.image_mod);
00638 }
00639 if(image_loc.is_void() || image_loc.get_filename() == "") {
00640 image_loc = image::locator(current_data.image,current_data.image_mod);
00641 }
00642
00643
00644
00645 std::set<map_location> result;
00646 if(tmp_offset==0 && current_data.x == 0 && current_data.directional_x == 0 && image::is_in_hex(image_loc)) {
00647 result.insert(src);
00648 int my_y = current_data.y;
00649 bool facing_north = direction == map_location::NORTH_WEST || direction == map_location::NORTH || direction == map_location::NORTH_EAST;
00650 if(!current_data.auto_vflip) facing_north = true;
00651 if(facing_north) {
00652 my_y += current_data.directional_y;
00653 } else {
00654 my_y -= current_data.directional_y;
00655 }
00656 if(my_y < 0) {
00657 result.insert(src.get_direction(map_location::NORTH));
00658 result.insert(src.get_direction(map_location::NORTH_EAST));
00659 result.insert(src.get_direction(map_location::NORTH_WEST));
00660 } else if(my_y > 0) {
00661 result.insert(src.get_direction(map_location::SOUTH));
00662 result.insert(src.get_direction(map_location::SOUTH_EAST));
00663 result.insert(src.get_direction(map_location::SOUTH_WEST));
00664 }
00665 } else {
00666 int w=0;
00667 int h =0;
00668 #ifdef _OPENMP
00669 #pragma omp critical(frame_surface) // with the way surfaces work it's hard to lock the refcount within sdl_utils
00670 #endif //_OPENMP
00671 {
00672 surface image;
00673 if(!image_loc.is_void() && image_loc.get_filename() != "") {
00674 image=image::get_image(image_loc,
00675 image::SCALED_TO_ZOOM
00676 );
00677 }
00678 if(image != NULL) {
00679 w = image->w;
00680 h = image->h;
00681 }
00682 }
00683 if (w != 0 || h != 0) {
00684 const int x = static_cast<int>(tmp_offset * xdst + (1.0-tmp_offset) * xsrc);
00685 const int y = static_cast<int>(tmp_offset * ydst + (1.0-tmp_offset) * ysrc);
00686 #ifdef LOW_MEM
00687 bool facing_west = false;
00688 #else
00689 bool facing_west = direction == map_location::NORTH_WEST || direction == map_location::SOUTH_WEST;
00690 #endif
00691 bool facing_north = direction == map_location::NORTH_WEST || direction == map_location::NORTH || direction == map_location::NORTH_EAST;
00692 if(!current_data.auto_vflip) facing_north = true;
00693 if(!current_data.auto_hflip) facing_west = false;
00694 int my_x = x +current_data.x+d2- w/2;
00695 int my_y = y +current_data.y+d2- h/2;
00696 if(facing_west) {
00697 my_x += current_data.directional_x;
00698 } else {
00699 my_x -= current_data.directional_x;
00700 }
00701 if(facing_north) {
00702 my_y += current_data.directional_y;
00703 } else {
00704 my_y -= current_data.directional_y;
00705 }
00706
00707 const SDL_Rect r = create_rect(my_x, my_y, w, h);
00708
00709
00710
00711
00712 result.insert(src);
00713 display::rect_of_hexes underlying_hex = disp->hexes_under_rect(r);
00714 result.insert(underlying_hex.begin(),underlying_hex.end());
00715 } else {
00716
00717
00718
00719 result.insert(src);
00720 result.insert(dst);
00721 }
00722 }
00723 return result;
00724 }
00725
00726
00727
00728 const frame_parameters unit_frame::merge_parameters(int current_time,const frame_parameters & animation_val,const frame_parameters & engine_val) const
00729 {
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 frame_parameters result;
00740 const frame_parameters & current_val = builder_.parameters(current_time);
00741
00742 result.primary_frame = engine_val.primary_frame;
00743 if(animation_val.primary_frame != t_unset) result.primary_frame = animation_val.primary_frame;
00744 if(current_val.primary_frame != t_unset) result.primary_frame = current_val.primary_frame;
00745 const bool primary = result.primary_frame;
00746
00747
00748 result.image = current_val.image.is_void() || current_val.image.get_filename() == ""?animation_val.image:current_val.image;
00749 if(primary && ( result.image.is_void() || result.image.get_filename().empty())) {
00750 result.image = engine_val.image;
00751 }
00752
00753
00754 result.image_diagonal = current_val.image_diagonal.is_void() || current_val.image_diagonal.get_filename() == ""?animation_val.image_diagonal:current_val.image_diagonal;
00755 if(primary && ( result.image_diagonal.is_void() || result.image_diagonal.get_filename().empty())) {
00756 result.image_diagonal = engine_val.image_diagonal;
00757 }
00758
00759
00760
00761
00762 result.image_mod = current_val.image_mod +animation_val.image_mod;
00763 if(primary) {
00764 result.image_mod += engine_val.image_mod;
00765 } else {
00766 result.image_mod += engine_val.halo_mod;
00767 }
00768
00769 assert(engine_val.halo.empty());
00770 result.halo = current_val.halo.empty()?animation_val.halo:current_val.halo;
00771
00772 assert(engine_val.halo_x == 0);
00773 result.halo_x = current_val.halo_x?current_val.halo_x:animation_val.halo_x;
00774
00775
00776 result.halo_y = current_val.halo_y?current_val.halo_y:animation_val.halo_y;
00777 result.halo_y += engine_val.halo_y;
00778
00779 result.halo_mod = current_val.halo_mod +animation_val.halo_mod;
00780 result.halo_mod += engine_val.halo_mod;
00781
00782 assert(engine_val.duration == 0);
00783 result.duration = current_val.duration;
00784
00785 assert(engine_val.sound.empty());
00786 result.sound = current_val.sound.empty()?animation_val.sound:current_val.sound;
00787
00788 assert(engine_val.text.empty());
00789 result.text = current_val.text.empty()?animation_val.text:current_val.text;
00790
00791 assert(engine_val.text_color == 0);
00792 result.text_color = current_val.text_color?current_val.text_color:animation_val.text_color;
00793
00794
00795 result.blend_with = current_val.blend_with?current_val.blend_with:animation_val.blend_with;
00796 if(primary&& engine_val.blend_with) result.blend_with = display::max_rgb(engine_val.blend_with,result.blend_with);
00797
00798
00799 result.blend_ratio = current_val.blend_ratio?current_val.blend_ratio:animation_val.blend_ratio;
00800 if(primary && engine_val.blend_ratio) {
00801 result.blend_ratio = std::min(
00802 result.blend_ratio + engine_val.blend_ratio
00803 , 1.0);
00804 }
00805
00806
00807 result.highlight_ratio = current_val.highlight_ratio!=1.0?current_val.highlight_ratio:animation_val.highlight_ratio;
00808 if(primary && engine_val.highlight_ratio != 1.0) result.highlight_ratio = result.highlight_ratio +engine_val.highlight_ratio - 1.0;
00809
00810 assert(engine_val.offset == 0);
00811 result.offset = (current_val.offset!=-1000)?current_val.offset:animation_val.offset;
00812 if(result.offset == -1000) result.offset = 0.0;
00813
00814
00815 result.submerge = current_val.submerge?current_val.submerge:animation_val.submerge;
00816 if(primary && engine_val.submerge && !result.submerge ) result.submerge = engine_val.submerge;
00817
00818 assert(engine_val.x == 0);
00819 result.x = current_val.x?current_val.x:animation_val.x;
00820
00821
00822 result.y = current_val.y?current_val.y:animation_val.y;
00823 result.y += engine_val.y;
00824
00825 assert(engine_val.directional_x == 0);
00826 result.directional_x = current_val.directional_x?current_val.directional_x:animation_val.directional_x;
00827 assert(engine_val.directional_y == 0);
00828 result.directional_y = current_val.directional_y?current_val.directional_y:animation_val.directional_y;
00829
00830 assert(engine_val.drawing_layer == display::LAYER_UNIT_DEFAULT-display::LAYER_UNIT_FIRST);
00831 result.drawing_layer = current_val.drawing_layer != display::LAYER_UNIT_DEFAULT-display::LAYER_UNIT_FIRST?
00832 current_val.drawing_layer:animation_val.drawing_layer;
00833
00834
00835 result.auto_hflip = engine_val.auto_hflip;
00836 if(animation_val.auto_hflip != t_unset) result.auto_hflip = animation_val.auto_hflip;
00837 if(current_val.auto_hflip != t_unset) result.auto_hflip = current_val.auto_hflip;
00838 if(result.auto_hflip == t_unset) result.auto_hflip = t_true;
00839
00840 result.auto_vflip = engine_val.auto_vflip;
00841 if(animation_val.auto_vflip != t_unset) result.auto_vflip = animation_val.auto_vflip;
00842 if(current_val.auto_vflip != t_unset) result.auto_vflip = current_val.auto_vflip;
00843 if(result.auto_vflip == t_unset) {
00844 if(primary) result.auto_vflip=t_false;
00845 else result.auto_vflip = t_true;
00846 }
00847 #ifdef LOW_MEM
00848 if(primary) {
00849 result.image= engine_val.image;
00850 result.image_diagonal= engine_val.image;
00851 }
00852 #endif
00853 return result;
00854 }