1 /*
2    Copyright (C) 2006 - 2018 by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
3    wesnoth playlevel Copyright (C) 2003 by David White <dave@whitevine.net>
4    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY.
12 
13    See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include "play_controller.hpp"
19 
20 #include "cursor.hpp"
21 #include "playturn_network_adapter.hpp"
22 #include "playturn.hpp"
23 #include "replay.hpp"
24 #include "saved_game.hpp"
25 #include "replay_controller.hpp"
26 
27 #include <exception>
28 
29 struct reset_gamestate_exception : public std::exception
30 {
reset_gamestate_exceptionreset_gamestate_exception31 	reset_gamestate_exception(std::shared_ptr<config> l, std::shared_ptr<config> stats, bool s = true) : level(l), stats_(stats), start_replay(s) {}
32 	std::shared_ptr<config> level;
33 	std::shared_ptr<config> stats_;
34 	bool start_replay;
35 };
36 
37 class playsingle_controller : public play_controller
38 {
39 public:
40 	playsingle_controller(const config& level, saved_game& state_of_game,
41 		const ter_data_cache & tdata, bool skip_replay);
42 
43 	LEVEL_RESULT play_scenario(const config& level);
44 	void play_scenario_init();
45 	void play_scenario_main_loop();
46 
47 	virtual void handle_generic_event(const std::string& name) override;
48 
49 	virtual void check_objectives() override;
on_not_observer()50 	virtual void on_not_observer() override {}
51 	virtual void maybe_linger();
52 
53 	void end_turn();
54 	void force_end_turn() override;
55 
56 	class hotkey_handler;
57 	std::string describe_result() const;
58 
get_player_type_changed() const59 	bool get_player_type_changed() const { return player_type_changed_; }
set_player_type_changed()60 	void set_player_type_changed() { player_type_changed_ = true; }
61 	virtual bool should_return_to_play_side() const override;
get_replay_controller() const62 	replay_controller * get_replay_controller() const override { return replay_controller_.get(); }
63 	void enable_replay(bool is_unit_test = false);
64 	void on_replay_end(bool is_unit_test);
65 protected:
66 	virtual void play_side_impl() override;
67 	void before_human_turn();
68 	void show_turn_dialog();
69 	void execute_gotos();
70 	virtual void play_human_turn();
71 	virtual void after_human_turn();
72 	void end_turn_enable(bool enable);
73 	void play_ai_turn();
74 	virtual void play_idle_loop();
75 	virtual void do_idle_notification();
76 	virtual void play_network_turn();
77 	virtual void init_gui() override;
78 
79 	const cursor::setter cursor_setter_;
80 	gui::floating_textbox textbox_info_;
81 
82 	replay_network_sender replay_sender_;
83 	playturn_network_adapter network_reader_;
84 	turn_info turn_data_;
85 	enum END_TURN_STATE
86 	{
87 		/// The turn was not ended yet
88 		END_TURN_NONE,
89 		/// And endturn was required eigher by the player, by the ai or by [end_turn]
90 		END_TURN_REQUIRED,
91 		/// An [end_turn] was added to the replay.
92 		END_TURN_SYNCED,
93 	};
94 	END_TURN_STATE end_turn_;
95 	bool skip_next_turn_, ai_fallback_;
96 	std::unique_ptr<replay_controller> replay_controller_;
97 	void linger();
98 	void sync_end_turn() override;
99 	void update_viewing_player() override;
100 	void reset_replay();
101 };
102