Engine automatically plays special music on defeat or victory;

default lists from which an option is randomly chosen at runtime are
provided as the default_victory_music and default_defeat_music
attributes in [game_config] node; this may be overriden per-scenario
using the victory_music and/or defeat_music attributes on its code -
it can also be overriden in a [endlevel] block by providing a music=
attribute with the desired list (feature request/bug #11203).
This commit is contained in:
Ignacio R. Morelle 2008-07-27 17:59:46 +00:00
parent ef61e6fc8a
commit 7e827b89f6
11 changed files with 105 additions and 10 deletions

View file

@ -4,6 +4,14 @@ Version 1.5.2+svn:
Latvian, Polish, Slovak Latvian, Polish, Slovak
* Multiplayer: * Multiplayer:
* removed the "Great War" MP era * removed the "Great War" MP era
* Music and sound effects:
* Engine automatically plays special music on defeat or victory; default
lists from which an option is randomly chosen at runtime are provided as
the default_victory_music and default_defeat_music attributes in
[game_config] node; this may be overriden per-scenario using the
victory_music and/or defeat_music attributes on its code - it can also
be overriden in a [endlevel] block by providing a music= attribute with
the desired list (feature request #11203).
* Python AI * Python AI
* Added ai_init.py and ai_launcher.py to make it easier to customize * Added ai_init.py and ai_launcher.py to make it easier to customize
AI environment and startup. Both are used by the new embedded python AI environment and startup. Both are used by the new embedded python

View file

@ -226,6 +226,9 @@
ellipsis_image="misc/icon-ellipsis.png" ellipsis_image="misc/icon-ellipsis.png"
{core/team-colors.cfg} {core/team-colors.cfg}
default_victory_music="victory.ogg,victory2.ogg"
default_defeat_music="defeat.ogg,defeat2.ogg"
[/game_config] [/game_config]
[textdomain] [textdomain]

View file

@ -1816,7 +1816,7 @@ void check_victory(unit_map& units, std::vector<team>& teams, display& disp)
LOG_NG << "throwing end level exception...\n"; LOG_NG << "throwing end level exception...\n";
throw end_level_exception(found_player ? VICTORY : DEFEAT, throw end_level_exception(found_player ? VICTORY : DEFEAT, "",
victory_conditions::get_carryover_percentage(), victory_conditions::get_carryover_percentage(),
victory_conditions::get_carryover_add()); victory_conditions::get_carryover_add());
} }

View file

@ -90,6 +90,9 @@ namespace game_config
std::string level_image; std::string level_image;
std::string ellipsis_image; std::string ellipsis_image;
std::string default_victory_music;
std::string default_defeat_music;
std::map<std::string, color_range > team_rgb_range; std::map<std::string, color_range > team_rgb_range;
std::map<std::string, t_string > team_rgb_name; std::map<std::string, t_string > team_rgb_name;
@ -195,6 +198,8 @@ namespace game_config
level_image = v["level_image"]; level_image = v["level_image"];
ellipsis_image = v["ellipsis_image"]; ellipsis_image = v["ellipsis_image"];
default_victory_music = v["default_victory_music"];
default_defeat_music = v["default_defeat_music"];
add_color_info(v); add_color_info(v);

View file

@ -64,7 +64,7 @@ namespace game_config
terrain_mask_image, grid_image, unreachable_image, linger_image, terrain_mask_image, grid_image, unreachable_image, linger_image,
observer_image, tod_bright_image, observer_image, tod_bright_image,
checked_menu_image, unchecked_menu_image, wml_menu_image, level_image, checked_menu_image, unchecked_menu_image, wml_menu_image, level_image,
ellipsis_image; ellipsis_image, default_victory_music, default_defeat_music;
extern double hp_bar_scaling, xp_bar_scaling; extern double hp_bar_scaling, xp_bar_scaling;

View file

@ -2520,6 +2520,8 @@ namespace {
} }
const std::string result = cfg["result"].base_str(); //do not translate const std::string result = cfg["result"].base_str(); //do not translate
const std::string endlevel_music = cfg["music"];
if(result.empty() || result == "victory") { if(result.empty() || result == "victory") {
const bool bonus = utils::string_bool(cfg["bonus"],true); const bool bonus = utils::string_bool(cfg["bonus"],true);
const int carry_over = lexical_cast_default<int> const int carry_over = lexical_cast_default<int>
@ -2528,14 +2530,14 @@ namespace {
const bool gold_add = utils::string_bool(cfg["carryover_add"], const bool gold_add = utils::string_bool(cfg["carryover_add"],
game_config::gold_carryover_add); game_config::gold_carryover_add);
throw end_level_exception(VICTORY, carry_over, gold_add, bonus); throw end_level_exception(VICTORY, endlevel_music, carry_over, gold_add, bonus);
} else if(result == "continue") { } else if(result == "continue") {
throw end_level_exception(LEVEL_CONTINUE); throw end_level_exception(LEVEL_CONTINUE, endlevel_music);
} else if(result == "continue_no_save") { } else if(result == "continue_no_save") {
throw end_level_exception(LEVEL_CONTINUE_NO_SAVE); throw end_level_exception(LEVEL_CONTINUE_NO_SAVE);
} else { } else {
LOG_NG << "throwing event defeat...\n"; LOG_NG << "throwing event defeat...\n";
throw end_level_exception(DEFEAT); throw end_level_exception(DEFEAT, endlevel_music);
} }
} }

View file

@ -51,18 +51,23 @@ enum LEVEL_RESULT { VICTORY, DEFEAT, QUIT, LEVEL_CONTINUE, LEVEL_CONTINUE_NO_SAV
} }
struct end_level_exception { struct end_level_exception {
end_level_exception(LEVEL_RESULT res, const int percentage = -1, end_level_exception(LEVEL_RESULT res,
const bool add = false, const bool bonus=true) : const std::string& endlevel_music_list="",
const int percentage = -1,
const bool add = false, const bool bonus=true
):
result(res), result(res),
gold_bonus(bonus), gold_bonus(bonus),
carryover_percentage(percentage), carryover_percentage(percentage),
carryover_add(add) carryover_add(add),
custom_endlevel_music(endlevel_music_list)
{} {}
LEVEL_RESULT result; LEVEL_RESULT result;
bool gold_bonus; bool gold_bonus;
int carryover_percentage; int carryover_percentage;
bool carryover_add; bool carryover_add;
std::string custom_endlevel_music;
}; };
struct end_turn_exception { struct end_turn_exception {

View file

@ -55,6 +55,10 @@ play_controller::play_controller(const config& level,
start_turn_(status_.turn()), is_host_(true), skip_replay_(skip_replay), start_turn_(status_.turn()), is_host_(true), skip_replay_(skip_replay),
linger_(false) linger_(false)
{ {
// Setup victory and defeat music
set_victory_music_list(level_["victory_music"]);
set_defeat_music_list(level_["defeat_music"]);
status_.teams = &teams_; status_.teams = &teams_;
game_config::add_color_info(level); game_config::add_color_info(level);
hotkey::deactivate_all_scopes(); hotkey::deactivate_all_scopes();
@ -908,3 +912,42 @@ hotkey::ACTION_STATE play_controller::get_action_state(hotkey::HOTKEY_COMMAND co
} }
} }
namespace {
static const std::string empty_str = "";
}
const std::string& play_controller::select_victory_music() const
{
if(victory_music_.empty())
return empty_str;
const size_t p = gamestate_.rng().get_random() % victory_music_.size();
assert(p < victory_music_.size());
return victory_music_[p];
}
const std::string& play_controller::select_defeat_music() const
{
if(defeat_music_.empty())
return empty_str;
const size_t p = gamestate_.rng().get_random() % defeat_music_.size();
assert(p < defeat_music_.size());
return defeat_music_[p];
}
void play_controller::set_victory_music_list(const std::string& list)
{
victory_music_ = utils::split(list);
if(victory_music_.empty())
victory_music_ = utils::split(game_config::default_victory_music);
}
void play_controller::set_defeat_music_list(const std::string& list)
{
defeat_music_ = utils::split(list);
if(defeat_music_.empty())
defeat_music_ = utils::split(game_config::default_defeat_music);
}

View file

@ -154,6 +154,12 @@ protected:
bool skip_replay_; bool skip_replay_;
bool linger_; bool linger_;
bool first_turn_; bool first_turn_;
const std::string& select_victory_music() const;
const std::string& select_defeat_music() const;
void set_victory_music_list(const std::string& list);
void set_defeat_music_list(const std::string& list);
private: private:
// Expand AUTOSAVES in the menu items, setting the real savenames. // Expand AUTOSAVES in the menu items, setting the real savenames.
@ -164,6 +170,8 @@ private:
std::vector<wml_menu_item *> wml_commands_; std::vector<wml_menu_item *> wml_commands_;
static const size_t MAX_WML_COMMANDS = 7; static const size_t MAX_WML_COMMANDS = 7;
std::vector<std::string> victory_music_;
std::vector<std::string> defeat_music_;
}; };

View file

@ -304,6 +304,16 @@ LEVEL_RESULT playsingle_controller::play_scenario(const std::vector<config*>& st
log.quit(status_.turn()); log.quit(status_.turn());
throw; throw;
} catch(end_level_exception& end_level) { } catch(end_level_exception& end_level) {
if(!end_level.custom_endlevel_music.empty()) {
switch(end_level.result) {
case DEFEAT:
set_defeat_music_list(end_level.custom_endlevel_music);
break;
default:
set_victory_music_list(end_level.custom_endlevel_music);
}
}
bool obs = team_manager_.is_observer(); bool obs = team_manager_.is_observer();
if (game_config::exit_at_end) { if (game_config::exit_at_end) {
exit(0); exit(0);
@ -338,10 +348,15 @@ LEVEL_RESULT playsingle_controller::play_scenario(const std::vector<config*>& st
} catch(end_level_exception&) { } catch(end_level_exception&) {
} }
if (!obs) if (!obs) {
const std::string& defeat_music = select_defeat_music();
if(defeat_music.empty() != true)
sound::play_music_once(defeat_music);
return DEFEAT; return DEFEAT;
else } else {
return QUIT; return QUIT;
}
} else if (end_level.result == VICTORY } else if (end_level.result == VICTORY
|| end_level.result == LEVEL_CONTINUE || end_level.result == LEVEL_CONTINUE
|| end_level.result == LEVEL_CONTINUE_NO_SAVE) { || end_level.result == LEVEL_CONTINUE_NO_SAVE) {
@ -349,6 +364,9 @@ LEVEL_RESULT playsingle_controller::play_scenario(const std::vector<config*>& st
gamestate_.completion = "running"; gamestate_.completion = "running";
} else { } else {
gamestate_.completion = "victory"; gamestate_.completion = "victory";
const std::string& victory_music = select_victory_music();
if(victory_music.empty() != true)
sound::play_music_once(victory_music);
} }
recorder.set_save_info_completion(gamestate_.completion); recorder.set_save_info_completion(gamestate_.completion);
try { try {

View file

@ -88,6 +88,9 @@ private:
int player_gold, int player_gold,
int remaining_gold, int finishing_bonus_per_turn, int remaining_gold, int finishing_bonus_per_turn,
int turns_left, int finishing_bonus); int turns_left, int finishing_bonus);
std::vector<std::string> victory_music_;
std::vector<std::string> defeat_music_;
}; };