ManaPlus
gamemodifiers.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2011-2018 The ManaPlus Developers
4  *
5  * This file is part of The ManaPlus Client.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "gamemodifiers.h"
22 
23 #include "configuration.h"
24 #include "game.h"
25 #include "settings.h"
26 #include "soundmanager.h"
27 
28 #include "being/localplayer.h"
29 
30 #include "gui/viewport.h"
31 
32 #include "gui/windows/chatwindow.h"
33 #include "gui/windows/okdialog.h"
35 
37 
39 
41 
42 #include "resources/map/map.h"
43 
44 #include "listeners/awaylistener.h"
46 
47 #include "utils/gettext.h"
48 
49 #include "debug.h"
50 
51 #define addModifier(name1, name2, sz, ...) \
52  const unsigned GameModifiers::m##name1##Size = sz; \
53  const char *const GameModifiers::m##name1##Strings[] = \
54  __VA_ARGS__; \
55  std::string GameModifiers::get##name1##String() \
56  { \
57  return gettext(getVarItem(&m##name1##Strings[0], \
58  CAST_U32(settings.name2), m##name1##Size)); \
59  }
60 
61 #define addModifier2(name1, name2, str, sz, ...) \
62  const unsigned GameModifiers::m##name1##Size = sz; \
63  const char *const GameModifiers::m##name1##Strings[] = \
64  __VA_ARGS__; \
65  void GameModifiers::change##name1(const bool forward) \
66  { \
67  changeMode(&settings.name2, m##name1##Size, str, \
68  &GameModifiers::get##name1##String, 0, true, forward); \
69  } \
70  std::string GameModifiers::get##name1##String() \
71  { \
72  return gettext(getVarItem(&m##name1##Strings[0], \
73  settings.name2, m##name1##Size)); \
74  }
75 
76 #define changeMethod(name1, name2, str) \
77  void GameModifiers::change##name1(const bool forward) \
78  { \
79  changeMode(&settings.name2, m##name1##Size, str, \
80  &GameModifiers::get##name1##String, 0, true, forward); \
81  }
82 
84 {
85  settings.crazyMoveType = config.getIntValue("crazyMoveType");
86  settings.moveToTargetType = config.getIntValue("moveToTargetType");
87  settings.followMode = config.getIntValue("followMode");
88  settings.attackWeaponType = config.getIntValue("attackWeaponType");
89  settings.attackType = config.getIntValue("attackType");
90  settings.targetingType = config.getIntValue("targetingType");
91  settings.quickDropCounter = config.getIntValue("quickDropCounter");
92  settings.pickUpType = config.getIntValue("pickUpType");
93  settings.magicAttackType = config.getIntValue("magicAttackType");
94  settings.pvpAttackType = config.getIntValue("pvpAttackType");
95  settings.imitationMode = config.getIntValue("imitationMode");
97  "disableGameModifiers");
98  settings.awayMode = false;
100 // UpdateStatusListener::distributeEvent();
101 }
102 
103 void GameModifiers::changeMode(unsigned *restrict const var,
104  const unsigned limit,
105  const char *restrict const conf,
106  std::string (*const func)(),
107  const unsigned def,
108  const bool save,
109  const bool forward)
110 {
111  if (var == nullptr)
112  return;
113 
114  if (forward)
115  {
116  (*var) ++;
117  if (*var >= limit)
118  *var = def;
119  }
120  else
121  {
122  if (*var == 0u)
123  *var = limit - 1;
124  else
125  (*var) --;
126  }
127 
128  if (save)
129  config.setValue(conf, *var);
132  const std::string str = (*func)();
133  if (str.size() > 4)
134  debugMsg(str.substr(4));
135 }
136 
137 const char *GameModifiers::getVarItem(const char *const *const arr,
138  const unsigned index,
139  const unsigned sz)
140 {
141  if (index < sz)
142  return arr[index];
143  return arr[sz];
144 }
145 
146 addModifier(MoveType, moveType, 5,
147 {
148  // TRANSLATORS: move type in status bar
149  N_("(D) default moves"),
150  // TRANSLATORS: move type in status bar
151  N_("(I) invert moves"),
152  // TRANSLATORS: move type in status bar
153  N_("(c) moves with some crazy moves"),
154  // TRANSLATORS: move type in status bar
155  N_("(C) moves with crazy moves"),
156  // TRANSLATORS: move type in status bar
157  N_("(d) double normal + crazy"),
158  // TRANSLATORS: move type in status bar
159  N_("(?) unknown move")
160 })
161 
162 void GameModifiers::changeMoveType(const bool forward)
163 {
165  changeMode(&settings.moveType, mMoveTypeSize, "invertMoveDirection",
166  &GameModifiers::getMoveTypeString, 0, false, forward);
167 }
168 
169 const unsigned GameModifiers::mCrazyMoveTypeSize = 11;
170 
171 void GameModifiers::changeCrazyMoveType(const bool forward)
172 {
175  &GameModifiers::getCrazyMoveTypeString, 1, true, forward);
176 }
177 
179 {
180  const unsigned int crazyMoveType = settings.crazyMoveType;
181  if (crazyMoveType < mCrazyMoveTypeSize - 1)
182  {
183  // TRANSLATORS: crazy move type in status bar
184  return strprintf(_("(%u) crazy move number %u"),
185  crazyMoveType, crazyMoveType);
186  }
187  else if (crazyMoveType == mCrazyMoveTypeSize - 1)
188  {
189  // TRANSLATORS: crazy move type in status bar
190  return _("(a) custom crazy move");
191  }
192  else
193  {
194  // TRANSLATORS: crazy move type in status bar
195  return _("(?) crazy move");
196  }
197 }
198 
199 addModifier2(MoveToTargetType, moveToTargetType, "moveToTargetType", 13,
200 {
201  // TRANSLATORS: move to target type in status bar
202  N_("(0) default moves to target"),
203  // TRANSLATORS: move to target type in status bar
204  N_("(1) moves to target in distance 1"),
205  // TRANSLATORS: move to target type in status bar
206  N_("(2) moves to target in distance 2"),
207  // TRANSLATORS: move to target type in status bar
208  N_("(3) moves to target in distance 3"),
209  // TRANSLATORS: move to target type in status bar
210  N_("(4) moves to target in distance 4"),
211  // TRANSLATORS: move to target type in status bar
212  N_("(5) moves to target in distance 5"),
213  // TRANSLATORS: move to target type in status bar
214  N_("(6) moves to target in distance 6"),
215  // TRANSLATORS: move to target type in status bar
216  N_("(7) moves to target in distance 7"),
217  // TRANSLATORS: move to target type in status bar
218  N_("(8) moves to target in distance 8"),
219  // TRANSLATORS: move to target type in status bar
220  N_("(9) moves to target in distance 9"),
221  // TRANSLATORS: move to target type in status bar
222  N_("(A) moves to target in attack range"),
223  // TRANSLATORS: move to target type in status bar
224  N_("(a) archer attack range"),
225  // TRANSLATORS: move to target type in status bar
226  N_("(B) moves to target in attack range - 1"),
227  // TRANSLATORS: move to target type in status bar
228  N_("(?) move to target")
229 })
230 
231 addModifier2(FollowMode, followMode, "followMode", 4,
232 {
233  // TRANSLATORS: folow mode in status bar
234  N_("(D) default follow"),
235  // TRANSLATORS: folow mode in status bar
236  N_("(R) relative follow"),
237  // TRANSLATORS: folow mode in status bar
238  N_("(M) mirror follow"),
239  // TRANSLATORS: folow mode in status bar
240  N_("(P) pet follow"),
241  // TRANSLATORS: folow mode in status bar
242  N_("(?) unknown follow")
243 })
244 
245 addModifier2(AttackWeaponType, attackWeaponType, "attackWeaponType", 4,
246 {
247  // TRANSLATORS: switch attack type in status bar
248  N_("(?) attack"),
249  // TRANSLATORS: switch attack type in status bar
250  N_("(D) default attack"),
251  // TRANSLATORS: switch attack type in status bar
252  N_("(s) switch attack without shield"),
253  // TRANSLATORS: switch attack type in status bar
254  N_("(S) switch attack with shield"),
255  // TRANSLATORS: switch attack type in status bar
256  N_("(?) attack")
257 })
258 
259 addModifier2(AttackType, attackType, "attackType", 4,
260 {
261  // TRANSLATORS: attack type in status bar
262  N_("(D) default attack"),
263  // TRANSLATORS: attack type in status bar
264  N_("(G) go and attack"),
265  // TRANSLATORS: attack type in status bar
266  N_("(A) go, attack, pickup"),
267  // TRANSLATORS: attack type in status bar
268  N_("(d) without auto attack"),
269  // TRANSLATORS: attack type in status bar
270  N_("(?) attack")
271 })
272 
273 addModifier2(TargetingType, targetingType, "targetingType", 2,
274 {
275  // TRANSLATORS: targeting type in status bar
276  N_("(D) don't switch target"),
277  // TRANSLATORS: targeting type in status bar
278  N_("(C) always attack closest"),
279  // TRANSLATORS: targeting type in status bar
280  N_("(?) targeting")
281 })
282 
283 const unsigned GameModifiers::mQuickDropCounterSize = 31;
284 
285 changeMethod(QuickDropCounter, quickDropCounter, "quickDropCounter")
286 
288 {
289  const unsigned int cnt = settings.quickDropCounter;
290  if (cnt > 9)
291  {
292  return strprintf("(%c) drop counter %u", CAST_S8(
293  'a' + cnt - 10), cnt);
294  }
295  return strprintf("(%u) drop counter %u", cnt, cnt);
296 }
297 
299 {
300  if (n < 1 || n >= CAST_S32(mQuickDropCounterSize))
301  return;
303  config.setValue("quickDropCounter", n);
306 }
307 
308 addModifier2(PickUpType, pickUpType, "pickUpType", 7,
309 {
310  // TRANSLATORS: pickup size in status bar
311  N_("(S) small pick up 1x1 cells"),
312  // TRANSLATORS: pickup size in status bar
313  N_("(D) default pick up 2x1 cells"),
314  // TRANSLATORS: pickup size in status bar
315  N_("(F) forward pick up 2x3 cells"),
316  // TRANSLATORS: pickup size in status bar
317  N_("(3) pick up 3x3 cells"),
318  // TRANSLATORS: pickup size in status bar
319  N_("(g) go and pick up in distance 4"),
320  // TRANSLATORS: pickup size in status bar
321  N_("(G) go and pick up in distance 8"),
322  // TRANSLATORS: pickup size in status bar
323  N_("(A) go and pick up in max distance"),
324  // TRANSLATORS: pickup size in status bar
325  N_("(?) pick up")
326 })
327 
328 addModifier2(MagicAttackType, magicAttackType, "magicAttackType", 5,
329 {
330  // TRANSLATORS: magic attack in status bar
331  N_("(f) use #flar for magic attack"),
332  // TRANSLATORS: magic attack in status bar
333  N_("(c) use #chiza for magic attack"),
334  // TRANSLATORS: magic attack in status bar
335  N_("(I) use #ingrav for magic attack"),
336  // TRANSLATORS: magic attack in status bar
337  N_("(F) use #frillyar for magic attack"),
338  // TRANSLATORS: magic attack in status bar
339  N_("(U) use #upmarmu for magic attack"),
340  // TRANSLATORS: magic attack in status bar
341  N_("(?) magic attack")
342 })
343 
344 addModifier2(PvpAttackType, pvpAttackType, "pvpAttackType", 4,
345 {
346  // TRANSLATORS: player attack type in status bar
347  N_("(a) attack all players"),
348  // TRANSLATORS: player attack type in status bar
349  N_("(f) attack all except friends"),
350  // TRANSLATORS: player attack type in status bar
351  N_("(b) attack bad relations"),
352  // TRANSLATORS: player attack type in status bar
353  N_("(d) don't attack players"),
354  // TRANSLATORS: player attack type in status bar
355  N_("(?) pvp attack")
356 })
357 
358 addModifier2(ImitationMode, imitationMode, "imitationMode", 2,
359 {
360  // TRANSLATORS: imitation type in status bar
361  N_("(D) default imitation"),
362  // TRANSLATORS: imitation type in status bar
363  N_("(O) outfits imitation"),
364  // TRANSLATORS: imitation type in status bar
365  N_("(?) imitation")
366 })
367 
368 addModifier(GameModifiers, disableGameModifiers, 2,
369 {
370  // TRANSLATORS: game modifiers state in status bar
371  N_("Game modifiers are enabled"),
372  // TRANSLATORS: game modifiers state in status bar
373  N_("Game modifiers are disabled"),
374  // TRANSLATORS: game modifiers state in status bar
375  N_("Game modifiers are unknown")
376 })
377 
379 {
381  config.setValue("disableGameModifiers", settings.disableGameModifiers);
384 }
385 
386 addModifier(MapDrawType, mapDrawType, 7,
387 {
388  // TRANSLATORS: map view type in status bar
389  N_("(N) normal map view"),
390  // TRANSLATORS: map view type in status bar
391  N_("(D) debug map view"),
392  // TRANSLATORS: map view type in status bar
393  N_("(u) ultra map view"),
394  // TRANSLATORS: map view type in status bar
395  N_("(U) ultra map view 2"),
396  // TRANSLATORS: map view type in status bar
397  N_("(e) empty map view with collision"),
398  // TRANSLATORS: map view type in status bar
399  N_("(E) empty map view"),
400  // TRANSLATORS: map view type in status bar
401  N_("(b) black & white map view"),
402  // TRANSLATORS: pickup size in status bar
403  N_("(?) map view")
404 })
405 
407 {
408  if (viewport != nullptr)
410 }
411 
412 addModifier(AwayMode, awayMode, 2,
413 {
414  // TRANSLATORS: away type in status bar
415  N_("(O) on keyboard"),
416  // TRANSLATORS: away type in status bar
417  N_("(A) away"),
418  // TRANSLATORS: away type in status bar
419  N_("(?) away")
420 })
421 
422 void GameModifiers::changeAwayMode(const bool forward A_UNUSED)
423 {
424  if (localPlayer == nullptr)
425  return;
426 
429  localPlayer->setHalfAway(false);
434  if (settings.awayMode)
435  {
436  if (chatWindow != nullptr)
438 
441  if (outfitWindow != nullptr)
443  OkDialog *const dialog = CREATEWIDGETR(OkDialog,
444  // TRANSLATORS: away message box header
445  _("Away"),
446  serverConfig.getValue("afkMessage", "I am away from keyboard."),
447  // TRANSLATORS: ok dialog button
448  _("OK"),
450  Modal_true,
452  nullptr,
453  260);
454  localPlayer->setAwayDialog(dialog);
458  }
459  else
460  {
461  localPlayer->setAwayDialog(nullptr);
463  if (chatWindow != nullptr)
464  {
467  }
469  }
470 }
471 
472 addModifier(CameraMode, cameraMode, 2,
473 {
474  // TRANSLATORS: camera mode in status bar
475  N_("(G) game camera mode"),
476  // TRANSLATORS: camera mode in status bar
477  N_("(F) free camera mode"),
478  // TRANSLATORS: camera mode in status bar
479  N_("(?) away")
480 })
481 
482 
484 {
485  if (viewport != nullptr)
487 }
488 
490 {
491  settings.moveType = 0;
492  settings.crazyMoveType = config.resetIntValue("crazyMoveType");
493  settings.moveToTargetType = config.resetIntValue("moveToTargetType");
494  settings.followMode = config.resetIntValue("followMode");
495  settings.attackWeaponType = config.resetIntValue("attackWeaponType");
496  settings.attackType = config.resetIntValue("attackType");
497  settings.magicAttackType = config.resetIntValue("magicAttackType");
498  settings.pvpAttackType = config.resetIntValue("pvpAttackType");
499  settings.quickDropCounter = config.resetIntValue("quickDropCounter");
500  settings.pickUpType = config.resetIntValue("pickUpType");
501  settings.targetingType = config.resetIntValue("targetingType");
503  if (viewport != nullptr)
504  {
505  if (settings.cameraMode != 0u)
507  Map *const map = viewport->getMap();
508  if (map != nullptr)
510  }
511  settings.imitationMode = config.resetIntValue("imitationMode");
513  "disableGameModifiers");
514 
517 }
ChatWindow * chatWindow
Definition: chatwindow.cpp:89
#define _(s)
Definition: gettext.h:34
void updateFrameRate(int fpsLimit)
Definition: game.cpp:1030
void toggleMapDrawType()
Definition: viewport.cpp:250
unsigned int attackType
Definition: settings.h:136
unsigned int followMode
Definition: settings.h:134
void displayAwayLog() const
OutfitWindow * outfitWindow
#define N_(s)
Definition: gettext.h:35
int resetIntValue(const std::string &key)
void setDrawLayersFlags(const MapTypeT &n)
Definition: map.cpp:1699
void wearAwayOutfit()
static void init()
void addActionListener(ActionListener *const actionListener)
Definition: widget.cpp:251
unsigned int crazyMoveState
Definition: settings.h:143
unsigned int attackWeaponType
Definition: settings.h:135
static void changeCrazyMoveType(const bool forward)
void volumeOff() const
SoundManager soundManager
Configuration config
void cancelFollow()
static void changeGameModifiers(const bool forward)
AwayListener * getAwayListener() const
Definition: localplayer.h:415
int getIntValue(const std::string &key) const
void setAwayDialog(OkDialog *const dialog)
Definition: localplayer.h:412
void toggleCameraMode()
Definition: viewport.cpp:254
void setHalfAway(const bool n)
Definition: localplayer.h:235
Configuration serverConfig
static void resetModifiers()
MapTypeT mapDrawType
Definition: settings.h:148
static const unsigned mMoveTypeSize
Definition: gamemodifiers.h:49
bool disableGameModifiers
Definition: settings.h:154
static const char * getVarItem(const char *const *const arr, const unsigned index, const unsigned sz)
unsigned int moveToTargetType
Definition: settings.h:133
unsigned int imitationMode
Definition: settings.h:141
static void changeMapDrawType(const bool forward)
unsigned int quickDropCounter
Definition: settings.h:137
static std::string getMoveTypeString()
Settings settings
Definition: settings.cpp:31
bool getBoolValue(const std::string &key) const
#define CAST_S32
Definition: cast.h:29
static void setQuickDropCounter(const int n)
std::string strprintf(const char *const format,...)
Definition: stringutils.cpp:99
static void changeMoveType(const bool forward)
#define addModifier(name1, name2, sz,...)
void navigateClean()
static void changeMode(unsigned *const var, const unsigned limit, const char *const conf, std::string(*const func)(), const unsigned def, const bool save, const bool forward)
void setMoveState(const unsigned int n)
Definition: localplayer.h:195
void removeAfkEffect()
Definition: being.cpp:4923
LocalPlayer * localPlayer
void setAfkTime(const int v)
Definition: localplayer.h:409
static std::string getQuickDropCounterString()
#define addModifier2(name1, name2, str, sz,...)
static const unsigned mQuickDropCounterSize
Definition: gamemodifiers.h:56
unsigned int pvpAttackType
Definition: settings.h:140
#define CAST_S8
Definition: cast.h:25
unsigned int moveType
Definition: settings.h:131
void addAfkEffect()
Definition: being.cpp:4918
#define changeMethod(name1, name2, str)
const bool ShowCenter_false
Definition: showcenter.h:29
static void changeCameraMode(const bool forward)
Definition: map.h:71
unsigned int cameraMode
Definition: settings.h:142
void updateName()
Definition: being.cpp:3425
std::string getValue(const std::string &key, const std::string &deflt) const
#define A_UNUSED
Definition: localconsts.h:151
static std::string getCrazyMoveTypeString()
bool awayMode
Definition: settings.h:155
static const unsigned mCrazyMoveTypeSize
Definition: gamemodifiers.h:50
static Game * instance()
Definition: game.h:81
void clearAwayLog()
Definition: chatwindow.h:256
#define restrict
Definition: localconsts.h:156
#define debugMsg(str)
Definition: chattab.h:41
unsigned int magicAttackType
Definition: settings.h:139
#define CREATEWIDGETR(type,...)
Definition: createwidget.h:35
Map * getMap() const
Definition: viewport.h:134
static void changeAwayMode(const bool forward)
bool resetBoolValue(const std::string &key)
void setValue(const std::string &key, const std::string &value)
unsigned int targetingType
Definition: settings.h:144
unsigned int pickUpType
Definition: settings.h:138
Viewport * viewport
Definition: viewport.cpp:35
unsigned int crazyMoveType
Definition: settings.h:132
void volumeRestore() const