Merge pull request #478 from ln-zookeeper/status_sounds

Fix problems with animation-based status sounds
This commit is contained in:
soliton- 2015-09-08 10:01:01 +02:00
commit 85a5c1c9c7
6 changed files with 37 additions and 5 deletions

View file

@ -977,29 +977,36 @@ namespace {
if (update_display_)
{
std::ostringstream float_text;
std::vector<std::string> extra_hit_sounds;
if (hits)
{
const unit &defender_unit = defender.get_unit();
if (attacker_stats->poisons && !defender_unit.get_state(unit::STATE_POISONED)) {
float_text << (defender_unit.gender() == unit_race::FEMALE ?
_("female^poisoned") : _("poisoned")) << '\n';
extra_hit_sounds.push_back(game_config::sounds::status::poisoned);
}
if (attacker_stats->slows && !defender_unit.get_state(unit::STATE_SLOWED)) {
float_text << (defender_unit.gender() == unit_race::FEMALE ?
_("female^slowed") : _("slowed")) << '\n';
extra_hit_sounds.push_back(game_config::sounds::status::slowed);
}
if (attacker_stats->petrifies) {
float_text << (defender_unit.gender() == unit_race::FEMALE ?
_("female^petrified") : _("petrified")) << '\n';
extra_hit_sounds.push_back(game_config::sounds::status::petrified);
}
}
unit_display::unit_attack(game_display::get_singleton(), *resources::gameboard,
attacker.loc_, defender.loc_, damage,
*attacker_stats->weapon, defender_stats->weapon,
abs_n, float_text.str(), drains_damage, "");
abs_n, float_text.str(), drains_damage, "", &extra_hit_sounds);
}
bool dies = defender.get_unit().take_hit(damage);

View file

@ -166,6 +166,12 @@ namespace game_config
menu_expand = "expand.wav",
menu_contract = "contract.wav",
menu_select = "select.wav";
namespace status {
std::string poisoned = "poison.ogg",
slowed = "slowed.wav",
petrified = "petrified.ogg";
}
}
#ifdef WESNOTH_PATH
@ -315,6 +321,13 @@ namespace game_config
if (s.has_attribute("game_user_leave")) game_user_leave = s["game_user_leave"].str();
if (s.has_attribute("ready_for_start")) ready_for_start = s["ready_for_start"].str();
if (s.has_attribute("game_has_begun")) game_has_begun = s["game_has_begun"].str();
if(const config & ss = s.child("status")) {
using namespace game_config::sounds::status;
if (ss.has_attribute("poisoned")) poisoned = ss["poisoned"].str();
if (ss.has_attribute("slowed")) slowed = ss["slowed"].str();
if (ss.has_attribute("petrified")) petrified = ss["petrified"].str();
}
}
}

View file

@ -152,6 +152,9 @@ namespace game_config
game_has_begun;
extern const std::string button_press, checkbox_release, slider_adjust,
menu_expand, menu_contract, menu_select;
namespace status {
extern std::string poisoned, slowed, petrified;
}
}
void load_config(const config &cfg);

View file

@ -592,7 +592,7 @@ void unit_animation::fill_initial_animations( std::vector<unit_animation> & anim
animations.back().event_ = utils::split("poisoned");
animations.back().unit_anim_.override(0,300,particule::NO_CYCLE,"","0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30,0.5:30,0:30",display::rgb(0,255,0));
animations.back().sub_anims_["_poison_sound"] = particule();
animations.back().sub_anims_["_poison_sound"].add_frame(1,frame_builder().sound("poison.ogg"),true);
animations.back().sub_anims_["_poison_sound"].add_frame(1,frame_builder().sound(game_config::sounds::status::poisoned),true);
}
@ -705,7 +705,7 @@ void unit_animation::add_anims( std::vector<unit_animation> & animations, const
anim["value"] = anim["damage"];
animations.push_back(unit_animation(anim));
animations.back().sub_anims_["_poison_sound"] = particule();
animations.back().sub_anims_["_poison_sound"].add_frame(1,frame_builder().sound("poison.ogg"),true);
animations.back().sub_anims_["_poison_sound"].add_frame(1,frame_builder().sound(game_config::sounds::status::poisoned),true);
}
add_simple_anim(animations, cfg, "pre_movement_anim", "pre_movement", display::LAYER_UNIT_MOVE_DEFAULT);

View file

@ -25,6 +25,7 @@
#include "log.hpp"
#include "mouse_events.hpp"
#include "resources.hpp"
#include "sound.hpp"
#include "terrain_filter.hpp"
#include "unit.hpp"
#include "unit_animation_component.hpp"
@ -573,7 +574,7 @@ void unit_die(const map_location& loc, unit& loser,
void unit_attack(display * disp, game_board & board,
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,int drain_amount,std::string att_text)
int swing,std::string hit_text,int drain_amount,std::string att_text, const std::vector<std::string>* extra_hit_sounds)
{
if(!disp ||disp->video().update_locked() || disp->video().faked() ||
(disp->fogged(a) && disp->fogged(b)) || preferences::show_combat() == false) {
@ -653,7 +654,15 @@ void unit_attack(display * disp, game_board & board,
animator.start_animations();
animator.wait_until(0);
int damage_left = damage;
bool extra_hit_sounds_played = false;
while(damage_left > 0 && !animator.would_end()) {
if(!extra_hit_sounds_played && extra_hit_sounds != NULL) {
BOOST_FOREACH (std::string hit_sound, *extra_hit_sounds) {
sound::play_sound(hit_sound);
}
extra_hit_sounds_played = true;
}
int step_left = (animator.get_end_time() - animator.get_animation_time() )/50;
if(step_left < 1) step_left = 1;
int removed_hp = damage_left/step_left ;

View file

@ -117,7 +117,7 @@ void unit_sheath_weapon( const map_location& loc, unit* u=NULL, const attack_typ
void unit_attack(display * disp, game_board & board, //TODO: Would be nice if this could be purely a display function and defer damage dealing to its caller
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, int drain_amount, std::string att_text);
int swing, std::string hit_text, int drain_amount, std::string att_text, const std::vector<std::string>* extra_hit_sounds=NULL);
void unit_recruited(const map_location& loc,