1 // _________ __ __
2 // / _____// |_____________ _/ |______ ____ __ __ ______
3 // \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
4 // / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
5 // /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
6 // \/ \/ \//_____/ \/
7 // ______________________ ______________________
8 // T H E W A R B E G I N S
9 // Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name animation_setplayervar.cpp - The animation SetPlayerVar. */
12 //
13 // (c) Copyright 2012 by Joris Dauphin
14 //
15 // This program is free software; you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation; only version 2 of the License.
18 //
19 // This program is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 // GNU General Public License for more details.
23 //
24 // You should have received a copy of the GNU General Public License
25 // along with this program; if not, write to the Free Software
26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 // 02111-1307, USA.
28 //
29
30 //@{
31
32 /*----------------------------------------------------------------------------
33 -- Includes
34 ----------------------------------------------------------------------------*/
35
36 #include "stratagus.h"
37
38 #include "animation/animation_setplayervar.h"
39
40 #include "animation.h"
41 #include "unit/unit.h"
42
43 #include <stdio.h>
44
45 /**
46 ** Gets the player data.
47 **
48 ** @param player Player number.
49 ** @param prop Player's property.
50 ** @param arg Additional argument (for resource and unit).
51 **
52 ** @return Returning value (only integer).
53 */
GetPlayerData(const int player,const char * prop,const char * arg)54 int GetPlayerData(const int player, const char *prop, const char *arg)
55 {
56 if (!strcmp(prop, "RaceName")) {
57 return Players[player].Race;
58 } else if (!strcmp(prop, "Resources")) {
59 const int resId = GetResourceIdByName(arg);
60 if (resId == -1) {
61 fprintf(stderr, "Invalid resource \"%s\"", arg);
62 Exit(1);
63 }
64 return Players[player].Resources[resId] + Players[player].StoredResources[resId];
65 } else if (!strcmp(prop, "StoredResources")) {
66 const int resId = GetResourceIdByName(arg);
67 if (resId == -1) {
68 fprintf(stderr, "Invalid resource \"%s\"", arg);
69 Exit(1);
70 }
71 return Players[player].StoredResources[resId];
72 } else if (!strcmp(prop, "MaxResources")) {
73 const int resId = GetResourceIdByName(arg);
74 if (resId == -1) {
75 fprintf(stderr, "Invalid resource \"%s\"", arg);
76 Exit(1);
77 }
78 return Players[player].MaxResources[resId];
79 } else if (!strcmp(prop, "Incomes")) {
80 const int resId = GetResourceIdByName(arg);
81 if (resId == -1) {
82 fprintf(stderr, "Invalid resource \"%s\"", arg);
83 Exit(1);
84 }
85 return Players[player].Incomes[resId];
86 //Wyrmgus start
87 } else if (!strcmp(prop, "Prices")) {
88 const int resId = GetResourceIdByName(arg);
89 if (resId == -1) {
90 fprintf(stderr, "Invalid resource \"%s\"", arg);
91 Exit(1);
92 }
93 return Players[player].GetResourcePrice(resId);
94 } else if (!strcmp(prop, "ResourceDemand")) {
95 const int resId = GetResourceIdByName(arg);
96 if (resId == -1) {
97 fprintf(stderr, "Invalid resource \"%s\"", arg);
98 Exit(1);
99 }
100 return Players[player].ResourceDemand[resId];
101 } else if (!strcmp(prop, "StoredResourceDemand")) {
102 const int resId = GetResourceIdByName(arg);
103 if (resId == -1) {
104 fprintf(stderr, "Invalid resource \"%s\"", arg);
105 Exit(1);
106 }
107 return Players[player].StoredResourceDemand[resId];
108 } else if (!strcmp(prop, "EffectiveResourceDemand")) {
109 const int resId = GetResourceIdByName(arg);
110 if (resId == -1) {
111 fprintf(stderr, "Invalid resource \"%s\"", arg);
112 Exit(1);
113 }
114 return Players[player].GetEffectiveResourceDemand(resId);
115 } else if (!strcmp(prop, "EffectiveResourceBuyPrice")) {
116 const int resId = GetResourceIdByName(arg);
117 if (resId == -1) {
118 fprintf(stderr, "Invalid resource \"%s\"", arg);
119 Exit(1);
120 }
121 return Players[player].GetEffectiveResourceBuyPrice(resId);
122 } else if (!strcmp(prop, "EffectiveResourceSellPrice")) {
123 const int resId = GetResourceIdByName(arg);
124 if (resId == -1) {
125 fprintf(stderr, "Invalid resource \"%s\"", arg);
126 Exit(1);
127 }
128 return Players[player].GetEffectiveResourceSellPrice(resId);
129 } else if (!strcmp(prop, "TradeCost")) {
130 return Players[player].TradeCost;
131 //Wyrmgus end
132 } else if (!strcmp(prop, "UnitTypesCount")) {
133 const std::string unit(arg);
134 CUnitType *type = UnitTypeByIdent(unit);
135 Assert(type);
136 return Players[player].GetUnitTypeCount(type);
137 } else if (!strcmp(prop, "UnitTypesUnderConstructionCount")) {
138 const std::string unit(arg);
139 CUnitType *type = UnitTypeByIdent(unit);
140 Assert(type);
141 return Players[player].GetUnitTypeUnderConstructionCount(type);
142 } else if (!strcmp(prop, "UnitTypesAiActiveCount")) {
143 const std::string unit(arg);
144 CUnitType *type = UnitTypeByIdent(unit);
145 Assert(type);
146 return Players[player].GetUnitTypeAiActiveCount(type);
147 } else if (!strcmp(prop, "AiEnabled")) {
148 return Players[player].AiEnabled;
149 } else if (!strcmp(prop, "TotalNumUnits")) {
150 return Players[player].GetUnitCount();
151 } else if (!strcmp(prop, "NumBuildings")) {
152 return Players[player].NumBuildings;
153 //Wyrmgus start
154 } else if (!strcmp(prop, "NumBuildingsUnderConstruction")) {
155 return Players[player].NumBuildingsUnderConstruction;
156 //Wyrmgus end
157 } else if (!strcmp(prop, "Supply")) {
158 return Players[player].Supply;
159 } else if (!strcmp(prop, "Demand")) {
160 return Players[player].Demand;
161 } else if (!strcmp(prop, "UnitLimit")) {
162 return Players[player].UnitLimit;
163 } else if (!strcmp(prop, "BuildingLimit")) {
164 return Players[player].BuildingLimit;
165 } else if (!strcmp(prop, "TotalUnitLimit")) {
166 return Players[player].TotalUnitLimit;
167 } else if (!strcmp(prop, "Score")) {
168 return Players[player].Score;
169 } else if (!strcmp(prop, "TotalUnits")) {
170 return Players[player].TotalUnits;
171 } else if (!strcmp(prop, "TotalBuildings")) {
172 return Players[player].TotalBuildings;
173 } else if (!strcmp(prop, "TotalResources")) {
174 const int resId = GetResourceIdByName(arg);
175 if (resId == -1) {
176 fprintf(stderr, "Invalid resource \"%s\"", arg);
177 Exit(1);
178 }
179 return Players[player].TotalResources[resId];
180 } else if (!strcmp(prop, "TotalRazings")) {
181 return Players[player].TotalRazings;
182 } else if (!strcmp(prop, "TotalKills")) {
183 return Players[player].TotalKills;
184 } else {
185 fprintf(stderr, "Invalid field: %s" _C_ prop);
186 Exit(1);
187 }
188 return 0;
189 }
190
191 /**
192 ** Sets the player data.
193 */
SetPlayerData(const int player,const char * prop,const char * arg,int value)194 static void SetPlayerData(const int player, const char *prop, const char *arg, int value)
195 {
196 if (!strcmp(prop, "RaceName")) {
197 //Wyrmgus start
198 // Players[player].Race = value;
199 Players[player].SetCivilization(value);
200 //Wyrmgus end
201 } else if (!strcmp(prop, "Resources")) {
202 const int resId = GetResourceIdByName(arg);
203 if (resId == -1) {
204 fprintf(stderr, "Invalid resource \"%s\"", arg);
205 Exit(1);
206 }
207 Players[player].SetResource(resId, value, STORE_BOTH);
208 } else if (!strcmp(prop, "StoredResources")) {
209 const int resId = GetResourceIdByName(arg);
210 if (resId == -1) {
211 fprintf(stderr, "Invalid resource \"%s\"", arg);
212 Exit(1);
213 }
214 Players[player].SetResource(resId, value, STORE_BUILDING);
215 } else if (!strcmp(prop, "UnitLimit")) {
216 Players[player].UnitLimit = value;
217 } else if (!strcmp(prop, "BuildingLimit")) {
218 Players[player].BuildingLimit = value;
219 } else if (!strcmp(prop, "TotalUnitLimit")) {
220 Players[player].TotalUnitLimit = value;
221 } else if (!strcmp(prop, "Score")) {
222 Players[player].Score = value;
223 } else if (!strcmp(prop, "TotalUnits")) {
224 Players[player].TotalUnits = value;
225 } else if (!strcmp(prop, "TotalBuildings")) {
226 Players[player].TotalBuildings = value;
227 } else if (!strcmp(prop, "TotalResources")) {
228 const int resId = GetResourceIdByName(arg);
229 if (resId == -1) {
230 fprintf(stderr, "Invalid resource \"%s\"", arg);
231 Exit(1);
232 }
233 Players[player].TotalResources[resId] = value;
234 } else if (!strcmp(prop, "TotalRazings")) {
235 Players[player].TotalRazings = value;
236 } else if (!strcmp(prop, "TotalKills")) {
237 Players[player].TotalKills = value;
238 } else {
239 fprintf(stderr, "Invalid field: %s" _C_ prop);
240 Exit(1);
241 }
242 }
243
244
Action(CUnit & unit,int &,int) const245 /* virtual */ void CAnimation_SetPlayerVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
246 {
247 Assert(unit.Anim.Anim == this);
248
249 const char *var = this->varStr.c_str();
250 const char *arg = this->argStr.c_str();
251 const int playerId = ParseAnimInt(unit, this->playerStr.c_str());
252 int rop = ParseAnimInt(unit, this->valueStr.c_str());
253 int data = GetPlayerData(playerId, var, arg);
254
255 switch (this->mod) {
256 case modAdd:
257 data += rop;
258 break;
259 case modSub:
260 data -= rop;
261 break;
262 case modMul:
263 data *= rop;
264 break;
265 case modDiv:
266 if (!rop) {
267 fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n");
268 Exit(1);
269 }
270 data /= rop;
271 break;
272 case modMod:
273 if (!rop) {
274 fprintf(stderr, "Division by zero in AnimationSetPlayerVar\n");
275 Exit(1);
276 }
277 data %= rop;
278 break;
279 case modAnd:
280 data &= rop;
281 break;
282 case modOr:
283 data |= rop;
284 break;
285 case modXor:
286 data ^= rop;
287 break;
288 case modNot:
289 data = !data;
290 break;
291 default:
292 data = rop;
293 }
294 rop = data;
295 SetPlayerData(playerId, var, arg, rop);
296 }
297
298 /*
299 ** s = "player var mod value [arg2]"
300 */
Init(const char * s,lua_State *)301 /* virtual */ void CAnimation_SetPlayerVar::Init(const char *s, lua_State *)
302 {
303 const std::string str(s);
304 const size_t len = str.size();
305
306 size_t begin = 0;
307 size_t end = str.find(' ', begin);
308 this->playerStr.assign(str, begin, end - begin);
309
310 begin = std::min(len, str.find_first_not_of(' ', end));
311 end = std::min(len, str.find(' ', begin));
312 this->varStr.assign(str, begin, end - begin);
313
314 begin = std::min(len, str.find_first_not_of(' ', end));
315 end = std::min(len, str.find(' ', begin));
316 const std::string modStr(str, begin, end - begin);
317 if (modStr == "=") {
318 this->mod = modSet;
319 } else if (modStr == "+=") {
320 this->mod = modAdd;
321 } else if (modStr == "-=") {
322 this->mod = modSub;
323 } else if (modStr == "*=") {
324 this->mod = modMul;
325 } else if (modStr == "/=") {
326 this->mod = modDiv;
327 } else if (modStr == "%=") {
328 this->mod = modMod;
329 } else if (modStr == "&=") {
330 this->mod = modAnd;
331 } else if (modStr == "|=") {
332 this->mod = modOr;
333 } else if (modStr == "^=") {
334 this->mod = modXor;
335 } else if (modStr == "!") {
336 this->mod = modNot;
337 } else {
338 this->mod = (SetVar_ModifyTypes)(atoi(modStr.c_str()));
339 }
340
341 begin = std::min(len, str.find_first_not_of(' ', end));
342 end = std::min(len, str.find(' ', begin));
343 this->valueStr.assign(str, begin, end - begin);
344
345 begin = std::min(len, str.find_first_not_of(' ', end));
346 end = std::min(len, str.find(' ', begin));
347 this->argStr.assign(str, begin, end - begin);
348 }
349
350 //@}
351