[[Multiplayer improvements]]

- added in possibility to customize the experience requirements in a
  multiplayer game

- added in 'eras' feature for multiplayer games
This commit is contained in:
Dave White 2004-04-15 21:24:57 +00:00
parent c229b80c35
commit 1c6cb6adbe
16 changed files with 370 additions and 135 deletions

View file

@ -300,6 +300,10 @@ ggggggggggggggggggggffffffffffffffffff
{battleworld.cfg}
[era]
name=Default
id=era_default
[multiplayer_side]
name=&human-general.png,Loyalists
type=General
@ -344,3 +348,104 @@ ggggggggggggggggggggffffffffffffffffff
music="wesnoth-7.ogg"
terrain_liked=hm
[/multiplayer_side]
[/era]
[era]
name=Classic
id=era_classic
[multiplayer_side]
name=&human-general.png,Humans
type=General
recruit=Cavalry,Horseman,Spearman,Fencer,Heavy Infantry,Bowman,Mage,Thief
recruitment_pattern=scout,fighter,fighter,fighter,archer
music="wesnoth-2.ogg"
terrain_liked=gcs
[/multiplayer_side]
[multiplayer_side]
name=&elvish-lord.png,Elves
type=Elvish Lord
recruit=Elvish Fighter,Elvish Archer,Elvish Shaman,Elvish Scout,Merman
recruitment_pattern=fighter,fighter,scout
music="elf-land.ogg"
terrain_liked=fwc
[/multiplayer_side]
[multiplayer_side]
name=&orcish-warlord.png,Orcs
type=Orcish Warlord
recruit=Orcish Grunt,Troll Whelp,Wolf Rider,Orcish Archer,Orcish Assassin,Naga
recruitment_pattern=fighter,fighter,archer,scout
music="wesnoth-5.ogg"
terrain_liked=hmw
[/multiplayer_side]
[multiplayer_side]
name=&undead-lich.png,Undead
type=Lich
recruit=Skeleton,Skeleton Archer,Walking Corpse,Ghost,Vampire Bat,Dark Adept
recruitment_pattern=scout,fighter,fighter,archer
music="wesnoth-3.ogg"
terrain_liked=whc
[/multiplayer_side]
[multiplayer_side]
name=&dwarf-lord.png,Dwarves
type=Dwarvish Lord
recruit=Dwarvish Fighter,Dwarvish Thunderer
recruitment_pattern=fighter,fighter,fighter,archer
music="wesnoth-7.ogg"
terrain_liked=hm
[/multiplayer_side]
[/era]
[era]
name=Age of Heroes
id=era_heroes
[multiplayer_side]
name=&human-general.png,Loyalists
type=General
recruit=Cavalry,Horseman,Spearman,Fencer,Heavy Infantry,Bowman,Mage,Naga,Ogre,Dragoon,Knight,Swordsman,Longbowman,White Mage
recruitment_pattern=scout,fighter,fighter,fighter,archer
music="wesnoth-2.ogg"
terrain_liked=gcs
[/multiplayer_side]
[multiplayer_side]
name=&elvish-lord.png,Rebels
type=Elvish Lord
recruit=Elvish Fighter,Elvish Archer,Mage,Elvish Shaman,Elvish Scout,Wose Sapling,Merman,Elvish Hero,Elvish Ranger,Elvish Marksman,Elvish Outrider,Merman Lord
recruitment_pattern=fighter,fighter,scout
music="wesnoth-4.ogg"
terrain_liked=fwc
[/multiplayer_side]
[multiplayer_side]
name=&orcish-warlord.png,Northerners
type=Orcish Warlord
recruit=Orcish Grunt,Troll Whelp,Wolf Rider,Orcish Archer,Orcish Assassin,Naga,Orcish Warrior,Troll,Goblin Knight
recruitment_pattern=fighter,fighter,archer,scout
music="wesnoth-5.ogg"
terrain_liked=hmw
[/multiplayer_side]
[multiplayer_side]
name=&undead-lich.png,Undead
type=Lich
recruit=Skeleton,Skeleton Archer,Walking Corpse,Ghost,Vampire Bat,Dark Adept,Revenant,Bone Shooter,Blood Bat
recruitment_pattern=scout,fighter,fighter,archer
music="wesnoth-3.ogg"
terrain_liked=whc
[/multiplayer_side]
[multiplayer_side]
name=&dwarf-lord.png,Knalgan Alliance
type=Dwarvish Lord
recruit=Thug,Thief,Poacher,Footpad,Dwarvish Fighter,Dwarvish Thunderer,Gryphon Rider,Dwarvish Berserker,Dwarvish Steelclad,Dwarvish Thunderguard,Bandit
recruitment_pattern=fighter,fighter,fighter,archer
music="wesnoth-7.ogg"
terrain_liked=hm
[/multiplayer_side]
[/era]

View file

@ -318,6 +318,7 @@ create_new_game="Create Game"
name_of_game="Name of game"
map_to_play="Map to play"
village_gold="Village Gold"
xp_modifier="Experience Requirements"
turns="Turns"
login="Login"

View file

@ -176,8 +176,7 @@ void draw(SDL_Surface* screen)
}
if(cursor_buf == NULL) {
cursor_buf = SDL_CreateRGBSurface(SDL_SWSURFACE,surf->w,surf->h,surf->format->BitsPerPixel,
surf->format->Rmask,surf->format->Gmask,surf->format->Bmask,surf->format->Amask);
cursor_buf = create_compatible_surface(surf);
if(cursor_buf == NULL) {
std::cerr << "Could not allocate surface for mouse cursor\n";
return;

View file

@ -561,9 +561,7 @@ SDL_Surface* floating_label::create_surface()
}
const SDL_PixelFormat* const format = surfaces.front()->format;
surf_.assign(SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,
format->BitsPerPixel,format->Rmask,format->Gmask,
format->Bmask,format->Amask));
surf_.assign(create_compatible_surface(surfaces.front(),width,height));
size_t ypos = 0;
for(i = surfaces.begin(); i != surfaces.end(); ++i) {
@ -581,8 +579,7 @@ SDL_Surface* floating_label::create_surface()
//if the surface has to be created onto some kind of background, then do that here
if(bgalpha_ != 0) {
std::cerr << "creating bg...\n";
shared_sdl_surface tmp(SDL_CreateRGBSurface(SDL_SWSURFACE,surf_->w+border_*2,surf_->h+border_*2,surf_->format->BitsPerPixel,
surf_->format->Rmask,surf_->format->Gmask,surf_->format->Bmask,surf_->format->Amask));
shared_sdl_surface tmp(create_compatible_surface(surf_,surf_->w+border_*2,surf_->h+border_*2));
if(tmp == NULL) {
return NULL;
}
@ -616,8 +613,7 @@ void floating_label::draw(SDL_Surface* screen)
}
if(buf_ == NULL) {
buf_.assign(SDL_CreateRGBSurface(SDL_SWSURFACE,surf_->w,surf_->h,surf_->format->BitsPerPixel,
surf_->format->Rmask,surf_->format->Gmask,surf_->format->Bmask,surf_->format->Amask));
buf_.assign(create_compatible_surface(surf_));
if(buf_ == NULL) {
return;
}

View file

@ -27,6 +27,7 @@
#include "replay.hpp"
#include "scoped_resource.hpp"
#include "show_dialog.hpp"
#include "util.hpp"
#include "widgets/textbox.hpp"
#include "widgets/button.hpp"
#include "widgets/combo.hpp"
@ -50,8 +51,6 @@ network_game_manager::~network_game_manager()
}
}
// TODO: This function is way to big. It should be split into 2 functions,
// one for each dialog.
int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
game_state& state, bool server)
{
@ -67,35 +66,40 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
//later allow configuration of amount of gold
state.gold = 100;
// Dialog width and height
int width=640;
int height=340;
int cur_selection = -1;
int cur_villagegold = 1;
int new_villagegold = 1;
int cur_turns = 50;
int new_turns = 50;
int cur_playergold = 100;
int new_playergold = 100;
int cur_xpmod = 100;
gui::draw_dialog_frame((disp.x()-width)/2, (disp.y()-height)/2,
width, height, disp);
// Dialog width and height
int width = 640;
int height = 440;
const int left = (disp.x()-width)/2;
const int top = (disp.y()-height)/2;
const int border_size = 5;
const int right = left + width;
const int bottom = top + height;
//Title
font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
string_table["create_new_game"],-1,(disp.y()-height)/2+5);
gui::draw_dialog_frame(left,top,width,height,disp);
int xpos = left + border_size;
int ypos = gui::draw_dialog_title(left,top,disp,string_table["create_new_game"]) + border_size;
//Name Entry
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["name_of_game"] + ":",(disp.x()-width)/2+10,(disp.y()-height)/2+38);
ypos += font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["name_of_game"] + ":",xpos,ypos).h + border_size;
gui::textbox name_entry(disp,width-20,string_table["game_prefix"] + preferences::login() + string_table["game_postfix"]);
name_entry.set_position((disp.x()-width)/2+10,(disp.y()-height)/2+55);
name_entry.set_position(xpos,ypos);
//Maps
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["map_to_play"] + ":",(disp.x()-width)/2+(int)(width*0.4),
(disp.y()-height)/2+83);
ypos += name_entry.location().h + border_size;
const int minimap_width = 200;
//the map selection menu goes near the middle of the dialog, to the right of
//the minimap
const int map_label_height = font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["map_to_play"] + ":",xpos + minimap_width + border_size,ypos).h;
//build the list of scenarios to play
std::vector<std::string> options;
const config::child_list& levels = cfg.get_children("multiplayer");
std::map<int,std::string> res_to_id;
@ -110,78 +114,118 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
options.push_back((**i)["name"]);
}
//add the 'load game' option
options.push_back(string_table["load_game"] + "...");
gui::menu maps_menu(disp,options);
maps_menu.set_loc((disp.x()-width)/2+(int)(width*0.4),(disp.y()-height)/2+100);
//Game Turns
rect.x = (disp.x()-width)/2+(int)(width*0.4)+maps_menu.width()+19;
rect.y = (disp.y()-height)/2+83;
rect.w = ((disp.x()-width)/2+width)-((disp.x()-width)/2+(int)(width*0.4)+maps_menu.width()+19)-10;
//create the scenarios menu
gui::menu maps_menu(disp,options);
maps_menu.set_loc(xpos + minimap_width + border_size,ypos + map_label_height + border_size);
//the sliders and other options on the right side of the dialog
rect.x = xpos + minimap_width + maps_menu.width() + border_size*2;
rect.y = ypos;
rect.w = maximum<int>(0,right - border_size - rect.x);
rect.h = 12;
SDL_Surface* village_bg=get_surface_portion(disp.video().getSurface(), rect);
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["turns"] + ": 50",rect.x,rect.y);
rect.y = (disp.y()-height)/2+100;
rect.h = name_entry.location().w;
SDL_Rect turns_rect = rect;
const scoped_sdl_surface village_bg(get_surface_portion(disp.video().getSurface(), rect));
rect.y += turns_rect.h + border_size*2;
gui::slider turns_slider(disp,rect);
turns_slider.set_min(20);
turns_slider.set_max(100);
turns_slider.set_value(50);
turns_slider.set_value(cur_turns);
//Village Gold
rect.x = (disp.x()-width)/2+(int)(width*0.4)+maps_menu.width()+19;
rect.y = (disp.y()-height)/2+130;
rect.w = ((disp.x()-width)/2+width)-((disp.x()-width)/2+(int)(width*0.4)+maps_menu.width()+19)-10;
rect.h = 12;
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["village_gold"] + ": 1",rect.x,rect.y);
rect.y = (disp.y()-height)/2+147;
rect.h = name_entry.location().w;
rect.y += rect.h + border_size*2;
SDL_Rect village_rect = rect;
rect.y += village_rect.h + border_size*2;
gui::slider villagegold_slider(disp,rect);
villagegold_slider.set_min(1);
villagegold_slider.set_max(10);
villagegold_slider.set_value(1);
villagegold_slider.set_value(cur_villagegold);
//Experience Modifier
rect.y += rect.h + border_size*2;
SDL_Rect xp_rect = rect;
rect.y += xp_rect.h + border_size*2;
gui::slider xp_modifier_slider(disp,rect);
xp_modifier_slider.set_min(25);
xp_modifier_slider.set_max(200);
xp_modifier_slider.set_value(cur_xpmod);
//FOG of war
rect.y += rect.h + border_size*2;
gui::button fog_game(disp,string_table["fog_of_war"],gui::button::TYPE_CHECK);
fog_game.set_check(false);
fog_game.set_xy(rect.x+6,rect.y+30);
fog_game.set_xy(rect.x,rect.y);
fog_game.draw();
rect.y += fog_game.location().h + border_size;
//Shroud
gui::button shroud_game(disp,string_table["shroud"],gui::button::TYPE_CHECK);
shroud_game.set_check(false);
shroud_game.set_xy(rect.x+6,rect.y+30+fog_game.height()+2);
shroud_game.set_xy(rect.x,rect.y);
shroud_game.draw();
rect.y += shroud_game.location().h + border_size;
//Observers
gui::button observers_game(disp,string_table["observers"],gui::button::TYPE_CHECK);
observers_game.set_check(true);
observers_game.set_xy(rect.x+6,rect.y+30+(2*fog_game.height())+4);
observers_game.set_xy(rect.x,rect.y);
observers_game.draw();
rect.y += observers_game.location().h + border_size;
//Buttons
gui::button cancel_game(disp,string_table["cancel_button"]);
gui::button launch_game(disp,string_table["ok_button"]);
launch_game.set_xy((disp.x()/2)-launch_game.width()*2-19,(disp.y()-height)/2+height-29);
cancel_game.set_xy((disp.x()/2)+cancel_game.width()+19,(disp.y()-height)/2+height-29);
launch_game.set_xy((disp.x()/2)-launch_game.width()*2-19,bottom-29);
cancel_game.set_xy((disp.x()/2)+cancel_game.width()+19,bottom-29);
gui::button regenerate_map(disp,string_table["regenerate_map"]);
regenerate_map.set_xy(rect.x+6,rect.y+30+(3*fog_game.height())+6);
regenerate_map.set_xy(rect.x,rect.y);
regenerate_map.backup_background();
rect.y += regenerate_map.location().h + border_size;
gui::button generator_settings(disp,string_table["generator_settings"]);
generator_settings.set_xy(rect.x+6,rect.y+30+(4*fog_game.height())+8);
generator_settings.set_xy(rect.x,rect.y);
generator_settings.backup_background();
//player amount number background
rect.x = ((disp.x()-width)/2+10)+35;
rect.y = (disp.y()-height)/2+235;
rect.w = 145;
rect.h = 25;
surface_restorer playernum_bg(&disp.video(),rect);
SDL_Rect player_num_rect = {xpos+minimap_width/2 - 30,ypos+minimap_width,100,25};
surface_restorer playernum_bg(&disp.video(),player_num_rect);
//the possible eras to play
const config::child_list& era_list = cfg.get_children("era");
std::vector<std::string> eras;
for(config::child_list::const_iterator er = era_list.begin(); er != era_list.end(); ++er) {
eras.push_back(translate_string_default((**er)["id"],(**er)["name"]));
}
if(eras.empty()) {
gui::show_dialog(disp,NULL,"",string_table["error_no_mp_sides"],gui::OK_ONLY);
std::cerr << "ERROR: no eras found\n";
return -1;
}
SDL_Rect era_rect = {xpos,player_num_rect.y+player_num_rect.h + border_size,50,20};
era_rect = font::draw_text(&disp,era_rect,12,font::GOOD_COLOUR,translate_string("Era") + ":",
era_rect.x,era_rect.y);
gui::combo era_combo(disp,eras);
era_combo.set_xy(era_rect.x+era_rect.w+border_size,era_rect.y);
update_whole_screen();
@ -198,6 +242,8 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
name_entry.process();
turns_slider.process();
villagegold_slider.process();
xp_modifier_slider.process();
era_combo.process(mousex,mousey,left_button);
maps_menu.process(mousex,mousey,left_button,
key[SDLK_UP],key[SDLK_DOWN],
@ -208,10 +254,12 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
if(launch_game.process(mousex,mousey,left_button)) {
if(name_entry.text().empty() == false) {
//Connector
mp_connect connector(disp, name_entry.text(), cfg, units_data, state);
const int res = connector.load_map(maps_menu.selection(), cur_turns, cur_villagegold, fog_game.checked(), shroud_game.checked(), observers_game.checked());
const int res = connector.load_map((*era_list[era_combo.selected()])["id"],
maps_menu.selection(), cur_turns, cur_villagegold, cur_xpmod, fog_game.checked(), shroud_game.checked(), observers_game.checked());
if(res == -1)
return -1;
@ -221,17 +269,8 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
connector.gui_do();
return -1;
} else {
rect.x=(disp.x()-width)/2;
rect.y=(disp.y()-height)/2;
rect.w=width;
rect.h=height;
SDL_Surface* dialog_bg=get_surface_portion(disp.video().getSurface(), rect);
gui::show_dialog(disp,NULL,"",
"You must enter a name.",gui::OK_ONLY);
SDL_BlitSurface(dialog_bg, NULL, disp.video().getSurface(), &rect);
SDL_FreeSurface(dialog_bg);
update_whole_screen();
}
}
@ -247,30 +286,31 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
//Turns per game
cur_turns = turns_slider.value();
rect.x = (disp.x()-width)/2+int(width*0.4)+maps_menu.width()+19;
rect.y = (disp.y()-height)/2+83;
rect.w = ((disp.x()-width)/2+width)-((disp.x()-width)/2+int(width*0.4)+maps_menu.width()+19)-10;
rect.h = 12;
SDL_BlitSurface(village_bg, NULL, disp.video().getSurface(), &rect);
SDL_BlitSurface(village_bg, NULL, disp.video().getSurface(), &turns_rect);
sprintf(buf,"Turns: %d", cur_turns);
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
buf,rect.x,rect.y);
update_rect(rect);
buf,turns_rect.x,turns_rect.y);
update_rect(turns_rect);
//work out if we have to generate a new map
bool map_changed = false;
//Villages can produce between 1 and 10 gold a turn
cur_villagegold = villagegold_slider.value();
rect.x = (disp.x()-width)/2+int(width*0.4)+maps_menu.width()+19;
rect.y = (disp.y()-height)/2+130;
rect.w = ((disp.x()-width)/2+width)-((disp.x()-width)/2+int(width*0.4)+maps_menu.width()+19)-10;
rect.h = 12;
SDL_BlitSurface(village_bg, NULL, disp.video().getSurface(), &rect);
SDL_BlitSurface(village_bg, NULL, disp.video().getSurface(), &village_rect);
sprintf(buf,": %d", cur_villagegold);
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["village_gold"] + buf,rect.x,rect.y);
update_rect(rect);
string_table["village_gold"] + buf,village_rect.x,village_rect.y);
update_rect(village_rect);
//experience modifier
cur_xpmod = xp_modifier_slider.value();
SDL_BlitSurface(village_bg, NULL, disp.video().getSurface(), &xp_rect);
sprintf(buf,": %d%%", cur_xpmod);
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
string_table["xp_modifier"] + buf,xp_rect.x,xp_rect.y);
update_rect(xp_rect);
if(maps_menu.selection() != cur_selection) {
map_changed = true;
@ -301,13 +341,9 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
update_rect(rect);
}
rect.x = ((disp.x()-width)/2+10)+35;
rect.y = (disp.y()-height)/2+235;
rect.w = 145;
rect.h = 25;
playernum_bg.restore();
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
" Load Map ",rect.x+45,rect.y);
" Load Map ",player_num_rect.x,player_num_rect.y);
update_rect(rect);
}
}
@ -361,31 +397,31 @@ int play_multiplayer(display& disp, game_data& units_data, const config& cfg,
level_ptr->remove_child("side",level_ptr->get_children("side").size()-1);
}
const scoped_sdl_surface mini(image::getMinimap(145,145,map,0));
const scoped_sdl_surface mini(image::getMinimap(minimap_width,minimap_width,map,0));
if(mini != NULL) {
rect.x = ((disp.x()-width)/2+10)+35;
rect.y = (disp.y()-height)/2+80;
rect.w = 145;
rect.h = 145;
SDL_Rect rect = {xpos,ypos,minimap_width,minimap_width};
SDL_BlitSurface(mini, NULL, disp.video().getSurface(), &rect);
update_rect(rect);
//Display the number of players
SDL_Rect players_rect = {xpos+minimap_width/2,ypos+minimap_width,145,25};
rect.x = ((disp.x()-width)/2+10)+35;
rect.y = (disp.y()-height)/2+235;
rect.w = 145;
rect.h = 25;
playernum_bg.restore();
config& level = *level_ptr;
const int nsides = level.get_children("side").size();
std::stringstream players;
players << string_table["num_players"] << ": " << nsides;
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
players.str(),player_num_rect.x,player_num_rect.y);
update_rect(rect);
}
//Display the number of players
rect.x = ((disp.x()-width)/2+10)+35;
rect.y = (disp.y()-height)/2+235;
rect.w = 145;
rect.h = 25;
playernum_bg.restore();
config& level = *level_ptr;
const int nsides = level.get_children("side").size();
std::stringstream players;
players << "Players: " << nsides;
font::draw_text(&disp,disp.screen_area(),12,font::GOOD_COLOUR,
players.str(),rect.x+45,rect.y);
update_rect(rect);
}
events::pump();

View file

@ -324,14 +324,22 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
const std::string& default_race = race_names[team_num-1];
const bool allow_changes = changes_allowed[team_num-1];
config response;
std::stringstream stream;
stream << team_num;
response["side"] = stream.str();
response["description"] = preferences::login();
const config::child_list& possible_sides = cfg.get_children("multiplayer_side");
const std::string& era = sides["era"];
const config* const era_cfg = cfg.find_child("era","id",era);
if(era_cfg == NULL) {
std::cerr << "era '" << era << "' not found\n";
return;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
if(possible_sides.empty()) {
std::cerr << "no multiplayer sides found\n";
return;
@ -342,7 +350,7 @@ void play_multiplayer_client(display& disp, game_data& units_data, config& cfg,
std::vector<std::string> choices;
for(config::child_list::const_iterator side =
possible_sides.begin(); side != possible_sides.end(); ++side) {
choices.push_back((**side)["name"]);
choices.push_back(translate_string_default((**side)["id"],(**side)["name"]));
if(choices.back() == default_race)
choice = side - possible_sides.begin();

View file

@ -25,6 +25,7 @@
#include "preferences.hpp"
#include "replay.hpp"
#include "show_dialog.hpp"
#include "util.hpp"
#include "widgets/textbox.hpp"
#include "widgets/button.hpp"
#include "widgets/combo.hpp"
@ -66,13 +67,15 @@ mp_connect::~mp_connect()
}
}
int mp_connect::load_map(int map, int num_turns, int village_gold,
int mp_connect::load_map(const std::string& era, int map, int num_turns, int village_gold, int xpmodifier,
bool fog_game, bool shroud_game, bool allow_observers)
{
log_scope("load_map");
// Setup the game
config* level_ptr;
era_ = era;
const config::child_list& levels = cfg_->get_children("multiplayer");
if(map == levels.size() )
@ -169,7 +172,16 @@ int mp_connect::load_map(int map, int num_turns, int village_gold,
level_->values["observer"] = allow_observers ? "yes" : "no";
const config::child_itors sides = level_->child_range("side");
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
const config* const era_cfg = cfg_->find_child("era","id",era_);
if(era_cfg == NULL) {
std::cerr << "ERROR: era '" << era_ << "' not found\n";
status_ = -1;
return status_;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
if(sides.first == sides.second || possible_sides.empty()) {
gui::show_dialog(*disp_, NULL, "",
@ -228,6 +240,9 @@ int mp_connect::load_map(int map, int num_turns, int village_gold,
(*level_)["objectives"] = "Victory:\n@Defeat enemy leader(s)\n";
}
(*level_)["experience_modifier"] = lexical_cast<std::string>(xpmodifier);
(*level_)["era"] = era;
lists_init();
gui_init();
status_ = 0;
@ -249,7 +264,13 @@ void mp_connect::lists_init()
//Races
const config::child_itors sides = level_->child_range("side");
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
const config* const era_cfg = cfg_->find_child("era","id",era_);
if(era_cfg == NULL) {
return;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
for(std::vector<config*>::const_iterator race = possible_sides.begin();
race != possible_sides.end(); ++race) {
player_races_.push_back(translate_string((**race)["name"]));
@ -349,7 +370,14 @@ void mp_connect::gui_init()
//Per player settings
const config::child_itors sides = level_->child_range("side");
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
const config* const era_cfg = cfg_->find_child("era","id",era_);
if(era_cfg == NULL) {
return;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
config::child_iterator sd;
SDL_Rect rect;
@ -408,7 +436,13 @@ void mp_connect::gui_update()
//Settings may change based on other networked
//players.
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
const config* const era_cfg = cfg_->find_child("era","id",era_);
if(era_cfg == NULL) {
return;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
const config::child_itors sides = level_->child_range("side");
SDL_Rect rect;
@ -480,7 +514,14 @@ int mp_connect::gui_do()
const events::event_context context;
SDL_Rect rect;
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
const config* const era_cfg = cfg_->find_child("era","id",era_);
if(era_cfg == NULL) {
return -1;
}
const config::child_list& possible_sides = era_cfg->get_children("multiplayer_side");
const config::child_itors sides = level_->child_range("side");
int new_playergold = -1;
int cur_playergold = -1;
@ -672,7 +713,6 @@ int mp_connect::gui_do()
void mp_connect::update_positions()
{
const config::child_itors sides = level_->child_range("side");
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
config::child_iterator sd;
for(sd = sides.first; sd != sides.second; ++sd) {
if((**sd)["taken"] != "yes") {
@ -807,7 +847,6 @@ void mp_connect::is_full()
//see if all positions are now filled
full_ = true;
const config::child_itors sides = level_->child_range("side");
const config::child_list& possible_sides = cfg_->get_children("multiplayer_side");
config::child_iterator sd;
for(sd = sides.first; sd != sides.second; ++sd) {
if((**sd)["controller"] == "network" &&

View file

@ -34,8 +34,8 @@ public:
game_state& state, bool join = false);
~mp_connect();
int load_map(int map, int num_turns, int village_gold,
bool fog_game, bool shroud_game, bool allow_observers);
int load_map(const std::string& era, int map, int num_turns, int village_gold, int xpmodifier,
bool fog_game, bool shroud_game, bool allow_observers);
int gui_do();
private:
@ -50,6 +50,8 @@ private:
display *disp_;
std::string era_;
const config *cfg_;
game_data *data_;
game_state *state_;

View file

@ -144,6 +144,9 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
const verification_manager verify_manager(units);
const int xp_modifier = atoi((*level)["experience_modifier"].c_str());
const unit_type::experience_accelerator xp_mod(xp_modifier > 0 ? xp_modifier : 100);
std::vector<team> teams;
int first_human_team = -1;

View file

@ -472,6 +472,21 @@ SDL_Surface* flop_surface(SDL_Surface* surface)
return clone_surface(surf);
}
SDL_Surface* create_compatible_surface(SDL_Surface* surf, int width, int height)
{
if(surf == NULL)
return NULL;
if(width == -1)
width = surf->w;
if(height == -1)
height = surf->h;
return SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,surf->format->BitsPerPixel,
surf->format->Rmask,surf->format->Gmask,surf->format->Bmask,surf->format->Amask);
}
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* target)
{
if(alpha == SDL_ALPHA_OPAQUE) {
@ -481,8 +496,7 @@ void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* ta
return;
}
scoped_sdl_surface tmp(SDL_CreateRGBSurface(0,rect.w,rect.h,target->format->BitsPerPixel,
target->format->Rmask,target->format->Gmask,target->format->Bmask,0));
scoped_sdl_surface tmp(create_compatible_surface(target,rect.w,rect.h));
if(tmp == NULL) {
return;
}
@ -508,11 +522,7 @@ SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& area)
area.h = src->h - area.y;
}
const SDL_PixelFormat* const fmt = src->format;
SDL_Surface* const dst = SDL_CreateRGBSurface(0,area.w,area.h,
fmt->BitsPerPixel,fmt->Rmask,
fmt->Gmask,fmt->Bmask,
fmt->Amask);
SDL_Surface* const dst = create_compatible_surface(src,area.w,area.h);
if(dst == NULL) {
std::cerr << "Could not create a new surface in get_surface_portion()\n";
return NULL;

View file

@ -55,6 +55,8 @@ SDL_Surface* blend_surface(SDL_Surface* surface, double amount, Uint32 colour);
SDL_Surface* flip_surface(SDL_Surface* surface);
SDL_Surface* flop_surface(SDL_Surface* surface);
SDL_Surface* create_compatible_surface(SDL_Surface* surf, int width=-1, int height=-1);
void fill_rect_alpha(SDL_Rect& rect, Uint32 colour, Uint8 alpha, SDL_Surface* target);
SDL_Rect get_non_transperant_portion(SDL_Surface* surf);

View file

@ -155,6 +155,13 @@ void draw_dialog_background(int x, int y, int w, int h, display& disp, const std
}
}
int draw_dialog_title(int x, int y, display& disp, const std::string& text)
{
const SDL_Rect rect = font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
text,x+5,y+5);
return rect.y + rect.h;
}
void draw_rectangle(int x, int y, int w, int h, Uint16 colour,SDL_Surface* target)
{
if(x < 0 || y < 0 || x+w >= target->w || y+h >= target->h) {

View file

@ -50,6 +50,10 @@ void draw_solid_tinted_rectangle(int x, int y, int w, int h,
int r, int g, int b,
double alpha, SDL_Surface* target);
//given the location of a dialog, will draw its title.
//Returns the y co-ordinate of the top of the dialog box after the title
int draw_dialog_title(int x, int y, display& disp, const std::string& text);
class dialog_action
{
public:

View file

@ -593,9 +593,23 @@ int unit_type::cost() const
return atoi(cfg_["cost"].c_str());
}
namespace {
int experience_modifier = 100;
}
unit_type::experience_accelerator::experience_accelerator(int modifier) : old_value_(experience_modifier)
{
experience_modifier = (experience_modifier*modifier)/100;
}
unit_type::experience_accelerator::~experience_accelerator()
{
experience_modifier = old_value_;
}
int unit_type::experience_needed() const
{
return atoi(cfg_["experience"].c_str());
return (atoi(cfg_["experience"].c_str())*experience_modifier)/100;
}
std::vector<std::string> unit_type::advances_to() const

View file

@ -159,6 +159,13 @@ public:
std::vector<std::string> advances_to() const;
const std::string& usage() const;
struct experience_accelerator {
experience_accelerator(int modifier);
~experience_accelerator();
private:
int old_value_;
};
int level() const;
int movement() const;
int cost() const;

View file

@ -71,8 +71,10 @@ void combo::draw()
bool combo::process(int x, int y, bool button)
{
if(button_.process(x,y,button)) {
const SDL_Rect rect = button_.location();
set_selected(gui::show_dialog(*display_,NULL,"","",
gui::MESSAGE,&items_));
gui::MESSAGE,&items_,NULL,"",NULL,NULL,NULL,
rect.x,rect.y+rect.h));
button_.draw();