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