diff --git a/projectfiles/CodeBlocks-SCons/wesnoth.cbp b/projectfiles/CodeBlocks-SCons/wesnoth.cbp index e3eb1844b5b..7db6a54a25c 100644 --- a/projectfiles/CodeBlocks-SCons/wesnoth.cbp +++ b/projectfiles/CodeBlocks-SCons/wesnoth.cbp @@ -986,6 +986,8 @@ + + diff --git a/projectfiles/CodeBlocks/wesnoth.cbp b/projectfiles/CodeBlocks/wesnoth.cbp index 5d94e32a01e..ce111871bda 100644 --- a/projectfiles/CodeBlocks/wesnoth.cbp +++ b/projectfiles/CodeBlocks/wesnoth.cbp @@ -1021,6 +1021,8 @@ + + diff --git a/projectfiles/VC9/wesnoth.vcproj b/projectfiles/VC9/wesnoth.vcproj index e773a6d56fd..f7cd58d536b 100644 --- a/projectfiles/VC9/wesnoth.vcproj +++ b/projectfiles/VC9/wesnoth.vcproj @@ -21068,6 +21068,14 @@ RelativePath="..\..\src\unit_animation.hpp" > + + + + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e8819a8926..6cdb2893c84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -890,6 +890,7 @@ set(wesnoth-main_SRC unit.cpp unit_abilities.cpp unit_animation.cpp + unit_animation_component.cpp unit_display.cpp unit_formula_manager.cpp unit_frame.cpp diff --git a/src/SConscript b/src/SConscript index 8d5c728f917..110015ecd80 100644 --- a/src/SConscript +++ b/src/SConscript @@ -523,6 +523,7 @@ wesnoth_sources = Split(""" unit.cpp unit_abilities.cpp unit_animation.cpp + unit_animation_component.cpp unit_display.cpp unit_formula_manager.cpp unit_frame.cpp diff --git a/src/actions/attack.cpp b/src/actions/attack.cpp index 6e0a6d35cac..573511f6e62 100644 --- a/src/actions/attack.cpp +++ b/src/actions/attack.cpp @@ -44,6 +44,7 @@ #include "../tod_manager.hpp" #include "../unit.hpp" #include "../unit_abilities.hpp" +#include "../unit_animation_component.hpp" #include "../unit_display.hpp" #include "../unit_helper.hpp" #include "../unit_map.hpp" @@ -1326,13 +1327,13 @@ namespace { if (a_.valid()) { unit &u = a_.get_unit(); - u.set_standing(); + u.anim_comp().set_standing(); u.set_experience(u.experience() + a_.xp_); } if (d_.valid()) { unit &u = d_.get_unit(); - u.set_standing(); + u.anim_comp().set_standing(); u.set_experience(u.experience() + d_.xp_); } diff --git a/src/actions/move.cpp b/src/actions/move.cpp index 4e403a51883..f3ab2bcb9d9 100644 --- a/src/actions/move.cpp +++ b/src/actions/move.cpp @@ -42,6 +42,7 @@ #include "../formula_string_utils.hpp" #include "../team.hpp" #include "../unit.hpp" +#include "../unit_animation_component.hpp" #include "../whiteboard/manager.hpp" #include @@ -494,7 +495,7 @@ namespace { // Private helpers for move_unit() moves_left_.pop_front(); // Invalidate before moving so we invalidate neighbor hexes if needed. - move_it_->invalidate(disp); + move_it_->anim_comp().invalidate(disp); // Attempt actually moving. // (Fails if *step_to is occupied). @@ -505,7 +506,7 @@ namespace { // Private helpers for move_unit() // Update the moving unit. move_it_ = move_result.first; move_it_->set_facing(step_from->get_relative_dir(*step_to)); - move_it_->set_standing(false); + move_it_->anim_comp().set_standing(false); disp.invalidate_unit_after_move(*move_loc_, *step_to); disp.invalidate(*step_to); move_loc_ = step_to; diff --git a/src/actions/undo.cpp b/src/actions/undo.cpp index de4fbee213c..f9c297840fd 100644 --- a/src/actions/undo.cpp +++ b/src/actions/undo.cpp @@ -30,6 +30,7 @@ #include "../resources.hpp" #include "../team.hpp" #include "../unit.hpp" +#include "../unit_animation_component.hpp" #include "../unit_display.hpp" #include "../unit_map.hpp" #include "../whiteboard/manager.hpp" @@ -746,7 +747,7 @@ bool undo_list::move_action::undo(int side, undo_list & /*undos*/) u = units.find(rev_route.back()); u->set_goto(map_location()); u->set_movement(saved_moves, true); - u->set_standing(); + u->anim_comp().set_standing(); gui.invalidate_unit_after_move(rev_route.front(), rev_route.back()); return true; @@ -964,7 +965,7 @@ bool undo_list::move_action::redo(int side) // Set the unit's state. u->set_goto(goto_hex); u->set_movement(saved_moves, true); - u->set_standing(); + u->anim_comp().set_standing(); if ( resources::gameboard->map().is_village(route.back()) ) { get_village(route.back(), u->side()); diff --git a/src/display.cpp b/src/display.cpp index 89ad38d2d5b..972c2e655ec 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -17,6 +17,7 @@ * Routines to set up the display, scroll and zoom the map. */ +#include "arrow.hpp" #include "cursor.hpp" #include "drawable_unit.hpp" #include "display.hpp" @@ -30,19 +31,20 @@ #include "map.hpp" #include "map_label.hpp" #include "minimap.hpp" +#include "overlay.hpp" #include "play_controller.hpp" //note: this can probably be refactored out #include "reports.hpp" +#include "resources.hpp" +#include "synced_context.hpp" #include "team.hpp" #include "terrain_builder.hpp" #include "text.hpp" #include "time_of_day.hpp" #include "tooltips.hpp" -#include "arrow.hpp" #include "tod_manager.hpp" -#include "resources.hpp" +#include "unit.hpp" +#include "unit_animation_component.hpp" #include "whiteboard/manager.hpp" -#include "overlay.hpp" -#include "synced_context.hpp" #include "SDL_image.h" @@ -3056,10 +3058,10 @@ void display::invalidate_animations() } const std::deque & unit_list = fake_unit_man_->get_fake_unit_list_for_invalidation(); BOOST_FOREACH(const unit* u, unit_list) { - u->refresh(); + u->anim_comp().refresh(); } BOOST_FOREACH(const unit & u, dc_->units()) { - u.refresh(); + u.anim_comp().refresh(); } bool new_inval; do { @@ -3068,10 +3070,10 @@ void display::invalidate_animations() #pragma omp parallel for reduction(|:new_inval) shared(unit_list) schedule(guided) #endif //_OPENMP BOOST_FOREACH(const unit* u, unit_list) { - new_inval |= u->invalidate(*this); + new_inval |= u->anim_comp().invalidate(*this); } BOOST_FOREACH(const unit & u, dc_->units()) { - new_inval |= u.invalidate(*this); + new_inval |= u.anim_comp().invalidate(*this); } }while(new_inval); } diff --git a/src/drawable_unit.cpp b/src/drawable_unit.cpp index b5e3039f343..942d76c9de1 100644 --- a/src/drawable_unit.cpp +++ b/src/drawable_unit.cpp @@ -21,6 +21,7 @@ #include "map.hpp" #include "team.hpp" #include "unit_animation.hpp" +#include "unit_animation_component.hpp" #include "unit_frame.hpp" #include @@ -33,24 +34,26 @@ void drawable_unit::redraw_unit (display & disp) const const team & viewing_team = teams[disp.viewing_team()]; + unit_animation_component & ac = *anim_comp_; + if ( hidden_ || disp.is_blindfolded() || !is_visible_to_team(viewing_team,map, disp.show_everything()) ) { - clear_haloes(); - if(anim_) { - anim_->update_last_draw_time(); + ac.clear_haloes(); + if(ac.anim_) { + ac.anim_->update_last_draw_time(); } return; } - if (!anim_) { - set_standing(); - if (!anim_) return; + if (!ac.anim_) { + ac.set_standing(); + if (!ac.anim_) return; } - if (refreshing_) return; - refreshing_ = true; + if (ac.refreshing_) return; + ac.refreshing_ = true; - anim_->update_last_draw_time(); + ac.anim_->update_last_draw_time(); frame_parameters params; const t_translation::t_terrain terrain = map.get_terrain(loc_); const terrain_type& terrain_info = map.get_terrain_info(terrain); @@ -106,7 +109,7 @@ void drawable_unit::redraw_unit (display & disp) const params.primary_frame = t_true; - const frame_parameters adjusted_params = anim_->get_current_params(params); + const frame_parameters adjusted_params = ac.anim_->get_current_params(params); const map_location dst = loc_.get_direction(facing_); const int xsrc = disp.get_location_x(loc_); @@ -118,20 +121,20 @@ void drawable_unit::redraw_unit (display & disp) const const int x = static_cast(adjusted_params.offset * xdst + (1.0-adjusted_params.offset) * xsrc) + d2; const int y = static_cast(adjusted_params.offset * ydst + (1.0-adjusted_params.offset) * ysrc) + d2; - if(unit_halo_ == halo::NO_HALO && !image_halo().empty()) { - unit_halo_ = halo::add(0, 0, image_halo()+TC_image_mods(), map_location(-1, -1)); + if(ac.unit_halo_ == halo::NO_HALO && !image_halo().empty()) { + ac.unit_halo_ = halo::add(0, 0, image_halo()+TC_image_mods(), map_location(-1, -1)); } - if(unit_halo_ != halo::NO_HALO && image_halo().empty()) { - halo::remove(unit_halo_); - unit_halo_ = halo::NO_HALO; - } else if(unit_halo_ != halo::NO_HALO) { - halo::set_location(unit_halo_, x, y - height_adjust); + if(ac.unit_halo_ != halo::NO_HALO && image_halo().empty()) { + halo::remove(ac.unit_halo_); + ac.unit_halo_ = halo::NO_HALO; + } else if(ac.unit_halo_ != halo::NO_HALO) { + halo::set_location(ac.unit_halo_, x, y - height_adjust); } // We draw bars only if wanted, visible on the map view - bool draw_bars = draw_bars_ ; + bool draw_bars = ac.draw_bars_ ; if (draw_bars) { const int d = disp.hex_size(); SDL_Rect unit_rect = sdl::create_rect(xsrc, ysrc +adjusted_params.y, d, d); @@ -291,7 +294,7 @@ void drawable_unit::redraw_unit (display & disp) const params.y -= height_adjust_unit - height_adjust; params.halo_y -= height_adjust_unit - height_adjust; - anim_->redraw(params); - refreshing_ = false; + ac.anim_->redraw(params); + ac.refreshing_ = false; } diff --git a/src/editor/action/action_item.cpp b/src/editor/action/action_item.cpp index 9cd50afeeda..dd3b6b91849 100644 --- a/src/editor/action/action_item.cpp +++ b/src/editor/action/action_item.cpp @@ -101,7 +101,7 @@ void editor_action_item_replace::perform_without_undo(map_context& /*mc*/) const // // item& u = *items.find(new_loc_); // //TODO do we still need set_standing? -// u.set_standing(); +// u.anim_comp().set_standing(); // // mc.add_changed_location(loc_); // mc.add_changed_location(new_loc_); diff --git a/src/editor/action/action_unit.cpp b/src/editor/action/action_unit.cpp index e3d69454c80..b65bff7598d 100644 --- a/src/editor/action/action_unit.cpp +++ b/src/editor/action/action_unit.cpp @@ -24,6 +24,9 @@ #include "editor/map/map_context.hpp" +#include "../../unit.hpp" +#include "../../unit_animation_component.hpp" + #include namespace editor { @@ -99,7 +102,7 @@ void editor_action_unit_replace::perform_without_undo(map_context& mc) const unit& u = *units.find(new_loc_); //TODO do we still need set_standing? - u.set_standing(); + u.anim_comp().set_standing(); mc.add_changed_location(loc_); mc.add_changed_location(new_loc_); @@ -135,7 +138,7 @@ void editor_action_unit_facing::perform_without_undo(map_context& mc) const if (unit_it != units.end()) { unit_it->set_facing(new_direction_); - unit_it->set_standing(); + unit_it->anim_comp().set_standing(); } } diff --git a/src/editor/editor_controller.cpp b/src/editor/editor_controller.cpp index aa61ed81bb2..38d2f5ad2a0 100644 --- a/src/editor/editor_controller.cpp +++ b/src/editor/editor_controller.cpp @@ -42,9 +42,11 @@ #include "../clipboard.hpp" #include "../game_preferences.hpp" #include "../gettext.hpp" +#include "../leader_scroll_dialog.hpp" #include "../preferences_display.hpp" #include "../sound.hpp" -#include "../leader_scroll_dialog.hpp" +#include "../unit.hpp" +#include "../unit_animation_component.hpp" #include "halo.hpp" @@ -655,7 +657,7 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i resources::units->find(gui_->mouseover_hex()); assert(un != resources::units->end()); un->set_facing(map_location::DIRECTION(index)); - un->set_standing(); + un->anim_comp().set_standing(); return true; } } @@ -766,7 +768,7 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i const unit_map::unit_iterator un = context_manager_->get_map_context().get_units().find(loc); bool canrecruit = un->can_recruit(); un->set_can_recurit(!canrecruit); - un->set_standing(); + un->anim_comp().set_standing(); } return true; case HOTKEY_DELETE_UNIT: diff --git a/src/fake_unit_manager.cpp b/src/fake_unit_manager.cpp index 9394dc1401e..cafae7b726d 100644 --- a/src/fake_unit_manager.cpp +++ b/src/fake_unit_manager.cpp @@ -18,6 +18,7 @@ #include "fake_unit.hpp" #include "log.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" static lg::log_domain log_engine("engine"); #define ERR_NG LOG_STREAM(err, log_engine) @@ -43,7 +44,7 @@ int fake_unit_manager::remove_temporary_unit(unit *u) fake_units_.erase(it, fake_units_.end()); my_display_.invalidate(u->get_location()); // Redraw with no location to get rid of haloes - u->clear_haloes(); + u->anim_comp().clear_haloes(); } if (removed > 1) { ERR_NG << "Error: duplicate temp unit found in fake_unit_manager::remove_temporary_unit" << std::endl; diff --git a/src/game_events/action_wml.cpp b/src/game_events/action_wml.cpp index b5a6209580b..fd602fc53e0 100644 --- a/src/game_events/action_wml.cpp +++ b/src/game_events/action_wml.cpp @@ -58,6 +58,8 @@ #include "../soundsource.hpp" #include "../synced_context.hpp" #include "../terrain_filter.hpp" +#include "../unit.hpp" +#include "../unit_animation_component.hpp" #include "../unit_display.hpp" #include "../unit_helper.hpp" #include "../wml_exception.hpp" @@ -857,7 +859,7 @@ WML_HANDLER_FUNCTION(heal_unit, event_info, cfg) u->set_state(unit::STATE_SLOWED, false); u->set_state(unit::STATE_PETRIFIED, false); u->set_state(unit::STATE_UNHEALABLE, false); - u->set_standing(); + u->anim_comp().set_standing(); } if (heal_amount_to_set) @@ -948,7 +950,7 @@ WML_HANDLER_FUNCTION(kill, event_info, cfg) resources::screen->invalidate(loc); unit_map::iterator iun = resources::units->find(loc); if ( iun != resources::units->end() && iun.valid() ) - iun->invalidate(*resources::screen); + iun->anim_comp().invalidate(*resources::screen); } resources::screen->redraw_minimap(); @@ -1422,7 +1424,7 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg) path_step[1] = paths[un][step]; unit_display::move_unit(path_step, *units[un]); units[un]->set_location(path_step[1]); - units[un]->set_standing(); + units[un]->anim_comp().set_standing(); } } @@ -2359,7 +2361,7 @@ WML_HANDLER_FUNCTION(teleport, event_info, cfg) unit::clear_status_caches(); u = resources::units->find(vacant_dst); - u->set_standing(); + u->anim_comp().set_standing(); if ( clear_shroud ) { // Now that the unit is visibly in position, clear the shroud. diff --git a/src/mouse_events.cpp b/src/mouse_events.cpp index 7fce837152f..93f96be210f 100644 --- a/src/mouse_events.cpp +++ b/src/mouse_events.cpp @@ -40,6 +40,8 @@ #include "replay_helper.hpp" #include "resources.hpp" #include "synced_context.hpp" +#include "unit.hpp" +#include "unit_animation_component.hpp" #include "wml_separators.hpp" #include "whiteboard/manager.hpp" @@ -725,7 +727,7 @@ void mouse_handler::select_hex(const map_location& hex, const bool browse, const if (!(browse || resources::whiteboard->unit_has_actions(&*u))) { sound::play_UI_sound("select-unit.wav"); - u->set_selecting(); + u->anim_comp().set_selecting(); if(fire_event) { // ensure unit map is back to normal while event is fired wb::real_map srum; diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 6a5c98fa84a..9f2e850a74e 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -65,6 +65,7 @@ #include "sound.hpp" #include "synced_context.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include "ai/lua/core.hpp" #include "version.hpp" #include "gui/widgets/clickable.hpp" @@ -2193,7 +2194,7 @@ static int intf_put_unit(lua_State *L) if (lu) { lu->put_map(loc); - lu->get()->set_standing(); + lu->get()->anim_comp().set_standing(); } else { u->set_location(loc); resources::units->insert(u); @@ -2268,7 +2269,7 @@ static int intf_extract_unit(lua_State *L) if (lu->on_map()) { u = resources::units->extract(u->get_location()); assert(u); - u->clear_haloes(); + u->anim_comp().clear_haloes(); } else if (int side = lu->on_recall_list()) { team &t = (*resources::teams)[side - 1]; UnitPtr v = UnitPtr(new unit(*u)); diff --git a/src/unit.cpp b/src/unit.cpp index 0e506b413b0..3b7bdc8515c 100644 --- a/src/unit.cpp +++ b/src/unit.cpp @@ -32,6 +32,7 @@ #include "resources.hpp" #include "unit_id.hpp" #include "unit_abilities.hpp" +#include "unit_animation_component.hpp" #include "unit_formula_manager.hpp" #include "scripting/lua.hpp" #include "side_filter.hpp" @@ -184,7 +185,6 @@ unit::unit(const unit& o): events_(o.events_), filter_recall_(o.filter_recall_), emit_zoc_(o.emit_zoc_), - state_(o.state_), overlays_(o.overlays_), @@ -202,17 +202,12 @@ unit::unit(const unit& o): modification_descriptions_(o.modification_descriptions_), + anim_comp_(new unit_animation_component(*this, *o.anim_comp_)), + animations_(o.animations_), - anim_(NULL), - next_idling_(0), - - frame_begin_time_(o.frame_begin_time_), - unit_halo_(halo::NO_HALO), getsHit_(o.getsHit_), - refreshing_(o.refreshing_), hidden_(o.hidden_), - draw_bars_(o.draw_bars_), hp_bar_scaling_(o.hp_bar_scaling_), xp_bar_scaling_(o.xp_bar_scaling_), @@ -265,7 +260,6 @@ unit::unit(const config &cfg, bool use_traits, const vconfig* vcfg) : events_(), filter_recall_(), emit_zoc_(0), - state_(STATE_STANDING), overlays_(), role_(cfg["role"]), attacks_(), @@ -278,15 +272,10 @@ unit::unit(const config &cfg, bool use_traits, const vconfig* vcfg) : is_fearless_(false), is_healthy_(false), modification_descriptions_(), + anim_comp_(new unit_animation_component(*this)), animations_(), - anim_(NULL), - next_idling_(0), - frame_begin_time_(0), - unit_halo_(halo::NO_HALO), getsHit_(0), - refreshing_(false), hidden_(false), - draw_bars_(false), hp_bar_scaling_(cfg["hp_bar_scaling"].blank() ? type_->hp_bar_scaling() : cfg["hp_bar_scaling"]), xp_bar_scaling_(cfg["xp_bar_scaling"].blank() ? type_->xp_bar_scaling() : cfg["xp_bar_scaling"]), modifications_(), @@ -370,7 +359,7 @@ unit::unit(const config &cfg, bool use_traits, const vconfig* vcfg) : unit_value_ = *v; } if (const config::attribute_value *v = cfg.get("halo")) { - clear_haloes(); + anim_comp_->clear_haloes(); cfg_["halo"] = *v; } if (const config::attribute_value *v = cfg.get("profile")) { @@ -570,7 +559,6 @@ unit::unit(const unit_type &u_type, int side, bool real_unit, events_(), filter_recall_(), emit_zoc_(0), - state_(STATE_STANDING), overlays_(), role_(), attacks_(), @@ -583,15 +571,10 @@ unit::unit(const unit_type &u_type, int side, bool real_unit, is_fearless_(false), is_healthy_(false), modification_descriptions_(), + anim_comp_(new unit_animation_component(*this)), animations_(), - anim_(NULL), - next_idling_(0), - frame_begin_time_(0), - unit_halo_(halo::NO_HALO), getsHit_(0), - refreshing_(false), hidden_(false), - draw_bars_(false), modifications_(), invisibility_cache_() { @@ -614,7 +597,7 @@ unit::unit(const unit_type &u_type, int side, bool real_unit, unit::~unit() { try { - clear_haloes(); + anim_comp_->clear_haloes(); // Remove us from the status cache std::vector::iterator itor = @@ -623,6 +606,8 @@ unit::~unit() if(itor != units_with_cache.end()) { units_with_cache.erase(itor); } + } catch (std::exception & e) { + ERR_UT << "Caught exception when destroying unit: " << e.what() << std::endl; } catch (...) {} } @@ -864,8 +849,7 @@ void unit::advance_to(const config &old_cfg, const unit_type &u_type, game_events::add_events(cfg_.child_range("event"), new_type.id()); cfg_.clear_children("event"); - refreshing_ = false; - anim_.reset(); + anim_comp_->reset_after_advance(); } std::string unit::big_profile() const @@ -1069,7 +1053,7 @@ void unit::expire_modifications(const std::string & duration) } if ( rebuild_from != NULL ) { - clear_haloes(); + anim_comp_->clear_haloes(); advance_to(*rebuild_from); } } @@ -1759,80 +1743,6 @@ const surface unit::still_image(bool scaled) const return unit_image; } -void unit::set_standing(bool with_bars) const -{ - display *disp = display::get_singleton(); - if (preferences::show_standing_animations()&& !incapacitated()) { - start_animation(INT_MAX, choose_animation(*disp, loc_, "standing"), - with_bars, "", 0, STATE_STANDING); - } else { - start_animation(INT_MAX, choose_animation(*disp, loc_, "_disabled_"), - with_bars, "", 0, STATE_STANDING); - } -} - -void unit::set_ghosted(bool with_bars) const -{ - display *disp = display::get_singleton(); - start_animation(INT_MAX, choose_animation(*disp, loc_, "ghosted"), - with_bars); -} - -void unit::set_disabled_ghosted(bool with_bars) const -{ - display *disp = display::get_singleton(); - start_animation(INT_MAX, choose_animation(*disp, loc_, "disabled_ghosted"), - with_bars); -} - -void unit::set_idling() const -{ - display *disp = display::get_singleton(); - start_animation(INT_MAX, choose_animation(*disp, loc_, "idling"), - true, "", 0, STATE_FORGET); -} - -void unit::set_selecting() const -{ - const display *disp = display::get_singleton(); - if (preferences::show_standing_animations() && !get_state(STATE_PETRIFIED)) { - start_animation(INT_MAX, choose_animation(*disp, loc_, "selected"), - true, "", 0, STATE_FORGET); - } else { - start_animation(INT_MAX, choose_animation(*disp, loc_, "_disabled_selected_"), - true, "", 0, STATE_FORGET); - } -} - -void unit::start_animation (int start_time, const unit_animation *animation, - bool with_bars, const std::string &text, Uint32 text_color, STATE state) const -{ - const display * disp = display::get_singleton(); - if (!animation) { - if (state == STATE_STANDING) - state_ = state; - if (!anim_ && state_ != STATE_STANDING) - set_standing(with_bars); - return ; - } - state_ = state; - // everything except standing select and idle - bool accelerate = (state != STATE_FORGET && state != STATE_STANDING); - draw_bars_ = with_bars; - anim_.reset(new unit_animation(*animation)); - const int real_start_time = start_time == INT_MAX ? anim_->get_begin_time() : start_time; - anim_->start_animation(real_start_time, loc_, loc_.get_direction(facing_), - text, text_color, accelerate); - frame_begin_time_ = anim_->get_begin_time() -1; - if (disp->idle_anim()) { - next_idling_ = get_current_animation_tick() - + static_cast((20000 + rand() % 20000) * disp->idle_anim_rate()); - } else { - next_idling_ = INT_MAX; - } -} - - void unit::set_facing(map_location::DIRECTION dir) const { if(dir != map_location::NDIRECTIONS) { facing_ = dir; @@ -1840,42 +1750,6 @@ void unit::set_facing(map_location::DIRECTION dir) const { // Else look at yourself (not available so continue to face the same direction) } -void unit::clear_haloes () const -{ - if(unit_halo_ != halo::NO_HALO) { - halo::remove(unit_halo_); - unit_halo_ = halo::NO_HALO; - } - if(anim_ ) anim_->clear_haloes(); -} -bool unit::invalidate (const display & disp) const -{ - bool result = false; - - // Very early calls, anim not initialized yet - if(get_animation()) { - frame_parameters params; - const gamemap & map = disp.get_map(); - const t_translation::t_terrain terrain = map.get_terrain(get_location()); - const terrain_type& terrain_info = map.get_terrain_info(terrain); - - int height_adjust = static_cast(terrain_info.unit_height_adjust() * disp.get_zoom_factor()); - if (is_flying() && height_adjust < 0) { - height_adjust = 0; - } - params.y -= height_adjust; - params.halo_y -= height_adjust; - params.image_mod = image_mods(); - params.halo_mod = TC_image_mods(); - params.image= absolute_image(); - - result |= get_animation()->invalidate(params); - } - - return result; - -} - int unit::upkeep() const { // Leaders do not incur upkeep. @@ -2333,7 +2207,7 @@ void unit::add_modification(const std::string& mod_type, const config& mod, bool cfg_["ellipse"] = effect["ellipse"]; } else if (apply_to == "halo") { - clear_haloes(); + anim_comp_->clear_haloes(); cfg_["halo"] = effect["halo"]; } else if (apply_to == "overlay") { @@ -2478,31 +2352,6 @@ std::string unit::absolute_image() const { return cfg_["image_icon"].empty() ? cfg_["image"] : cfg_["image_icon"]; } -const unit_animation* unit::choose_animation(const display& disp, const map_location& loc,const std::string& event, - const map_location& second_loc,const int value,const unit_animation::hit_type hit, - const attack_type* attack, const attack_type* second_attack, int swing_num) const -{ - // Select one of the matching animations at random - std::vector options; - int max_val = unit_animation::MATCH_FAIL; - for(std::vector::const_iterator i = animations_.begin(); i != animations_.end(); ++i) { - int matching = i->matches(disp,loc,second_loc,this,event,value,hit,attack,second_attack,swing_num); - if(matching > unit_animation::MATCH_FAIL && matching == max_val) { - options.push_back(&*i); - } else if(matching > max_val) { - max_val = matching; - options.clear(); - options.push_back(&*i); - } - } - - if(max_val == unit_animation::MATCH_FAIL) { - return NULL; - } - return options[rand()%options.size()]; -} - - void unit::apply_modifications() { log_scope("apply mods"); @@ -2720,33 +2569,6 @@ int side_upkeep(int side) return res; } -void unit::refresh() const -{ - if (state_ == STATE_FORGET && anim_ && anim_->animation_finished_potential()) - { - set_standing(); - return; - } - display &disp = *display::get_singleton(); - if (state_ != STATE_STANDING || get_current_animation_tick() < next_idling_ || - !disp.tile_nearly_on_screen(loc_) || incapacitated()) - { - return; - } - if (get_current_animation_tick() > next_idling_ + 1000) - { - // prevent all units animating at the same time - if (disp.idle_anim()) { - next_idling_ = get_current_animation_tick() - + static_cast((20000 + rand() % 20000) * disp.idle_anim_rate()); - } else { - next_idling_ = INT_MAX; - } - } else { - set_idling(); - } -} - team_data calculate_team_data(const team& tm, int side) { team_data res; @@ -2802,7 +2624,7 @@ void unit::set_hidden(bool state) const { hidden_ = state; if(!state) return; // We need to get rid of haloes immediately to avoid display glitches - clear_haloes(); + anim_comp_->clear_haloes(); } // Filters unimportant stats from the unit config and returns a checksum of diff --git a/src/unit.hpp b/src/unit.hpp index 365bf389018..9975c331c01 100644 --- a/src/unit.hpp +++ b/src/unit.hpp @@ -28,6 +28,7 @@ class display; class gamemap; class team; +class unit_animation_component; class unit_formula_manager; class vconfig; @@ -204,7 +205,6 @@ public: void end_turn(); void new_scenario(); /** Called on every draw */ - void refresh() const; bool take_hit(int damage) { hit_points_ -= damage; return hit_points_ <= 0; } void heal(int amount); @@ -248,21 +248,10 @@ public: /** A SDL surface, ready for display for place where we need a still-image of the unit. */ const surface still_image(bool scaled = false) const; - /** Clear unit_halo_ */ - void clear_haloes() const; - - void set_standing(bool with_bars = true) const; - - void set_ghosted(bool with_bars = true) const; - void set_disabled_ghosted(bool with_bars = true) const; - - void set_idling() const; - void set_selecting() const; - unit_animation* get_animation() const { return anim_.get();} + unit_animation_component & anim_comp() const { return *anim_comp_; } void set_facing(map_location::DIRECTION dir) const; map_location::DIRECTION facing() const { return facing_; } - bool invalidate(const display & disp) const; const std::vector& trait_names() const { return trait_names_; } const std::vector& trait_descriptions() const { return trait_descriptions_; } std::vector get_traits_list() const; @@ -319,15 +308,6 @@ public: const map_location& get_interrupted_move() const { return interrupted_move_; } void set_interrupted_move(const map_location& interrupted_move) { interrupted_move_ = interrupted_move; } - /** States for animation. */ - enum STATE { - STATE_STANDING, /** anim must fit in a hex */ - STATE_FORGET, /** animation will be automatically replaced by a standing anim when finished */ - STATE_ANIM}; /** normal anims */ - void start_animation (int start_time, const unit_animation *animation, - bool with_bars, const std::string &text = "", - Uint32 text_color = 0, STATE state = STATE_ANIM) const; - /** The name of the file to game_display (used in menus). */ std::string absolute_image() const; std::string image_halo() const { return cfg_["halo"]; } @@ -342,13 +322,6 @@ public: /// Never returns NULL, but may point to the null race. const unit_race* race() const { return race_; } - const unit_animation* choose_animation(const display& disp, - const map_location& loc, const std::string& event, - const map_location& second_loc = map_location::null_location(), - const int damage=0, - const unit_animation::hit_type hit_type = unit_animation::INVALID, - const attack_type* attack=NULL,const attack_type* second_attack = NULL, - int swing_num =0) const; /** * Returns true if the unit is currently under effect by an ability with this given TAG NAME. @@ -477,7 +450,6 @@ private: protected: bool emit_zoc_; - mutable STATE state_; //animation state private: std::vector overlays_; @@ -497,19 +469,14 @@ private: utils::string_map modification_descriptions_; // Animations: + friend class unit_animation_component; + protected: + boost::scoped_ptr anim_comp_; std::vector animations_; - mutable boost::scoped_ptr anim_; - mutable int next_idling_; // used for animation - mutable int frame_begin_time_; // used for animation - - - mutable int unit_halo_; // flag used for drawing / animation bool getsHit_; - mutable bool refreshing_; // avoid infinite recursion. flag used for drawing / animation mutable bool hidden_; - mutable bool draw_bars_; // flag used for drawing / animation double hp_bar_scaling_, xp_bar_scaling_; private: diff --git a/src/unit_animation.cpp b/src/unit_animation.cpp index aaf27153f65..a48a7341f38 100644 --- a/src/unit_animation.cpp +++ b/src/unit_animation.cpp @@ -19,10 +19,11 @@ #include "game_display.hpp" #include "halo.hpp" #include "map.hpp" -#include "unit.hpp" -#include "variable.hpp" -#include "resources.hpp" #include "play_controller.hpp" +#include "resources.hpp" +#include "unit.hpp" +#include "unit_animation_component.hpp" +#include "variable.hpp" #include @@ -1283,7 +1284,7 @@ void unit_animator::add_animation(const unit* animated_unit tmp.text_color = text_color; tmp.src = src; tmp.with_bars= with_bars; - tmp.animation = animated_unit->choose_animation(*disp,src,event,dst,value,hit_type,attack,second_attack,value2); + tmp.animation = animated_unit->anim_comp().choose_animation(*disp,src,event,dst,value,hit_type,attack,second_attack,value2); if(!tmp.animation) return; start_time_ = std::max(start_time_,tmp.animation->get_begin_time()); @@ -1326,9 +1327,9 @@ void unit_animator::replace_anim_if_invalid(const unit* animated_unit { if(!animated_unit) return; display*disp = display::get_singleton(); - if(animated_unit->get_animation() && - !animated_unit->get_animation()->animation_finished_potential() && - animated_unit->get_animation()->matches(*disp,src,dst,animated_unit,event,value,hit_type,attack,second_attack,value2) >unit_animation::MATCH_FAIL) { + if(animated_unit->anim_comp().get_animation() && + !animated_unit->anim_comp().get_animation()->animation_finished_potential() && + animated_unit->anim_comp().get_animation()->matches(*disp,src,dst,animated_unit,event,value,hit_type,attack,second_attack,value2) >unit_animation::MATCH_FAIL) { anim_elem tmp; tmp.my_unit = animated_unit; tmp.text = text; @@ -1347,21 +1348,21 @@ void unit_animator::start_animations() int begin_time = INT_MAX; std::vector::iterator anim; for(anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - if(anim->my_unit->get_animation()) { + if(anim->my_unit->anim_comp().get_animation()) { if(anim->animation) { begin_time = std::min(begin_time,anim->animation->get_begin_time()); } else { - begin_time = std::min(begin_time,anim->my_unit->get_animation()->get_begin_time()); + begin_time = std::min(begin_time,anim->my_unit->anim_comp().get_animation()->get_begin_time()); } } } for(anim = animated_units_.begin(); anim != animated_units_.end();++anim) { if(anim->animation) { - anim->my_unit->start_animation(begin_time, anim->animation, + anim->my_unit->anim_comp().start_animation(begin_time, anim->animation, anim->with_bars, anim->text, anim->text_color); anim->animation = NULL; } else { - anim->my_unit->get_animation()->update_parameters(anim->src,anim->src.get_direction(anim->my_unit->facing())); + anim->my_unit->anim_comp().get_animation()->update_parameters(anim->src,anim->src.get_direction(anim->my_unit->facing())); } } @@ -1371,7 +1372,7 @@ bool unit_animator::would_end() const { bool finished = true; for(std::vector::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - finished &= anim->my_unit->get_animation()->animation_finished_potential(); + finished &= anim->my_unit->anim_comp().get_animation()->animation_finished_potential(); } return finished; } @@ -1381,7 +1382,7 @@ void unit_animator::wait_until(int animation_time) const display*disp = display::get_singleton(); double speed = disp->turbo_speed(); resources::controller->play_slice(false); - int end_tick = animated_units_[0].my_unit->get_animation()->time_to_tick(animation_time); + int end_tick = animated_units_[0].my_unit->anim_comp().get_animation()->time_to_tick(animation_time); while (SDL_GetTicks() < static_cast(end_tick) - std::min(static_cast(20/speed),20)) { @@ -1389,7 +1390,7 @@ void unit_animator::wait_until(int animation_time) const std::min(10, static_cast((animation_time - get_animation_time()) * speed)))); resources::controller->play_slice(false); - end_tick = animated_units_[0].my_unit->get_animation()->time_to_tick(animation_time); + end_tick = animated_units_[0].my_unit->anim_comp().get_animation()->time_to_tick(animation_time); } disp->delay(std::max(0,end_tick - SDL_GetTicks() +5)); new_animation_frame(); @@ -1442,25 +1443,25 @@ void unit_animator::wait_for_end() const disp->delay(10); finished = true; for(std::vector::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - finished &= anim->my_unit->get_animation()->animation_finished_potential(); + finished &= anim->my_unit->anim_comp().get_animation()->animation_finished_potential(); } } } int unit_animator::get_animation_time() const{ - return animated_units_[0].my_unit->get_animation()->get_animation_time() ; + return animated_units_[0].my_unit->anim_comp().get_animation()->get_animation_time() ; } int unit_animator::get_animation_time_potential() const{ - return animated_units_[0].my_unit->get_animation()->get_animation_time_potential() ; + return animated_units_[0].my_unit->anim_comp().get_animation()->get_animation_time_potential() ; } int unit_animator::get_end_time() const { int end_time = INT_MIN; for(std::vector::const_iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - if(anim->my_unit->get_animation()) { - end_time = std::max(end_time,anim->my_unit->get_animation()->get_end_time()); + if(anim->my_unit->anim_comp().get_animation()) { + end_time = std::max(end_time,anim->my_unit->anim_comp().get_animation()->get_end_time()); } } return end_time; @@ -1469,8 +1470,8 @@ int unit_animator::get_end_time() const void unit_animator::pause_animation() { for(std::vector::iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - if(anim->my_unit->get_animation()) { - anim->my_unit->get_animation()->pause_animation(); + if(anim->my_unit->anim_comp().get_animation()) { + anim->my_unit->anim_comp().get_animation()->pause_animation(); } } } @@ -1478,8 +1479,8 @@ void unit_animator::pause_animation() void unit_animator::restart_animation() { for(std::vector::iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - if(anim->my_unit->get_animation()) { - anim->my_unit->get_animation()->restart_animation(); + if(anim->my_unit->anim_comp().get_animation()) { + anim->my_unit->anim_comp().get_animation()->restart_animation(); } } } @@ -1487,6 +1488,6 @@ void unit_animator::restart_animation() void unit_animator::set_all_standing() { for(std::vector::iterator anim = animated_units_.begin(); anim != animated_units_.end();++anim) { - anim->my_unit->set_standing(); + anim->my_unit->anim_comp().set_standing(); } } diff --git a/src/unit_animation_component.cpp b/src/unit_animation_component.cpp new file mode 100644 index 00000000000..36f45e175a0 --- /dev/null +++ b/src/unit_animation_component.cpp @@ -0,0 +1,188 @@ +/* + Copyright (C) 2014 by Chris Beck + 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 as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +#include "unit_animation_component.hpp" + +#include "display.hpp" +#include "map.hpp" +#include "preferences.hpp" +#include "unit_animation.hpp" +#include "unit.hpp" + +const unit_animation* unit_animation_component::choose_animation(const display& disp, const map_location& loc,const std::string& event, + const map_location& second_loc,const int value,const unit_animation::hit_type hit, + const attack_type* attack, const attack_type* second_attack, int swing_num) +{ + // Select one of the matching animations at random + std::vector options; + int max_val = unit_animation::MATCH_FAIL; + for(std::vector::const_iterator i = u_.animations_.begin(); i != u_.animations_.end(); ++i) { + int matching = i->matches(disp,loc,second_loc,&u_,event,value,hit,attack,second_attack,swing_num); + if(matching > unit_animation::MATCH_FAIL && matching == max_val) { + options.push_back(&*i); + } else if(matching > max_val) { + max_val = matching; + options.clear(); + options.push_back(&*i); + } + } + + if(max_val == unit_animation::MATCH_FAIL) { + return NULL; + } + return options[rand()%options.size()]; +} + +void unit_animation_component::set_standing(bool with_bars) +{ + display *disp = display::get_singleton(); + if (preferences::show_standing_animations()&& !u_.incapacitated()) { + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "standing"), + with_bars, "", 0, STATE_STANDING); + } else { + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "_disabled_"), + with_bars, "", 0, STATE_STANDING); + } +} + +void unit_animation_component::set_ghosted(bool with_bars) +{ + display *disp = display::get_singleton(); + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "ghosted"), + with_bars); +} + +void unit_animation_component::set_disabled_ghosted(bool with_bars) +{ + display *disp = display::get_singleton(); + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "disabled_ghosted"), + with_bars); +} + +void unit_animation_component::set_idling() +{ + display *disp = display::get_singleton(); + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "idling"), + true, "", 0, STATE_FORGET); +} + +void unit_animation_component::set_selecting() +{ + const display *disp = display::get_singleton(); + if (preferences::show_standing_animations() && !u_.incapacitated()) { + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "selected"), + true, "", 0, STATE_FORGET); + } else { + start_animation(INT_MAX, choose_animation(*disp, u_.loc_, "_disabled_selected_"), + true, "", 0, STATE_FORGET); + } +} + +void unit_animation_component::start_animation (int start_time, const unit_animation *animation, + bool with_bars, const std::string &text, Uint32 text_color, STATE state) +{ + const display * disp = display::get_singleton(); + if (!animation) { + if (state == STATE_STANDING) + state_ = state; + if (!anim_ && state_ != STATE_STANDING) + set_standing(with_bars); + return ; + } + state_ = state; + // everything except standing select and idle + bool accelerate = (state != STATE_FORGET && state != STATE_STANDING); + draw_bars_ = with_bars; + anim_.reset(new unit_animation(*animation)); + const int real_start_time = start_time == INT_MAX ? anim_->get_begin_time() : start_time; + anim_->start_animation(real_start_time, u_.loc_, u_.loc_.get_direction(u_.facing_), + text, text_color, accelerate); + frame_begin_time_ = anim_->get_begin_time() -1; + if (disp->idle_anim()) { + next_idling_ = get_current_animation_tick() + + static_cast((20000 + rand() % 20000) * disp->idle_anim_rate()); + } else { + next_idling_ = INT_MAX; + } +} + +void unit_animation_component::refresh() +{ + if (state_ == STATE_FORGET && anim_ && anim_->animation_finished_potential()) + { + set_standing(); + return; + } + display &disp = *display::get_singleton(); + if (state_ != STATE_STANDING || get_current_animation_tick() < next_idling_ || + !disp.tile_nearly_on_screen(u_.loc_) || u_.incapacitated()) + { + return; + } + if (get_current_animation_tick() > next_idling_ + 1000) + { + // prevent all units animating at the same time + if (disp.idle_anim()) { + next_idling_ = get_current_animation_tick() + + static_cast((20000 + rand() % 20000) * disp.idle_anim_rate()); + } else { + next_idling_ = INT_MAX; + } + } else { + set_idling(); + } +} + +void unit_animation_component::clear_haloes () +{ + if(unit_halo_ != halo::NO_HALO) { + halo::remove(unit_halo_); + unit_halo_ = halo::NO_HALO; + } + if(anim_ ) anim_->clear_haloes(); +} + +bool unit_animation_component::invalidate (const display & disp) +{ + bool result = false; + + // Very early calls, anim not initialized yet + if(get_animation()) { + frame_parameters params; + const gamemap & map = disp.get_map(); + const t_translation::t_terrain terrain = map.get_terrain(u_.loc_); + const terrain_type& terrain_info = map.get_terrain_info(terrain); + + int height_adjust = static_cast(terrain_info.unit_height_adjust() * disp.get_zoom_factor()); + if (u_.is_flying() && height_adjust < 0) { + height_adjust = 0; + } + params.y -= height_adjust; + params.halo_y -= height_adjust; + params.image_mod = u_.image_mods(); + params.halo_mod = u_.TC_image_mods(); + params.image= u_.absolute_image(); + + result |= get_animation()->invalidate(params); + } + + return result; + +} + +void unit_animation_component::reset_after_advance() +{ + refreshing_ = false; + anim_.reset(); +} diff --git a/src/unit_animation_component.hpp b/src/unit_animation_component.hpp new file mode 100644 index 00000000000..0748aa2acda --- /dev/null +++ b/src/unit_animation_component.hpp @@ -0,0 +1,104 @@ +/* + Copyright (C) 2014 by Chris Beck + 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 as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. + + See the COPYING file for more details. +*/ + +// This class encapsulates the animation functionality of unit. + +#ifndef UNIT_ANIM_COMP_HPP +#define UNIT_ANIM_COMP_HPP + +#include "halo.hpp" +#include "unit_animation.hpp" //Note: only needed for enum + +#include + +class unit; + +class unit_animation_component +{ +public: + /** States for animation. */ + enum STATE { + STATE_STANDING, /** anim must fit in a hex */ + STATE_FORGET, /** animation will be automatically replaced by a standing anim when finished */ + STATE_ANIM}; /** normal anims */ + + unit_animation_component(unit & my_unit) : + u_(my_unit), + anim_(NULL), + state_(STATE_STANDING), + next_idling_(0), + frame_begin_time_(0), + draw_bars_(false), + refreshing_(false), + unit_halo_(halo::NO_HALO) {} + + unit_animation_component(unit & my_unit, const unit_animation_component & o) : + u_(my_unit), + anim_(NULL), + state_(o.state_), + next_idling_(0), + frame_begin_time_(o.frame_begin_time_), + draw_bars_(o.draw_bars_), + refreshing_(o.refreshing_), + unit_halo_(halo::NO_HALO) {} + + const unit_animation* choose_animation(const display& disp, + const map_location& loc, const std::string& event, + const map_location& second_loc = map_location::null_location(), + const int damage=0, + const unit_animation::hit_type hit_type = unit_animation::INVALID, + const attack_type* attack=NULL,const attack_type* second_attack = NULL, + int swing_num =0); + + void set_standing(bool with_bars = true); + + void set_ghosted(bool with_bars = true); + void set_disabled_ghosted(bool with_bars = true); + + void set_idling(); + void set_selecting(); + + void start_animation (int start_time, const unit_animation *animation, + bool with_bars, const std::string &text = "", + Uint32 text_color = 0, STATE state = STATE_ANIM); + + bool invalidate(const display & disp); + + void refresh(); + + void clear_haloes(); + + void reset_after_advance(); + + unit_animation* get_animation() const { return anim_.get(); } + + friend class unit; + friend class drawable_unit; +private: + const unit & u_; + + boost::scoped_ptr anim_; + + STATE state_; //animation state + + int next_idling_; // used for animation + int frame_begin_time_; // used for animation + + bool draw_bars_; + bool refreshing_; // avoid infinite recursion. flag used for drawing / animation + + int unit_halo_; // flag used for drawing / animation +}; + +#endif diff --git a/src/unit_display.cpp b/src/unit_display.cpp index 5de5413942b..3ccbe3c4c7a 100644 --- a/src/unit_display.cpp +++ b/src/unit_display.cpp @@ -26,6 +26,8 @@ #include "mouse_events.hpp" #include "resources.hpp" #include "terrain_filter.hpp" +#include "unit.hpp" +#include "unit_animation_component.hpp" #include "unit_map.hpp" #include @@ -92,7 +94,7 @@ static void teleport_unit_between(const map_location& a, const map_location& b, animator.wait_for_end(); } - temp_unit.set_standing(); + temp_unit.anim_comp().set_standing(); disp.update_display(); events::pump(); } @@ -267,7 +269,7 @@ void unit_mover::start(unit& u) // Initialize our temporary unit for the move. temp_unit_ptr_->set_location(path_[0]); temp_unit_ptr_->set_facing(path_[0].get_relative_dir(path_[1])); - temp_unit_ptr_->set_standing(false); + temp_unit_ptr_->anim_comp().set_standing(false); disp_->invalidate(path_[0]); // If the unit can be seen here by the viewing side: @@ -299,7 +301,7 @@ void unit_mover::start(unit& u) // Switch the display back to the real unit. u.set_facing(temp_unit_ptr_->facing()); - u.set_standing(false); // Need to reset u's animation so the new facing takes effect. + u.anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. u.set_hidden(was_hidden_); temp_unit_ptr_->set_hidden(true); } @@ -353,13 +355,13 @@ void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) temp_unit_ptr_->set_location(path_[current_]); disp_->invalidate(path_[current_]); // scroll in as much of the remaining path as possible - if ( temp_unit_ptr_->get_animation() ) - temp_unit_ptr_->get_animation()->pause_animation(); + if ( temp_unit_ptr_->anim_comp().get_animation() ) + temp_unit_ptr_->anim_comp().get_animation()->pause_animation(); disp_->scroll_to_tiles(path_.begin() + current_, path_.end(), game_display::ONSCREEN, true, false, 0.0, force_scroll_); - if ( temp_unit_ptr_->get_animation() ) - temp_unit_ptr_->get_animation()->restart_animation(); + if ( temp_unit_ptr_->anim_comp().get_animation() ) + temp_unit_ptr_->anim_comp().get_animation()->restart_animation(); } if ( tiles_adjacent(path_[current_], path_[current_+1]) ) @@ -375,7 +377,7 @@ void unit_mover::proceed_to(unit& u, size_t path_index, bool update, bool wait) // Update the unit's facing. u.set_facing(temp_unit_ptr_->facing()); - u.set_standing(false); // Need to reset u's animation so the new facing takes effect. + u.anim_comp().set_standing(false); // Need to reset u's animation so the new facing takes effect. // Remember the unit to unhide when the animation finishes. shown_unit_ = &u; if ( wait ) @@ -458,7 +460,7 @@ void unit_mover::finish(unit &u, map_location::DIRECTION dir) // Facing gets set even when not animating. u.set_facing(dir == map_location::NDIRECTIONS ? final_dir : dir); - u.set_standing(true); // Need to reset u's animation so the new facing takes effect. + u.anim_comp().set_standing(true); // Need to reset u's animation so the new facing takes effect. // Redraw path ends (even if not animating). disp_->invalidate(path_.front()); @@ -532,10 +534,10 @@ void unit_sheath_weapon(const map_location& primary_loc, unit* primary_unit, animator.wait_for_end(); } if(primary_unit) { - primary_unit->set_standing(); + primary_unit->anim_comp().set_standing(); } if(secondary_unit) { - secondary_unit->set_standing(); + secondary_unit->anim_comp().set_standing(); } reset_helpers(primary_unit,secondary_unit); @@ -618,7 +620,7 @@ void unit_attack(display * disp, game_board & board, hit_type, &attack, secondary_attack, swing); // note that we take an anim from the real unit, we'll use it later - const unit_animation *defender_anim = def->choose_animation(*disp, + const unit_animation *defender_anim = def->anim_comp().choose_animation(*disp, def->get_location(), "defend", att->get_location(), damage, hit_type, &attack, secondary_attack, swing); animator.add_animation(&defender, defender_anim, def->get_location(), @@ -660,7 +662,7 @@ void unit_attack(display * disp, game_board & board, } animator.wait_for_end(); // pass the animation back to the real unit - def->start_animation(animator.get_end_time(), defender_anim, true); + def->anim_comp().start_animation(animator.get_end_time(), defender_anim, true); reset_helpers(&*att, &*def); def->set_hitpoints(def_hitpoints); } @@ -675,7 +677,7 @@ void reset_helpers(const unit *attacker,const unit *defender) BOOST_FOREACH (const unit_ability & ability, leaders) { unit_map::const_iterator leader = units.find(ability.second); assert(leader != units.end()); - leader->set_standing(); + leader->anim_comp().set_standing(); } } @@ -684,7 +686,7 @@ void reset_helpers(const unit *attacker,const unit *defender) BOOST_FOREACH (const unit_ability & ability, helpers) { unit_map::const_iterator helper = units.find(ability.second); assert(helper != units.end()); - helper->set_standing(); + helper->anim_comp().set_standing(); } } } diff --git a/src/whiteboard/highlighter.cpp b/src/whiteboard/highlighter.cpp index e6aadee3e7b..18516117e15 100644 --- a/src/whiteboard/highlighter.cpp +++ b/src/whiteboard/highlighter.cpp @@ -42,6 +42,7 @@ #include "play_controller.hpp" #include "resources.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include "unit_map.hpp" #include @@ -198,7 +199,7 @@ void highlighter::last_action_redraw(move_ptr move) bool this_is_second_to_last_action = (second_to_last_action != sa.end() && move == *second_to_last_action); if(this_is_last_action || (this_is_second_to_last_action && !last_action_has_fake_unit)) { - move->get_fake_unit()->set_standing(true); + move->get_fake_unit()->anim_comp().set_standing(true); } } } @@ -276,7 +277,7 @@ void highlighter::highlight_main_visitor::visit(move_ptr move) } if(move->get_fake_unit()) { ///@todo find some highlight animation - move->get_fake_unit()->set_ghosted(true); + move->get_fake_unit()->anim_comp().set_ghosted(true); //Make sure the fake unit is the only one displayed in its hex resources::screen->add_exclusive_draw(move->get_fake_unit()->get_location(), *move->get_fake_unit()); highlighter_.exclusive_display_hexes_.insert(move->get_fake_unit()->get_location()); @@ -308,7 +309,7 @@ void highlighter::highlight_secondary_visitor::visit(move_ptr move) move->set_arrow_brightness(move::ARROW_BRIGHTNESS_HIGHLIGHTED); } if(move->get_fake_unit()) { - move->get_fake_unit()->set_ghosted(true); + move->get_fake_unit()->anim_comp().set_ghosted(true); //Make sure the fake unit is the only one displayed in its hex resources::screen->add_exclusive_draw(move->get_fake_unit()->get_location(), *move->get_fake_unit()); highlighter_.exclusive_display_hexes_.insert(move->get_fake_unit()->get_location()); @@ -328,7 +329,7 @@ void highlighter::unhighlight_visitor::visit(move_ptr move) move->set_arrow_brightness(move::ARROW_BRIGHTNESS_STANDARD); } if(move->get_fake_unit()) { - move->get_fake_unit()->set_disabled_ghosted(false); + move->get_fake_unit()->anim_comp().set_disabled_ghosted(false); highlighter_.last_action_redraw(move); } diff --git a/src/whiteboard/manager.cpp b/src/whiteboard/manager.cpp index bdcca51c26d..ba2c0028439 100644 --- a/src/whiteboard/manager.cpp +++ b/src/whiteboard/manager.cpp @@ -45,6 +45,8 @@ #include "play_controller.hpp" #include "resources.hpp" #include "team.hpp" +#include "unit.hpp" +#include "unit_animation_component.hpp" #include "unit_display.hpp" #include @@ -334,7 +336,7 @@ void manager::post_delete_action(action_ptr action) if(action_it != side_actions->end()) { move_ptr move = boost::dynamic_pointer_cast(*action_it); if(move && move->get_fake_unit()) { - move->get_fake_unit()->set_standing(true); + move->get_fake_unit()->anim_comp().set_standing(true); } } } @@ -714,13 +716,13 @@ void manager::create_temp_move() // Create temp ghost unit fake_unit.reset(new class fake_unit(*temp_moved_unit)); fake_unit->place_on_fake_unit_manager( resources::fake_units); - fake_unit->set_ghosted(true); + fake_unit->anim_comp().set_ghosted(true); } unit_display::move_unit(path, *fake_unit, false); //get facing right - fake_unit->invalidate(*game_display::get_singleton()); + fake_unit->anim_comp().invalidate(*game_display::get_singleton()); fake_unit->set_location(*curr_itor); - fake_unit->set_ghosted(true); + fake_unit->anim_comp().set_ghosted(true); } else //zero-hex path -- don't bother drawing a fake unit fake_unit.reset(); @@ -730,7 +732,7 @@ void manager::create_temp_move() } //in case path shortens on next step and one ghosted unit has to be removed int ind = fake_units_.size() - 1; - fake_units_[ind]->invalidate(*game_display::get_singleton()); + fake_units_[ind]->anim_comp().invalidate(*game_display::get_singleton()); //toss out old arrows and fake units move_arrows_.resize(turn+1); fake_units_.resize(turn+1); @@ -741,7 +743,7 @@ void manager::erase_temp_move() move_arrows_.clear(); BOOST_FOREACH(fake_unit_ptr const& tmp, fake_units_) { if(tmp) { - tmp->invalidate(*game_display::get_singleton()); + tmp->anim_comp().invalidate(*game_display::get_singleton()); } } fake_units_.clear(); @@ -812,7 +814,7 @@ void manager::save_temp_attack(const map_location& attacker_loc, const map_locat assert(route_->steps.back() == attacker_loc); source_hex = route_->steps.front(); - fake_unit->set_disabled_ghosted(true); + fake_unit->anim_comp().set_disabled_ghosted(true); } else { diff --git a/src/whiteboard/move.cpp b/src/whiteboard/move.cpp index 33bd61b36fe..e6ded93e559 100644 --- a/src/whiteboard/move.cpp +++ b/src/whiteboard/move.cpp @@ -35,6 +35,7 @@ #include "resources.hpp" #include "team.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include "unit_display.hpp" #include "unit_map.hpp" @@ -135,7 +136,7 @@ move::move(config const& cfg, bool hidden) if(hidden) fake_unit_->set_hidden(true); fake_unit_->place_on_fake_unit_manager(resources::fake_units); - fake_unit_->set_ghosted(true); + fake_unit_->anim_comp().set_ghosted(true); unit_display::move_unit(route_->steps, *fake_unit_, false); //get facing right fake_unit_->set_location(route_->steps.back()); @@ -151,7 +152,7 @@ void move::init() //than previous actions' fake units if (fake_unit_) { - fake_unit_->set_ghosted(true); + fake_unit_->anim_comp().set_ghosted(true); } side_actions_ptr side_actions = resources::teams->at(team_index()).get_side_actions(); side_actions::iterator action = side_actions->find_last_action_of(*(get_unit())); @@ -160,7 +161,7 @@ void move::init() if (move_ptr move = boost::dynamic_pointer_cast(*action)) { if (move->fake_unit_) - move->fake_unit_->set_disabled_ghosted(true); + move->fake_unit_->anim_comp().set_disabled_ghosted(true); } } diff --git a/src/whiteboard/recall.cpp b/src/whiteboard/recall.cpp index 0b1b96d9a1b..d2b00c67526 100644 --- a/src/whiteboard/recall.cpp +++ b/src/whiteboard/recall.cpp @@ -33,6 +33,7 @@ #include "synced_context.hpp" #include "team.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include @@ -98,7 +99,7 @@ void recall::init() fake_unit_->set_location(recall_hex_); fake_unit_->set_movement(0, true); fake_unit_->set_attacks(0); - fake_unit_->set_ghosted(false); + fake_unit_->anim_comp().set_ghosted(false); fake_unit_->place_on_fake_unit_manager( resources::fake_units); } diff --git a/src/whiteboard/recruit.cpp b/src/whiteboard/recruit.cpp index 0ad53fd7953..2c1feaa6ec8 100644 --- a/src/whiteboard/recruit.cpp +++ b/src/whiteboard/recruit.cpp @@ -29,6 +29,7 @@ #include "play_controller.hpp" #include "resources.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include "unit_map.hpp" #include "unit_types.hpp" @@ -87,7 +88,7 @@ void recruit::init() fake_unit_->set_location(recruit_hex_); fake_unit_->set_movement(0, true); fake_unit_->set_attacks(0); - fake_unit_->set_ghosted(false); + fake_unit_->anim_comp().set_ghosted(false); fake_unit_->place_on_fake_unit_manager(resources::fake_units); cost_ = fake_unit_->type().cost(); diff --git a/src/whiteboard/utility.cpp b/src/whiteboard/utility.cpp index d50f2859b09..36861f6a5d1 100644 --- a/src/whiteboard/utility.cpp +++ b/src/whiteboard/utility.cpp @@ -32,6 +32,7 @@ #include "resources.hpp" #include "team.hpp" #include "unit.hpp" +#include "unit_animation_component.hpp" #include @@ -140,13 +141,13 @@ temporary_unit_hider::~temporary_unit_hider() void ghost_owner_unit(unit* unit) { - unit->set_disabled_ghosted(false); + unit->anim_comp().set_disabled_ghosted(false); resources::screen->invalidate(unit->get_location()); } void unghost_owner_unit(unit* unit) { - unit->set_standing(true); + unit->anim_comp().set_standing(true); resources::screen->invalidate(unit->get_location()); }