Introduced FileSystem and Out classes
[openstranded.git] / src / defparse / defaction.cc
blob3e6614ddc6a06fca9592bcbbecd34e785f99e675
1 /*
2 * This file implements general functions and classes
3 * from the defaction.hh header
5 * Copyright (C) 2008 Hermann Walth
7 * This file is part of OpenStranded
9 * OpenStranded is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * OpenStranded is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with OpenStranded. If not, see <http://www.gnu.org/licenses/>.
23 #include <iostream>
24 #include <string>
25 #include <sstream>
26 #include <cstring>
27 #include "../filesystem.hh"
28 #include "../output.hh"
29 #include "../s2string.hh"
30 #include "../kingdom.hh"
31 #include "../error.hh"
32 #include "defaction.hh"
34 ID currentType = 0;
37 * Action List methods
40 def::ActionList::ActionList ():
41 std::map <std::string, def::Action*> () {}
44 // Destructor, deletes all list's elements
45 def::ActionList::~ActionList ()
47 std::map <std::string, def::Action*>::iterator iter;
48 for (iter = this->begin (); iter != this->end (); iter++)
49 delete (iter->second);
52 // Wrapper operator[] method for const char* strings
53 def::Action*&
54 def::ActionList::listItem (const char* index)
56 return (*this) [std::string (index)];
57 //return (this->find (std::string (index)))->second;
62 * Action classes method definitions
65 def::Action::Action (ID kingdom)
67 this->kingdomID = kingdom;
68 this->lastType = 0;
72 def::IDAction::IDAction (ID kingdom):
73 Action (kingdom) {}
75 def::NameAction::NameAction (ID kingdom):
76 Action (kingdom) {}
78 def::ModelAction::ModelAction (ID kingdom):
79 Action (kingdom) {}
81 def::IconAction::IconAction (ID kingdom):
82 Action (kingdom) {}
84 def::XAction::XAction (ID kingdom):
85 Action (kingdom) {}
87 def::YAction::YAction (ID kingdom):
88 Action (kingdom) {}
90 def::ZAction::ZAction (ID kingdom):
91 Action (kingdom) {}
93 def::ScaleAction::ScaleAction (ID kingdom):
94 Action (kingdom) {}
96 def::RAction::RAction (ID kingdom):
97 Action (kingdom) {}
99 def::GAction::GAction (ID kingdom):
100 Action (kingdom) {}
102 def::BAction::BAction (ID kingdom):
103 Action (kingdom) {}
105 def::ColorAction::ColorAction (ID kingdom):
106 Action (kingdom) {}
108 def::AutofadeAction::AutofadeAction (ID kingdom):
109 Action (kingdom) {}
111 def::AlphaAction::AlphaAction (ID kingdom):
112 Action (kingdom) {}
114 def::ShineAction::ShineAction (ID kingdom):
115 Action (kingdom) {}
119 void
120 def::IDAction::operator() (std::string rtext)
122 ID newID;
123 std::istringstream (rtext, std::ios::in) >> newID;
125 currentType = newID;
127 if (Kingdom::kingdomList.find (kingdomID) != Kingdom::kingdomList.end ())
129 if (!Kingdom::kingdomList[kingdomID]->typeExists(newID))
130 Kingdom::kingdomList[kingdomID]->insertType (newID);
131 else
133 Out::fatal << "Type #" << newID << " has already been declared!" << Out::endl;
136 else
138 Out::fatal << "Kingdom does not exist!" << Out::endl;
144 void
145 def::NameAction::operator() (std::string rtext)
147 if (currentType == 0)
149 Out::warning << "No type ID specified, assignment of value \"name\" not possible" << Out::endl;
150 return;
153 if (this->lastType != currentType)
154 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setName (rtext);
155 else
156 Out::warning << "Double assignment of value \"name\" in object type #" << currentType << Out::endl;
161 void
162 def::ModelAction::operator() (std::string rtext)
164 if (currentType == 0)
166 Out::warning << "No type ID specified, assignment of value \"model\" not possible" << Out::endl;
167 return;
170 // Spot legacy file paths, transform and give a deprecation warning
171 // Since Stranded II had all files given relative to the mod directory,
172 // we use the "gfx\" piece to spot legacy file paths
173 std::string::size_type pos;
174 if((pos = rtext.find("gfx\\")) != std::string::npos)
176 Out::warning << "Deprecated model file path format in type # " << currentType << Out::endl;
178 // Remove old directory part
179 rtext = rtext.substr(pos+4);
181 // Remove file extension
182 pos = rtext.find_last_of('.');
183 rtext = rtext.substr(0, pos);
186 // Remove backslashes
187 for (unsigned int i = 0; i < rtext.size(); i++)
188 if (rtext[i] == '\\') rtext[i] = '/';
190 if (this->lastType != currentType)
192 FileInfo *modelInfo = FileSystem::getModelFileInfo(rtext);
193 Kingdom::kingdomList[kingdomID]->getType (currentType)->setModel (modelInfo->path);
194 delete modelInfo;
196 else
198 Out::warning << "Double assignment of value \"model\" in type #" << currentType << Out::endl;
205 void
206 def::IconAction::operator() (std::string rtext)
208 if (currentType == 0)
209 Out::warning << "No type ID specified, assignment of value \"icon\" not possible" << Out::endl;
211 if (this->lastType != currentType)
212 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setIconPath (rtext);
213 else
214 Out::warning << "Double assignment of value \"icon\" in type #" << currentType << Out::endl;
219 void
220 def::XAction::operator() (std::string rtext)
222 float newScaleX;
223 std::istringstream (rtext) >> newScaleX;
225 if (currentType == 0)
227 Out::warning << "No type ID specified, assignment of value \"x\" not possible" << Out::endl;
228 return;
231 if (newScaleX <= 0)
233 Out::warning << "Invalid value \"x\"; fallback to 1.0 in type #" << currentType << Out::endl;
234 newScaleX = 1.0;
237 if (this->lastType != currentType)
238 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleX (newScaleX);
239 else
240 Out::warning << "Double assignment of value \"x\" in type #" << currentType << Out::endl;
245 void
246 def::YAction::operator() (std::string rtext)
248 float newScaleY;
249 std::istringstream (rtext) >> newScaleY;
251 if (currentType == 0)
253 Out::warning << "No type ID specified, assignment of value \"y\" not possible" << Out::endl;
254 return;
257 if (newScaleY <= 0)
259 Out::warning << "Invalid value \"y\"; fallback to 1.0 in type #" << currentType << Out::endl;
260 newScaleY = 1.0;
263 if (this->lastType != currentType)
264 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleY (newScaleY);
265 else
266 Out::warning << "Double assignment of value \"y\" in Object type #" << currentType << Out::endl;
271 void
272 def::ZAction::operator() (std::string rtext)
274 float newScaleZ;
275 std::istringstream (rtext) >> newScaleZ;
277 if (currentType == 0)
279 Out::warning << "No type ID specified, assignment of value \"z\" not possible" << Out::endl;
280 return;
283 if (newScaleZ <= 0)
285 Out::warning << "Invalid value \"z\"; fallback to 1.0 in type #" << currentType << Out::endl;
286 newScaleZ = 1.0;
289 if (this->lastType != currentType)
290 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleZ (newScaleZ);
291 else
292 Out::warning << "Double assignment of value \"z\" in type #" << currentType << Out::endl;
297 void
298 def::ScaleAction::operator() (std::string rtext)
300 std::string scaleValues[3];
301 int warnFlag;
302 float endValue;
305 if (currentType == 0)
307 Out::warning << "No type ID specified, assignment of value \"scale\" not possible" << Out::endl;
308 return;
311 warnFlag = s2str::explode (rtext, scaleValues, ",", 3);
313 // Display error message when number of arguments wasn't either 1 or 3
314 if (warnFlag != EXPLODE_OK && !inFlag (warnFlag, EXPLODE_NO_TOKEN))
316 Out::warning << "Warning: Wrong number of arguments for value \"scale\"" << Out::endl;
320 if (this->lastType != currentType)
322 // Catch special case when only one value was given and needs to be applied
323 // to all x, y and z
324 if (inFlag (warnFlag, EXPLODE_NO_TOKEN))
326 if (!s2str::stof (scaleValues[0], endValue))
328 Out::warning << "Invalid value in \"scale\"; fallback to 1.0 in type #" << currentType << Out::endl;
329 endValue = 1.0;
331 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleX (endValue);
332 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleY (endValue);
333 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleZ (endValue);
334 return;
337 // scaleX
338 if (!s2str::stof (scaleValues[0], endValue))
340 Out::warning << "Invalid x value in \"scale\"; fallback to 1.0 in type #" << currentType << Out::endl;
341 endValue = 1.0;
343 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleX (endValue);
346 // scaleY
347 if (!s2str::stof (scaleValues[1], endValue))
349 Out::warning << "Invalid y value in \"scale\"; fallback to 1.0 in type #" << currentType << Out::endl;
350 endValue = 1.0;
352 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleY (endValue);
356 // scaleZ
357 if (!s2str::stof (scaleValues[2], endValue))
359 Out::warning << "Invalid z value in \"scale\"; fallback to 1.0 in type #" << currentType << Out::endl;
360 endValue = 1.0;
362 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setScaleZ (endValue);
364 else
366 Out::warning << "Double assignment of value \"scale\" in type #" << currentType << Out::endl;
372 void
373 def::RAction::operator() (std::string rtext)
375 int newColorR;
376 bool strValid;
378 if (currentType == 0)
380 Out::warning << "No type ID specified, assignment of value \"r\" not possible" << Out::endl;
381 return;
384 strValid = s2str::stoi (rtext, newColorR);
385 if (!strValid || newColorR < 0 || newColorR > 255)
387 Out::warning << "Invalid argument for \"r\" value in type #" << currentType << ", fallback to 0" << Out::endl;
388 newColorR = 0;
391 if (this->lastType != currentType)
392 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorR ( (uint8_t) newColorR);
393 else
394 Out::warning << "Double assignment of value \"r\" in type #" << currentType << Out::endl;
399 void
400 def::GAction::operator() (std::string rtext)
402 int newColorG;
403 bool strValid;
405 if (currentType == 0)
407 Out::warning << "No type ID specified, assignment of value \"g\" not possible" << Out::endl;
408 return;
411 strValid = s2str::stoi (rtext, newColorG);
412 if (!strValid || newColorG < 0 || newColorG > 255)
414 Out::warning << "Invalid argument for \"g\" value in type #" << currentType << ", fallback to 0" << Out::endl;
415 newColorG = 0;
418 if (this->lastType != currentType)
419 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorG ( (uint8_t) newColorG);
420 else
421 Out::warning << "Double assignment of value \"g\" in type #" << currentType << Out::endl;
426 void
427 def::BAction::operator() (std::string rtext)
429 int newColorB;
430 bool strValid;
432 if (currentType == 0)
434 Out::warning << "No type ID specified, assignment of value \"b\" not possible" << Out::endl;
435 return;
438 strValid = s2str::stoi (rtext, newColorB);
439 if (!strValid || newColorB < 0 || newColorB > 255)
441 Out::warning << "Invalid argument for \"b\" value in type #" << currentType << ", fallback to 0" << Out::endl;
442 newColorB = 0;
445 if (this->lastType != currentType)
446 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorB ( (uint8_t) newColorB);
447 else
448 Out::warning << "Double assignment of value \"b\" in type #" << currentType << Out::endl;
453 void
454 def::ColorAction::operator() (std::string rtext)
456 std::string colorValues[3];
457 int endValue;
458 int warnFlag;
459 bool strValid;
461 if (currentType == 0)
463 Out::warning << "No type ID specified, assignment of value \"color\" not possible" << Out::endl;
464 return;
467 warnFlag = s2str::explode (rtext, colorValues, ",", 3);
469 // Display error message when number of arguments wasn't either 1 or 3
470 if (warnFlag != EXPLODE_OK && !inFlag (warnFlag, EXPLODE_NO_TOKEN))
472 Out::warning << "Warning: Wrong number of arguments for value \"color\"" << Out::endl;
475 if (this->lastType != currentType)
477 // Catch special case when only one value was given and needs to be applied
478 // to all r, g and b
479 if (inFlag (warnFlag, EXPLODE_NO_TOKEN))
481 strValid = s2str::stoi (colorValues[0], endValue);
482 if (!strValid || endValue < 0 || endValue > 255)
484 Out::warning << "Invalid value in \"color\"; fallback to 0.0 in type #" << currentType << Out::endl;
485 endValue = 0;
487 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorR (endValue);
488 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorG (endValue);
489 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorB (endValue);
490 return;
493 // R
494 strValid = s2str::stoi (colorValues[0], endValue);
495 if (!strValid || endValue < 0 || endValue > 255)
497 Out::warning << "Invalid argument for \"r\" value in \"color\" in type #" << currentType << ", fallback to 0" << Out::endl;
498 endValue = 0;
501 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorR ( (uint8_t) endValue);
504 // G
505 strValid = s2str::stoi (colorValues[1], endValue);
506 if (!strValid || endValue < 0 || endValue > 255)
508 Out::warning << "Invalid argument for \"g\" value in \"color\" in type #" << currentType << ", fallback to 0" << Out::endl;
509 endValue = 0;
512 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorG ( (uint8_t) endValue);
515 // B
516 strValid = s2str::stoi (colorValues[2], endValue);
517 if (!strValid || endValue > 255)
519 Out::warning << "Invalid argument for \"b\" value in \"color\" in type #" << currentType << ", fallback to 0" << Out::endl;
520 endValue = 0;
523 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setColorB ( (uint8_t) endValue);
526 else
528 Out::warning << "Double assignment of value \"color\" in type #" << currentType << Out::endl;
534 void
535 def::AutofadeAction::operator() (std::string rtext)
537 float endValue;
539 if (currentType == 0)
541 Out::warning << "No type id specified, assignment of value \"autofade\" not possible" << Out::endl;
542 return;
545 if (this->lastType != currentType)
547 if (!s2str::stof (rtext, endValue))
549 Out::warning << "Invalid argument for value \"autofade\" in type #" << currentType << ", fallback to 500" << Out::endl;
550 endValue = 500.0;
553 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setFadingDistance (endValue);
555 else
557 Out::warning << "Double assignment of value \"autofade\" in type #" << currentType << Out::endl;
563 void
564 def::AlphaAction::operator() (std::string rtext)
566 float endValue;
568 if (currentType == 0)
570 Out::warning << "No type id specified, assignment of value \"alpha\" not possible" << Out::endl;
571 return;
574 if (this->lastType != currentType)
576 if (!s2str::stof (rtext, endValue) || endValue < 0.0 || endValue > 1.0)
578 Out::warning << "Invalid argument for value \"alpha\" in type #" << currentType << ", fallback to 1.0" << Out::endl;
579 endValue = 1.0;
582 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setAlpha (endValue);
584 else
586 Out::warning << "Double assignment of value \"alpha\" in type #" << currentType << Out::endl;
592 void
593 def::ShineAction::operator() (std::string rtext)
595 float endValue;
597 if (currentType == 0)
599 Out::warning << "No type id specified, assignment of value \"shine\" not possible" << Out::endl;
600 return;
603 if (this->lastType != currentType)
605 if (!s2str::stof (rtext, endValue) || endValue < 0.0 || endValue > 1.0)
607 Out::warning << "Invalid argument for value \"shine\" in type #" << currentType << ", fallback to 0.0" << Out::endl;
608 endValue = 0.0;
611 Kingdom::kingdomList[kingdomID]->getType (currentType) ->setShine (endValue);
613 else
615 Out::warning << "Double assignment of value \"shine\" in type #" << currentType << Out::endl;