added in Wesbowl multiplayer scenario

This commit is contained in:
Dave White 2004-05-10 20:47:03 +00:00
parent 14d38ab28c
commit 39b1b25ffe
10 changed files with 800 additions and 12 deletions

721
data/scenarios/Wesbowl.cfg Normal file
View file

@ -0,0 +1,721 @@
[multiplayer]
name=Wesbowl
map=wesbowl
turns=20
id=multiplayer1
{DAWN}
{MORNING}
{AFTERNOON}
{DUSK}
{FIRST_WATCH}
{SECOND_WATCH}
[side]
side=1
enemy=2
canrecruit=1
controller=human
[/side]
[side]
side=2
enemy=1
canrecruit=1
controller=human
[/side]
#define WESBOWL_UNIT SIDE FACING TYPE X Y
[unit]
side={SIDE}
type={TYPE}
facing={FACING}
x={X}
y={Y}
[/unit]
#enddef
#define WESBOWL_SIDE LEADER SIDE FACING X A B C D E F G H I J K
[if]
[have_unit]
type={LEADER}
side={SIDE}
[/have_unit]
[then]
{WESBOWL_UNIT {SIDE} {FACING} ({A}) {X} 10}
{WESBOWL_UNIT {SIDE} {FACING} ({B}) {X} 8}
{WESBOWL_UNIT {SIDE} {FACING} ({C}) {X} 12}
{WESBOWL_UNIT {SIDE} {FACING} ({D}) {X} 6}
{WESBOWL_UNIT {SIDE} {FACING} ({E}) {X} 14}
{WESBOWL_UNIT {SIDE} {FACING} ({F}) {X} 4}
{WESBOWL_UNIT {SIDE} {FACING} ({G}) {X} 16}
{WESBOWL_UNIT {SIDE} {FACING} ({H}) {X} 2}
{WESBOWL_UNIT {SIDE} {FACING} ({I}) {X} 18}
{WESBOWL_UNIT {SIDE} {FACING} ({J}) {X} 1}
{WESBOWL_UNIT {SIDE} {FACING} ({K}) {X} 20}
[/then]
[/if]
#enddef
#define WESBOWL_SIDE_DEFS SIDE FACING X
{WESBOWL_SIDE (Elvish Lord) {SIDE} {FACING} {X} Merman (Elvish Fighter) (Elvish Fighter) (Elvish Archer) (Elvish Archer) Mage Mage (Wose Sapling) (Wose Sapling) (Elvish Scout) (Elvish Scout)}
{WESBOWL_SIDE (Orcish Warlord) {SIDE} {FACING} {X} Naga (Orcish Grunt) (Orcish Grunt) (Orcish Archer) (Orcish Archer) Lizardman Lizardman (Troll Whelp) (Troll Whelp) (Wolf Rider) (Wolf Rider)}
{WESBOWL_SIDE Lich {SIDE} {FACING} {X} (Vampire Bat) Skeleton Skeleton (Skeleton Archer) (Skeleton Archer) Skeleton Skeleton (Dark Adept) (Dark Adept) Ghost Ghost}
{WESBOWL_SIDE (Dwarvish Lord) {SIDE} {FACING} {X} Poacher (Dwarvish Fighter) (Dwarvish Fighter) (Dwarvish Thunderer) (Dwarvish Thunderer) Footpad Footpad Thief Thief (Gryphon Rider) (Gryphon Rider)}
{WESBOWL_SIDE General {SIDE} {FACING} {X} Naga Spearman Spearman Fencer Fencer Horseman Horseman (Heavy Infantry) (Heavy Infantry) Cavalry Cavalry}
#enddef
[event]
name=prestart
{WESBOWL_SIDE_DEFS 1 normal 5}
{WESBOWL_SIDE_DEFS 2 reverse 37}
{VARIABLE b1x 7}
{VARIABLE b1y 9}
{VARIABLE b2x 35}
{VARIABLE b2y 11}
{VARIABLE b1down yes}
{VARIABLE b2down yes}
{VARIABLE redscore 0}
{VARIABLE bluescore 0}
[item]
image=misc/ball.png
x,y=$b1x,$b1y
[/item]
[item]
image=misc/ball.png
x,y=$b2x,$b2y
[/item]
[/event]
[event]
name=moveto
first_time_only=no
[filter]
x,y=$b1x,$b1y
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$b1x,$b1y
[/filter]
[/store_unit]
[if]
[variable]
name=b1down
equals=yes
[/variable]
[variable]
name=unit.variables.has_ball2
not_equals=yes
[/variable]
[then]
[removeitem]
x,y=$b1x,$b1y
[/removeitem]
{VARIABLE b1down no}
{VARIABLE unit.variables.has_ball1 yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[unit_overlay]
x,y=$b1x,$b1y
image=misc/ball.png
[/unit_overlay]
[/then]
[/if]
[/event]
[event]
name=die
first_time_only=no
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball1
equals=yes
[/variable]
[then]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$x1,$y1
image=misc/ball.png
[/item]
{VARIABLE b1x $x1}
{VARIABLE b1y $y1}
{VARIABLE unit.variables.has_ball1 no}
{VARIABLE b1down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[/then]
[/if]
[/event]
[event]
name=moveto
first_time_only=no
[filter]
side=1
x=38-40
y=1-20
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball1
equals=yes
[/variable]
[then]
[set_variable]
name=redscore
add=1
[/set_variable]
[message]
speaker=narrator
message="Red scores! Current score is $redscore-$bluescore"
[/message]
{VARIABLE b1x 7}
{VARIABLE b1y 9}
{VARIABLE unit.variables.has_ball1 no}
{VARIABLE b1down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$b1x,$b1y
image=misc/ball.png
[/item]
[/then]
[/if]
[/event]
[event]
name=moveto
first_time_only=no
[filter]
side=2
x=1-3
y=1-20
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball1
equals=yes
[/variable]
[then]
[set_variable]
name=bluescore
add=1
[/set_variable]
[message]
speaker=narrator
message="Blue scores! Current score is $redscore-$bluescore"
[/message]
{VARIABLE b1x 35}
{VARIABLE b1y 11}
{VARIABLE unit.variables.has_ball1 no}
{VARIABLE b1down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$b1x,$b1y
image=misc/ball.png
[/item]
[/then]
[/if]
[/event]
#event to transfer control of the ball by passing, after movement
[event]
name=moveto
first_time_only=no
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball1
equals=yes
[/variable]
[then]
[store_locations]
variable=locs
x,y,radius=$x1,$y1,1
[/store_locations]
{VARIABLE passed no}
{FOREACH locs i}
{VARIABLE_OP xloc to_variable locs[$i].x}
{VARIABLE_OP yloc to_variable locs[$i].y}
[if]
[or]
[variable]
name=xloc
not_equals=$x1
[/variable]
[variable]
name=passed
equals=no
[/variable]
[have_unit]
x,y=$xloc,$yloc
side=$unit.side
[/have_unit]
[/or]
[or]
[variable]
name=yloc
not_equals=$y1
[/variable]
[variable]
name=passed
equals=no
[/variable]
[have_unit]
x,y=$xloc,$yloc
side=$unit.side
[/have_unit]
[/or]
[then]
[store_unit]
variable=passto
[filter]
x,y=$xloc,$yloc
[/filter]
[/store_unit]
[if]
[variable]
name=passto.variables.has_ball2
not_equals=yes
[/variable]
[then]
[message]
speaker=unit
message="Should I pass the ball to $passto.type ($xloc,$yloc)?"
[option]
message="Yes!"
[command]
{VARIABLE passed yes}
{VARIABLE unit.variables.has_ball1 no}
{VARIABLE passto.variables.has_ball1 yes}
[unstore_unit]
variable=passto
[/unstore_unit]
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[unit_overlay]
x,y=$xloc,$yloc
image=misc/ball.png
[/unit_overlay]
[/command]
[/option]
[option]
message="No"
[/option]
[/message]
[/then]
[/if]
[/then]
[/if]
{NEXT i}
[/then]
[/if]
[/event]
#control of the second ball. Exactly the same as control of the first
#ball, with different variable names
[event]
name=moveto
first_time_only=no
[filter]
x,y=$b2x,$b2y
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$b2x,$b2y
[/filter]
[/store_unit]
[if]
[variable]
name=b2down
equals=yes
[/variable]
[variable]
name=unit.variables.has_ball1
not_equals=yes
[/variable]
[then]
[removeitem]
x,y=$b2x,$b2y
[/removeitem]
{VARIABLE b2down no}
{VARIABLE unit.variables.has_ball2 yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[unit_overlay]
x,y=$b2x,$b2y
image=misc/ball.png
[/unit_overlay]
[/then]
[/if]
[/event]
[event]
name=die
first_time_only=no
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball2
equals=yes
[/variable]
[then]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$x1,$y1
image=misc/ball.png
[/item]
{VARIABLE b2x $x1}
{VARIABLE b2y $y1}
{VARIABLE unit.variables.has_ball2 no}
{VARIABLE b2down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[/then]
[/if]
[/event]
[event]
name=moveto
first_time_only=no
[filter]
side=1
x=38-40
y=1-20
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball2
equals=yes
[/variable]
[then]
[set_variable]
name=redscore
add=1
[/set_variable]
[message]
speaker=narrator
message="Red scores! Current score is $redscore-$bluescore"
[/message]
{VARIABLE b2x 7}
{VARIABLE b2y 9}
{VARIABLE unit.variables.has_ball2 no}
{VARIABLE b2down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$b2x,$b2y
image=misc/ball.png
[/item]
[/then]
[/if]
[/event]
[event]
name=moveto
first_time_only=no
[filter]
side=2
x=1-3
y=1-20
[/filter]
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball2
equals=yes
[/variable]
[then]
[set_variable]
name=bluescore
add=1
[/set_variable]
[message]
speaker=narrator
message="Blue scores! Current score is $redscore-$bluescore"
[/message]
{VARIABLE b2x 35}
{VARIABLE b2y 11}
{VARIABLE unit.variables.has_ball2 no}
{VARIABLE b2down yes}
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[item]
x,y=$b2x,$b2y
image=misc/ball.png
[/item]
[/then]
[/if]
[/event]
#event to transfer control of the ball by passing, after movement
[event]
name=moveto
first_time_only=no
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.variables.has_ball2
equals=yes
[/variable]
[then]
[store_locations]
variable=locs
x,y,radius=$x1,$y1,1
[/store_locations]
{VARIABLE passed no}
{FOREACH locs i}
{VARIABLE_OP xloc to_variable locs[$i].x}
{VARIABLE_OP yloc to_variable locs[$i].y}
[if]
[or]
[variable]
name=xloc
not_equals=$x1
[/variable]
[variable]
name=passed
equals=no
[/variable]
[have_unit]
x,y=$xloc,$yloc
side=$unit.side
[/have_unit]
[/or]
[or]
[variable]
name=yloc
not_equals=$y1
[/variable]
[variable]
name=passed
equals=no
[/variable]
[have_unit]
x,y=$xloc,$yloc
side=$unit.side
[/have_unit]
[/or]
[then]
[store_unit]
variable=passto
[filter]
x,y=$xloc,$yloc
[/filter]
[/store_unit]
[if]
[variable]
name=passto.variables.has_ball1
not_equals=yes
[/variable]
[then]
[message]
speaker=unit
message="Should I pass the ball to $passto.type ($xloc,$yloc)?"
[option]
message="Yes!"
[command]
{VARIABLE passed yes}
{VARIABLE unit.variables.has_ball2 no}
{VARIABLE passto.variables.has_ball2 yes}
[unstore_unit]
variable=passto
[/unstore_unit]
[unstore_unit]
variable=unit
[/unstore_unit]
[remove_unit_overlay]
x,y=$x1,$y1
image=misc/ball.png
[/remove_unit_overlay]
[unit_overlay]
x,y=$xloc,$yloc
image=misc/ball.png
[/unit_overlay]
[/command]
[/option]
[option]
message="No"
[/option]
[/message]
[/then]
[/if]
[/then]
[/if]
{NEXT i}
[/then]
[/if]
[/event]
[event]
name=time over
[if]
[variable]
name=redscore
less_than=$bluescore
[/variable]
[then]
[message]
speaker=narrator
message="Blue team wins! Final score: $redscore-$bluescore"
[/message]
[/then]
[/if]
[if]
[variable]
name=redscore
greater_than=$bluescore
[/variable]
[then]
[message]
speaker=narrator
message="Red team wins! Final score: $redscore-$bluescore"
[/message]
[/then]
[/if]
[if]
[variable]
name=redscore
equals=$bluescore
[/variable]
[then]
[message]
speaker=narrator
message="Draw! Final score: $redscore-$bluescore"
[/message]
[/then]
[/if]
[endlevel]
result=continue
[/endlevel]
[/event]
#if a unit dies, then it gets sent to its side's starting location
[event]
name=die
[store_unit]
variable=unit
[filter]
x,y=$x1,$y1
[/filter]
[/store_unit]
[if]
[variable]
name=unit.side
equals=1
[/variable]
[then]
{VARIABLE unit.x 2}
{VARIABLE unit.y 10}
[/then]
[else]
{VARIABLE unit.x 40}
{VARIABLE unit.y 10}
[/else]
[/if]
{VARIABLE unit.hitpoints "-"}
[unstore_unit]
find_vacant=yes
variable=unit
[/unstore_unit]
[/event]
[/multiplayer]

BIN
images/misc/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 B

View file

@ -179,7 +179,7 @@ std::vector<std::string> parse_macro_arguments(const std::string& macro)
res.back() += " " + i->substr(begin,end-begin);
config::strip(res.back());
if(begin == 1) {
if(begin == 1 && end == i->size()) {
in_braces = true;
}
}
@ -238,7 +238,7 @@ void internal_preprocess_data(const std::string& data,
if(val.arguments.size() != items.size()) {
std::cerr << "error: preprocessor symbol '" << symbol << "' has "
<< items.size() << " arguments, "
<< val.arguments.size() << " expected\n";
<< val.arguments.size() << " expected: '" << newfilename << "'\n";
}
std::string str = val.value;
@ -1121,6 +1121,19 @@ const config* config::find_child(const std::string& key,
return NULL;
}
std::string config::join(const std::vector<std::string>& v, char c)
{
std::stringstream str;
for(std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i) {
str << *i;
if(i+1 != v.end()) {
str << c;
}
}
return str.str();
}
std::vector<std::string> config::split(const std::string& val, char c, bool remove_empty)
{
std::vector<std::string> res;
@ -1267,7 +1280,7 @@ namespace {
bool not_id(char c)
{
return !isalpha(c) && c != '.' && c != '_';
return !isdigit(c) && !isalpha(c) && c != '.' && c != '_';
}
void do_interpolation(std::string& res, size_t npos, const string_map* m)

View file

@ -152,6 +152,7 @@ struct config
void clear_children(const std::string& key);
config* remove_child(const std::string& key, size_t index);
static std::string join(const std::vector<std::string>& v, char c=',');
static std::vector<std::string> split(const std::string& val, char c=',', bool remove_empty=true);
static std::vector<std::string> quoted_split(const std::string& val, char c=',',
bool remove_empty=true, char quote='\\');

View file

@ -513,7 +513,6 @@ void draw_label(display& disp, SDL_Surface* target, const theme::label& label)
void display::draw(bool update,bool force)
{
std::cerr << "starting draw...\n";
if(!panelsDrawn_) {
std::cerr << "drawing panels...\n";
SDL_Surface* const screen = screen_.getSurface();
@ -581,10 +580,7 @@ void display::draw(bool update,bool force)
update_display();
else
drawSkips_++;
}
std::cerr << "done draw...\n";
}
void display::update_display()
@ -1423,6 +1419,16 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image, double alpha, Uin
}
}
const std::vector<std::string>& overlays = un->second.overlays();
for(std::vector<std::string>::const_iterator ov = overlays.begin(); ov != overlays.end(); ++ov) {
const scoped_sdl_surface img(image::get_image(*ov));
std::cerr << "drawing overlay: '" << *ov << "'\n";
if(img.get() != NULL) {
std::cerr << "AA\n";
draw_unit(xpos,ypos,img);
}
}
if(grid_) {
scoped_sdl_surface grid_surface(image::get_image("terrain/grid.png"));
if(grid_surface != NULL) {

View file

@ -616,6 +616,25 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
screen->remove_overlay(loc);
}
else if(cmd == "unit_overlay") {
for(std::map<gamemap::location,unit>::iterator itor = units->begin(); itor != units->end(); ++itor) {
if(game_events::unit_matches_filter(itor,cfg)) {
std::cerr << "adding overlay '" << cfg["image"] << "' to '" << itor->second.description() << "'\n";
itor->second.add_overlay(cfg["image"]);
break;
}
}
}
else if(cmd == "remove_unit_overlay") {
for(std::map<gamemap::location,unit>::iterator itor = units->begin(); itor != units->end(); ++itor) {
if(game_events::unit_matches_filter(itor,cfg)) {
itor->second.remove_overlay(cfg["image"]);
break;
}
}
}
//hiding units
else if(cmd == "hide_unit") {
const gamemap::location loc(cfg);
@ -1007,6 +1026,8 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
const std::string& terrain = cfg["terrain"];
const config* const unit_filter = cfg.child("filter");
state_of_game->variables.clear_children(variable);
std::vector<gamemap::location> locs = parse_location_range(cfg["x"],cfg["y"]);
if(locs.size() > MaxLoop) {
locs.resize(MaxLoop);

View file

@ -692,6 +692,7 @@ lobby::RESULT mp_connect::process()
}
if(start_game) {
std::cerr << "multiplayer_connect returning create...\n";
return lobby::CREATE;
}

View file

@ -112,6 +112,8 @@ LEVEL_RESULT play_level(game_data& gameinfo, const config& game_config,
game_state& state_of_game,
const std::vector<config*>& story)
{
std::cerr << "in play_level()...\n";
//if the entire scenario should be randomly generated
if((*level)["scenario_generation"] != "") {
std::cerr << "randomly generating scenario...\n";

View file

@ -523,6 +523,21 @@ bool unit::has_flag(const std::string& flag) const
return statusFlags_.count(flag) != 0;
}
void unit::add_overlay(const std::string& overlay)
{
overlays_.push_back(overlay);
}
void unit::remove_overlay(const std::string& overlay)
{
overlays_.erase(std::remove(overlays_.begin(),overlays_.end(),overlay),overlays_.end());
}
const std::vector<std::string>& unit::overlays() const
{
return overlays_;
}
void unit::read(game_data& data, const config& cfg)
{
std::map<std::string,unit_type>::iterator i = data.unit_types.find(cfg["type"]);
@ -595,6 +610,11 @@ void unit::read(game_data& data, const config& cfg)
}
}
overlays_ = config::split(cfg["overlays"]);
if(overlays_.size() == 1 && overlays_.front() == "") {
overlays_.clear();
}
const config* const variables = cfg.child("variables");
if(variables != NULL) {
variables_ = *variables;
@ -618,10 +638,7 @@ void unit::read(game_data& data, const config& cfg)
moves_ = atoi(moves.c_str());
const std::string& hitpoints = cfg["hitpoints"];
if(hitpoints.size() == 0)
hitpoints_ = maxHitpoints_;
else
hitpoints_ = atoi(hitpoints.c_str());
hitpoints_ = lexical_cast_default<int>(hitpoints,maxHitpoints_);
const std::string& experience = cfg["experience"];
if(experience.size() == 0)
@ -656,9 +673,10 @@ void unit::write(config& cfg) const
}
cfg.add_child("variables",variables_);
cfg.add_child("status",status_flags);
cfg["overlays"] = config::join(overlays_);
cfg["user_description"] = description_;
cfg["description"] = underlying_description_;
cfg["unit_description"] = custom_unit_description_;

View file

@ -88,6 +88,10 @@ public:
void remove_flag(const std::string& flag);
bool has_flag(const std::string& flag) const;
void add_overlay(const std::string& overlay);
void remove_overlay(const std::string& overlay);
const std::vector<std::string>& overlays() const;
void read(game_data& data, const config& cfg);
void write(config& cfg) const;
@ -173,6 +177,7 @@ private:
std::string role_;
std::set<std::string> statusFlags_;
std::vector<std::string> overlays_;
//this field stores user-variables associated with the unit
config variables_;