mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-15 17:25:32 +00:00
added support for animated deaths
This commit is contained in:
parent
df5a3bf920
commit
d63773ebc1
@ -1,4 +1,5 @@
|
||||
CVS HEAD:
|
||||
* Added support for animated deaths, and added animations for skeleton and revenant
|
||||
* Balancing of water units: swimmer units (merfolk) have defense on water and swamp reduced by 10%. Merman Hunter cost: 13 -> 15. Melee attack: 5-2 -> 4-2. Naga have defense on shallow water reduced by 10%. Deep sea creatures have defense on water reduced by 10%. Naga Fighter cost: 13 -> 14.
|
||||
* Added UNIT and PLACE_IMAGE macros to utils.cfg
|
||||
* terrain improvements
|
||||
|
BIN
images/undead-revenant-dying-2.png
Executable file
BIN
images/undead-revenant-dying-2.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
BIN
images/undead-revenant-dying.png
Executable file
BIN
images/undead-revenant-dying.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
images/undead-skeleton-dying-2.png
Executable file
BIN
images/undead-skeleton-dying-2.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
images/undead-skeleton-dying.png
Executable file
BIN
images/undead-skeleton-dying.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -267,7 +267,7 @@ void move_unit(display& disp, const gamemap& map, const std::vector<gamemap::loc
|
||||
}
|
||||
}
|
||||
|
||||
void unit_die(display& disp, const gamemap::location& loc, const unit& u)
|
||||
void unit_die(display& disp, const gamemap::location& loc, const unit& u, const attack_type* attack)
|
||||
{
|
||||
if(disp.update_locked() || disp.fogged(loc.x,loc.y) || preferences::show_combat() == false) {
|
||||
return;
|
||||
@ -278,11 +278,34 @@ void unit_die(display& disp, const gamemap::location& loc, const unit& u)
|
||||
sound::play_sound(die_sound);
|
||||
}
|
||||
|
||||
surface unit_image(NULL);
|
||||
|
||||
const unit_animation* const anim_ptr = u.type().die_animation(attack);
|
||||
if(anim_ptr != NULL) {
|
||||
unit_animation anim(*anim_ptr);
|
||||
|
||||
anim.start_animation(anim.get_first_frame_time(),unit_animation::UNIT_FRAME,disp.turbo() ? 5:1);
|
||||
anim.update_current_frames();
|
||||
|
||||
while(!anim.animation_finished()) {
|
||||
|
||||
const unit_animation::frame& frame = anim.get_current_frame();
|
||||
|
||||
unit_image = surface(image::get_image(frame.image));
|
||||
disp.draw_tile(loc.x,loc.y,unit_image);
|
||||
disp.update_display();
|
||||
|
||||
SDL_Delay(10);
|
||||
|
||||
anim.update_current_frames();
|
||||
}
|
||||
}
|
||||
|
||||
const int frame_time = 30;
|
||||
int ticks = SDL_GetTicks();
|
||||
|
||||
for(fixed_t alpha = ftofxp(1.0); alpha > ftofxp(0.0); alpha -= ftofxp(0.05)) {
|
||||
disp.draw_tile(loc.x,loc.y,NULL,alpha);
|
||||
disp.draw_tile(loc.x,loc.y,unit_image,alpha);
|
||||
|
||||
const int wait_time = ticks + frame_time - SDL_GetTicks();
|
||||
|
||||
@ -294,7 +317,7 @@ void unit_die(display& disp, const gamemap::location& loc, const unit& u)
|
||||
disp.update_display();
|
||||
}
|
||||
|
||||
disp.draw_tile(loc.x,loc.y,NULL,ftofxp(0.0));
|
||||
disp.draw_tile(loc.x,loc.y,unit_image,ftofxp(0.0));
|
||||
disp.update_display();
|
||||
}
|
||||
|
||||
@ -591,7 +614,7 @@ bool unit_attack_ranged(display& disp, unit_map& units,
|
||||
}
|
||||
|
||||
if(dead) {
|
||||
unit_die(disp,def->first,def->second);
|
||||
unit_die(disp,def->first,def->second,&attack);
|
||||
}
|
||||
|
||||
return dead;
|
||||
@ -853,7 +876,7 @@ bool unit_attack(display& disp, unit_map& units, const gamemap& map,
|
||||
def->second.set_standing();
|
||||
|
||||
if(dead) {
|
||||
unit_display::unit_die(disp,def->first,def->second);
|
||||
unit_display::unit_die(disp,def->first,def->second,&attack);
|
||||
}
|
||||
|
||||
return dead;
|
||||
|
@ -17,7 +17,7 @@ void move_unit(display& disp, const gamemap& map, const std::vector<gamemap::loc
|
||||
|
||||
///a function to show a unit fading out. Note that this only shows the effect, it doesn't
|
||||
///actually kill the unit.
|
||||
void unit_die(display& disp, const gamemap::location& loc, const unit& u);
|
||||
void unit_die(display& disp, const gamemap::location& loc, const unit& u, const attack_type* attack=NULL);
|
||||
|
||||
///a function to make the unit on tile 'a' attack the unit on tile 'b'.
|
||||
///the 'damage' will be subtracted from the unit's hitpoints, and a die effect will be
|
||||
|
@ -531,7 +531,7 @@ unit_type::unit_type(const unit_type& o)
|
||||
can_advance_(o.can_advance_), alignment_(o.alignment_),
|
||||
movementType_(o.movementType_), possibleTraits_(o.possibleTraits_),
|
||||
genders_(o.genders_), defensive_animations_(o.defensive_animations_),
|
||||
teleport_animations_(o.teleport_animations_)
|
||||
teleport_animations_(o.teleport_animations_), death_animations_(o.death_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;
|
||||
@ -658,6 +658,11 @@ unit_type::unit_type(const config& cfg, const movement_type_map& mv_types,
|
||||
for(config::child_list::const_iterator t = teleports.begin(); t != teleports.end(); ++t) {
|
||||
teleport_animations_.push_back(unit_animation(**t));
|
||||
}
|
||||
|
||||
const config::child_list& deaths = cfg_.get_children("death");
|
||||
for(config::child_list::const_iterator death = deaths.begin(); death != deaths.end(); ++death) {
|
||||
death_animations_.push_back(death_animation(**death));
|
||||
}
|
||||
}
|
||||
|
||||
unit_type::~unit_type()
|
||||
@ -1038,6 +1043,28 @@ bool unit_type::defensive_animation::matches(bool h, attack_type::RANGE r) const
|
||||
}
|
||||
}
|
||||
|
||||
unit_type::death_animation::death_animation(const config& cfg)
|
||||
: damage_type(utils::split(cfg["damage_type"])), special(utils::split(cfg["attack_special"])), animation(cfg)
|
||||
{
|
||||
}
|
||||
|
||||
bool unit_type::death_animation::matches(const attack_type* attack) const
|
||||
{
|
||||
if(attack == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(damage_type.empty() == false && std::find(damage_type.begin(),damage_type.end(),attack->type()) == damage_type.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(special.empty() == false && std::find(special.begin(),special.end(),attack->special()) == special.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const unit_animation* unit_type::defend_animation(bool hits, attack_type::RANGE range) const
|
||||
{
|
||||
//select one of the matching animations at random
|
||||
@ -1067,6 +1094,36 @@ const unit_animation* unit_type::teleport_animation( ) const
|
||||
return &teleport_animations_[rand() % teleport_animations_.size()];
|
||||
}
|
||||
|
||||
const unit_animation* unit_type::die_animation(const attack_type* attack) const
|
||||
{
|
||||
if(death_animations_.empty()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(attack == NULL) {
|
||||
return &death_animations_[rand()%death_animations_.size()].animation;
|
||||
}
|
||||
|
||||
const unit_animation* res = NULL;
|
||||
std::vector<const unit_animation*> options;
|
||||
for(std::vector<death_animation>::const_iterator i = death_animations_.begin(); i != death_animations_.end(); ++i) {
|
||||
if(i->matches(attack)) {
|
||||
if(res != NULL) {
|
||||
options.push_back(res);
|
||||
}
|
||||
|
||||
res = &i->animation;
|
||||
}
|
||||
}
|
||||
|
||||
if(options.empty()) {
|
||||
return res;
|
||||
} else {
|
||||
options.push_back(res);
|
||||
return options[rand()%options.size()];
|
||||
}
|
||||
}
|
||||
|
||||
game_data::game_data()
|
||||
{}
|
||||
|
||||
|
@ -245,6 +245,7 @@ public:
|
||||
|
||||
const unit_animation* defend_animation(bool hits, attack_type::RANGE range) const;
|
||||
const unit_animation* teleport_animation() const;
|
||||
const unit_animation* die_animation(const attack_type* attack) const;
|
||||
|
||||
private:
|
||||
void operator=(const unit_type& o);
|
||||
@ -284,7 +285,7 @@ private:
|
||||
|
||||
struct defensive_animation
|
||||
{
|
||||
defensive_animation(const config& cfg);
|
||||
explicit defensive_animation(const config& cfg);
|
||||
bool matches(bool hits, attack_type::RANGE range) const;
|
||||
|
||||
enum { HIT, MISS, HIT_OR_MISS } hits;
|
||||
@ -295,6 +296,17 @@ private:
|
||||
std::vector<defensive_animation> defensive_animations_;
|
||||
|
||||
std::vector<unit_animation> teleport_animations_;
|
||||
|
||||
struct death_animation
|
||||
{
|
||||
explicit death_animation(const config& cfg);
|
||||
bool matches(const attack_type* attack) const;
|
||||
|
||||
std::vector<std::string> damage_type, special;
|
||||
unit_animation animation;
|
||||
};
|
||||
|
||||
std::vector<death_animation> death_animations_;
|
||||
};
|
||||
|
||||
struct game_data
|
||||
|
Loading…
x
Reference in New Issue
Block a user