1 // Copyright 2014-2018 the openage authors. See copying.md for legal info.
2 
3 #pragma once
4 
5 #include <unordered_set>
6 
7 #include "../coord/phys.h"
8 #include "ability.h"
9 
10 namespace openage {
11 
12 /**
13  * additional flags which may affect some abilities
14  */
15 enum class command_flag {
16 	interrupt, // the user directly issued this command, stopping other actions
17 	use_range, // move command account for units range
18 	attack_res // allow attack on a resource object
19 };
20 
21 } // namespace openage
22 
23 namespace std {
24 
25 /**
26  * hasher for game command flags
27  */
28 template<>
29 struct hash<openage::command_flag> {
30 	typedef underlying_type<openage::command_flag>::type underlying_type;
31 
32 	size_t operator()(const openage::command_flag &arg) const {
33 		hash<underlying_type> hasher;
34 		return hasher(static_cast<underlying_type>(arg));
35 	}
36 };
37 
38 } // namespace std
39 
40 namespace openage {
41 
42 class Player;
43 class Research;
44 class Unit;
45 class UnitType;
46 
47 /*
48  * Game command from the ui
49  * TODO reorganize the names of the optional variables and their getters
50  */
51 class Command {
52 public:
53 
54 	/**
55 	 * target another unit
56 	 */
57 	Command(const Player &, Unit *unit);
58 
59 	/**
60 	 * target a position
61 	 */
62 	Command(const Player &, coord::phys3 position);
63 
64 	/**
65 	 * target another unit or a position
66 	 */
67 	Command(const Player &, Unit *unit, coord::phys3 position);
68 
69 	/**
70 	 * select a type
71 	 */
72 	Command(const Player &, UnitType *t);
73 
74 	/**
75 	 * select a research
76 	 */
77 	Command(const Player &, Research *res);
78 
79 	/**
80 	 * place building foundation
81 	 */
82 	Command(const Player &, UnitType *, coord::phys3);
83 
84 	bool has_unit() const;
85 	bool has_position() const;
86 	bool has_type() const;
87 	bool has_research() const;
88 
89 	Unit *unit() const;
90 	coord::phys3 position() const;
91 	UnitType *type() const;
92 	Research *research() const;
93 
94 	/**
95 	 * sets invoked ability type, no other type may be used if
96 	 * this gets set
97 	 *
98 	 * @param type allows a specific ability type to be used
99 	 * for example to set a unit to patrol rather than the default move
100 	 */
101 	void set_ability(ability_type t);
102 
103 	/**
104 	 * restricts action to a set of possible ability types
105 	 */
106 	void set_ability_set(ability_set set);
107 
108 	/**
109 	 * the ability types allowed to use this command
110 	 */
111 	const ability_set &ability() const;
112 
113 	/**
114 	 * add addition option to this command
115 	 */
116 	void add_flag(command_flag flag);
117 
118 	/**
119 	 * read the range setting
120 	 */
121 	bool has_flag(command_flag flag) const;
122 
123 	/**
124 	 * player who created the command
125 	 */
126 	const Player &player;
127 
128 private:
129 
130 	/**
131 	 * basic constructor, which shouldnt be used directly
132 	 */
133 	Command(const Player &, Unit *unit, bool haspos, UnitType *t, Research *res);
134 
135 	bool has_pos;
136 	Unit *u;
137 	coord::phys3 pos = {0, 0, 0}; // TODO: make pos a c++17 optional
138 	UnitType *unit_type;
139 	Research *res;
140 
141 	/**
142 	 * additional options
143 	 */
144 	std::unordered_set<command_flag> flags;
145 
146 	/**
147 	 * select actions to use when targeting
148 	 */
149 	ability_set modifiers;
150 
151 };
152 
153 } // namespace openage
154