mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-06 17:31:18 +00:00
Added Boucman's patch on teleportation animation, after a few corrections.
This patch adds a teleport_anim WML tag. Also add the Silver Mage to the test scenario so that it can be tested. And comment about a long standing bug in move_unit_between so that it does not get forgotten again.
This commit is contained in:
parent
1702b387ed
commit
864385898e
@ -96,7 +96,7 @@ name=moveto
|
||||
canrecruit=1
|
||||
controller=human
|
||||
hitpoints=80
|
||||
recruit=Assassin,Elvish Hero,Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Red Mage,Spearman,Swordsman,Duelist,Fencer,Elvish Captain,Elvish Ranger,Elvish Shyde,Thief,Rogue,Merman,Elvish Lord,White Mage,Mage of Light,Elvish Sharpshooter,Merman Lord
|
||||
recruit=Assassin,Elvish Hero,Elvish Fighter,Elvish Archer,Horseman,Mage,Elvish Shaman,Red Mage,Spearman,Swordsman,Duelist,Fencer,Elvish Captain,Elvish Ranger,Elvish Shyde,Thief,Rogue,Merman,Elvish Lord,White Mage,Mage of Light,Elvish Sharpshooter,Merman Lord,Silver Mage
|
||||
gold=2000
|
||||
enemy=2
|
||||
[/side]
|
||||
|
@ -71,14 +71,45 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
|
||||
|
||||
int skips = 0;
|
||||
|
||||
const int acceleration = disp.turbo() ? 5:1;
|
||||
|
||||
gamemap::location src_adjacent[6];
|
||||
get_adjacent_tiles(a, src_adjacent);
|
||||
|
||||
const std::string& halo = u.type().image_halo();
|
||||
util::scoped_resource<int,halo::remover> halo_effect(0);
|
||||
if(halo.empty() == false && !disp.fogged(b.x,b.y)) {
|
||||
halo_effect.assign(halo::add(0,0,halo));
|
||||
}
|
||||
|
||||
gamemap::location src_adjacent[6];
|
||||
get_adjacent_tiles(a, src_adjacent);
|
||||
|
||||
const unit_animation *teleport_animation_p = u.type().teleport_animation();
|
||||
if (teleport_animation_p && !tiles_adjacent(a, b) && !disp.fogged(a.x, a.y)) { // teleport
|
||||
unit_animation teleport_animation = *teleport_animation_p;
|
||||
int animation_time;
|
||||
const int begin_at = teleport_animation.get_first_frame_time(unit_animation::UNIT_FRAME);
|
||||
teleport_animation.start_animation(begin_at, unit_animation::UNIT_FRAME, acceleration);
|
||||
animation_time = teleport_animation.get_animation_time();
|
||||
adjust_map_position(disp, xsrc, ysrc, disp.hex_size(), disp.hex_size());
|
||||
while(animation_time < 0) {
|
||||
const std::string* unit_image = &teleport_animation.get_current_frame(unit_animation::UNIT_FRAME).image;
|
||||
if (unit_image->empty()) {
|
||||
unit_image = &u.type().image();
|
||||
}
|
||||
surface image(image::get_image(*unit_image));
|
||||
if (!face_left) {
|
||||
image.assign(image::reverse_image(image));
|
||||
}
|
||||
disp.draw_tile(a.x,a.y);
|
||||
for(int tile = 0; tile != 6; ++tile) {
|
||||
disp.draw_tile(src_adjacent[tile].x, src_adjacent[tile].y);
|
||||
}
|
||||
disp.draw_unit(xsrc,ysrc,image,false, 1.0, 0, 0.0, src_submerge);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
teleport_animation.update_current_frames();
|
||||
animation_time = teleport_animation.get_animation_time();
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < nsteps; ++i) {
|
||||
events::pump();
|
||||
@ -113,6 +144,10 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
|
||||
|
||||
//invalidate the source tile and all adjacent tiles,
|
||||
//since the unit can partially overlap adjacent tiles
|
||||
/* FIXME: This code is wrong for short-range teleportation since the teleported unit is not
|
||||
* near its source location; consequently the unit leaves a ghost trace behind it. It does
|
||||
* not happen for long-range teleportation since the scrolling has the nice side effect of
|
||||
* cleaning up the display. -- silene */
|
||||
disp.draw_tile(a.x,a.y);
|
||||
for(int tile = 0; tile != 6; ++tile) {
|
||||
disp.draw_tile(src_adjacent[tile].x, src_adjacent[tile].y);
|
||||
@ -146,6 +181,37 @@ void move_unit_between(display& disp, const gamemap& map, const gamemap::locatio
|
||||
++skips;
|
||||
}
|
||||
}
|
||||
|
||||
gamemap::location dst_adjacent[6];
|
||||
get_adjacent_tiles(b, dst_adjacent);
|
||||
|
||||
if (teleport_animation_p && !tiles_adjacent(a, b) && !disp.fogged(b.x, b.y)) { // teleport
|
||||
unit_animation teleport_animation = *teleport_animation_p;
|
||||
int animation_time;
|
||||
const int end_at = teleport_animation.get_last_frame_time();
|
||||
teleport_animation.start_animation(0, unit_animation::UNIT_FRAME, acceleration);
|
||||
animation_time = teleport_animation.get_animation_time();
|
||||
adjust_map_position(disp, xdst, ydst, disp.hex_size(), disp.hex_size());
|
||||
while(animation_time < end_at) {
|
||||
const std::string* unit_image = &teleport_animation.get_current_frame(unit_animation::UNIT_FRAME).image;
|
||||
if (unit_image->empty()) {
|
||||
unit_image = &u.type().image();
|
||||
}
|
||||
surface image(image::get_image(*unit_image));
|
||||
if (!face_left) {
|
||||
image.assign(image::reverse_image(image));
|
||||
}
|
||||
disp.draw_tile(b.x,b.y);
|
||||
for(int tile = 0; tile != 6; ++tile) {
|
||||
disp.draw_tile(dst_adjacent[tile].x,dst_adjacent[tile].y);
|
||||
}
|
||||
disp.draw_unit(xdst, ydst, image, false, 1.0, 0, 0.0, dst_submerge);
|
||||
disp.update_display();
|
||||
events::pump();
|
||||
teleport_animation.update_current_frames();
|
||||
animation_time = teleport_animation.get_animation_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -521,7 +521,8 @@ unit_type::unit_type(const unit_type& o)
|
||||
nightvision_(o.nightvision_), steadfast_(o.steadfast_),
|
||||
can_advance_(o.can_advance_),
|
||||
movementType_(o.movementType_), possibleTraits_(o.possibleTraits_),
|
||||
genders_(o.genders_), defensive_animations_(o.defensive_animations_)
|
||||
genders_(o.genders_), defensive_animations_(o.defensive_animations_),
|
||||
teleport_animations_(o.teleport_animations_)
|
||||
{
|
||||
gender_types_[0] = o.gender_types_[0] != NULL ? new unit_type(*o.gender_types_[0]) : NULL;
|
||||
gender_types_[1] = o.gender_types_[1] != NULL ? new unit_type(*o.gender_types_[1]) : NULL;
|
||||
@ -620,6 +621,10 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
||||
for(config::child_list::const_iterator d = defends.begin(); d != defends.end(); ++d) {
|
||||
defensive_animations_.push_back(defensive_animation(**d));
|
||||
}
|
||||
const config::child_list& teleports = cfg_.get_children("teleport_anim");
|
||||
for(config::child_list::const_iterator d = teleports.begin(); d != teleports.end(); ++d) {
|
||||
teleport_animations_.push_back(unit_animation(**d));
|
||||
}
|
||||
}
|
||||
|
||||
unit_type::~unit_type()
|
||||
@ -1016,6 +1021,12 @@ const unit_animation* unit_type::defend_animation(bool hits, attack_type::RANGE
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const unit_animation* unit_type::teleport_animation( ) const
|
||||
{
|
||||
if (teleport_animations_.empty()) return NULL;
|
||||
return &teleport_animations_[rand() % teleport_animations_.size()];
|
||||
}
|
||||
|
||||
game_data::game_data()
|
||||
{}
|
||||
|
||||
|
@ -240,6 +240,7 @@ public:
|
||||
const std::string& race() const;
|
||||
|
||||
const unit_animation* defend_animation(bool hits, attack_type::RANGE range) const;
|
||||
const unit_animation* teleport_animation() const;
|
||||
|
||||
private:
|
||||
void operator=(const unit_type& o);
|
||||
@ -287,6 +288,8 @@ private:
|
||||
};
|
||||
|
||||
std::vector<defensive_animation> defensive_animations_;
|
||||
|
||||
std::vector<unit_animation> teleport_animations_;
|
||||
};
|
||||
|
||||
struct game_data
|
||||
|
Loading…
x
Reference in New Issue
Block a user