[[Game[lay fixes]]
- added randomization of temples in Muff Malal's peninsula - made it so in MP games, players can receive labels and messages while it's their turn - added patch to 'show possible enemy moves'
This commit is contained in:
parent
20908a5087
commit
5238dcc75a
12 changed files with 303 additions and 130 deletions
|
@ -125,12 +125,13 @@ Defeat:
|
|||
[/message]
|
||||
[/event]
|
||||
|
||||
#define MOREMIRMU_TRAP X Y
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
side=1
|
||||
x=5
|
||||
y=7
|
||||
x={X}
|
||||
y={Y}
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg4_7
|
||||
|
@ -141,8 +142,8 @@ Defeat:
|
|||
description=Moremirmu
|
||||
side=1
|
||||
type=White Mage
|
||||
x=5
|
||||
y=7
|
||||
x={X}
|
||||
y={Y}
|
||||
[/unit]
|
||||
#set the variable to say the Moremirmu is alive
|
||||
[set_variable]
|
||||
|
@ -155,13 +156,15 @@ Defeat:
|
|||
message="I was hiding in this holy place, planning how to defeat the evil undeads. Now with your help, I can destroy them."
|
||||
[/message]
|
||||
[/event]
|
||||
#enddef
|
||||
|
||||
#define XAKAE_TRAP X Y
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
side=1
|
||||
x=10
|
||||
y=10
|
||||
x={X}
|
||||
y={Y}
|
||||
[/filter]
|
||||
[message]
|
||||
id=msg4_9
|
||||
|
@ -172,27 +175,27 @@ Defeat:
|
|||
description=Xakae
|
||||
side=2
|
||||
type=Revenant
|
||||
x=10
|
||||
y=10
|
||||
x={X}
|
||||
y={Y}
|
||||
[/unit]
|
||||
[unit]
|
||||
side=2
|
||||
type=Walking Corpse
|
||||
x=10
|
||||
y=10
|
||||
x={X}
|
||||
y={Y}
|
||||
[/unit]
|
||||
[unit]
|
||||
side=2
|
||||
type=Walking Corpse
|
||||
x=10
|
||||
y=10
|
||||
x={X}
|
||||
y={Y}
|
||||
[/unit]
|
||||
#ifdef HARD
|
||||
[unit]
|
||||
side=2
|
||||
type=Walking Corpse
|
||||
x=10
|
||||
y=10
|
||||
x={X}
|
||||
y={Y}
|
||||
[/unit]
|
||||
#endif
|
||||
[message]
|
||||
|
@ -201,6 +204,28 @@ Defeat:
|
|||
message="Surprise! Searching for Mages, and all I get is elves!"
|
||||
[/message]
|
||||
[/event]
|
||||
#enddef
|
||||
|
||||
[event]
|
||||
name=start
|
||||
{RANDOM 1..2}
|
||||
[if]
|
||||
[variable]
|
||||
name=random
|
||||
numerical_equals=1
|
||||
[/variable]
|
||||
[then]
|
||||
{MOREMIRMU_TRAP 5 7}
|
||||
{XAKAE_TRAP 10 10}
|
||||
[/then]
|
||||
[else]
|
||||
{MOREMIRMU_TRAP 10 10}
|
||||
{XAKAE_TRAP 5 7}
|
||||
[/else]
|
||||
|
||||
[/if]
|
||||
[/event]
|
||||
|
||||
[event]
|
||||
name=moveto
|
||||
[filter]
|
||||
|
|
|
@ -39,7 +39,7 @@ height=600
|
|||
|
||||
[menu]
|
||||
is_context_menu=true
|
||||
items=undo,redo,cycle,describeunit,speak,recruit,recall,createunit,renameunit,labelterrain,endturn
|
||||
items=undo,redo,cycle,describeunit,speak,recruit,recall,createunit,renameunit,labelterrain,endturn,showenemymoves,bestenemymoves
|
||||
[/menu]
|
||||
|
||||
# top panel
|
||||
|
|
|
@ -114,6 +114,16 @@ language="English"
|
|||
key=l
|
||||
ctrl=yes
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=showenemymoves
|
||||
key=v
|
||||
ctrl=yes
|
||||
[/hotkey]
|
||||
[hotkey]
|
||||
command=bestenemymoves
|
||||
key=b
|
||||
ctrl=yes
|
||||
[/hotkey]
|
||||
|
||||
game_title="The Battle for Wesnoth"
|
||||
version="Version"
|
||||
|
@ -426,6 +436,8 @@ action_recruit="Recruit"
|
|||
action_repeatrecruit="Repeat Recruit"
|
||||
action_mute="Mute"
|
||||
action_labelterrain="Set Label"
|
||||
action_showenemymoves="Show Enemy Moves"
|
||||
action_bestenemymoves="Best Possible Enemy Moves"
|
||||
save_hotkeys_button="Save Hotkeys"
|
||||
change_hotkey_button="Change Hotkey"
|
||||
hotkeys_dialog="Hotkey Settings"
|
||||
|
@ -494,6 +506,34 @@ attacks="attacks"
|
|||
damage="damage"
|
||||
hexes="hexes"
|
||||
|
||||
# Weapon special effect descriptions
|
||||
weapon_special_backstab_description="Backstab:
|
||||
This attack deals double damage if a friendly unit is on the opposite side of the target."
|
||||
|
||||
weapon_special_charge_description="Charge:
|
||||
This attack deals double damage to the target. It also causes this unit to take double damage from the target's counterattack."
|
||||
|
||||
weapon_special_drain_description="Drain:
|
||||
This unit drains health from living units, healing itself for half the amount of damage it deals."
|
||||
|
||||
weapon_special_magical_description="Magical:
|
||||
This attack always has a 70% chance to hit."
|
||||
|
||||
weapon_special_marksman_description="Marksman:
|
||||
When used offensively, this attack always has at least a 60% chance to hit."
|
||||
|
||||
weapon_special_plague_description="Plague:
|
||||
If this unit kills a living target and that unit was not stationed in a village, the dead target's corpse will rise up and fight for you."
|
||||
|
||||
weapon_special_poison_description="Poison:
|
||||
This attack poisons the target. Poisoned units lose 8 HP every turn until they are cured or are reduced to 1 HP."
|
||||
|
||||
weapon_special_slow_description="Slow:
|
||||
This attack slows the target. Slowed units move at half normal speed and receive one less attack than normal in combat."
|
||||
|
||||
weapon_special_stone_description="Stone:
|
||||
This attack turns the target to stone. Units that have been turned to stone may not move or attack."
|
||||
|
||||
#Multiplayer lobby/dialogs
|
||||
game_lobby="Game Lobby"
|
||||
shroud="Shroud"
|
||||
|
|
|
@ -51,3 +51,14 @@ y={Y}
|
|||
type=cross
|
||||
[/dot]
|
||||
#enddef
|
||||
|
||||
|
||||
#macro to quickly pick a random value (in the $random variable, to avoid
|
||||
#cluterring up savegames with such temporary variables)
|
||||
|
||||
#define RANDOM RANGE
|
||||
[set_variable]
|
||||
name=random
|
||||
random={RANGE}
|
||||
[/set_variable]
|
||||
#enddef
|
||||
|
|
|
@ -65,6 +65,8 @@ HOTKEY_COMMAND string_to_command(const std::string& str)
|
|||
m.insert(val("statistics",HOTKEY_STATISTICS));
|
||||
m.insert(val("quit",HOTKEY_QUIT_GAME));
|
||||
m.insert(val("labelterrain",HOTKEY_LABEL_TERRAIN));
|
||||
m.insert(val("showenemymoves",HOTKEY_SHOW_ENEMY_MOVES));
|
||||
m.insert(val("bestenemymoves",HOTKEY_BEST_ENEMY_MOVES));
|
||||
}
|
||||
|
||||
const std::map<std::string,HOTKEY_COMMAND>::const_iterator i = m.find(str);
|
||||
|
@ -358,6 +360,14 @@ void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* ex
|
|||
if(executor)
|
||||
executor->label_terrain();
|
||||
break;
|
||||
case HOTKEY_SHOW_ENEMY_MOVES:
|
||||
if(executor)
|
||||
executor->show_enemy_moves(false);
|
||||
break;
|
||||
case HOTKEY_BEST_ENEMY_MOVES:
|
||||
if(executor)
|
||||
executor->show_enemy_moves(true);
|
||||
break;
|
||||
case HOTKEY_QUIT_GAME: {
|
||||
const int res = gui::show_dialog(disp,NULL,"",string_table["quit_message"],gui::YES_NO);
|
||||
if(res == 0) {
|
||||
|
|
|
@ -33,7 +33,8 @@ enum HOTKEY_COMMAND { HOTKEY_CYCLE_UNITS, HOTKEY_END_UNIT_TURN, HOTKEY_LEADER,
|
|||
HOTKEY_TOGGLE_GRID, HOTKEY_STATUS_TABLE, HOTKEY_MUTE,
|
||||
HOTKEY_SPEAK, HOTKEY_CREATE_UNIT, HOTKEY_PREFERENCES,
|
||||
HOTKEY_OBJECTIVES, HOTKEY_UNIT_LIST, HOTKEY_STATISTICS, HOTKEY_QUIT_GAME,
|
||||
HOTKEY_LABEL_TERRAIN, HOTKEY_NULL };
|
||||
HOTKEY_LABEL_TERRAIN, HOTKEY_SHOW_ENEMY_MOVES, HOTKEY_BEST_ENEMY_MOVES,
|
||||
HOTKEY_NULL };
|
||||
|
||||
struct hotkey_item {
|
||||
explicit hotkey_item(const config& cfg);
|
||||
|
@ -98,6 +99,7 @@ public:
|
|||
virtual void unit_list() = 0;
|
||||
virtual void show_statistics() = 0;
|
||||
virtual void label_terrain() = 0;
|
||||
virtual void show_enemy_moves(bool ignore_units) = 0;
|
||||
|
||||
virtual bool can_execute_command(HOTKEY_COMMAND command) const = 0;
|
||||
};
|
||||
|
|
|
@ -67,8 +67,7 @@ void queue_disconnect(connection connection_num);
|
|||
//received in cfg. Times out after timeout milliseconds. Returns
|
||||
//the connection that data was received from, or 0 if timeout
|
||||
//occurred. Throws error if an error occurred.
|
||||
connection receive_data(config& cfg, connection connection_num=0,
|
||||
int timeout=0);
|
||||
connection receive_data(config& cfg, connection connection_num=0, int timeout=0);
|
||||
|
||||
//sets the default maximum number of bytes to send to a client at a time
|
||||
void set_default_send_size(size_t send_size);
|
||||
|
|
|
@ -459,110 +459,26 @@ redo_turn:
|
|||
} else if(!replaying && team_it->is_network()) {
|
||||
std::cerr << "is networked...\n";
|
||||
|
||||
bool turn_end = false;
|
||||
turn_info turn_data(gameinfo,state_of_game,status,
|
||||
game_config,level,key,gui,
|
||||
map,teams,player_number,units,true);
|
||||
|
||||
while(!turn_end) {
|
||||
turn_info turn_data(gameinfo,state_of_game,status,
|
||||
game_config,level,key,gui,
|
||||
map,teams,player_number,units,true);
|
||||
for(;;) {
|
||||
|
||||
config cfg;
|
||||
|
||||
for(;;) {
|
||||
cfg = config();
|
||||
network::connection res = network::receive_data(cfg);
|
||||
const network::connection res = network::receive_data(cfg);
|
||||
|
||||
if(res) {
|
||||
std::cerr << "received network data: '" << cfg.write() << "'\n";
|
||||
}
|
||||
|
||||
if(res && cfg.child("observer") != NULL) {
|
||||
const config::child_list& observers = cfg.get_children("observer");
|
||||
for(config::child_list::const_iterator ob = observers.begin(); ob != observers.end(); ++ob) {
|
||||
gui.add_observer((**ob)["name"]);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(res && cfg.child("observer_quit") != NULL) {
|
||||
const config::child_list& observers = cfg.get_children("observer_quit");
|
||||
for(config::child_list::const_iterator ob = observers.begin(); ob != observers.end(); ++ob) {
|
||||
gui.remove_observer((**ob)["name"]);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(res && cfg.child("leave_game") != NULL) {
|
||||
throw network::error("");
|
||||
}
|
||||
|
||||
//if a side has dropped out of the game.
|
||||
if(res && cfg["side_drop"] != "") {
|
||||
const size_t side = atoi(cfg["side_drop"].c_str())-1;
|
||||
if(side >= teams.size()) {
|
||||
std::cerr << "unknown side " << side << " is dropping game\n";
|
||||
throw network::error("");
|
||||
}
|
||||
|
||||
int action = 0;
|
||||
|
||||
//see if the side still has a leader alive. If they have
|
||||
//no leader, we assume they just want to be replaced by
|
||||
//the AI.
|
||||
const unit_map::const_iterator leader = find_leader(units,side+1);
|
||||
if(leader != units.end()) {
|
||||
std::vector<std::string> options;
|
||||
options.push_back(string_table["replace_ai_message"]);
|
||||
options.push_back(string_table["replace_local_message"]);
|
||||
options.push_back(string_table["abort_game_message"]);
|
||||
|
||||
const std::string msg = leader->second.description() + " " + string_table["player_leave_message"];
|
||||
action = gui::show_dialog(gui,NULL,"",msg,gui::OK_ONLY,&options);
|
||||
}
|
||||
|
||||
//make the player an AI, and redo this turn, in case
|
||||
//it was the current player's team who has just changed into
|
||||
//an AI.
|
||||
if(action == 0) {
|
||||
teams[side].make_ai();
|
||||
goto redo_turn;
|
||||
} else if(action == 1) {
|
||||
teams[side].make_human();
|
||||
goto redo_turn;
|
||||
} else {
|
||||
throw network::error("");
|
||||
}
|
||||
}
|
||||
|
||||
if(res && cfg.child("turn") != NULL) {
|
||||
//forward the data to other peers
|
||||
network::send_data_all_except(cfg,res);
|
||||
break;
|
||||
}
|
||||
|
||||
const int ncommand = recorder.ncommands();
|
||||
turn_data.turn_slice();
|
||||
turn_data.send_data(ncommand);
|
||||
gui.draw();
|
||||
const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg,res);
|
||||
if(result == turn_info::PROCESS_RESTART_TURN) {
|
||||
goto redo_turn;
|
||||
} else if(result == turn_info::PROCESS_END_TURN) {
|
||||
break;
|
||||
}
|
||||
|
||||
replay replay_obj(*cfg.child("turn"));
|
||||
replay_obj.start_replay();
|
||||
|
||||
try {
|
||||
turn_end = do_replay(gui,map,gameinfo,units,teams,
|
||||
player_number,status,state_of_game,&replay_obj);
|
||||
} catch(replay::error&) {
|
||||
turn_data.save_game(string_table["network_sync_error"]);
|
||||
|
||||
return QUIT;
|
||||
}
|
||||
|
||||
recorder.add_config(*cfg.child("turn"));
|
||||
|
||||
gui.invalidate_all();
|
||||
const int ncommand = recorder.ncommands();
|
||||
turn_data.turn_slice();
|
||||
turn_data.send_data(ncommand);
|
||||
gui.draw();
|
||||
}
|
||||
|
||||
|
|
153
src/playturn.cpp
153
src/playturn.cpp
|
@ -130,6 +130,10 @@ void play_turn(game_data& gameinfo, game_state& state_of_game,
|
|||
while(!turn_data.turn_over()) {
|
||||
|
||||
try {
|
||||
config cfg;
|
||||
const network::connection res = network::receive_data(cfg);
|
||||
turn_data.process_network_data(cfg,res);
|
||||
|
||||
turn_data.turn_slice();
|
||||
} catch(end_level_exception& e) {
|
||||
turn_data.send_data(start_command);
|
||||
|
@ -194,9 +198,28 @@ int turn_info::send_data(int first_command)
|
|||
if(network::nconnections() > 0 && (undo_stack_.empty() || end_turn_) &&
|
||||
first_command < recorder.ncommands()) {
|
||||
config cfg;
|
||||
cfg.add_child("turn",recorder.get_data_range(first_command,recorder.ncommands()));
|
||||
network::send_data(cfg);
|
||||
const config& obj = cfg.add_child("turn",recorder.get_data_range(first_command,recorder.ncommands()));
|
||||
|
||||
if(obj.empty() == false) {
|
||||
network::send_data(cfg);
|
||||
}
|
||||
|
||||
return recorder.ncommands();
|
||||
} else if(network::nconnections() > 0 && first_command < recorder.ncommands()) {
|
||||
|
||||
std::cerr << "getting non-undo commands\n";
|
||||
|
||||
//we don't want to send any moves that haven't been committed, however if there
|
||||
//are any non-undoable moves (speaking, labelling), we want to send it now.
|
||||
config cfg;
|
||||
const config& obj = cfg.add_child("turn",recorder.get_data_range(first_command,recorder.ncommands(),replay::NON_UNDO_DATA));
|
||||
|
||||
if(obj.empty() == false) {
|
||||
std::cerr << "sending non-undo commands\n";
|
||||
network::send_data(cfg);
|
||||
}
|
||||
|
||||
return first_command;
|
||||
} else {
|
||||
return first_command;
|
||||
}
|
||||
|
@ -269,8 +292,9 @@ void turn_info::handle_event(const SDL_Event& event)
|
|||
|
||||
void turn_info::mouse_motion(const SDL_MouseMotionEvent& event)
|
||||
{
|
||||
if(commands_disabled)
|
||||
if(commands_disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(minimap_scrolling_) {
|
||||
//if the game is run in a window, we could miss a LMB up event
|
||||
|
@ -820,6 +844,8 @@ bool turn_info::can_execute_command(hotkey::HOTKEY_COMMAND command) const
|
|||
case hotkey::HOTKEY_UNIT_LIST:
|
||||
case hotkey::HOTKEY_STATISTICS:
|
||||
case hotkey::HOTKEY_QUIT_GAME:
|
||||
case hotkey::HOTKEY_SHOW_ENEMY_MOVES:
|
||||
case hotkey::HOTKEY_BEST_ENEMY_MOVES:
|
||||
return true;
|
||||
|
||||
case hotkey::HOTKEY_SPEAK:
|
||||
|
@ -1659,10 +1685,6 @@ void turn_info::speak()
|
|||
|
||||
recorder.speak(cfg);
|
||||
dialogs::unit_speak(cfg,gui_,units_);
|
||||
|
||||
//speaking is an unretractable operation
|
||||
undo_stack_.clear();
|
||||
redo_stack_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1854,6 +1876,33 @@ void turn_info::label_terrain()
|
|||
}
|
||||
}
|
||||
|
||||
// Highlights squares that an enemy could move to on their turn
|
||||
void turn_info::show_enemy_moves(bool ignore_units)
|
||||
{
|
||||
team& current_team = teams_[team_num_-1];
|
||||
all_paths_ = paths();
|
||||
|
||||
// Compute enemy movement positions
|
||||
for(unit_map::const_iterator u = units_.begin(); u != units_.end(); ++u) {
|
||||
if(current_team.is_enemy(u->second.side()) && !gui_.fogged(u->first.x,u->first.y)) {
|
||||
const bool is_skirmisher = u->second.type().is_skirmisher();
|
||||
const bool teleports = u->second.type().teleports();
|
||||
unit_map units;
|
||||
units.insert(*u);
|
||||
const paths& path = paths(map_,status_,gameinfo_,ignore_units?units:units_,
|
||||
u->first,teams_,is_skirmisher,teleports,1);
|
||||
|
||||
for (paths::routes_map::const_iterator route = path.routes.begin(); route != path.routes.end(); ++route) {
|
||||
// map<...>::operator[](const key_type& key) inserts key into
|
||||
// the map with a default instance of value_type
|
||||
all_paths_.routes[route->first];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gui_.set_paths(&all_paths_);
|
||||
}
|
||||
|
||||
unit_map::iterator turn_info::current_unit()
|
||||
{
|
||||
unit_map::iterator i = units_.end();
|
||||
|
@ -1895,3 +1944,93 @@ unit_map::const_iterator turn_info::current_unit() const
|
|||
|
||||
return i;
|
||||
}
|
||||
|
||||
turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg, network::connection from)
|
||||
{
|
||||
if(from == 0) {
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
if(cfg.child("observer") != NULL) {
|
||||
const config::child_list& observers = cfg.get_children("observer");
|
||||
for(config::child_list::const_iterator ob = observers.begin(); ob != observers.end(); ++ob) {
|
||||
gui_.add_observer((**ob)["name"]);
|
||||
}
|
||||
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
if(cfg.child("observer_quit") != NULL) {
|
||||
const config::child_list& observers = cfg.get_children("observer_quit");
|
||||
for(config::child_list::const_iterator ob = observers.begin(); ob != observers.end(); ++ob) {
|
||||
gui_.remove_observer((**ob)["name"]);
|
||||
}
|
||||
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
if(cfg.child("leave_game") != NULL) {
|
||||
throw network::error("");
|
||||
}
|
||||
|
||||
//if a side has dropped out of the game.
|
||||
if(cfg["side_drop"] != "") {
|
||||
const size_t side = atoi(cfg["side_drop"].c_str())-1;
|
||||
if(side >= teams_.size()) {
|
||||
std::cerr << "unknown side " << side << " is dropping game\n";
|
||||
throw network::error("");
|
||||
}
|
||||
|
||||
int action = 0;
|
||||
|
||||
//see if the side still has a leader alive. If they have
|
||||
//no leader, we assume they just want to be replaced by
|
||||
//the AI.
|
||||
const unit_map::const_iterator leader = find_leader(units_,side+1);
|
||||
if(leader != units_.end()) {
|
||||
std::vector<std::string> options;
|
||||
options.push_back(string_table["replace_ai_message"]);
|
||||
options.push_back(string_table["replace_local_message"]);
|
||||
options.push_back(string_table["abort_game_message"]);
|
||||
|
||||
const std::string msg = leader->second.description() + " " + string_table["player_leave_message"];
|
||||
action = gui::show_dialog(gui_,NULL,"",msg,gui::OK_ONLY,&options);
|
||||
}
|
||||
|
||||
//make the player an AI, and redo this turn, in case
|
||||
//it was the current player's team who has just changed into
|
||||
//an AI.
|
||||
if(action == 0) {
|
||||
teams_[side].make_ai();
|
||||
return PROCESS_RESTART_TURN;
|
||||
} else if(action == 1) {
|
||||
teams_[side].make_human();
|
||||
return PROCESS_RESTART_TURN;
|
||||
} else {
|
||||
throw network::error("");
|
||||
}
|
||||
}
|
||||
|
||||
bool turn_end = false;
|
||||
|
||||
if(cfg.child("turn") != NULL) {
|
||||
//forward the data to other peers
|
||||
network::send_data_all_except(cfg,from);
|
||||
|
||||
replay replay_obj(*cfg.child("turn"));
|
||||
replay_obj.start_replay();
|
||||
|
||||
try {
|
||||
turn_end = do_replay(gui_,map_,gameinfo_,units_,teams_,
|
||||
team_num_,status_,state_of_game_,&replay_obj);
|
||||
} catch(replay::error& e) {
|
||||
save_game(string_table["network_sync_error"]);
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
recorder.add_config(*cfg.child("turn"));
|
||||
}
|
||||
|
||||
return turn_end ? PROCESS_END_TURN : PROCESS_CONTINUE;
|
||||
}
|
|
@ -74,6 +74,11 @@ public:
|
|||
|
||||
void save_game(const std::string& message);
|
||||
|
||||
enum PROCESS_DATA_RESULT { PROCESS_CONTINUE, PROCESS_RESTART_TURN, PROCESS_END_TURN };
|
||||
|
||||
//function which will process incoming network data, and act on it.
|
||||
PROCESS_DATA_RESULT process_network_data(const config& cfg, network::connection from);
|
||||
|
||||
private:
|
||||
|
||||
void write_game_snapshot(config& cfg) const;
|
||||
|
@ -101,6 +106,7 @@ private:
|
|||
void unit_list();
|
||||
void show_statistics();
|
||||
void label_terrain();
|
||||
void show_enemy_moves(bool ignore_units);
|
||||
|
||||
void do_recruit(const std::string& name);
|
||||
|
||||
|
@ -134,7 +140,7 @@ private:
|
|||
bool left_button_, right_button_, middle_button_;
|
||||
bool minimap_scrolling_;
|
||||
gamemap::location next_unit_;
|
||||
paths current_paths_;
|
||||
paths current_paths_, all_paths_;
|
||||
paths::route current_route_;
|
||||
bool enemy_paths_;
|
||||
gamemap::location last_hex_;
|
||||
|
|
|
@ -72,7 +72,7 @@ void set_random_results(const config& cfg)
|
|||
replay::replay() : pos_(0), current_(NULL), skip_(0)
|
||||
{}
|
||||
|
||||
replay::replay(config& cfg) : cfg_(cfg), pos_(0), current_(NULL), skip_(0)
|
||||
replay::replay(const config& cfg) : cfg_(cfg), pos_(0), current_(NULL), skip_(0)
|
||||
{}
|
||||
|
||||
config& replay::get_config()
|
||||
|
@ -225,6 +225,8 @@ void replay::add_label(const std::string& text, const gamemap::location& loc)
|
|||
{
|
||||
config* const cmd = add_command();
|
||||
|
||||
(*cmd)["undo"] = "no";
|
||||
|
||||
config val;
|
||||
|
||||
loc.write(val);
|
||||
|
@ -241,10 +243,14 @@ void replay::end_turn()
|
|||
|
||||
void replay::speak(const config& cfg)
|
||||
{
|
||||
add_command()->add_child("speak") = cfg;
|
||||
config* const cmd = add_command();
|
||||
if(cmd != NULL) {
|
||||
cmd->add_child("speak",cfg);
|
||||
(*cmd)["undo"] = "no";
|
||||
}
|
||||
}
|
||||
|
||||
config replay::get_data_range(int cmd_start, int cmd_end)
|
||||
config replay::get_data_range(int cmd_start, int cmd_end, DATA_TYPE data_type)
|
||||
{
|
||||
log_scope("get_data_range\n");
|
||||
|
||||
|
@ -252,7 +258,14 @@ config replay::get_data_range(int cmd_start, int cmd_end)
|
|||
|
||||
const config::child_list& cmd = commands();
|
||||
while(cmd_start < cmd_end) {
|
||||
res.add_child("command",*cmd[cmd_start]);
|
||||
if((data_type == ALL_DATA || (*cmd[cmd_start])["undo"] == "no") && (*cmd[cmd_start])["sent"] != "yes") {
|
||||
res.add_child("command",*cmd[cmd_start]);
|
||||
|
||||
if(data_type == NON_UNDO_DATA) {
|
||||
(*cmd[cmd_start])["sent"] = "yes";
|
||||
}
|
||||
}
|
||||
|
||||
++cmd_start;
|
||||
}
|
||||
|
||||
|
@ -261,7 +274,11 @@ config replay::get_data_range(int cmd_start, int cmd_end)
|
|||
|
||||
void replay::undo()
|
||||
{
|
||||
const config::child_itors& cmd = cfg_.child_range("command");
|
||||
config::child_itors cmd = cfg_.child_range("command");
|
||||
while(cmd.first != cmd.second && (**(cmd.second-1))["undo"] == "no") {
|
||||
--cmd.second;
|
||||
}
|
||||
|
||||
if(cmd.first != cmd.second) {
|
||||
delete *(cmd.second-1);
|
||||
cfg_.remove_child("command",cmd.second - cmd.first - 1);
|
||||
|
|
|
@ -26,7 +26,7 @@ class replay
|
|||
{
|
||||
public:
|
||||
replay();
|
||||
replay(config& cfg);
|
||||
explicit replay(const config& cfg);
|
||||
|
||||
config& get_config();
|
||||
|
||||
|
@ -50,7 +50,15 @@ public:
|
|||
|
||||
void speak(const config& cfg);
|
||||
|
||||
config get_data_range(int cmd_start, int cmd_end);
|
||||
//get data range will get a range of moves from the replay system.
|
||||
//if data_type is 'ALL_DATA' then it will return all data in this range
|
||||
//except for undoable data that has already been sent. If data_type is
|
||||
//NON_UNDO_DATA, then it will only retrieve undoable data, and will mark
|
||||
//it as already sent.
|
||||
//undoable data includes moves such as placing a label or speaking, which is
|
||||
//ignored by the undo system.
|
||||
enum DATA_TYPE { ALL_DATA, NON_UNDO_DATA };
|
||||
config get_data_range(int cmd_start, int cmd_end, DATA_TYPE data_type=ALL_DATA);
|
||||
config get_last_turn(int num_turns=1);
|
||||
|
||||
void undo();
|
||||
|
|
Loading…
Add table
Reference in a new issue