ManaPlus
skilldialog.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2019 The ManaPlus Developers
6  * Copyright (C) 2019-2021 Andrei Karas
7  *
8  * This file is part of The ManaPlus Client.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  */
23 
25 
26 #include "configuration.h"
27 #include "effectmanager.h"
28 #include "spellmanager.h"
29 
30 #include "being/localplayer.h"
31 #include "being/playerinfo.h"
32 
34 
36 
38 
41 
42 #include "gui/widgets/button.h"
44 #include "gui/widgets/label.h"
45 #include "gui/widgets/scrollarea.h"
46 #include "gui/widgets/tabbedarea.h"
47 
49 
50 #include "gui/windows/textdialog.h"
51 
53 
54 #include "net/playerhandler.h"
55 #include "net/skillhandler.h"
56 
57 #include "utils/checkutils.h"
58 #include "utils/dtor.h"
59 #include "utils/gettext.h"
60 #include "utils/timer.h"
61 
62 #include "resources/beingcommon.h"
63 
64 #include "debug.h"
65 
67 
68 namespace
69 {
71 } // namespace
72 
73 static SkillOwner::Type parseOwner(const std::string &str)
74 {
75  if (str == "player")
76  return SkillOwner::Player;
77  else if (str == "mercenary")
78  return SkillOwner::Mercenary;
79  else if (str == "homunculus")
81  return SkillOwner::Player;
82 }
83 
85  // TRANSLATORS: skills dialog name
86  Window(_("Skills"), Modal_false, nullptr, "skills.xml"),
88  mSkills(),
89  mDurations(),
90  mTabs(CREATEWIDGETR(TabbedArea, this)),
91  mDeleteTabs(),
92  mPointsLabel(new Label(this, "0")),
93  // TRANSLATORS: skills dialog button
94  mUseButton(new Button(this, _("Use"), "use", BUTTON_SKIN, this)),
95  // TRANSLATORS: skills dialog button
96  mIncreaseButton(new Button(this, _("Up"), "inc", BUTTON_SKIN, this)),
97  mDefaultModel(nullptr),
98  mDefaultTab(nullptr)
99 {
100  setWindowName("Skills");
101  setCloseButton(true);
102  setResizable(true);
103  setSaveVisible(true);
104  setStickyButtonLock(true);
105  setDefaultSize(windowContainer->getWidth() - 280, 30, 275, 425);
106  if (setupWindow != nullptr)
108 
109  mUseButton->setEnabled(false);
110  mIncreaseButton->setEnabled(false);
111  mTabs->setSelectable(false);
114 
115  place(0, 0, mTabs, 5, 5);
116  place(0, 5, mPointsLabel, 4, 1);
117  place(3, 5, mUseButton, 1, 1);
118  place(4, 5, mIncreaseButton, 1, 1);
119 }
120 
122 {
125  loadWindowState();
126  enableVisibleSound(true);
127 }
128 
130 {
131  clearSkills();
132 }
133 
135 {
137  SkillListBox *const listbox = new SkillListBox(this,
138  mDefaultModel);
139  listbox->setActionEventId("sel");
140  listbox->addActionListener(this);
141  ScrollArea *const scroll = new ScrollArea(this,
142  listbox,
143  Opaque_false,
144  std::string());
147  // TRANSLATORS: unknown skills tab name
148  mDefaultTab = new SkillTab(this, _("Unknown"), listbox);
149  mDeleteTabs.push_back(mDefaultTab);
151  mTabs->addTab(mDefaultTab, scroll);
154 }
155 
157 {
158  const std::string &eventId = event.getId();
159  if (eventId == "inc")
160  {
161  if (playerHandler == nullptr)
162  return;
163  const SkillTab *const tab = static_cast<const SkillTab *>(
164  mTabs->getSelectedTab());
165  if (tab != nullptr)
166  {
167  if (const SkillInfo *const info = tab->getSelectedInfo())
169  }
170  }
171  else if (eventId == "sel")
172  {
173  const SkillTab *const tab = static_cast<const SkillTab *>(
174  mTabs->getSelectedTab());
175  if (tab != nullptr)
176  {
177  if (const SkillInfo *const info = tab->getSelectedInfo())
178  {
179  mUseButton->setEnabled(info->isUsable());
180  mUseButton->setCaption(info->useButton);
182  const int num = itemShortcutWindow->getTabIndex();
183  if (num >= 0 && num < CAST_S32(SHORTCUT_TABS)
184  && (itemShortcut[num] != nullptr))
185  {
187  info->id + SKILL_MIN_ID);
188  }
189  }
190  else
191  {
192  mUseButton->setEnabled(false);
193  mIncreaseButton->setEnabled(false);
194  // TRANSLATORS: skills dialog button
195  mUseButton->setCaption(_("Use"));
196  }
197  }
198  }
199  else if (eventId == "use")
200  {
201  const SkillTab *const tab = static_cast<const SkillTab *>(
202  mTabs->getSelectedTab());
203  if (tab != nullptr)
204  {
205  const SkillInfo *const info = tab->getSelectedInfo();
206  if (info == nullptr)
207  return;
208  useSkill(info,
209  fromBool(config.getBoolValue("skillAutotarget"), AutoTarget),
210  info->customSelectedLevel,
211  info->useTextParameter,
212  std::string(),
213  info->customCastType,
214  info->customOffsetX,
215  info->customOffsetY);
216  }
217  }
218  else if (eventId == "close")
219  {
221  }
222 }
223 
224 std::string SkillDialog::update(const int id)
225 {
226  const SkillMap::const_iterator i = mSkills.find(id);
227 
228  if (i != mSkills.end())
229  {
230  SkillInfo *const info = i->second;
231  if (info != nullptr)
232  {
233  info->update();
234  return info->data->name;
235  }
236  }
237 
238  return std::string();
239 }
240 
242 {
243  // TRANSLATORS: skills dialog label
244  mPointsLabel->setCaption(strprintf(_("Skill points available: %d"),
247 
248  ItemShortcut *const shortcuts = itemShortcut[SHORTCUT_AUTO_TAB];
249  shortcuts->clear();
250  size_t idx = 0;
251 
252  FOR_EACH (SkillMap::const_iterator, it, mSkills)
253  {
254  SkillInfo *const info = (*it).second;
255  if (info == nullptr)
256  continue;
257  if (info->modifiable == Modifiable_true)
258  info->update();
259  if (info->visible == Visible_false ||
260  idx >= SHORTCUT_ITEMS ||
261  !info->data->autoTab)
262  {
263  continue;
264  }
265  const SkillType::SkillType type = info->type;
266  if (type == SkillType::Attack ||
267  type == SkillType::Ground ||
268  type == SkillType::Self ||
269  type == SkillType::Support)
270  {
271  shortcuts->setItemFast(idx,
272  info->id + SKILL_MIN_ID,
273  fromInt(info->customSelectedLevel, ItemColor));
274 
275  shortcuts->setItemData(idx,
276  info->toDataStr());
277  idx ++;
278  }
279  }
280 
281  skillPopup->reset();
282 }
283 
285 {
286  std::set<SkillModel*> models;
287 
288  FOR_EACH (SkillMap::const_iterator, it, mSkills)
289  {
290  SkillInfo *const info = (*it).second;
291  if (info != nullptr)
292  {
293  SkillModel *const model = info->model;
294  if (model != nullptr)
295  models.insert(model);
296  }
297  }
298  FOR_EACH (std::set<SkillModel*>::iterator, it, models)
299  {
300  SkillModel *const model = *it;
301  if (model != nullptr)
302  model->updateVisibilities();
303  }
304 }
305 
307 {
308  std::set<SkillModel*> models;
309 
310  FOR_EACH (SkillMap::const_iterator, it, mSkills)
311  {
312  SkillInfo *const info = (*it).second;
313  if (info != nullptr)
314  {
315  if (info->visible == Visible_false)
316  {
317  SkillModel *const model = info->model;
318  if (model != nullptr)
319  models.insert(model);
320  }
321  }
322  }
323  FOR_EACH (std::set<SkillModel*>::iterator, it, models)
324  {
325  SkillModel *const model = *it;
326  if (model != nullptr)
327  model->updateVisibilities();
328  }
329 }
330 
332 {
333  mTabs->removeAll(true);
334  mDeleteTabs.clear();
335  mDefaultTab = nullptr;
336  mDefaultModel = nullptr;
337 
339  mSkills.clear();
340  mDurations.clear();
341 }
342 
344 {
345  FOR_EACH (SkillMap::iterator, it, mSkills)
346  {
347  SkillInfo *const info = (*it).second;
348  if ((info != nullptr) && info->owner == owner)
349  {
351  if (info->alwaysVisible == Visible_false)
352  info->visible = Visible_false;
353  }
354  }
355 }
356 
358 {
359  clearSkills();
361  if (mSkills.empty())
363  loadXmlFile(paths.getStringValue("skillsPatchFile"), SkipError_true);
364  loadXmlDir("skillsPatchDir", loadXmlFile)
365  addDefaultTab();
366 
367  update();
368 }
369 
370 void SkillDialog::loadXmlFile(const std::string &fileName,
371  const SkipError skipError)
372 {
375  skipError);
376  XmlNodePtrConst root = doc.rootNode();
377 
378  int setCount = 0;
379 
380  if ((root == nullptr) || !xmlNameEqual(root, "skills"))
381  {
382  logger->log("Error loading skills: " + fileName);
383  return;
384  }
385 
386  for_each_xml_child_node(set, root)
387  {
388  if (xmlNameEqual(set, "include"))
389  {
390  const std::string name = XML::getProperty(set, "name", "");
391  if (!name.empty())
392  loadXmlFile(name, skipError);
393  continue;
394  }
395  else if (xmlNameEqual(set, "set"))
396  {
397  setCount++;
398  const std::string setName = XML::getProperty(set, "name",
399  // TRANSLATORS: skills dialog default skill tab
400  strprintf(_("Skill Set %d"), setCount));
401 
402  const std::string setTypeStr = XML::getProperty(set, "type", "");
404  if (setTypeStr.empty() ||
405  setTypeStr == "list" ||
406  setTypeStr == "vertical")
407  {
408  setType = SkillSetType::VerticalList;
409  }
410  else if (setTypeStr == "rectangle")
411  {
412  setType = SkillSetType::Rectangle;
413  }
414 
415  bool alwaysVisible = false;
416  SkillModel *const model = new SkillModel;
417  SkillTab *tab = nullptr;
418  ScrollArea *scroll = nullptr;
419 
420  switch (setType)
421  {
423  {
424  // possible leak listbox, scroll
425  SkillListBox *const listbox = new SkillListBox(this,
426  model);
427  listbox->setActionEventId("sel");
428  listbox->addActionListener(this);
429  scroll = new ScrollArea(this,
430  listbox,
431  Opaque_false,
432  std::string());
435  tab = new SkillTab(this, setName, listbox);
436  break;
437  }
439  {
440  SkillRectangleListBox *const listbox =
441  new SkillRectangleListBox(this,
442  model);
443  listbox->setActionEventId("sel");
444  listbox->addActionListener(this);
445  scroll = new ScrollArea(this,
446  listbox,
447  Opaque_false,
448  std::string());
451  tab = new SkillTab(this, setName, listbox);
452  break;
453  }
454  default:
455  reportAlways("Unsupported skillset type: %s",
456  setTypeStr.c_str())
457  return;
458  }
459  if (mDefaultModel == nullptr)
460  {
461  mDefaultModel = model;
462  mDefaultTab = tab;
463  }
464 
465  mDeleteTabs.push_back(tab);
466  if (alwaysVisible == true)
467  tab->setVisible(Visible_true);
468  else
470  mTabs->addTab(tab, scroll);
471 
472  for_each_xml_child_node(node, set)
473  {
474  if (xmlNameEqual(node, "skill"))
475  {
476  SkillInfo *const skill = loadSkill(node, model);
477  if (skill == nullptr)
478  continue;
479  if (skill->alwaysVisible == Visible_true)
480  alwaysVisible = true;
481  skill->tab = tab;
482  for_each_xml_child_node(levelNode, node)
483  {
484  if (!xmlNameEqual(levelNode, "level"))
485  continue;
486  loadSkillData(node, skill);
487  }
488  }
489  }
490 
491  model->updateVisibilities();
492  }
493  }
494 }
495 
496 SkillInfo *SkillDialog::loadSkill(XmlNodeConstPtr node,
497  SkillModel *const model)
498 {
499  int id = XML::getIntProperty(node, "id", -1, -1, 1000000);
500  if (id == -1)
501  {
502  id = XML::getIntProperty(node, "var", -1, -1, 100000);
503  if (id == -1)
504  return nullptr;
505  id += SKILL_VAR_MIN_ID;
506  }
507 
508  SkillInfo *skill = getSkill(id);
509  if (skill == nullptr)
510  {
511  std::string name = XML::langProperty(node, "name",
512  // TRANSLATORS: skills dialog. skill id
513  strprintf(_("Skill %d"), id));
514 
515  skill = new SkillInfo;
516  skill->id = CAST_U32(id);
517  skill->modifiable = Modifiable_false;
518  skill->model = model;
519  skill->update();
520  skill->useButton = XML::getProperty(
521  // TRANSLATORS: skills dialog button
522  node, "useButton", _("Use"));
524  node, "owner", "player"));
525  skill->errorText = XML::getProperty(
526  node, "errorText", name);
527  skill->alwaysVisible = fromBool(XML::getBoolProperty(
528  node, "alwaysVisible", false), Visible);
529  skill->castingAction = XML::getProperty(node,
530  "castingAction", SpriteAction::CAST);
531  skill->castingRideAction = XML::getProperty(node,
532  "castingRideAction", SpriteAction::CASTRIDE);
533  skill->castingSkyAction = XML::getProperty(node,
534  "castingSkyAction", SpriteAction::CASTSKY);
535  skill->castingWaterAction = XML::getProperty(node,
536  "castingWaterAction", SpriteAction::CASTWATER);
537  skill->useTextParameter = XML::getBoolProperty(
538  node, "useTextParameter", false);
539  skill->x = XML::getProperty(node,
540  "x", 0);
541  skill->y = XML::getProperty(node,
542  "y", 0);
543  skill->visible = skill->alwaysVisible;
544  model->addSkill(skill);
545  mSkills[id] = skill;
546  }
547 
548  loadSkillData(node, skill);
549  return skill;
550 }
551 
552 void SkillDialog::loadSkillData(XmlNodeConstPtr node,
553  SkillInfo *const skill)
554 {
555  if (skill == nullptr)
556  return;
557  const int level = (skill->alwaysVisible == Visible_true) ?
558  0 : XML::getProperty(node, "level", 0);
559  SkillData *data = skill->getData(level);
560  if (data == nullptr)
561  data = new SkillData;
562 
563  const std::string name = XML::langProperty(node, "name",
564  // TRANSLATORS: skills dialog. skill id
565  strprintf(_("Skill %u"), skill->id));
566  data->name = name;
567  const std::string icon = XML::getProperty(node, "icon", "");
568  if (icon.empty())
569  {
570  data->setIcon(paths.getStringValue("missingSkillIcon"));
571  data->haveIcon = false;
572  }
573  else
574  {
575  data->setIcon(icon);
576  data->haveIcon = true;
577  }
578  if (skill->id < SKILL_VAR_MIN_ID)
579  {
580  data->dispName = strprintf("%s, %u",
581  name.c_str(),
582  skill->id);
583  }
584  else
585  {
586  data->dispName = strprintf("%s, (%u)",
587  name.c_str(),
588  skill->id - SKILL_VAR_MIN_ID);
589  }
590  data->shortName = XML::langProperty(node,
591  "shortName", name.substr(0, 3));
592  data->description = XML::langProperty(
593  node, "description", "");
594 
595  MissileInfo &missile = data->missile;
596  missile.particle = XML::getProperty(
597  node, "missile-particle", "");
598  missile.z = XML::getFloatProperty(
599  node, "missile-z", 32.0F);
600  missile.lifeTime = XML::getProperty(
601  node, "missile-lifetime", 500);
602  missile.speed = XML::getFloatProperty(
603  node, "missile-speed", 7.0F);
605  node, "missile-diedistance", 8.0F);
606 
607  MissileInfo &castingMissile = data->castingMissile;
608  castingMissile.particle = XML::getProperty(
609  node, "castingMissile-particle", "");
610  castingMissile.z = XML::getFloatProperty(
611  node, "castingMissile-z", 32.0F);
612  castingMissile.lifeTime = XML::getProperty(
613  node, "castingMissile-lifetime", 500);
614  castingMissile.speed = XML::getFloatProperty(
615  node, "castingMissile-speed", 7.0F);
616  castingMissile.dieDistance = XML::getFloatProperty(
617  node, "castingMissile-diedistance", 8.0F);
618 
619  data->castingAnimation = XML::getProperty(
620  node,
621  "castingAnimation",
622  paths.getStringValue("skillCastingAnimation"));
623 
624  data->soundHit.sound = XML::getProperty(
625  node, "soundHit", "");
626  data->soundHit.delay = XML::getProperty(
627  node, "soundHitDelay", 0);
628  data->soundMiss.sound = XML::getProperty(
629  node, "soundMiss", "");
630  data->soundMiss.delay = XML::getProperty(
631  node, "soundMissDelay", 0);
632  data->invokeCmd = XML::getProperty(
633  node, "invokeCmd", "");
634  data->updateEffectId = XML::getProperty(
635  node, "levelUpEffectId", -1);
636  data->removeEffectId = XML::getProperty(
637  node, "removeEffectId", -1);
638  data->hitEffectId = XML::getProperty(
639  node, "hitEffectId", -1);
640  data->missEffectId = XML::getProperty(
641  node, "missEffectId", -1);
642  data->castingSrcEffectId = XML::getProperty(
643  node, "castingSrcEffectId", -1);
644  data->castingDstEffectId = XML::getProperty(
645  node, "castingDstEffectId", -1);
646  data->srcEffectId = XML::getProperty(
647  node, "srcEffectId", -1);
648  data->dstEffectId = XML::getProperty(
649  node, "dstEffectId", -1);
650  data->castingGroundEffectId = XML::getProperty(
651  node, "castingGroundEffectId", -1);
652  data->autoTab = XML::getBoolProperty(
653  node, "autoTab", true);
654 
655  skill->addData(level, data);
656 }
657 
658 void SkillDialog::removeSkill(const int id)
659 {
660  const SkillMap::const_iterator it = mSkills.find(id);
661 
662  if (it != mSkills.end())
663  {
664  SkillInfo *const info = it->second;
665  if (info != nullptr)
666  {
667  info->level = 0;
668  info->update();
670  if (info->alwaysVisible == Visible_false)
671  info->visible = Visible_false;
672  }
673  }
674 }
675 
676 bool SkillDialog::updateSkill(const int id,
677  const int range,
678  const Modifiable modifiable,
679  const SkillType::SkillType type,
680  const int sp)
681 {
682  const SkillMap::const_iterator it = mSkills.find(id);
683 
684  if (it != mSkills.end())
685  {
686  SkillInfo *const info = it->second;
687  if (info != nullptr)
688  {
689  info->modifiable = modifiable;
690  info->range = range;
691  info->type = type;
692  info->sp = sp;
693  info->update();
694  if (info->tab != nullptr)
695  {
696  info->tab->setVisible(Visible_true);
699  }
700  }
701  return true;
702  }
703  return false;
704 }
705 
707 {
708  std::string icon;
709  switch (type)
710  {
711  case SkillType::Attack:
712  icon = paths.getStringValue("attackSkillIcon");
713  break;
714  case SkillType::Ground:
715  icon = paths.getStringValue("groundSkillIcon");
716  break;
717  case SkillType::Self:
718  icon = paths.getStringValue("selfSkillIcon");
719  break;
720  case SkillType::Unused:
721  icon = paths.getStringValue("unusedSkillIcon");
722  break;
723  case SkillType::Support:
724  icon = paths.getStringValue("supportSkillIcon");
725  break;
727  icon = paths.getStringValue("trapSkillIcon");
728  break;
729  case SkillType::Unknown:
730  icon = paths.getStringValue("unknownSkillIcon");
731  break;
732  default:
733  break;
734  }
735  return icon;
736 }
737 
739  const int id,
740  const std::string &name,
741  const int level,
742  const int range,
743  const Modifiable modifiable,
744  const SkillType::SkillType type,
745  const int sp)
746 {
747  if (mDefaultModel != nullptr)
748  {
749  SkillInfo *const skill = new SkillInfo;
750  skill->id = CAST_U32(id);
751  skill->type = type;
752  skill->owner = owner;
753  SkillData *const data = skill->data;
754  if (name.empty())
755  {
756  data->name = "Unknown skill Id: " + toString(id);
757  data->dispName = data->name;
758  }
759  else
760  {
761  data->name = name;
762  data->dispName = strprintf("%s, %u", name.c_str(), skill->id);
763  }
764  data->description.clear();
765  const std::string icon = getDefaultSkillIcon(type);
766  if (icon.empty())
767  {
768  data->setIcon(paths.getStringValue("missingSkillIcon"));
769  data->haveIcon = false;
770  }
771  else
772  {
773  data->setIcon(icon);
774  data->haveIcon = true;
775  }
777  data->shortName = toString(skill->id);
778  skill->modifiable = modifiable;
779  skill->visible = Visible_false;
780  skill->alwaysVisible = Visible_false;
781  skill->model = mDefaultModel;
782  skill->level = level;
783  // TRANSLATORS: skills dialog. skill level
784  skill->skillLevel = strprintf(_("Lvl: %d"), level);
785  skill->range = range;
786  skill->sp = sp;
787  skill->update();
788  // TRANSLATORS: skills dialog button
789  skill->useButton = _("Use");
790  // TRANSLATORS: skill error message
791  skill->errorText = strprintf(_("Failed skill: %s"), name.c_str());
792  skill->tab = mDefaultTab;
797 
798  mSkills[id] = skill;
800  }
801 }
802 
803 SkillInfo* SkillDialog::getSkill(const int id) const
804 {
805  SkillMap::const_iterator it = mSkills.find(id);
806  if (it != mSkills.end())
807  return (*it).second;
808  return nullptr;
809 }
810 
811 SkillInfo* SkillDialog::getSkillByItem(const int itemId) const
812 {
813  SkillMap::const_iterator it = mSkills.find(itemId - SKILL_MIN_ID);
814  if (it != mSkills.end())
815  return (*it).second;
816  return nullptr;
817 }
818 
820  const int id,
821  const int duration)
822 {
823  SkillMap::const_iterator it = mSkills.find(id);
824  SkillInfo *info = nullptr;
825  if (it == mSkills.end())
826  {
827  addSkill(owner, id, "", 0, 0, Modifiable_false, SkillType::Unknown, 0);
828  it = mSkills.find(id);
829  }
830  if (it != mSkills.end())
831  {
832  info = (*it).second;
833  }
834  if (info != nullptr)
835  {
836  info->duration = duration;
837  info->durationTime = tick_time;
839  }
840 }
841 
843 {
844  Window::widgetResized(event);
845 
846  if (mTabs != nullptr)
847  mTabs->adjustSize();
848 }
849 
850 void SkillDialog::useItem(const int itemId,
851  const AutoTarget autoTarget,
852  const int level,
853  const std::string &data) const
854 {
855  const std::map<int, SkillInfo*>::const_iterator
856  it = mSkills.find(itemId - SKILL_MIN_ID);
857  if (it == mSkills.end())
858  return;
859 
860  const SkillInfo *const info = (*it).second;
861  CastTypeT castType = CastType::Default;
862  int offsetX = 0;
863  int offsetY = 0;
864 
865  if (!data.empty())
866  {
867  STD_VECTOR<int> vect;
868  splitToIntVector(vect, data, ' ');
869  const size_t sz = vect.size();
870  if (sz > 0)
871  castType = static_cast<CastTypeT>(vect[0]);
872  if (sz > 2)
873  {
874  offsetX = vect[1];
875  offsetY = vect[2];
876  }
877  }
878  useSkill(info,
879  autoTarget,
880  level,
881  false,
882  std::string(),
883  castType,
884  offsetX,
885  offsetY);
886 }
887 
889 {
890  const SkillTab *const tab = static_cast<SkillTab*>(
891  mTabs->getSelectedTab());
892  if (tab != nullptr)
893  {
894  if (const SkillInfo *const info = tab->getSelectedInfo())
895  {
896  mUseButton->setEnabled(info->range > 0);
898  mUseButton->setCaption(info->useButton);
899  }
900  else
901  {
902  mUseButton->setEnabled(false);
903  // TRANSLATORS: inventory button
904  mUseButton->setCaption(_("Use"));
905  }
906  }
907 }
908 
909 void SkillDialog::updateQuest(const int var,
910  const int val1,
911  const int val2 A_UNUSED,
912  const int val3 A_UNUSED,
913  const int time1 A_UNUSED)
914 {
915  const int id = var + SKILL_VAR_MIN_ID;
916  const SkillMap::const_iterator it = mSkills.find(id);
917 
918  if (it != mSkills.end())
919  {
920  SkillInfo *const info = it->second;
921  if (info != nullptr)
922  {
923  PlayerInfo::setSkillLevel(id, val1);
924  info->level = val1;
925  info->update();
926  }
927  }
928 }
929 
931 {
932  const SkillMap::const_iterator it = mSkills.find(id);
933  if (it != mSkills.end())
934  {
935  SkillInfo *const info = it->second;
936  if (info != nullptr)
937  return info->data;
938  }
939  return nullptr;
940 }
941 
943  const int level) const
944 {
945  const SkillMap::const_iterator it = mSkills.find(id);
946  if (it != mSkills.end())
947  {
948  SkillInfo *const info = it->second;
949  if (info != nullptr)
950  return info->getData1(level);
951  }
952  return nullptr;
953 }
954 
955 void SkillDialog::playUpdateEffect(const int id) const
956 {
957  if (effectManager == nullptr)
958  return;
959  const SkillData *const data = getSkillData(id);
960  if (data == nullptr)
961  return;
962  effectManager->triggerDefault(data->updateEffectId,
963  localPlayer,
964  paths.getIntValue("skillLevelUpEffectId"));
965 }
966 
967 void SkillDialog::playRemoveEffect(const int id) const
968 {
969  if (effectManager == nullptr)
970  return;
971  const SkillData *const data = getSkillData(id);
972  if (data == nullptr)
973  return;
974  effectManager->triggerDefault(data->removeEffectId,
975  localPlayer,
976  paths.getIntValue("skillRemoveEffectId"));
977 }
978 
980  const int level,
981  const int x,
982  const int y,
983  const int delay) const
984 {
985  if (effectManager == nullptr)
986  return;
987  SkillData *const data = getSkillDataByLevel(id, level);
988  if (data == nullptr)
989  return;
990  effectManager->triggerDefault(data->castingGroundEffectId,
991  x * 32,
992  y * 32,
993  cur_time + delay / 1000, // end time in seconds
994  paths.getIntValue("skillCastingGroundEffectId"));
995 }
996 
997 void SkillDialog::useSkill(const int skillId,
998  const AutoTarget autoTarget,
999  int level,
1000  const bool withText,
1001  const std::string &text,
1002  CastTypeT castType,
1003  const int offsetX,
1004  const int offsetY)
1005 {
1006  SkillInfo *const info = skillDialog->getSkill(skillId);
1007  if (info == nullptr)
1008  return;
1009  if (castType == CastType::Default)
1010  castType = info->customCastType;
1011  useSkill(info,
1012  autoTarget,
1013  level,
1014  withText,
1015  text,
1016  castType,
1017  offsetX,
1018  offsetY);
1019 }
1020 
1022  const AutoTarget autoTarget,
1023  int level,
1024  const bool withText,
1025  const std::string &text,
1026  const CastTypeT castType,
1027  const int offsetX,
1028  const int offsetY)
1029 {
1030  if ((info == nullptr) || (localPlayer == nullptr))
1031  return;
1032  if (level == 0)
1033  level = info->level;
1034 
1035  const SkillData *data = info->getData1(level);
1036  if (data != nullptr)
1037  {
1038  const std::string cmd = data->invokeCmd;
1039  if (!cmd.empty())
1041  }
1042  switch (castType)
1043  {
1044  default:
1045  case CastType::Default:
1047  autoTarget,
1048  level,
1049  withText,
1050  text,
1051  offsetX,
1052  offsetY);
1053  break;
1054  case CastType::Target:
1055  {
1056  const Being *const being = localPlayer->getTarget();
1058  autoTarget,
1059  level,
1060  withText,
1061  text,
1062  being,
1063  offsetX,
1064  offsetY);
1065  break;
1066  }
1067  case CastType::Position:
1068  {
1069  int x = 0;
1070  int y = 0;
1071  viewport->getMouseTile(x, y);
1073  level,
1074  withText,
1075  text,
1076  x,
1077  y,
1078  offsetX,
1079  offsetY);
1080  break;
1081  }
1082  case CastType::Self:
1083  // +++ probably need call useSkillSelf
1085  autoTarget,
1086  level,
1087  withText,
1088  text,
1089  localPlayer,
1090  offsetX,
1091  offsetY);
1092  break;
1093  }
1094 }
1095 
1097  const AutoTarget autoTarget,
1098  int level,
1099  const bool withText,
1100  const std::string &text,
1101  const Being *being,
1102  int offsetX,
1103  int offsetY)
1104 {
1105  SkillType::SkillType type = info->type;
1106  if ((type & SkillType::Attack) != 0)
1107  {
1108  if ((being == nullptr) && autoTarget == AutoTarget_true)
1109  {
1110  if (localPlayer != nullptr)
1111  {
1113  AllowSort_true);
1114  }
1115  }
1116  if (being != nullptr)
1117  {
1118  skillHandler->useBeing(info->id,
1119  level,
1120  being->getId());
1121  }
1122  }
1123  else if ((type & SkillType::Support) != 0)
1124  {
1125  if (being == nullptr)
1126  being = localPlayer;
1127  if (being != nullptr)
1128  {
1129  skillHandler->useBeing(info->id,
1130  level,
1131  being->getId());
1132  }
1133  }
1134  else if ((type & SkillType::Self) != 0)
1135  {
1136  skillHandler->useBeing(info->id,
1137  level,
1138  localPlayer->getId());
1139  }
1140  else if ((type & SkillType::Ground) != 0)
1141  {
1142  if (being == nullptr)
1143  return;
1144  being->fixDirectionOffsets(offsetX, offsetY);
1145  const int x = being->getTileX() + offsetX;
1146  const int y = being->getTileY() + offsetY;
1147  if (info->useTextParameter)
1148  {
1149  if (withText)
1150  {
1151  skillHandler->usePos(info->id,
1152  level,
1153  x, y,
1154  text);
1155  }
1156  else
1157  {
1158  const SkillData *data = info->getData1(level);
1160  x,
1161  y,
1162  level);
1163  TextDialog *const dialog = CREATEWIDGETR(TextDialog,
1164  // TRANSLATORS: text skill dialog header
1165  strprintf(_("Add text to skill %s"),
1166  data->name.c_str()),
1167  // TRANSLATORS: text skill dialog field
1168  _("Text: "),
1169  nullptr,
1170  false);
1171  dialog->setModal(Modal_true);
1172  textSkillListener.setDialog(dialog);
1173  dialog->setActionEventId("ok");
1175  }
1176  }
1177  else
1178  {
1179  skillHandler->usePos(info->id,
1180  level,
1181  x, y);
1182  }
1183  }
1184  else if ((type & SkillType::TargetTrap) != 0)
1185  {
1186  // for now unused
1187  }
1188  else if (type == SkillType::Unknown ||
1189  type == SkillType::Unused)
1190  {
1191  // unknown / unused
1192  }
1193  else
1194  {
1195  reportAlways("Unsupported skill type: %d", type)
1196  }
1197 }
1198 
1200  int level,
1201  const bool withText,
1202  const std::string &text,
1203  const int x,
1204  const int y,
1205  int offsetX,
1206  int offsetY)
1207 {
1208  SkillType::SkillType type = info->type;
1209  if ((type & SkillType::Ground) != 0)
1210  {
1211  localPlayer->fixDirectionOffsets(offsetX, offsetY);
1212  if (info->useTextParameter)
1213  {
1214  if (withText)
1215  {
1216  skillHandler->usePos(info->id,
1217  level,
1218  x + offsetX,
1219  y + offsetY,
1220  text);
1221  }
1222  else
1223  {
1224  const SkillData *data = info->getData1(level);
1226  x + offsetX,
1227  y + offsetY,
1228  level);
1229  TextDialog *const dialog = CREATEWIDGETR(TextDialog,
1230  // TRANSLATORS: text skill dialog header
1231  strprintf(_("Add text to skill %s"),
1232  data->name.c_str()),
1233  // TRANSLATORS: text skill dialog field
1234  _("Text: "),
1235  nullptr,
1236  false);
1237  dialog->setModal(Modal_true);
1238  textSkillListener.setDialog(dialog);
1239  dialog->setActionEventId("ok");
1241  }
1242  }
1243  else
1244  {
1245  skillHandler->usePos(info->id,
1246  level,
1247  x + offsetX,
1248  y + offsetY);
1249  }
1250  }
1251  else if ((type & SkillType::Support) != 0)
1252  {
1253  // wrong type
1254  skillHandler->useBeing(info->id,
1255  level,
1256  localPlayer->getId());
1257  }
1258  else if ((type & SkillType::Self) != 0)
1259  {
1260  skillHandler->useBeing(info->id,
1261  level,
1262  localPlayer->getId());
1263  }
1264  else if ((type & SkillType::Attack) != 0)
1265  {
1266  // do nothing
1267  // +++ probably need select some target on x,y position?
1268  }
1269  else if ((type & SkillType::TargetTrap) != 0)
1270  {
1271  // for now unused
1272  }
1273  else if (type == SkillType::Unknown ||
1274  type == SkillType::Unused)
1275  {
1276  // unknown / unused
1277  }
1278  else
1279  {
1280  reportAlways("Unsupported skill type: %d", type)
1281  }
1282 }
1283 
1285  const AutoTarget autoTarget,
1286  int level,
1287  const bool withText,
1288  const std::string &text,
1289  int offsetX,
1290  int offsetY)
1291 {
1292  SkillType::SkillType type = info->type;
1293  if ((type & SkillType::Attack) != 0)
1294  {
1295  const Being *being = localPlayer->getTarget();
1296  if ((being == nullptr) && autoTarget == AutoTarget_true)
1297  {
1299  AllowSort_true);
1300  }
1301  if (being != nullptr)
1302  {
1303  skillHandler->useBeing(info->id,
1304  level,
1305  being->getId());
1306  }
1307  }
1308  else if ((type & SkillType::Support) != 0)
1309  {
1310  const Being *being = localPlayer->getTarget();
1311  if (being == nullptr)
1312  being = localPlayer;
1313  if (being != nullptr)
1314  {
1315  skillHandler->useBeing(info->id,
1316  level,
1317  being->getId());
1318  }
1319  }
1320  else if ((type & SkillType::Self) != 0)
1321  {
1322  skillHandler->useBeing(info->id,
1323  level,
1324  localPlayer->getId());
1325  }
1326  else if ((type & SkillType::Ground) != 0)
1327  {
1328  int x = 0;
1329  int y = 0;
1330  viewport->getMouseTile(x, y);
1331  localPlayer->fixDirectionOffsets(offsetX, offsetY);
1332  x += offsetX;
1333  y += offsetY;
1334  if (info->useTextParameter)
1335  {
1336  if (withText)
1337  {
1338  skillHandler->usePos(info->id,
1339  level,
1340  x, y,
1341  text);
1342  }
1343  else
1344  {
1345  const SkillData *data = info->getData1(level);
1347  x,
1348  y,
1349  level);
1350  TextDialog *const dialog = CREATEWIDGETR(TextDialog,
1351  // TRANSLATORS: text skill dialog header
1352  strprintf(_("Add text to skill %s"),
1353  data->name.c_str()),
1354  // TRANSLATORS: text skill dialog field
1355  _("Text: "),
1356  nullptr,
1357  false);
1358  dialog->setModal(Modal_true);
1359  textSkillListener.setDialog(dialog);
1360  dialog->setActionEventId("ok");
1362  }
1363  }
1364  else
1365  {
1366  skillHandler->usePos(info->id,
1367  level,
1368  x, y);
1369  }
1370  }
1371  else if ((type & SkillType::TargetTrap) != 0)
1372  {
1373  // for now unused
1374  }
1375  else if (type == SkillType::Unknown ||
1376  type == SkillType::Unused)
1377  {
1378  // unknown / unused
1379  }
1380  else
1381  {
1382  reportAlways("Unsupported skill type: %d", type)
1383  }
1384 }
1385 
1387 {
1388  if (skill == nullptr)
1389  return;
1390 
1391  FOR_EACH (STD_VECTOR<SkillInfo*>::const_iterator, it, mDurations)
1392  {
1393  if ((*it)->id == skill->id)
1394  return;
1395  }
1396  mDurations.push_back(skill);
1397 }
1398 
1400 {
1401  FOR_EACH_SAFE (STD_VECTOR<SkillInfo*>::iterator, it, mDurations)
1402  {
1403  SkillInfo *const skill = *it;
1404  if (skill != nullptr)
1405  {
1406  const int time = get_elapsed_time(skill->durationTime);
1407  if (time >= skill->duration)
1408  {
1409  it = mDurations.erase(it);
1410  skill->cooldown = 0;
1411  skill->duration = 0;
1412  skill->durationTime = 0;
1413  if (it == mDurations.end())
1414  return;
1415  if (it != mDurations.begin())
1416  -- it;
1417  }
1418  else if (time != 0)
1419  {
1420  skill->cooldown = skill->duration * 100 / time;
1421  }
1422  }
1423  }
1424 }
1425 
1426 void SkillDialog::selectSkillLevel(const int skillId,
1427  const int level)
1428 {
1429  SkillInfo *const info = getSkill(skillId);
1430  if (info == nullptr)
1431  return;
1432  if (level > info->level)
1433  info->customSelectedLevel = info->level;
1434  else
1435  info->customSelectedLevel = level;
1436  info->update();
1437 }
1438 
1439 void SkillDialog::selectSkillCastType(const int skillId,
1440  const CastTypeT type)
1441 {
1442  SkillInfo *const info = getSkill(skillId);
1443  if (info == nullptr)
1444  return;
1445  info->customCastType = type;
1446  info->update();
1447 }
1448 
1449 void SkillDialog::setSkillOffsetX(const int skillId,
1450  const int offset)
1451 {
1452  SkillInfo *const info = getSkill(skillId);
1453  if (info == nullptr)
1454  return;
1455  info->customOffsetX = offset;
1456  info->update();
1457 }
1458 
1459 void SkillDialog::setSkillOffsetY(const int skillId,
1460  const int offset)
1461 {
1462  SkillInfo *const info = getSkill(skillId);
1463  if (info == nullptr)
1464  return;
1465  info->customOffsetY = offset;
1466  info->update();
1467 }
const bool AllowSort_true
Definition: allowsort.h:30
const bool AutoTarget_true
Definition: autotarget.h:30
bool AutoTarget
Definition: autotarget.h:30
volatile time_t cur_time
Definition: timer.cpp:58
#define loadXmlDir(name, function)
Definition: beingcommon.h:39
#define fromBool(val, name)
Definition: booldefines.h:49
const std::string BUTTON_SKIN
Definition: button.h:89
#define CAST_U16
Definition: cast.h:29
#define CAST_S32
Definition: cast.h:30
#define CAST_U32
Definition: cast.h:31
CastType ::T CastTypeT
Definition: casttype.h:34
#define reportAlways(...)
Definition: checkutils.h:253
BeingId getId() const
Definition: actorsprite.h:64
Definition: being.h:96
int getTileX() const
Definition: being.h:168
int getTileY() const
Definition: being.h:174
void fixDirectionOffsets(int &offsetX, int &offsetY) const
Definition: being.cpp:5528
Definition: button.h:102
void setCaption(const std::string &caption)
Definition: button.h:214
bool getBoolValue(const std::string &key) const
std::string getStringValue(const std::string &key) const
int getIntValue(const std::string &key) const
void triggerDefault(int effectId, Being *const being, const int defaultEffectId)
Definition: event.h:79
void setItemFast(const size_t index, const int item, const ItemColor color)
void setItemSelected(const int itemId)
Definition: itemshortcut.h:126
void setItemData(const size_t index, const std::string &data)
Definition: itemshortcut.h:76
Definition: label.h:91
void adjustSize()
Definition: label.cpp:200
void setCaption(const std::string &caption)
Definition: label.cpp:264
Being * getTarget() const
Being * setNewTarget(const ActorTypeT type, const AllowSort allowSort)
void log(const char *const log_text,...)
Definition: logger.cpp:269
virtual void increaseSkill(const uint16_t skillId) const =0
virtual void useBeing(const int id, const int level, const BeingId beingId) const =0
virtual void usePos(const int id, const int level, const int x, const int y) const =0
void setVerticalScrollPolicy(const ScrollPolicy vPolicy)
void setHorizontalScrollPolicy(const ScrollPolicy hPolicy)
bool unknownSkillsAutoTab
Definition: settings.h:164
void registerWindowForReset(Window *const window)
int getTabIndex() const
static void useSkillDefault(const SkillInfo *const info, const AutoTarget autoTarget, int level, const bool withText, const std::string &text, int offsetX, int offsetY)
void setSkillDuration(const SkillOwner::Type owner, const int id, const int duration)
void selectSkillLevel(const int skillId, const int level)
SkillData * getSkillData(const int id) const
void setSkillOffsetY(const int skillId, const int offset)
SkillModel * mDefaultModel
Definition: skilldialog.h:234
void updateQuest(const int var, const int val1, const int val2, const int val3, const int time1)
SkillMap mSkills
Definition: skilldialog.h:227
void slowLogic()
std::vector< SkillInfo * > mDurations
Definition: skilldialog.h:228
void selectSkillCastType(const int skillId, const CastTypeT type)
void clearSkills()
SkillInfo * loadSkill(const xmlNodePtr node, SkillModel *const model)
void addDefaultTab()
SkillTab * mDefaultTab
Definition: skilldialog.h:235
void postInit()
Label * mPointsLabel
Definition: skilldialog.h:231
SkillInfo * getSkill(const int id) const
bool updateSkill(const int id, const int range, const Modifiable modifiable, const SkillType::SkillType type, const int sp)
std::list< Tab * > mDeleteTabs
Definition: skilldialog.h:230
SkillInfo * getSkillByItem(const int itemId) const
void updateTabSelection()
void widgetResized(const Event &event)
void playRemoveEffect(const int id) const
void updateModelsHidden()
void action(const ActionEvent &event)
void removeSkill(const int id)
void playCastingDstTileEffect(const int id, const int level, const int x, const int y, const int delay) const
void playUpdateEffect(const int id) const
void loadSkills()
static void loadSkillData(const xmlNodePtr node, SkillInfo *const skill)
void updateModels()
Button * mUseButton
Definition: skilldialog.h:232
static void useSkill(const int skillId, const AutoTarget autoTarget, int level, const bool withText, const std::string &text, CastTypeT castType, const int offsetX, const int offsetY)
static void useSkillPosition(const SkillInfo *const info, int level, const bool withText, const std::string &text, const int x, const int y, int offsetX, int offsetY)
void addSkillDuration(SkillInfo *const skill)
Button * mIncreaseButton
Definition: skilldialog.h:233
static void useSkillTarget(const SkillInfo *const info, const AutoTarget autoTarget, int level, const bool withText, const std::string &text, const Being *being, int offsetX, int offsetY)
TabbedArea * mTabs
Definition: skilldialog.h:229
void addSkill(const SkillOwner::Type owner, const int id, const std::string &name, const int level, const int range, const Modifiable modifiable, const SkillType::SkillType type, const int sp)
void useItem(const int itemId, const AutoTarget autoTarget, const int level, const std::string &data) const
void setSkillOffsetX(const int skillId, const int offset)
SkillData * getSkillDataByLevel(const int id, const int level) const
static std::string getDefaultSkillIcon(const SkillType::SkillType type)
void loadXmlFile(const std::string &fileName, const SkipError skipError)
void hideSkills(const SkillOwner::Type owner)
void updateVisibilities()
Definition: skillmodel.cpp:54
void addSkill(SkillInfo *const info)
Definition: skillmodel.h:49
void reset()
Definition: skillpopup.cpp:249
SkillInfo * getSelectedInfo() const
Definition: skilltab.h:67
static void invokeCommand(const std::string &command, const Being *const target)
void adjustSize()
Definition: tabbedarea.cpp:569
void setSelectedTabDefault()
Definition: tabbedarea.cpp:432
Widget * getTabContainer() const
Definition: tabbedarea.h:241
void adjustTabPositions()
Definition: tabbedarea.cpp:606
void removeAll(const bool del)
Definition: tabbedarea.cpp:730
Widget * getWidgetContainer() const
Definition: tabbedarea.h:244
void addTab(Tab *const tab, Widget *const widget)
Definition: tabbedarea.cpp:238
Tab * getSelectedTab() const
Definition: tabbedarea.h:175
void setDialog(TextDialog *dialog)
void setSkill(const int skillId, const int x, const int y, const int level)
void getMouseTile(int &destX, int &destY) const
Definition: viewport.cpp:614
void setVisible(Visible visible)
Definition: widget.cpp:225
void setEnabled(const bool enabled)
Definition: widget.h:352
void setActionEventId(const std::string &actionEventId)
Definition: widget.h:596
void setSelectable(const bool selectable)
Definition: widget.h:948
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:252
Widget * getParent() const
Definition: widget.h:202
int getWidth() const
Definition: widget.h:221
Definition: window.h:102
void setSaveVisible(const bool save)
Definition: window.h:300
void setResizable(const bool resize)
Definition: window.cpp:627
virtual void setVisible(Visible visible)
Definition: window.cpp:778
void setWindowName(const std::string &name)
Definition: window.h:355
void setModal(const Modal modal)
Definition: window.cpp:1069
void postInit()
Definition: window.cpp:249
void enableVisibleSound(bool b)
Definition: window.h:481
void widgetResized(const Event &event)
Definition: window.cpp:655
void setCloseButton(const bool flag)
Definition: window.cpp:749
void setStickyButtonLock(const bool sticky)
Definition: window.cpp:772
LayoutCell & place(const int x, const int y, Widget *const wg, const int w, const int h)
Definition: window.cpp:1384
void setDefaultSize()
Definition: window.cpp:1198
void setLocationRelativeTo(const Widget *const widget)
Definition: window.cpp:509
void loadWindowState()
Definition: window.cpp:1087
xmlNodePtr rootNode()
Definition: libxml.cpp:169
Configuration config
Configuration paths
const size_t SHORTCUT_AUTO_TAB
Definition: itemshortcut.h:29
const unsigned int SHORTCUT_ITEMS
Definition: itemshortcut.h:27
const unsigned int SHORTCUT_TABS
Definition: itemshortcut.h:28
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:36
#define new
Definition: debug_new.h:147
void delete_all(Container &c)
Definition: dtor.h:56
Viewport * viewport
Definition: viewport.cpp:36
EffectManager * effectManager
#define FOR_EACH_SAFE(type, iter, array)
Definition: foreach.h:34
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
#define _(s)
Definition: gettext.h:35
#define fromInt(val, name)
Definition: intdefines.h:46
uint16_t ItemColor
Definition: itemcolor.h:30
ItemShortcut * itemShortcut[SHORTCUT_TABS]
#define for_each_xml_child_node(var, parent)
Definition: libxml.h:161
#define nullptr
Definition: localconsts.h:45
#define A_UNUSED
Definition: localconsts.h:160
LocalPlayer * localPlayer
Logger * logger
Definition: logger.cpp:89
uint32_t data
volatile int tick_time
Definition: timer.cpp:53
const bool Modal_false
Definition: modal.h:30
const bool Modal_true
Definition: modal.h:30
const bool Modifiable_true
Definition: modifiable.h:30
bool Modifiable
Definition: modifiable.h:30
const bool Modifiable_false
Definition: modifiable.h:30
bool info(InputEvent &event)
Definition: commands.cpp:57
bool skill(InputEvent &event)
Definition: commands.cpp:97
@ PLAYER_SKILL_POINTS
Definition: attributes.h:48
@ Position
Definition: casttype.h:31
@ Default
Definition: casttype.h:29
@ Target
Definition: casttype.h:30
@ Self
Definition: casttype.h:32
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:1774
int32_t getAttribute(const AttributesT id)
Definition: playerinfo.cpp:102
void setSkillLevel(const int id, const int value)
Definition: playerinfo.cpp:128
@ TargetTrap
Definition: skilltype.h:36
static const std::string CASTSKY("castsky")
static const std::string CASTWATER("castwater")
static const std::string CASTRIDE("castride")
static const std::string CAST("cast")
std::string langProperty(const xmlNodePtr node, const char *const name, const std::string &def)
Definition: libxml.cpp:258
float getFloatProperty(const xmlNodePtr node, const char *const name, float def)
Definition: libxml.cpp:211
bool getBoolProperty(const xmlNodePtr node, const char *const name, const bool def)
Definition: libxml.cpp:269
int getProperty(const xmlNodePtr node, const char *const name, int def)
Definition: libxml.cpp:174
int getIntProperty(const xmlNodePtr node, const char *const name, int def, const int min, const int max)
Definition: libxml.cpp:190
Net::SkillHandler * skillHandler
Definition: net.cpp:97
Net::PlayerHandler * playerHandler
Definition: net.cpp:96
const bool Opaque_false
Definition: opaque.h:30
const int SKILL_MIN_ID
Definition: skill.h:25
const unsigned int SKILL_VAR_MIN_ID
Definition: skill.h:26
Settings settings
Definition: settings.cpp:32
SetupWindow * setupWindow
Definition: setupwindow.cpp:64
ShortcutWindow * itemShortcutWindow
static SkillOwner::Type parseOwner(const std::string &str)
Definition: skilldialog.cpp:73
SkillDialog * skillDialog
Definition: skilldialog.cpp:66
SkillPopup * skillPopup
Definition: skillpopup.cpp:42
SkillSetType ::T SkillSetTypeT
Definition: skillsettype.h:32
const bool SkipError_false
Definition: skiperror.h:30
const bool SkipError_true
Definition: skiperror.h:30
bool SkipError
Definition: skiperror.h:30
void splitToIntVector(std::vector< int > &tokens, const std::string &text, const char separator)
std::string strprintf(const char *const format,...)
std::string particle
Definition: missileinfo.h:41
float dieDistance
Definition: missileinfo.h:44
float speed
Definition: missileinfo.h:43
std::string fileName
Definition: testmain.cpp:39
int get_elapsed_time(const int startTime)
Definition: timer.cpp:94
const bool UseVirtFs_true
Definition: usevirtfs.h:30
bool Visible
Definition: visible.h:30
const bool Visible_false
Definition: visible.h:30
const bool Visible_true
Definition: visible.h:30
WindowContainer * windowContainer