1 /*
2  * Copyright (C) 2002-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  *
18  */
19 
20 #ifndef WL_LOGIC_MAP_OBJECTS_MAP_OBJECT_PROGRAM_H
21 #define WL_LOGIC_MAP_OBJECTS_MAP_OBJECT_PROGRAM_H
22 
23 #include <limits>
24 #include <string>
25 #include <vector>
26 
27 #include "logic/widelands.h"
28 #include "sound/constants.h"
29 
30 namespace Widelands {
31 
32 struct MapObjectDescr;
33 
34 /// Superclass for Worker, Immovable and Productionsite programs. Includes a program name and
35 /// diverse parsing convenience functions. The creation and execution of program actions is left to
36 /// the sub-classes.
37 struct MapObjectProgram {
38 	const std::string& name() const;
39 
40 	explicit MapObjectProgram(const std::string& init_name);
41 	virtual ~MapObjectProgram() = default;
42 
43 protected:
44 	/// Splits a string by separators.
45 	/// \note This ignores empty elements, so do not use this for example to split
46 	/// a string with newline characters into lines, because it would ignore empty
47 	/// lines.
48 	static std::vector<std::string> split_string(const std::string&, char const* separators);
49 
50 	/// Reads an int value from a string. Throws a GameDataError if 'min_value' or 'max_value' are
51 	/// exceeded
52 	static unsigned int read_int(const std::string& input,
53 	                             int min_value,
54 	                             int max_value = std::numeric_limits<int32_t>::max());
55 	/// Same as 'read_int', with 'min_value' == 1
56 	static unsigned int read_positive(const std::string& input,
57 	                                  int max_value = std::numeric_limits<int32_t>::max());
58 
59 	/**
60 	 * @brief Reads a key-value pair from a string using the given separator, e.g. "attrib:tree",
61 	 * "meat:2", "return=skipped unless economy needs meal"
62 	 * @param input The string to parse
63 	 * @param separator The separator for splitting the string, e.g. ':' or '='
64 	 * @param default_value A default to assign to the right-hand value if the separator is not found
65 	 * @param expected_key If this is not empty, the left-hand key must match this string
66 	 * @return A key, value pair
67 	 */
68 	static const std::pair<std::string, std::string>
69 	read_key_value_pair(const std::string& input,
70 	                    const char separator,
71 	                    const std::string& default_value = "",
72 	                    const std::string& expected_key = "");
73 
74 	/// Left-hand and right-hand elements of a line in a program, e.g. parsed from "return=skipped
75 	/// unless economy needs meal"
76 	struct ProgramParseInput {
77 		/// Program name, e.g. "return"
78 		std::string name;
79 		/// Program arguments, e.g. { "skipped", "unless", "economy", "needs", "meal" }
80 		std::vector<std::string> arguments;
81 	};
82 	/// Reads the program name and arguments from a string
83 	static ProgramParseInput parse_program_string(const std::string& line);
84 
85 	/// Animation information
86 	struct AnimationParameters {
87 		/// Animation ID
88 		uint32_t animation = 0;
89 		/// Animation duration. 0 will play the animation forever.
90 		Duration duration = 0;
91 	};
92 	/// Parses the arguments for an animation action, e.g. { "working", "24000" }. If
93 	/// 'is_idle_allowed' == false, throws a GameDataError if the animation is called "idle".
94 	static AnimationParameters parse_act_animate(const std::vector<std::string>& arguments,
95 	                                             const MapObjectDescr& descr,
96 	                                             bool is_idle_allowed);
97 
98 	/// Sound effect information
99 	struct PlaySoundParameters {
100 		/// Sound effect ID
101 		FxId fx;
102 		/// Sound effect priority
103 		uint8_t priority = 0;
104 	};
105 	/// Parses the arguments for a play_sound action, e.g. { "sound/smiths/sharpening", "120" }
106 	static PlaySoundParameters parse_act_play_sound(const std::vector<std::string>& arguments,
107 	                                                uint8_t default_priority);
108 
109 private:
110 	const std::string name_;
111 };
112 }  // namespace Widelands
113 
114 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_MAP_OBJECT_PROGRAM_H
115