33 return cfg[
"healed_sound"].
empty() ?
"heal.wav" : cfg[
"healed_sound"].str();
54 std::vector<config::const_all_children_iterator>
children;
62 : itors(cfg.all_children_range()), branches(1), parent(nullptr)
64 branches.back().attributes.merge_attributes(cfg);
68 : itors(cfg.all_children_range()), branches(p->branches), parent(p)
74 bool previously_hits_set =
false;
75 bool previously_direction_set =
false;
76 bool previously_terrain_set =
false;
77 bool previously_value_set =
false;
78 bool previously_value_2nd_set =
false;
80 const std::string s_cfg_hits = cfg[
"hits"];
81 const std::string s_cfg_direction = cfg[
"direction"];
82 const std::string s_cfg_terrain = cfg[
"terrain_types"];
83 const std::string s_cfg_value = cfg[
"value"];
84 const std::string s_cfg_value_2nd = cfg[
"value_2nd"];
86 for(
const auto& branch : branches) {
87 const std::string s_branch_hits = branch.attributes[
"hits"];
88 const std::string s_branch_direction = branch.attributes[
"direction"];
89 const std::string s_branch_terrain = branch.attributes[
"terrain_types"];
90 const std::string s_branch_value = branch.attributes[
"value"];
91 const std::string s_branch_value_2nd = branch.attributes[
"value_second"];
93 if(!s_branch_hits.empty() && s_branch_hits == s_cfg_hits) {
94 previously_hits_set =
true;
97 if(!s_branch_direction.empty() && s_branch_direction == s_cfg_direction) {
98 previously_direction_set =
true;
101 if(!s_branch_terrain.empty() && s_branch_terrain == s_cfg_terrain) {
102 previously_terrain_set =
true;
105 if(!s_branch_value.empty() && s_branch_value == s_cfg_value) {
106 previously_value_set =
true;
109 if(!s_branch_value_2nd.empty() && s_branch_value_2nd == s_cfg_value_2nd) {
110 previously_value_2nd_set =
true;
116 for(
auto iter = branches.begin(); iter != branches.end(); ) {
117 const std::string s_branch_hits = (*iter).attributes[
"hits"];
118 const std::string s_branch_direction = (*iter).attributes[
"direction"];
119 const std::string s_branch_terrain = (*iter).attributes[
"terrain_types"];
120 const std::string s_branch_value = (*iter).attributes[
"value"];
121 const std::string s_branch_value_2nd = (*iter).attributes[
"value_second"];
123 const bool hits_match = (previously_hits_set && s_branch_hits != s_cfg_hits);
124 const bool direction_match = (previously_direction_set && s_branch_direction != s_cfg_direction);
125 const bool terrain_match = (previously_terrain_set && s_branch_terrain != s_cfg_terrain);
126 const bool value_match = (previously_value_set && s_branch_value != s_cfg_value);
127 const bool value_2nd_match = (previously_value_2nd_set && s_branch_value_2nd != s_cfg_value_2nd);
129 if((!previously_hits_set || hits_match) &&
130 (!previously_direction_set || direction_match) &&
131 (!previously_terrain_set || terrain_match) &&
132 (!previously_value_set || value_match) &&
133 (!previously_value_2nd_set || value_2nd_match) &&
134 (hits_match || direction_match || terrain_match || value_match || value_2nd_match))
136 branches.
erase(iter++);
138 (*iter).attributes.merge_attributes(cfg);
145 for(
auto iter = parent->branches.begin(); iter != parent->branches.end(); ) {
146 const std::string s_branch_hits = (*iter).attributes[
"hits"];
147 const std::string s_branch_direction = (*iter).attributes[
"direction"];
148 const std::string s_branch_terrain = (*iter).attributes[
"terrain_types"];
149 const std::string s_branch_value = (*iter).attributes[
"value"];
150 const std::string s_branch_value_2nd = (*iter).attributes[
"value_second"];
152 const bool hits_match = (previously_hits_set && s_branch_hits == s_cfg_hits);
153 const bool direction_match = (previously_direction_set && s_branch_direction == s_cfg_direction);
154 const bool terrain_match = (previously_terrain_set && s_branch_terrain == s_cfg_terrain);
155 const bool value_match = (previously_value_set && s_branch_value == s_cfg_value);
156 const bool value_2nd_match = (previously_value_2nd_set && s_branch_value_2nd == s_cfg_value_2nd);
158 if((!previously_hits_set || hits_match) &&
159 (!previously_direction_set || direction_match) &&
160 (!previously_terrain_set || terrain_match) &&
161 (!previously_value_set || value_match) &&
162 (!previously_value_2nd_set || value_2nd_match) &&
163 (hits_match || direction_match || terrain_match || value_match || value_2nd_match))
165 parent->branches.erase(iter++);
185 std::list<animation_cursor> anim_cursors;
186 anim_cursors.emplace_back(anim_cfg);
188 while(!anim_cursors.empty()) {
192 if(ac.
itors.empty()) {
197 anim_cursors.pop_back();
201 if(ac.
itors.front().key !=
"if") {
207 ac.
itors.pop_front();
215 anim_cursors.emplace_back(ac.
itors.front().cfg, &ac);
216 ac.
itors.pop_front();
218 }
while (!ac.
itors.empty() && ac.
itors.front().key ==
"else");
229 std::cout <<
"--branch--\n" << ab.attributes;
231 std::cout <<
"--branchcfg--\n" << ci->cfg;
238 assert(anim_cursors.size() == 1);
240 expanded_anims.splice(expanded_anims.end(), ac.branches, ac.branches.begin(), ac.branches.end());
250 return expanded_animations;
257 , secondary_unit_filter_()
260 , base_score_(variation)
263 , primary_attack_filter_()
264 , secondary_attack_filter_()
268 , unit_anim_(start_time,builder)
271 , invalidated_(false)
272 , play_offscreen_(true)
302 if(fr.key == frame_string) {
306 if(fr.key.find(
"_frame", fr.key.size() - 6) == std::string::npos) {
319 const std::vector<std::string>& my_directions =
utils::split(cfg[
"direction"]);
320 for(
const auto& direction : my_directions) {
345 value_.push_back(atoi(v.c_str()));
349 if(
h ==
"yes" ||
h ==
"hit") {
350 hits_.push_back(hit_type::HIT);
353 if(
h ==
"no" ||
h ==
"miss") {
354 hits_.push_back(hit_type::MISS);
357 if(
h ==
"yes" ||
h ==
"kill" ) {
358 hits_.push_back(hit_type::KILL);
362 for(
const auto& v2 :
utils::split(cfg[
"value_second"])) {
363 value2_.push_back(atoi(v2.c_str()));
383 if(!event.empty() && !
event_.empty()) {
465 if(!attack->matches_filter(iter))
return MATCH_FAIL;
476 if(!second_attack->matches_filter(iter))
return MATCH_FAIL;
487 std::vector<unit_animation> animation_base;
488 for(
const auto& anim : animations) {
489 if(std::find(anim.event_.begin(), anim.event_.end(),
"default") != anim.event_.end()) {
490 animation_base.push_back(anim);
492 animation_base.back().event_.clear();
496 const std::string default_image = cfg[
"image"];
498 if(animation_base.empty()) {
504 frame_builder().
image(default_image).duration(300).blend(
"0.0~0.3:100,0.3~0.0:200", {255,255,255}),
505 "_disabled_selected_", 0));
507 for(
const auto& base : animation_base) {
508 animations.push_back(base);
509 animations.back().event_ = {
"standing" };
510 animations.back().play_offscreen_ =
false;
512 animations.push_back(base);
513 animations.back().event_ = {
"_ghosted_" };
514 animations.back().unit_anim_.override(0, animations.back().unit_anim_.get_animation_duration(),
particle::UNSET,
"0.9",
"", {0,0,0},
"",
"",
"~GS()");
516 animations.push_back(base);
517 animations.back().event_ = {
"_disabled_ghosted_" };
518 animations.back().unit_anim_.override(0, 1,
particle::UNSET,
"0.4",
"", {0,0,0},
"",
"",
"~GS()");
520 animations.push_back(base);
521 animations.back().event_ = {
"selected" };
522 animations.back().unit_anim_.override(0, 300,
particle::UNSET,
"",
"0.0~0.3:100,0.3~0.0:200", {255,255,255});
524 animations.push_back(base);
525 animations.back().event_ = {
"recruited" };
528 animations.push_back(base);
529 animations.back().event_ = {
"levelin" };
530 animations.back().unit_anim_.override(0, 600,
particle::NO_CYCLE,
"",
"1~0:600", {255,255,255});
532 animations.push_back(base);
533 animations.back().event_ = {
"levelout" };
534 animations.back().unit_anim_.override(0, 600,
particle::NO_CYCLE,
"",
"0~1:600,1", {255,255,255});
536 animations.push_back(base);
537 animations.back().event_ = {
"pre_movement" };
540 animations.push_back(base);
541 animations.back().event_ = {
"post_movement" };
544 animations.push_back(base);
545 animations.back().event_ = {
"movement" };
546 animations.back().unit_anim_.override(0, 200,
549 animations.push_back(base);
550 animations.back().event_ = {
"defend" };
551 animations.back().unit_anim_.override(0, animations.back().unit_anim_.get_animation_duration(),
553 animations.back().hits_.push_back(hit_type::HIT);
554 animations.back().hits_.push_back(hit_type::KILL);
556 animations.push_back(base);
557 animations.back().event_ = {
"defend" };
559 animations.push_back(base);
560 animations.back().event_ = {
"attack" };
561 animations.back().unit_anim_.override(-150, 300,
particle::NO_CYCLE,
"",
"", {0,0,0},
"0~0.6:150,0.6~0:150", std::to_string(
display::LAYER_UNIT_MOVE_DEFAULT-
display::LAYER_UNIT_FIRST));
562 animations.back().primary_attack_filter_.emplace_back(
"range",
"melee");
564 animations.push_back(base);
565 animations.back().event_ = {
"attack" };
567 animations.back().primary_attack_filter_.emplace_back(
"range",
"ranged");
569 animations.push_back(base);
570 animations.back().event_ = {
"death" };
572 animations.back().sub_anims_[
"_death_sound"] =
particle();
573 animations.back().sub_anims_[
"_death_sound"].add_frame(1,
frame_builder().
sound(cfg[
"die_sound"]),
true);
575 animations.push_back(base);
576 animations.back().event_ = {
"victory" };
577 animations.back().unit_anim_.override(0, animations.back().unit_anim_.get_animation_duration(),
particle::CYCLE);
579 animations.push_back(base);
581 animations.back().event_ = {
"pre_teleport" };
583 animations.push_back(base);
585 animations.back().event_ = {
"post_teleport" };
587 animations.push_back(base);
588 animations.back().event_ = {
"healing" };
590 animations.push_back(base);
591 animations.back().event_ = {
"healed" };
592 animations.back().unit_anim_.override(0, 300,
particle::NO_CYCLE,
"",
"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30", {255,255,255});
596 animations.back().sub_anims_[
"_healed_sound"].add_frame(1,
frame_builder().
sound(healed_sound),
true);
598 animations.push_back(base);
599 animations.back().event_ = {
"poisoned" };
600 animations.back().unit_anim_.override(0, 300,
particle::NO_CYCLE,
"",
"0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30", {0,255,0});
601 animations.back().sub_anims_[
"_poison_sound"] =
particle();
607 const config& cfg,
char const* tag_name,
char const* apply_to,
609 bool offscreen =
true)
613 anim[
"apply_to"] = apply_to;
617 if(v.
empty()) v =
false;
623 animations.emplace_back(anim);
630 animations.emplace_back(ab.merge());
648 anim[
"apply_to"] =
"standing";
649 anim[
"cycles"] =
true;
653 std::string sub_frame_name = ci->key;
654 std::size_t pos = sub_frame_name.find(
"_frame");
655 if(pos != std::string::npos) {
656 anim[sub_frame_name.substr(0, pos) +
"_cycles"] =
true;
660 if(anim[
"layer"].empty()) {
661 anim[
"layer"] = default_layer;
664 if(anim[
"offscreen"].empty()) {
665 anim[
"offscreen"] =
false;
668 animations.emplace_back(anim);
674 anim[
"apply_to"] =
"default";
675 anim[
"cycles"] =
true;
678 std::string sub_frame_name = ci->key;
679 std::size_t pos = sub_frame_name.find(
"_frame");
680 if(pos != std::string::npos) {
681 anim[sub_frame_name.substr(0, pos) +
"_cycles"] =
true;
685 if(anim[
"layer"].empty()) {
686 anim[
"layer"] = default_layer;
689 if(anim[
"offscreen"].empty()) {
690 anim[
"offscreen"] =
false;
693 animations.emplace_back(anim);
698 anim[
"apply_to"] =
"healing";
699 anim[
"value"] = anim[
"damage"];
701 if(anim[
"layer"].empty()) {
702 anim[
"layer"] = default_layer;
705 animations.emplace_back(anim);
710 anim[
"apply_to"] =
"healed";
711 anim[
"value"] = anim[
"healing"];
713 if(anim[
"layer"].empty()) {
714 anim[
"layer"] = default_layer;
717 animations.emplace_back(anim);
718 animations.back().sub_anims_[
"_healed_sound"] =
particle();
721 animations.back().sub_anims_[
"_healed_sound"].add_frame(1,
frame_builder().
sound(healed_sound),
true);
726 anim[
"apply_to"] =
"poisoned";
727 anim[
"value"] = anim[
"damage"];
729 if(anim[
"layer"].empty()) {
730 anim[
"layer"] = default_layer;
733 animations.emplace_back(anim);
734 animations.back().sub_anims_[
"_poison_sound"] =
particle();
742 anim[
"apply_to"] =
"movement";
744 if(anim[
"offset"].empty()) {
745 anim[
"offset"] =
"0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,0~1:200,";
748 if(anim[
"layer"].empty()) {
749 anim[
"layer"] = move_layer;
752 animations.emplace_back(anim);
759 anim[
"apply_to"] =
"defend";
761 if(anim[
"layer"].empty()) {
762 anim[
"layer"] = default_layer;
765 if(!anim[
"damage"].empty() && anim[
"value"].empty()) {
766 anim[
"value"] = anim[
"damage"];
769 if(anim[
"hits"].empty()) {
770 anim[
"hits"] =
false;
771 animations.emplace_back(anim);
772 animations.back().base_score_--;
775 animations.emplace_back(anim);
776 animations.back().base_score_--;
778 image::locator image_loc = animations.back().get_last_frame().end_parameters().image;
782 .blend(
"0.0,0.5:75,0.0:75,0.5:75,0.0", {255,0,0}));
784 for(
const std::string& hit_type :
utils::split(anim[
"hits"])) {
786 tmp[
"hits"] = hit_type;
788 animations.emplace_back(tmp);
790 image::locator image_loc = animations.back().get_last_frame().end_parameters().image;
791 if(hit_type ==
"yes" || hit_type ==
"hit" || hit_type==
"kill") {
795 .blend(
"0.0,0.5:75,0.0:75,0.5:75,0.0", {255,0,0}));
806 anim[
"apply_to"] =
"attack";
808 if(anim[
"layer"].empty()) {
809 anim[
"layer"] = move_layer;
813 if(anim[
"offset"].empty() && missile_fs.
empty()) {
814 anim[
"offset"] =
"0~0.6,0.6~0";
817 if(!missile_fs.empty()) {
818 if(anim[
"missile_offset"].empty()) {
819 anim[
"missile_offset"] =
"0~0.8";
822 if(anim[
"missile_layer"].empty()) {
823 anim[
"missile_layer"] = missile_layer;
833 animations.emplace_back(anim);
838 anim[
"apply_to"] =
"death";
840 if(anim[
"layer"].empty()) {
841 anim[
"layer"] = default_layer;
844 animations.emplace_back(anim);
845 image::locator image_loc = animations.back().get_last_frame().end_parameters().image;
850 .highlight(
"1~0:600"));
852 if(!cfg[
"die_sound"].empty()) {
853 animations.back().sub_anims_[
"_death_sound"] =
particle();
854 animations.back().sub_anims_[
"_death_sound"].add_frame(1,
frame_builder().
sound(cfg[
"die_sound"]),
true);
862 anim[
"apply_to"] = anim[
"flag"];
864 if(anim[
"layer"].empty()) {
865 anim[
"layer"] = default_layer;
868 animations.emplace_back(anim);
873 if(anim[
"layer"].empty()) {
874 anim[
"layer"] = default_layer;
877 anim[
"apply_to"] =
"pre_teleport";
878 animations.emplace_back(anim);
879 animations.back().unit_anim_.set_end_time(0);
881 anim[
"apply_to"] =
"post_teleport";
882 animations.emplace_back(anim);
883 animations.back().unit_anim_.remove_frames_until(0);
890 ,
const std::string& highlight
891 ,
const std::string& blend_ratio
893 ,
const std::string& offset
894 ,
const std::string& layer
895 ,
const std::string& modifiers)
897 set_begin_time(start_time);
898 parameters_.override(duration,highlight,blend_ratio,blend_color,offset,layer,modifiers);
900 if(cycles == CYCLE) {
902 }
else if(cycles==NO_CYCLE) {
906 if(get_animation_duration() < duration) {
908 }
else if(get_animation_duration() > duration) {
909 set_end_time(duration);
917 if(parameters_.need_update())
return true;
931 , last_frame_begin_time_(0)
937 if(!range.empty() && cfg[frame_string +
"start_time"].
empty()) {
938 for(
const config& frame : range) {
945 for(
const config& frame : range) {
950 cycles_ = cfg[frame_string +
"cycles"].to_bool(
false);
962 if(anim.second.need_update())
return true;
977 if(anim.second.need_minimal_update())
return true;
987 if(!anim.second.animation_finished())
return false;
997 if(!anim.second.animation_finished_potential())
return false;
1008 anim.second.update_last_draw_time(acceleration);
1016 result = std::max<int>(result, anim.second.get_end_time());
1026 result = std::min<int>(result, anim.second.get_begin_time());
1035 ,
const std::string& text
1054 anim.second.start_animation(start_time);
1069 anim.second.pause_animation();
1078 anim.second.restart_animation();
1092 anim.second.redraw(value,
src_,
dst_, halo_man);
1101 anim.second.clear_halo();
1113 if(complete_redraw) {
1119 std::set<map_location> tmp = anim.second.get_overlaped_hex(value,
src_,
dst_);
1129 if(complete_redraw) {
1151 std::ostringstream outstream;
1153 return outstream.str();
1159 outstream <<
"[" << events_string <<
"]\n";
1161 outstream <<
"\tstart_time=" << u_animation.
get_begin_time() <<
'\n';
1163 if(u_animation.
hits_.size() > 0) {
1164 std::vector<std::string> hits;
1165 std::transform(u_animation.
hits_.begin(), u_animation.
hits_.end(), std::back_inserter(hits), unit_animation::hit_type::enum_to_string);
1166 outstream <<
"\thits=" <<
utils::join(hits) <<
'\n';
1170 std::vector<std::string> dirs;
1172 outstream <<
"\tdirections=" <<
utils::join(dirs) <<
'\n';
1182 outstream <<
"[filter]\n";
1184 outstream << cfg.
debug();
1187 outstream <<
"[/filter]\n";
1191 outstream <<
"[filter_second]\n";
1193 outstream << cfg.
debug();
1196 outstream <<
"[/filter_second]\n";
1200 outstream <<
"[filter_attack]\n";
1202 outstream << cfg.
debug();
1205 outstream <<
"[/filter_attack]\n";
1209 outstream <<
"[filter_second_attack]\n";
1211 outstream << cfg.
debug();
1214 outstream <<
"[/filter_second_attack]\n";
1218 outstream <<
"\t[frame]\n";
1220 outstream <<
"\t\t" << frame_string <<
"\n";
1222 outstream <<
"\t[/frame]\n";
1225 for(std::pair<std::string, unit_animation::particle>
p : u_animation.
sub_anims_) {
1226 for(std::size_t
i = 0;
i < p.second.get_frames_count();
i++) {
1227 std::string sub_frame_name = p.first;
1228 std::size_t pos = sub_frame_name.find(
"_frame");
1229 if(pos != std::string::npos) sub_frame_name = sub_frame_name.substr(0, pos);
1231 outstream <<
"\t" << sub_frame_name <<
"_start_time=" << p.second.get_begin_time() <<
'\n';
1232 outstream <<
"\t[" << p.first <<
"]\n";
1234 for(
const std::string& frame_string : p.second.get_frame(
i).debug_strings()) {
1235 outstream <<
"\t\t" << frame_string <<
'\n';
1238 outstream <<
"\t[/" << p.first <<
"]\n";
1242 outstream <<
"[/" << events_string <<
"]\n";
1296 ,
const std::string& event
1301 ,
const std::string& text
1303 ,
const unit_animation::hit_type hit_type
1308 if(!animated_unit)
return;
1313 tmp.
my_unit = std::move(animated_unit);
1318 tmp.
animation = tmp.
my_unit->anim_comp().choose_animation(*disp, src, event, dst, value, hit_type, attack, second_attack, value2);
1323 animated_units_.push_back(std::move(tmp));
1330 ,
const std::string& text
1333 if(!animated_unit)
return;
1336 tmp.
my_unit = std::move(animated_unit);
1346 animated_units_.push_back(std::move(tmp));
1350 ,
const std::string& event
1354 ,
const unit_animation::hit_type hit_type
1360 return (animated_unit && animated_unit->anim_comp().choose_animation(*disp, src, event, dst, value, hit_type, attack, second_attack, value2));
1364 ,
const std::string& event
1369 ,
const std::string& text
1371 ,
const unit_animation::hit_type hit_type
1376 if(!animated_unit)
return;
1379 if(animated_unit->anim_comp().get_animation() &&
1380 !animated_unit->anim_comp().get_animation()->animation_finished_potential() &&
1381 animated_unit->anim_comp().get_animation()->matches(
1392 animated_units_.push_back(std::move(tmp));
1394 add_animation(animated_unit,event,src,dst,value,with_bars,text,text_color,hit_type,attack,second_attack,value2);
1400 int begin_time = INT_MAX;
1402 for(
const auto& anim : animated_units_) {
1403 if(anim.my_unit->anim_comp().get_animation()) {
1404 if(anim.animation) {
1405 begin_time = std::min<int>(begin_time, anim.animation->get_begin_time());
1407 begin_time = std::min<int>(begin_time, anim.my_unit->anim_comp().get_animation()->get_begin_time());
1412 for(
auto& anim : animated_units_) {
1413 if(anim.animation) {
1414 anim.my_unit->anim_comp().start_animation(begin_time, anim.animation, anim.with_bars, anim.text, anim.text_color);
1415 anim.animation =
nullptr;
1417 anim.my_unit->anim_comp().get_animation()->update_parameters(anim.src, anim.src.get_direction(anim.my_unit->facing()));
1424 bool finished =
true;
1425 for(
const auto& anim : animated_units_) {
1426 finished &= anim.my_unit->anim_comp().get_animation()->animation_finished_potential();
1436 animated_units_[0].my_unit->anim_comp().get_animation()->set_max_animation_time(animation_time);
1443 int end_tick = animated_units_[0].my_unit->anim_comp().get_animation()->time_to_tick(animation_time);
1444 while(SDL_GetTicks() < static_cast<unsigned int>(end_tick) - std::min<int>(static_cast<unsigned int>(20 / speed), 20)) {
1448 end_tick = animated_units_[0].my_unit->anim_comp().get_animation()->time_to_tick(animation_time);
1451 CVideo::delay(std::max<int>(0, end_tick - SDL_GetTicks() + 5));
1454 animated_units_[0].my_unit->anim_comp().get_animation()->set_max_animation_time(0);
1461 bool finished =
false;
1468 for(
const auto& anim : animated_units_) {
1469 finished &= anim.my_unit->anim_comp().get_animation()->animation_finished_potential();
1476 return animated_units_[0].my_unit->anim_comp().get_animation()->get_animation_time() ;
1481 return animated_units_[0].my_unit->anim_comp().get_animation()->get_animation_time_potential() ;
1486 int end_time = INT_MIN;
1487 for(
const auto& anim : animated_units_) {
1488 if(anim.my_unit->anim_comp().get_animation()) {
1489 end_time = std::max<int>(end_time, anim.my_unit->anim_comp().get_animation()->get_end_time());
1498 for(
const auto& anim : animated_units_) {
1499 if(anim.my_unit->anim_comp().get_animation()) {
1500 anim.my_unit->anim_comp().get_animation()->pause_animation();
1507 for(
const auto& anim : animated_units_) {
1508 if(anim.my_unit->anim_comp().get_animation()) {
1509 anim.my_unit->anim_comp().get_animation()->restart_animation();
1516 for(
const auto& anim : animated_units_) {
1517 anim.my_unit->anim_comp().set_standing();
const frame_parameters parameters(int current_time) const
Getters for the different parameters.
play_controller * controller
void wait_for_end() const
const std::string & get_modifications() const
bool empty() const
Tests for an attribute that either was never set or was set to "".
Describes a unit's animation sequence.
Reserve layers to be selected for WML.
int get_current_frame_end_time() const
std::set< map_location > 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
std::size_t get_frames_count() const
static DIRECTION parse_direction(const std::string &str)
All parameters from a frame at a given instant.
static display * get_singleton()
Returns the display object if a display object exists.
std::vector< config::const_all_children_iterator > children
const_all_children_itors all_children_range() const
In-order iteration over all children.
static std::string get_heal_sound(const config &cfg)
animation_cursor * parent
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
std::vector< hit_type > hits_
This class represents a single unit of a specific type.
int last_frame_begin_time_
Keep most parameters in a separate class to simplify the handling of the large number of parameters b...
int get_current_frame_begin_time() const
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
boost::iterator_range< const_all_children_iterator > const_all_children_itors
Variant for storing WML attributes.
std::vector< map_location::DIRECTION > directions_
bool terrain_matches(const terrain_code &src, const terrain_code &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
frame_parsed_parameters parameters_
animation_cursor(const config &cfg)
static void add_anims(std::vector< unit_animation > &animations, const config &cfg)
std::vector< config > secondary_attack_filter_
static void prepare_single_animation(const config &anim_cfg, animation_branches &expanded_anims)
child_itors child_range(config_key_type key)
int get_current_frame_begin_time() const
bool animation_finished_potential() const
void add_frame(int duration, const unit_frame &value, bool force_change=false)
const unit_animation * animation
std::vector< int > value_
const unit_map & get_units() const
virtual void play_slice(bool is_delay_enabled=true)
int get_begin_time() const
Audio output for sound and music.
void override(int duration, const std::string &highlight="", const std::string &blend_ratio="", color_t blend_color={0, 0, 0}, const std::string &offset="", const std::string &layer="", const std::string &modifiers="")
drawing_layer
The layers to render something on.
bool need_minimal_update() const
void add_frame(int duration, const unit_frame &value, bool force_change=false)
Adds a frame to an animation.
std::vector< std::string > debug_strings() const
int get_animation_time_potential() const
void wait_until(int animation_time) const
int get_animation_duration() const
std::shared_ptr< const unit > unit_const_ptr
int get_begin_time() const
int get_current_frame_time() const
particle(int start_time=0, const frame_builder &builder=frame_builder())
void start_animation(int start_time)
double turbo_speed() const
void new_animation_frame()
const T & get_frame(std::size_t n) const
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
config & add_child_at(config_key_type key, const config &val, unsigned index)
std::set< map_location > overlaped_hex_
bool does_not_change() const
std::vector< config > secondary_unit_filter_
std::vector< std::string > event_
map_display and display: classes which take care of displaying the map and game-data on the screen...
void redraw(const frame_parameters &value, const map_location &src, const map_location &dst, halo::manager &halo_man)
all_children_iterator erase(const all_children_iterator &i)
const unit_frame & get_last_frame() const
Generic locator abstracting the location of an image.
Encapsulates the map of the game.
boost::iterator_range< const_child_iterator > const_child_itors
void add_animation(unit_const_ptr animated_unit, const unit_animation *animation, const map_location &src=map_location::null_location(), bool with_bars=false, const std::string &text="", const color_t text_color={0, 0, 0})
unit_iterator find(std::size_t id)
void redraw(const int frame_time, bool on_start_time, bool in_scope_of_frame, const map_location &src, const map_location &dst, halo::handle &halo_id, halo::manager &halo_man, const frame_parameters &animation_val, const frame_parameters &engine_val) const
animation_branches branches
const unit_frame & get_current_frame() const
static void add_simple_anim(std::vector< unit_animation > &animations, const config &cfg, char const *tag_name, char const *apply_to, display::drawing_layer layer=display::LAYER_UNIT_DEFAULT, bool offscreen=true)
default layer for drawing moving units
friend std::ostream & operator<<(std::ostream &outstream, const unit_animation &u_animation)
std::list< animation_branch > animation_branches
void update_last_draw_time(double acceleration=0)
default layer for drawing units
void replace_anim_if_invalid(unit_const_ptr animated_unit, const std::string &event, const map_location &src=map_location::null_location(), const map_location &dst=map_location::null_location(), const int value=0, bool with_bars=false, const std::string &text="", const color_t text_color={0, 0, 0}, const unit_animation::hit_type hit_type=unit_animation::hit_type::INVALID, const_attack_ptr attack=nullptr, const_attack_ptr second_attack=nullptr, int value2=0)
default layer for missile frames
void start_animation(int start_time, bool cycles=false)
Starts an animation cycle.
bool tile_nearly_on_screen(const map_location &loc) const
Checks if location loc or one of the adjacent tiles is visible on screen.
std::vector< int > value2_
config::const_all_children_itors itors
DIRECTION
Valid directions which can be moved in our hexagonal world.
static void fill_initial_animations(std::vector< unit_animation > &animations, const config &cfg)
const std::string & get_filename() const
std::vector< config > unit_filter_
config & add_child(config_key_type key)
void start_animation(int start_time, const map_location &src=map_location::null_location(), const map_location &dst=map_location::null_location(), const std::string &text="", const color_t text_color={0, 0, 0}, const bool accelerate=true)
void override(int start_time, int duration, const cycle_state cycles, const std::string &highlight="", const std::string &blend_ratio="", color_t blend_color={0, 0, 0}, const std::string &offset="", const std::string &layer="", const std::string &modifiers="")
std::vector< config > primary_attack_filter_
int get_animation_time() const
const gamemap & get_map() const
void update_parameters(const map_location &src, const map_location &dst)
std::map< std::string, particle > sub_anims_
std::vector< std::string > split(const config_attribute_value &val)
std::string debug() const
bool has_animation(unit_const_ptr animated_unit, const std::string &event, const map_location &src=map_location::null_location(), const map_location &dst=map_location::null_location(), const int value=0, const unit_animation::hit_type hit_type=unit_animation::hit_type::INVALID, const_attack_ptr attack=nullptr, const_attack_ptr second_attack=nullptr, int value2=0) const
has_animation : return an boolean value if animated unit present and have animation specified...
A variable-expanding proxy for the config class.
Functions to load and save images from/to disk.
static animation_branches prepare_animation(const config &cfg, const std::string &animation_tag)
static void delay(unsigned int milliseconds)
Waits a given number of milliseconds before returning.
void redraw(frame_parameters &value, halo::manager &halo_man)
void update_last_draw_time()
bool need_minimal_update() const
bool animation_finished_potential() const
A config object defines a single node in a WML file, with access to child nodes.
int matches(const display &disp, const map_location &loc, const map_location &second_loc, unit_const_ptr my_unit, const std::string &event="", const int value=0, hit_type hit=hit_type::INVALID, const_attack_ptr attack=nullptr, const_attack_ptr second_attack=nullptr, int value2=0) const
std::shared_ptr< const attack_type > const_attack_ptr
t_translation::ter_list terrain_types_
static std::string write_direction(DIRECTION dir)
animation_cursor(const config &cfg, animation_cursor *p)
boost::tribool primary_frame
static rng & default_instance()
bool does_not_change() const
bool animation_finished() const
Returns true if the current animation was finished.
std::string debug() const
ter_list read_list(std::string_view str, const ter_layer filler)
Reads a list of terrains from a string, when reading the.
std::set< map_location > get_overlaped_hex(const frame_parameters &value, const map_location &src, const map_location &dst)
bool propagate_invalidation(const std::set< map_location > &locs)
If this set is partially invalidated, invalidate all its hexes.
bool invalidate(frame_parameters &value)
bool animation_finished() const
int get_animation_time() const