commit patch #1316 : store original orientation in undo

This commit is contained in:
Jérémy Rosen 2009-09-27 10:48:40 +00:00
parent 7aeb53a523
commit ffba6d57b9
9 changed files with 140 additions and 62 deletions

View file

@ -72,6 +72,7 @@ Version 1.7.5+svn:
next scenario)
* Started with the a new event handler for gui2
* Fix unit facings after moving (bug #14336)
* Fix unit facings after undo/redo
* Improved the teamcoloring script for images.
* Animations
* new animations to help drakes to take off and land : pre-movement post-movement draw_weapon sheath_weapon

View file

@ -912,6 +912,9 @@
wikiuser = "Lord Ork"
email = "asqueados_AT_gmail.com"
[/entry]
[entry]
name = "Patryk Obara (dreamer_)
[/entry]
[entry]
name = "Paul Smedley (Creeping)"
[/entry]

View file

@ -32,7 +32,15 @@
mirror="true"
image="portraits/drakes/transparent/fighter.png"
[/portrait]
# default standing anim
[standing_anim]
[frame]
image="units/drakes/fighter.png"
[/frame]
[/standing_anim]
# flying terrain anims
[standing_anim]
terrain_type=Wo,Ww,Ww^Vm,Chs,Chw,Ss
start_time=0
layer=60
[frame]
@ -68,6 +76,24 @@
image="units/drakes/fighter-fly-2-upstroke.png"
[/frame]
[/standing_anim]
[pre_movement_anim]
#take off, only do it when we're not already flying
terrain_type=!,Wo,Ww,Ww^Vm,Chs,Chw,Ss
[frame]
duration=300
image="units/drakes/fighter-fire-inhale-3.png"
text="take-off"
[/frame]
[/pre_movement_anim]
[post_movement_anim]
#landing, only do it when we're not already flying
terrain_type=!,Wo,Ww,Ww^Vm,Chs,Chw,Ss
[frame]
duration=300
image="units/drakes/fighter-fire-inhale-3.png"
text="landing"
[/frame]
[/post_movement_anim]
[movement_anim]
start_time=0
[frame]
@ -121,6 +147,24 @@
damage=3
number=3
[/attack]
[draw_weapon_anim]
#landing, only do it when we're not already flying
terrain_type=Wo,Ww,Ww^Vm,Chs,Chw,Ss
[frame]
duration=300
image="units/drakes/fighter-fire-inhale-3.png"
text="pre-fight"
[/frame]
[/draw_weapon_anim]
[sheath_weapon_anim]
#landing, only do it when we're not already flying
terrain_type=Wo,Ww,Ww^Vm,Chs,Chw,Ss
[frame]
duration=300
image="units/drakes/fighter-fire-inhale-3.png"
text="post-fight"
[/frame]
[/sheath_weapon_anim]
[attack_anim]
[filter_attack]
name=fire breath

View file

@ -2278,20 +2278,11 @@ size_t move_unit(move_unit_spectator *move_spectator,
return 0;
}
if (next_unit != NULL)
if(next_unit != NULL)
*next_unit = steps.back();
if (show_move) {
// Move the unit on the screen. Hide the unit in its current location,
// but don't actually remove it until the move is done,
// so that while the unit is moving status etc.
// will still display the correct number of units.
unit_display::move_unit(steps,ui->second,teams);
} else {
// not showing move but still need to invalidate changes
disp.invalidate(steps.front());
disp.invalidate(steps.back());
}
map_location::DIRECTION orig_dir = ui->second.facing();
unit_display::move_unit(steps, ui->second, teams, show_move);
// move the real unit
units.move(ui->first, steps.back());
@ -2358,7 +2349,9 @@ size_t move_unit(move_unit_spectator *move_spectator,
undo_stack->clear();
} else {
// MP_COUNTDOWN: added param
undo_stack->push_back(undo_action(ui->second,steps,starting_moves,action_time_bonus,orig_village_owner));
undo_stack->push_back(
undo_action(ui->second,steps, starting_moves, action_time_bonus,
orig_village_owner, orig_dir));
}
}

View file

@ -333,11 +333,11 @@ int combat_modifier(const unit_map &units, const map_location &loc,
/** Records information to be able to undo a movement. */
struct undo_action {
enum ACTION_TYPE { NONE, RECRUIT, RECALL, DISMISS};
enum ACTION_TYPE { NONE, RECRUIT, RECALL, DISMISS };
undo_action(const unit& u,
const std::vector<map_location>& rt,
int sm, int timebonus = 0, int orig = -1) :
undo_action(const unit& u, const std::vector<map_location>& rt, int sm,
int timebonus=0, int orig=-1,
map_location::DIRECTION dir=map_location::NDIRECTIONS) :
route(rt),
starting_moves(sm),
original_village_owner(orig),
@ -345,16 +345,22 @@ struct undo_action {
type(NONE),
affected_unit(u),
countdown_time_bonus(timebonus)
{}
{
if(dir == map_location::NDIRECTIONS)
dir = u.facing();
starting_dir = dir;
}
undo_action(const unit& u, const map_location& loc, const ACTION_TYPE action_type=NONE) :
route(),
starting_moves(),
original_village_owner(),
recall_loc(loc),
type(action_type),
affected_unit(u),
countdown_time_bonus(1)
undo_action(const unit& u, const map_location& loc,
const ACTION_TYPE action_type=NONE) :
route(),
starting_moves(),
original_village_owner(),
recall_loc(loc),
type(action_type),
affected_unit(u),
countdown_time_bonus(1),
starting_dir(u.facing())
{}
std::vector<map_location> route;
@ -364,6 +370,8 @@ struct undo_action {
ACTION_TYPE type;
unit affected_unit;
int countdown_time_bonus;
map_location::DIRECTION starting_dir;
bool is_dismiss() const { return type == DISMISS; }
bool is_recall() const { return type == RECALL; }
bool is_recruit() const { return type == RECRUIT; }

View file

@ -652,15 +652,11 @@ WML_HANDLER_FUNCTION(teleport, event_info, cfg)
const map_location src_loc = u->first;
if (utils::string_bool(cfg["animate"])) {
std::vector<map_location> teleport_path;
teleport_path.push_back(src_loc);
teleport_path.push_back(vacant_dst);
unit_display::move_unit(teleport_path, u->second, *resources::teams);
} else {
resources::screen->invalidate(src_loc);
resources::screen->invalidate(dst);
}
std::vector<map_location> teleport_path;
teleport_path.push_back(src_loc);
teleport_path.push_back(vacant_dst);
bool animate = utils::string_bool(cfg["animate"]);
unit_display::move_unit(teleport_path, u->second, *resources::teams, animate);
resources::units->move(src_loc, vacant_dst);
unit::clear_status_caches();

View file

@ -1041,7 +1041,7 @@ void menu_handler::undo(int side_num)
action.starting_moves = u->second.movement_left();
unit_display::move_unit(route,u->second,teams_);
unit_display::move_unit(route, u->second, teams_, true, action.starting_dir);
units_.move(u->first, route.back());
unit::clear_status_caches();
@ -1052,7 +1052,6 @@ void menu_handler::undo(int side_num)
u->second.set_standing();
gui_->invalidate_unit_after_move(route.front(), route.back());
gui_->invalidate(route.back());
gui_->draw();
}
@ -1159,7 +1158,6 @@ void menu_handler::redo(int side_num)
//MP_COUNTDOWN: restore recruitment bonus
current_team.set_action_bonus_count(1 + current_team.action_bonus_count());
gui_->invalidate(loc);
gui_->draw();
//gui_.invalidate_game_status();
//gui_.invalidate_all();
@ -1200,7 +1198,6 @@ void menu_handler::redo(int side_num)
}
gui_->invalidate_unit_after_move(route.front(), route.back());
gui_->invalidate(route.back());
gui_->draw();
recorder.add_movement(action.route);

View file

@ -68,8 +68,6 @@ static void move_unit_between(const map_location& a, const map_location& b, unit
return;
}
temp_unit.set_location(a);
disp->place_temporary_unit(temp_unit);
temp_unit.set_facing(a.get_relative_dir(b));
@ -114,23 +112,33 @@ static void move_unit_between(const map_location& a, const map_location& b, unit
namespace unit_display
{
void move_unit(const std::vector<map_location>& path, unit& u, const std::vector<team>& teams)
void move_unit(const std::vector<map_location>& path, unit& u,
const std::vector<team>& teams, bool animate,
map_location::DIRECTION dir)
{
game_display* disp = game_display::get_singleton();
assert(!path.empty());
assert(disp);
if(!disp || disp->video().update_locked() || disp->video().faked() ) {
if(!disp || disp->video().update_locked() || disp->video().faked())
return;
// One hex path (strange), nothing to do
if(path.size() == 1)
return;
if(dir == map_location::NDIRECTIONS)
dir = path[path.size()-2].get_relative_dir(path.back());
// Don't animate, only set facing and redraw path ends
if(!animate) {
u.set_facing(dir);
disp->invalidate(path.front());
disp->invalidate(path.back());
return;
}
// One hex path (strange), nothing to do
if (path.size()==1) return;
const unit_map& units = disp->get_units();
bool invisible = teams[u.side()-1].is_enemy(int(disp->viewing_team()+1)) &&
u.invisible(path[0],units,teams);
bool was_hidden = u.get_hidden();
// Original unit is usually hidden (but still on map, so count is correct)
unit temp_unit = u;
@ -206,13 +214,16 @@ void move_unit(const std::vector<map_location>& path, unit& u, const std::vector
animator.wait_for_end();
disp->remove_temporary_unit();
u.set_facing(path[path.size()-2].get_relative_dir(path[path.size()-1]));
u.set_facing(dir);
u.set_hidden(was_hidden);
events::mouse_handler* mousehandler = events::mouse_handler::get_singleton();
if (mousehandler) {
mousehandler->invalidate_reachmap();
}
disp->invalidate(path.front());
disp->invalidate(path.back());
}

View file

@ -37,8 +37,25 @@ class unit;
namespace unit_display
{
/** Display a unit moving along a given path. */
void move_unit(const std::vector<map_location>& path, unit& u, const std::vector<team>& teams);
/**
* Display a unit moving along a given path.
*
* Note: Hide the unit in its current location,
* but don't actually remove it until the move is done,
* so that while the unit is moving status etc.
* will still display the correct number of units.
*
* @param path
* @param u
* @param teams
* @param animate If set to false, only side-effects of move
* are applied (correct unit facing, path hexes redrawing).
* @param dir Unit will be set facing this direction after move.
* If nothing passed, direction will be set based on path.
*/
void move_unit(const std::vector<map_location>& path, unit& u,
const std::vector<team>& teams, bool animate=true,
map_location::DIRECTION dir=map_location::NDIRECTIONS);
/**
* Play a pre-fight animation
@ -57,7 +74,11 @@ void unit_sheath_weapon( const map_location& loc, unit* u=NULL, const attack_typ
*
* Note: this only shows the effect, it doesn't actually kill the unit.
*/
void unit_die( const map_location& loc, unit& u, const attack_type* attack=NULL, const attack_type*secondary_attack=NULL,const map_location& winner_loc = map_location::null_location, unit * winner=NULL);
void unit_die( const map_location& loc, unit& u,
const attack_type* attack=NULL, const attack_type* secondary_attack=NULL,
const map_location& winner_loc=map_location::null_location,
unit* winner=NULL);
/**
* Make the unit on tile 'a' attack the unit on tile 'b'.
@ -68,28 +89,32 @@ void unit_die( const map_location& loc, unit& u, const attack_type* attack=NULL,
* @retval true if the defending unit is dead, should be
* removed from the playing field.
*/
void unit_attack(
const map_location& a, const map_location& b, int damage,
const attack_type& attack, const attack_type* secondary_attack,
int swing,std::string hit_text,bool drain,std::string att_text);
void unit_attack(const map_location& a, const map_location& b, int damage,
const attack_type& attack, const attack_type* secondary_attack,
int swing, std::string hit_text, bool drain, std::string att_text);
void unit_recruited(const map_location& loc,const map_location& leader_loc=map_location::null_location);
void unit_recruited(const map_location& loc,
const map_location& leader_loc=map_location::null_location);
/**
* Set healer_loc to an invalid location if there are no healers.
* Set healer_loc to an invalid location if there are no healers.
*
* This will use a poisoning anim if healing<0.
* This will use a poisoning anim if healing<0.
*/
void unit_healing(unit& healed,map_location& healed_loc, std::vector<unit_map::iterator> healers, int healing);
void unit_healing(unit& healed, map_location& healed_loc,
std::vector<unit_map::iterator> healers, int healing);
/**
* parse a standard WML for animations and play the corresponding animation, returns once animation is played
* this is used for the animate_unit action, but can easily be generalized if other wml-decribed animations are needed
*
* Parse a standard WML for animations and play the corresponding animation.
* Returns once animation is played.
*
* This is used for the animate_unit action, but can easily be generalized if
* other wml-decribed animations are needed.
*/
void wml_animation(const vconfig &cfg, const map_location &default_location = map_location::null_location);
void wml_animation(const vconfig &cfg,
const map_location& default_location=map_location::null_location);
}