Merge pull request #216 from Rift-Walker/scenario_era_mod_defines_mergable
Add define functionality to scenarios, eras, and mods
This commit is contained in:
commit
5ca7121822
14 changed files with 157 additions and 12 deletions
|
@ -87,6 +87,7 @@ Version 1.13.0-dev:
|
|||
* Added support for [elseif] tags inside [if]
|
||||
* Schema validator messages now conform better to the new WML
|
||||
parser/preprocessor diagnostics format introduced in version 1.11.10.
|
||||
* Added define= functionality to scenarios, eras, and modifications.
|
||||
* Miscellaneous and bug fixes:
|
||||
* replace 'fight_on_without_leader'=yes/no with defeat_condition=no_leader/
|
||||
no_units/always/never which allows the wml developer to decide when a side
|
||||
|
|
|
@ -1174,6 +1174,10 @@
|
|||
email = "greywhind_AT_users.sourceforge.net"
|
||||
wikiuser = "Greywhind"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Nathan Walker (RiftWalker)"
|
||||
email = "nathan.b.walker@vanderbilt.edu"
|
||||
[/entry]
|
||||
[entry]
|
||||
name = "Oleg Tsarev"
|
||||
email = "zabivator@gmail.com"
|
||||
|
|
|
@ -10,7 +10,9 @@ Note: You need to use the default map settings for the scenario to work right."
|
|||
experience_modifier="100"
|
||||
map_data="{multiplayer/maps/Dark_Forecast.map}"
|
||||
victory_when_enemies_defeated=no
|
||||
define=MULTIPLAYER_2P_DARK_FORECAST_LOAD
|
||||
|
||||
#ifdef MULTIPLAYER_2P_DARK_FORECAST_LOAD
|
||||
#define RANDOMIZE NUMBER
|
||||
{VARIABLE_OP random rand 1..{NUMBER}}
|
||||
#enddef
|
||||
|
@ -1006,6 +1008,7 @@ Note: You need to use the default map settings for the scenario to work right."
|
|||
{FIRST_WATCH}
|
||||
{SECOND_WATCH}
|
||||
|
||||
#endif
|
||||
[side]
|
||||
side=1
|
||||
team_name="revolt"
|
||||
|
@ -1015,6 +1018,7 @@ Note: You need to use the default map settings for the scenario to work right."
|
|||
no_leader=yes
|
||||
controller="ai"
|
||||
village_gold=1
|
||||
#ifdef MULTIPLAYER_2P_DARK_FORECAST_LOAD
|
||||
[unit]
|
||||
type=Ancient Lich
|
||||
canrecruit=yes
|
||||
|
@ -1033,6 +1037,7 @@ Note: You need to use the default map settings for the scenario to work right."
|
|||
[/object]
|
||||
[/modifications]
|
||||
[/unit]
|
||||
#endif
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
|
@ -1088,6 +1093,7 @@ Note: You need to use the default map settings for the scenario to work right."
|
|||
share_view="yes"
|
||||
[/side]
|
||||
|
||||
#ifdef MULTIPLAYER_2P_DARK_FORECAST_LOAD
|
||||
[event]
|
||||
name=prestart
|
||||
{SET_TIMID_AI_AND_BOLD_AI 2 1}
|
||||
|
@ -1406,4 +1412,5 @@ The weather will also change randomly, affecting the layout of the map.
|
|||
#undef WEATHER_ALERT
|
||||
#undef ADJUST_WEATHER
|
||||
#undef INIT_WEATHER
|
||||
#endif
|
||||
[/multiplayer]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#textdomain wesnoth-multiplayer
|
||||
|
||||
#ifdef MULTIPLAYER_HORNSHARK_ISLAND_LOAD
|
||||
#define MODIFY_BOWMAN X Y
|
||||
[object]
|
||||
silent=yes
|
||||
|
@ -18,6 +19,7 @@
|
|||
[/effect]
|
||||
[/object]
|
||||
#enddef
|
||||
#endif
|
||||
|
||||
[multiplayer]
|
||||
id=multiplayer_Hornshark_Island
|
||||
|
@ -26,10 +28,13 @@
|
|||
description= _ "Players must forge strange alliances with the local inhabitants, in order to survive on this most unusual of islands. Designed by Doc Paterson."
|
||||
map_data="{multiplayer/maps/2p_Hornshark_Island.map}"
|
||||
random_start_time="no"
|
||||
define=MULTIPLAYER_HORNSHARK_ISLAND_LOAD
|
||||
|
||||
#ifdef MULTIPLAYER_HORNSHARK_ISLAND_LOAD
|
||||
{DEFAULT_SCHEDULE_MORNING}
|
||||
|
||||
{DEFAULT_MUSIC_PLAYLIST}
|
||||
#endif
|
||||
|
||||
[side]
|
||||
[ai]
|
||||
|
@ -56,6 +61,7 @@
|
|||
fog=yes
|
||||
[/side]
|
||||
|
||||
#ifdef MULTIPLAYER_HORNSHARK_ISLAND_LOAD
|
||||
[event]
|
||||
name=prestart
|
||||
|
||||
|
@ -1011,4 +1017,5 @@
|
|||
{MODIFY_BOWMAN 1 1}
|
||||
{MODIFY_BOWMAN 28 24}
|
||||
[/event]
|
||||
#endif
|
||||
[/multiplayer]
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
description= _ "This 4p survival scenario allows you to construct buildings and terraform the land. Use map settings. The recommended starting gold is 100."
|
||||
experience_modifier=70%
|
||||
turns=unlimited
|
||||
define=MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
{DEFAULT_SCHEDULE}
|
||||
{DEFAULT_MUSIC_PLAYLIST}
|
||||
# ------------------------------------------------------
|
||||
|
@ -36,6 +38,7 @@
|
|||
[/objective]
|
||||
[/objectives]
|
||||
[/event]
|
||||
#endif
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Side Definitions
|
||||
|
@ -120,6 +123,7 @@
|
|||
income_lock=yes
|
||||
type=Death Knight
|
||||
allow_player=no
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
[modifications]
|
||||
{MOVEMENT_RESTRICTION flat shallow_water}
|
||||
[/modifications]
|
||||
|
@ -130,6 +134,7 @@
|
|||
[village]
|
||||
x,y=10,25
|
||||
[/village]
|
||||
#endif
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
|
@ -147,6 +152,7 @@
|
|||
income_lock=yes
|
||||
type=Orcish Sovereign
|
||||
allow_player=no
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
[modifications]
|
||||
{MOVEMENT_RESTRICTION flat shallow_water}
|
||||
[/modifications]
|
||||
|
@ -157,6 +163,7 @@
|
|||
[village]
|
||||
x,y=50,25
|
||||
[/village]
|
||||
#endif
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
|
@ -174,6 +181,7 @@
|
|||
income_lock=yes
|
||||
type=Orcish Sovereign
|
||||
allow_player=no
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
[modifications]
|
||||
{MOVEMENT_RESTRICTION flat shallow_water}
|
||||
[/modifications]
|
||||
|
@ -184,6 +192,7 @@
|
|||
[village]
|
||||
x,y=10,30
|
||||
[/village]
|
||||
#endif
|
||||
[/side]
|
||||
|
||||
[side]
|
||||
|
@ -201,6 +210,7 @@
|
|||
income_lock=yes
|
||||
type=Death Knight
|
||||
allow_player=no
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
[modifications]
|
||||
{MOVEMENT_RESTRICTION flat shallow_water}
|
||||
[/modifications]
|
||||
|
@ -211,6 +221,7 @@
|
|||
[village]
|
||||
x,y=50,30
|
||||
[/village]
|
||||
#endif
|
||||
[/side]
|
||||
|
||||
# This side is for trapped units. It is allied to the AI so they don't attack it.
|
||||
|
@ -233,6 +244,7 @@
|
|||
[/ai]
|
||||
[/side]
|
||||
|
||||
#ifdef MULTIPLAYER_A_NEW_LAND_LOAD
|
||||
# ------------------------------------------------------
|
||||
# ANL Building Logic
|
||||
# ------------------------------------------------------
|
||||
|
@ -840,4 +852,5 @@
|
|||
type=Necrophage,Bone Shooter,Revenant
|
||||
[/allow_recruit]
|
||||
[/event]
|
||||
#endif
|
||||
[/multiplayer]
|
||||
|
|
|
@ -49,6 +49,7 @@ _s , _s , _s , _s , _s , _s
|
|||
_s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s
|
||||
_s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s , _s
|
||||
#enddef
|
||||
#ifdef 6P_TEAM_SURVIVAL_LOAD
|
||||
#define TS_WALL_MASK_NORTH
|
||||
usage=mask
|
||||
|
||||
|
@ -311,6 +312,7 @@ usage=mask
|
|||
{TS_SPAWN2 "Goblin Rouser"}{TS_SPAWN2 "Goblin Spearman"}{TS_SPAWN2 "Goblin Spearman"}{TS_SPAWN2 "Goblin Spearman"}{TS_SPAWN2 "Goblin Spearman"}{TS_SPAWN2 "Goblin Spearman"}{TS_SPAWN2 "Goblin Spearman"}
|
||||
[/event]
|
||||
#enddef
|
||||
#endif
|
||||
|
||||
[multiplayer]
|
||||
id=multiplayer_6p_Team_Survival
|
||||
|
@ -321,9 +323,12 @@ usage=mask
|
|||
turns=32
|
||||
victory_when_enemies_defeated=yes
|
||||
random_start_time="no"
|
||||
define=6P_TEAM_SURVIVAL_LOAD
|
||||
|
||||
#ifdef 6P_TEAM_SURVIVAL_LOAD
|
||||
{DEFAULT_MUSIC_PLAYLIST}
|
||||
{DEFAULT_SCHEDULE}
|
||||
#endif
|
||||
|
||||
[side]
|
||||
user_team_name=_ "Attacker"
|
||||
|
@ -420,6 +425,7 @@ usage=mask
|
|||
[/ai]
|
||||
[/side]
|
||||
|
||||
#ifdef 6P_TEAM_SURVIVAL_LOAD
|
||||
[event]
|
||||
name=prestart
|
||||
|
||||
|
@ -600,9 +606,11 @@ usage=mask
|
|||
image=portraits/undead/transparent/spectre.png
|
||||
[/message]
|
||||
[/event]
|
||||
#endif
|
||||
[/multiplayer]
|
||||
|
||||
#undef TS_MAP_DATA
|
||||
#ifdef 6P_TEAM_SURVIVAL_LOAD
|
||||
#undef TS_WALL_MASK_NORTH
|
||||
#undef TS_WALL_MASK_NORTH_EAST
|
||||
#undef TS_WALL_MASK_NORTH_WEST
|
||||
|
@ -622,3 +630,4 @@ usage=mask
|
|||
#undef TS_LAKE_SPAWN
|
||||
#undef TS_HOME_SPAWN
|
||||
#undef TS_SPAWNS
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,9 @@ game_classification::game_classification():
|
|||
campaign_type(),
|
||||
campaign_define(),
|
||||
campaign_xtra_defines(),
|
||||
scenario_define(),
|
||||
era_define(),
|
||||
mod_defines(),
|
||||
campaign(),
|
||||
abbrev(),
|
||||
completion(),
|
||||
|
@ -51,6 +54,9 @@ game_classification::game_classification(const config& cfg):
|
|||
campaign_type(lexical_cast_default<game_classification::CAMPAIGN_TYPE> (cfg["campaign_type"].str(), game_classification::SCENARIO)),
|
||||
campaign_define(cfg["campaign_define"]),
|
||||
campaign_xtra_defines(utils::split(cfg["campaign_extra_defines"])),
|
||||
scenario_define(cfg["scenario_define"]),
|
||||
era_define(cfg["era_define"]),
|
||||
mod_defines(utils::split(cfg["mod_defines"])),
|
||||
campaign(cfg["campaign"]),
|
||||
abbrev(cfg["abbrev"]),
|
||||
completion(cfg["completion"]),
|
||||
|
@ -68,6 +74,9 @@ game_classification::game_classification(const game_classification& gc):
|
|||
campaign_type(gc.campaign_type),
|
||||
campaign_define(gc.campaign_define),
|
||||
campaign_xtra_defines(gc.campaign_xtra_defines),
|
||||
scenario_define(gc.scenario_define),
|
||||
era_define(gc.era_define),
|
||||
mod_defines(gc.mod_defines),
|
||||
campaign(gc.campaign),
|
||||
abbrev(gc.abbrev),
|
||||
completion(gc.completion),
|
||||
|
@ -88,6 +97,9 @@ config game_classification::to_config() const
|
|||
cfg["campaign_type"] = lexical_cast<std::string> (campaign_type);
|
||||
cfg["campaign_define"] = campaign_define;
|
||||
cfg["campaign_extra_defines"] = utils::join(campaign_xtra_defines);
|
||||
cfg["scenario_define"] = scenario_define;
|
||||
cfg["era_define"] = era_define;
|
||||
cfg["mod_defines"] = utils::join(mod_defines);
|
||||
cfg["campaign"] = campaign;
|
||||
cfg["abbrev"] = abbrev;
|
||||
cfg["completion"] = completion;
|
||||
|
|
|
@ -43,6 +43,9 @@ public:
|
|||
CAMPAIGN_TYPE campaign_type;
|
||||
std::string campaign_define; /**< If there is a define the campaign uses to customize data */
|
||||
std::vector<std::string> campaign_xtra_defines; /**< more customization of data */
|
||||
std::string scenario_define; /**< If there is a define the scenario uses to customize data */
|
||||
std::string era_define; /**< If there is a define the era uses to customize data */
|
||||
std::vector<std::string> mod_defines; /**< If there are defines the modifications use to customize data */
|
||||
|
||||
std::string campaign; /**< the campaign being played */
|
||||
|
||||
|
|
|
@ -374,6 +374,10 @@ void game_config_manager::load_game_config_for_game(
|
|||
!classification.difficulty.empty());
|
||||
game_config::scoped_preproc_define campaign(classification.campaign_define,
|
||||
!classification.campaign_define.empty());
|
||||
game_config::scoped_preproc_define scenario(classification.scenario_define,
|
||||
!classification.scenario_define.empty());
|
||||
game_config::scoped_preproc_define era(classification.era_define,
|
||||
!classification.era_define.empty());
|
||||
game_config::scoped_preproc_define multiplayer("MULTIPLAYER",
|
||||
classification.campaign_type == game_classification::MULTIPLAYER);
|
||||
|
||||
|
@ -385,6 +389,13 @@ void game_config_manager::load_game_config_for_game(
|
|||
(new game_config::scoped_preproc_define(extra_define));
|
||||
extra_defines.push_back(new_define);
|
||||
}
|
||||
std::deque<define> modification_defines;
|
||||
BOOST_FOREACH(const std::string& mod_define,
|
||||
classification.mod_defines) {
|
||||
define new_define
|
||||
(new game_config::scoped_preproc_define(mod_define, !mod_define.empty()));
|
||||
modification_defines.push_back(new_define);
|
||||
}
|
||||
|
||||
try{
|
||||
load_game_config(NO_FORCE_RELOAD, &classification);
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#include "settings.hpp"
|
||||
#include "sound.hpp"
|
||||
#include "unit_id.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "game_config_manager.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -785,13 +787,34 @@ void start_local_game_commandline(game_display& disp, const config& game_config,
|
|||
// None of the other parameters need to be set, as their creation values above are good enough for CL mode.
|
||||
// In particular, we do not want to use the preferences values.
|
||||
|
||||
// Override era, faction (side) and scenario if set on the commandline
|
||||
if (cmdline_opts.multiplayer_era) parameters.mp_era = *cmdline_opts.multiplayer_era;
|
||||
const config &era_cfg = game_config.find_child("era", "id", parameters.mp_era);
|
||||
if (!era_cfg) {
|
||||
std::cerr << "Could not find era '" << parameters.mp_era << "'\n";
|
||||
return;
|
||||
// scope for config objects that will become invalid after reload
|
||||
{
|
||||
// Override era, faction (side) and scenario if set on the commandline
|
||||
if (cmdline_opts.multiplayer_era)
|
||||
parameters.mp_era = *cmdline_opts.multiplayer_era;
|
||||
const config& era_cfg_preload = game_config.find_child("era", "id", parameters.mp_era);
|
||||
if (!era_cfg_preload) {
|
||||
std::cerr << "Could not find era '" << parameters.mp_era << "'\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmdline_opts.multiplayer_scenario)
|
||||
parameters.name = *cmdline_opts.multiplayer_scenario;
|
||||
const config &level_preload = game_config.find_child("multiplayer", "id", parameters.name);
|
||||
if (!level_preload) {
|
||||
std::cerr << "Could not find scenario '" << parameters.name << "'\n";
|
||||
return;
|
||||
}
|
||||
|
||||
game_classification classification;
|
||||
classification.campaign_type = game_classification::MULTIPLAYER;
|
||||
classification.scenario_define = level_preload["define"].str();
|
||||
classification.era_define = era_cfg_preload["define"].str();
|
||||
resources::config_manager->load_game_config_for_game(classification);
|
||||
}
|
||||
|
||||
const config& era_cfg = resources::config_manager->game_config().find_child("era", "id", parameters.mp_era);
|
||||
const config& level = resources::config_manager->game_config().find_child("multiplayer", "id", parameters.name);
|
||||
|
||||
if (cmdline_opts.multiplayer_side) {
|
||||
for(std::vector<boost::tuple<unsigned int, std::string> >::const_iterator
|
||||
|
@ -805,12 +828,6 @@ void start_local_game_commandline(game_display& disp, const config& game_config,
|
|||
}
|
||||
}
|
||||
|
||||
if (cmdline_opts.multiplayer_scenario) parameters.name = *cmdline_opts.multiplayer_scenario;
|
||||
const config &level = game_config.find_child("multiplayer", "id", parameters.name);
|
||||
if (!level) {
|
||||
std::cerr << "Could not find scenario '" << parameters.name << "'\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// Should the map be randomly generated?
|
||||
if (level["map_generation"].empty()) {
|
||||
|
|
|
@ -223,6 +223,9 @@ void create::process_event()
|
|||
|
||||
if (launch_game_.pressed() || levels_menu_.double_clicked()) {
|
||||
if (engine_.current_level().can_launch_game()) {
|
||||
|
||||
engine_.prepare_for_era_and_mods();
|
||||
|
||||
if (engine_.current_level_type() == level::CAMPAIGN ||
|
||||
engine_.current_level_type() == level::SP_CAMPAIGN) {
|
||||
|
||||
|
@ -232,6 +235,8 @@ void create::process_event()
|
|||
}
|
||||
|
||||
engine_.prepare_for_campaign(difficulty);
|
||||
} else {
|
||||
engine_.prepare_for_scenario();
|
||||
}
|
||||
|
||||
engine_.prepare_for_new_level();
|
||||
|
|
|
@ -412,6 +412,34 @@ void create_engine::prepare_for_new_level()
|
|||
state_.mp_settings().hash = current_level().data().hash();
|
||||
}
|
||||
|
||||
void create_engine::prepare_for_era_and_mods()
|
||||
{
|
||||
state_.classification().era_define =
|
||||
resources::config_manager->game_config().find_child(
|
||||
"era", "id", get_parameters().mp_era)["define"].str();
|
||||
BOOST_FOREACH(const std::string& mod_id, get_parameters().active_mods) {
|
||||
state_.classification().mod_defines.push_back(
|
||||
resources::config_manager->game_config().find_child(
|
||||
"modification", "id", mod_id)["define"].str());
|
||||
}
|
||||
}
|
||||
|
||||
void create_engine::prepare_for_scenario()
|
||||
{
|
||||
DBG_MP << "preparing data for scenario by reloading game config\n";
|
||||
|
||||
state_.classification().scenario_define =
|
||||
current_level().data()["define"].str();
|
||||
|
||||
resources::config_manager->
|
||||
load_game_config_for_game(state_.classification());
|
||||
|
||||
current_level().set_data(
|
||||
resources::config_manager->game_config().find_child(
|
||||
lexical_cast<std::string> (game_classification::MULTIPLAYER),
|
||||
"id", current_level().data()["id"]));
|
||||
}
|
||||
|
||||
void create_engine::prepare_for_campaign(const std::string& difficulty)
|
||||
{
|
||||
DBG_MP << "preparing data for campaign by reloading game config\n";
|
||||
|
|
|
@ -180,6 +180,8 @@ public:
|
|||
void init_generated_level_data();
|
||||
|
||||
void prepare_for_new_level();
|
||||
void prepare_for_era_and_mods();
|
||||
void prepare_for_scenario();
|
||||
void prepare_for_campaign(const std::string& difficulty);
|
||||
void prepare_for_saved_game();
|
||||
|
||||
|
|
|
@ -237,6 +237,14 @@ void wait::join_game(bool observe)
|
|||
const config* campaign = &resources::config_manager->
|
||||
game_config().find_child("campaign", "id",
|
||||
level_.child("multiplayer")["mp_campaign"]);
|
||||
|
||||
const config* scenario = &resources::config_manager->
|
||||
game_config().find_child("multiplayer", "id",
|
||||
level_.child(lexical_cast<std::string>(game_classification::MULTIPLAYER))["id"]);
|
||||
|
||||
const config* era = &resources::config_manager->
|
||||
game_config().find_child("era", "id", level_.child("era")["id"]);
|
||||
|
||||
if (*campaign) {
|
||||
state_.classification().difficulty =
|
||||
level_.child("multiplayer")["difficulty_define"].str();
|
||||
|
@ -246,6 +254,24 @@ void wait::join_game(bool observe)
|
|||
utils::split((*campaign)["extra_defines"]);
|
||||
}
|
||||
|
||||
if (*scenario)
|
||||
state_.classification().scenario_define =
|
||||
(*scenario)["define"].str();
|
||||
|
||||
if (*era)
|
||||
state_.classification().era_define =
|
||||
(*era)["define"].str();
|
||||
|
||||
BOOST_FOREACH(const config& mod, level_.child_range("modification")) {
|
||||
const config* modification = &resources::config_manager->
|
||||
game_config().find_child("modification", "id", mod["id"]);
|
||||
if (*modification) {
|
||||
state_.classification().mod_defines.push_back(
|
||||
(*modification)["define"].str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make sure that we have the same config as host, if possible.
|
||||
resources::config_manager->
|
||||
load_game_config_for_game(state_.classification());
|
||||
|
|
Loading…
Add table
Reference in a new issue