Crossfire Server, Trunk  R21466
c_misc.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #define WANT_UNARMED_SKILLS
21 
22 #include "global.h"
23 
24 #include <assert.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 
30 #undef SS_STATISTICS
31 #include "loader.h"
32 #include "shstr.h"
33 #include "sounds.h"
34 #include "sproto.h"
35 #include "version.h"
36 
45 void map_info(object *op, const char *search) {
46  if ( *search != 0 ) {
48  i18n(op, "Maps matching search: '%s'"), search);
49  }
50  if (QUERY_FLAG(op, FLAG_WIZ)) {
52  i18n(op, "[fixed]Path Reset In (HH:MM:SS) Pl IM TO"));
53  } else {
55  i18n(op, "[fixed]Path Reset In (HH:MM)"));
56  }
57 
58  /* Allow a comma-separate list of search strings; more complicated because of the const */
59  char *to_be_freed = NULL;
60  char *search_array[64];
61  int search_array_count = 0;
62  if ( search[0] ) {
63  to_be_freed = strdup(search);
64  if ( !to_be_freed ) {
65  search_array[0] = to_be_freed;
66  search_array_count = 1;
67  } else {
68  search_array_count = split_string(to_be_freed,search_array,64,',');
69  }
70  }
71 
72  for (mapstruct *m = first_map; m != NULL; m = m->next) {
73  bool match = TRUE;
74  if ( search_array_count ) {
75  match = FALSE;
76  for (int i=0; i<search_array_count; ++i) {
77  if ( strstr(m->path,search_array[i]) ) {
78  match=TRUE;
79  break;
80  }
81  }
82  }
83  if ( !match ) continue; /* Skip unwanted maps */
84 
85  /* Print out the last 26 characters of the map name... */
86  char map_path[MAX_BUF];
87  if (strlen(m->path) <= 26) {
88  strcpy(map_path, m->path);
89  } else {
90  safe_strncpy(map_path, m->path + strlen(m->path) - 26, sizeof(map_path));
91  }
92 
93  uint32_t ttr = MAP_WHEN_RESET(m) - seconds() > 0 ? MAP_WHEN_RESET(m) - seconds() : 0;
94  if ( !m->reset_timeout && !m->unique ) set_map_reset_time(m);
95  if (m->players) {
96  ttr = (m->unique ? 0 : m->reset_timeout) + 300;
97  }
98  else if (m->timeout) {
99  ttr = (m->unique ? 0 : m->reset_timeout) + m->timeout;
100  }
101  const uint32_t hh = ttr/3600, mm = (ttr%3600)/60, ss = ttr%60;
102  if (QUERY_FLAG(op, FLAG_WIZ)) {
105  i18n(op, "[fixed]%-26.26s %2d:%02d:%02d %2d %2d %4d"),
106  map_path, hh, mm, ss, m->players, m->in_memory, m->timeout);
107  } else {
110  i18n(op, "[fixed]%-26.26s %2d:%02d%s"), map_path, hh, mm,
111  m->players ? " (in use)" : "");
112  }
113  }
114  if ( to_be_freed ) free( to_be_freed );
115 }
116 
125 void command_language(object *op, const char *params) {
126  int language = -1;
127 
128  if (!op->contr)
129  return;
130 
131  if (*params == '\0' || (!strcmp(params, ""))) {
133  i18n(op, "Your current language is set to: English."));
135  i18n(op, "Available languages:"));
137  return;
138  }
139 
140  language = i18n_find_language_by_code(params);
141 
142  /* Error out if unknown language. */
143  if (language == -1) {
145  i18n(op, "Unknown language."));
146  return;
147  }
148 
149  op->contr->language = language;
150 
152  i18n(op, "Your current language is set to English."));
153 }
154 
168 void command_body(object *op, const char *params) {
169  int i;
170 
171  /* Too hard to try and make a header that lines everything up, so just
172  * give a description.
173  */
175  i18n(op, "The first column is the name of the body location."));
176 
178  i18n(op, "The second column is how many of those locations your body has."));
179 
181  i18n(op, "The third column is how many slots in that location are available."));
182 
183  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
184  /* really debugging - normally body_used should not be set to anything
185  * if body_info isn't also set.
186  */
187  if (op->body_info[i] || op->body_used[i]) {
189  i18n(op, "[fixed]%-30s %5d %5d"),
190  i18n(op, body_locations[i].use_name), op->body_info[i], op->body_used[i]);
191  }
192  }
193  if (!QUERY_FLAG(op, FLAG_USE_ARMOUR))
195  i18n(op, "You are not allowed to wear armor."));
196  if (!QUERY_FLAG(op, FLAG_USE_WEAPON))
198  i18n(op, "You are not allowed to use weapons."));
199 }
200 
209 void command_motd(object *op, const char *params) {
210  display_motd(op);
211 }
212 
221 void command_rules(object *op, const char *params) {
222  send_rules(op);
223 }
224 
233 void command_news(object *op, const char *params) {
234  send_news(op);
235 }
236 
243 static void malloc_info(object *op) {
244  int ob_used = object_count_used(), ob_free = object_count_free(), players, nrofmaps;
245  int nrm = 0, mapmem = 0, anr, anims, sum_alloc = 0, sum_used = 0, i, tlnr, alnr;
246  treasurelist *tl;
247  player *pl;
248  mapstruct *m;
249  archetype *at;
250  artifactlist *al;
251 
252  for (tl = first_treasurelist, tlnr = 0; tl != NULL; tl = tl->next, tlnr++)
253  ;
254  for (al = first_artifactlist, alnr = 0; al != NULL; al = al->next, alnr++)
255  ;
256 
257  for (at = first_archetype, anr = 0, anims = 0; at != NULL; at = at->more == NULL ? at->next : at->more, anr++)
258  ;
259 
260  for (i = 1; i < num_animations; i++)
261  anims += animations[i].num_animations;
262 
263  for (pl = first_player, players = 0; pl != NULL; pl = pl->next, players++)
264  ;
265 
266  for (m = first_map, nrofmaps = 0; m != NULL; m = m->next, nrofmaps++)
267  if (m->in_memory == MAP_IN_MEMORY) {
268  mapmem += map_size(m) * (sizeof(object *) + sizeof(MapSpace));
269  nrm++;
270  }
271 
273  i18n(op, "Sizeof: object=%d player=%d map=%d"),
274  sizeof(object), sizeof(player), sizeof(mapstruct));
275 
277  i18n(op, "[fixed]Objects:"));
278 
280  i18n(op, "[fixed]%6d used"), ob_used);
281 
282  if (ob_used != nrofallocobjects - nroffreeobjects) {
284  i18n(op, "[fixed] (used list mismatch: %d)"),
286  }
287 
289  i18n(op, "[fixed]%6d free (%.2f%% of %d allocated)"),
290  ob_free, (float)ob_free / nrofallocobjects * 100, nrofallocobjects);
291 
292  if (ob_free != nroffreeobjects) {
294  i18n(op, "[fixed] (free list mismatch: %d)"),
296  }
297 
299  i18n(op, "[fixed]%6d on active list"),
301 
302  i = (ob_used*sizeof(object));
303  sum_used += i;
304  sum_alloc += i;
305 
307  i18n(op, "[fixed] object total: %11d"), i);
308 
309  i = (ob_free*sizeof(object));
310  sum_alloc += i;
311 
313  i18n(op, "[fixed]%4d players: %8d"),
314  players, i = (players*sizeof(player)));
315 
316  sum_alloc += i;
317  sum_used += i;
318 
320  i18n(op, "[fixed]%4d maps allocated: %8d"),
321  nrofmaps, i = (nrofmaps*sizeof(mapstruct)));
322 
323  sum_alloc += i;
324  sum_used += nrm*sizeof(mapstruct);
325 
327  i18n(op, "[fixed]%4d maps in memory: %8d"),
328  nrm, mapmem);
329 
330  sum_alloc += mapmem;
331  sum_used += mapmem;
332 
334  i18n(op, "[fixed]%4d archetypes: %8d"),
335  anr, i = (anr*sizeof(archetype)));
336 
337  sum_alloc += i;
338  sum_used += i;
339 
341  i18n(op, "[fixed]%4d animations: %8d"),
342  anims, i = (anims*sizeof(uint16_t)));
343 
344  sum_alloc += i;
345  sum_used += i;
346 
348  i18n(op, "[fixed]%4d treasurelists %8d"),
349  tlnr, i = (tlnr*sizeof(treasurelist)));
350 
351  sum_alloc += i;
352  sum_used += i;
353 
355  i18n(op, "[fixed]%4ld treasures %8d"),
356  nroftreasures, i = (nroftreasures*sizeof(treasure)));
357 
358  sum_alloc += i;
359  sum_used += i;
360 
362  i18n(op, "[fixed]%4ld artifacts %8d"),
363  nrofartifacts, i = (nrofartifacts*sizeof(artifact)));
364 
365  sum_alloc += i;
366  sum_used += i;
367 
369  i18n(op, "[fixed]%4ld artifacts strngs %8d"),
370  nrofallowedstr, i = (nrofallowedstr*sizeof(linked_char)));
371 
372  sum_alloc += i;
373  sum_used += i;
374 
376  i18n(op, "[fixed]%4d artifactlists %8d"),
377  alnr, i = (alnr*sizeof(artifactlist)));
378 
379  sum_alloc += i;
380  sum_used += i;
381 
383  i18n(op, "[fixed]Total space allocated:%8d"),
384  sum_alloc);
385 
387  i18n(op, "[fixed]Total space used: %8d"),
388  sum_used);
389 }
390 
402 void current_region_info(object *op) {
403  /*
404  * Ok I /suppose/ I should write a seperate function for this, but it isn't
405  * going to be /that/ slow, and won't get called much
406  */
408 
409  /* This should only be possible if regions are not operating on this server. */
410  if (!r)
411  return;
412 
414  i18n(op, "You are in %s.\n%s"),
416 }
417 
424 void current_map_info(object *op) {
425  mapstruct *m = op->map;
426 
427  if (!m)
428  return;
429 
430  char *p = m->path;
431  // Don't expose local file system paths
432  if ( strncmp(p,settings.localdir,strlen(settings.localdir)) == 0 )
433  {
434  p += strlen(settings.localdir);
435  if ( *p == '/' ) ++p;
436  if ( strncmp(p,settings.playerdir,strlen(settings.playerdir)) == 0 )
437  {
438  p += strlen(settings.playerdir);
439  }
440  }
442  "%s (%s) in %s",
444 
445  if (QUERY_FLAG(op, FLAG_WIZ)) {
447  i18n(op, "players:%d difficulty:%d size:%dx%d start:%dx%d timeout %d"),
448  m->players, m->difficulty,
449  MAP_WIDTH(m), MAP_HEIGHT(m),
450  MAP_ENTER_X(m), MAP_ENTER_Y(m),
451  MAP_TIMEOUT(m));
452  }
453  if (m->msg)
455 }
456 
457 #ifdef DEBUG_MALLOC_LEVEL
458 
466 void command_malloc_verify(object *op, char *parms) {
467  extern int malloc_verify(void);
468 
469  if (!malloc_verify())
471  i18n(op, "Heap is corrupted."));
472  else
474  i18n(op, "Heap checks out OK."));
475 
476  return 1;
477 }
478 #endif
479 
490 void command_whereabouts(object *op, const char *params) {
491  region *reg;
492  player *pl;
493 
494  /*
495  * reset the counter on the region, then use it to store the number of
496  * players there.
497  * I don't know how thread-safe this would be, I suspect not very....
498  */
499  for (reg = first_region; reg != NULL; reg = reg->next) {
500  reg->counter = 0;
501  }
502  for (pl = first_player; pl != NULL; pl = pl->next)
503  if (pl->ob->map != NULL)
504  get_region_by_map(pl->ob->map)->counter++;
505 
506  /* we only want to print out by places with a 'longname' field...*/
507  for (reg = first_region; reg != NULL; reg = reg->next) {
508  if (reg->longname == NULL && reg->counter > 0) {
509  if (reg->parent != NULL) {
510  reg->parent->counter += reg->counter;
511  reg->counter = 0;
512  } else /*uh oh, we shouldn't be here. */
513  LOG(llevError, "command_whereabouts() Region %s with no longname has no parent\n", reg->name);
514  }
515  }
517  i18n(op, "In the world currently there are:"));
518 
519  for (reg = first_region; reg != NULL; reg = reg->next)
520  if (reg->counter > 0) {
522  i18n(op, "%u players in %s"),
523  reg->counter, get_region_longname(reg));
524  }
525 }
526 
528 typedef struct {
529  char namebuf[MAX_BUF];
531 } chars_names;
532 
542 static int name_cmp(const chars_names *c1, const chars_names *c2) {
543  return strcasecmp(c1->namebuf, c2->namebuf);
544 }
545 
556 void list_players(object *op, region *reg, partylist *party) {
557  player *pl;
558  uint16_t i;
559  char *format;
560  int num_players = 0, num_wiz = 0, num_afk = 0, num_bot = 0;
561  chars_names *chars = NULL;
562 
563  if (op == NULL || QUERY_FLAG(op, FLAG_WIZ))
564  format = settings.who_wiz_format;
565  else
566  format = settings.who_format;
567 
568  for (pl = first_player; pl != NULL; pl = pl->next) {
569  if (pl->ob->map == NULL)
570  continue;
571  if (pl->hidden && !QUERY_FLAG(op, FLAG_WIZ))
572  continue;
573 
574  if (reg && !region_is_child_of_region(get_region_by_map(pl->ob->map), reg))
575  continue;
576  if (party && pl->party != party)
577  continue;
578 
579  if (pl->state == ST_PLAYING || pl->state == ST_GET_PARTY_PASSWORD) {
580  num_players++;
581  chars = (chars_names *)realloc(chars, num_players*sizeof(chars_names));
582  if (chars == NULL) {
584  i18n(op, "who failed - out of memory!"));
585  return;
586  }
587  sprintf(chars[num_players-1].namebuf, "%s", pl->ob->name);
588  chars[num_players-1].login_order = num_players;
589 
590  /* Check for WIZ's & AFK's*/
591  if (QUERY_FLAG(pl->ob, FLAG_WIZ))
592  num_wiz++;
593 
594  if (QUERY_FLAG(pl->ob, FLAG_AFK))
595  num_afk++;
596 
597  if (pl->socket.is_bot)
598  num_bot++;
599  }
600  }
601  if (first_player != (player *)NULL) {
602  if (reg == NULL && party == NULL)
604  i18n(op, "Total Players (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
605  num_players, num_wiz, num_afk, num_bot);
606  else if (party == NULL)
608  i18n(op, "Total Players in %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
609  reg->longname ? reg->longname : reg->name, num_players, num_wiz, num_afk, num_bot);
610  else
612  i18n(op, "Total Players in party %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
613  party->partyname, num_players, num_wiz, num_afk, num_bot);
614  }
615  qsort(chars, num_players, sizeof(chars_names), (int (*)(const void *, const void *))name_cmp);
616  for (i = 0; i < num_players; i++)
617  display_who_entry(op, find_player(chars[i].namebuf), format);
618  free(chars);
619 }
620 
629 void command_who(object *op, const char *params) {
630  region *reg;
631 
632  reg = get_region_from_string(params);
633  list_players(op, reg, NULL);
634 }
635 
646 void display_who_entry(object *op, player *pl, const char *format) {
647  char tmpbuf[MAX_BUF];
648  char outbuf[MAX_BUF];
649  size_t i;
650 
651  strcpy(outbuf, "[fixed]");
652 
653  if (pl == NULL) {
654  LOG(llevError, "display_who_entry(): I was passed a null player\n");
655  return;
656  }
657  for (i = 0; i <= strlen(format); i++) {
658  if (format[i] == '%') {
659  i++;
660  get_who_escape_code_value(tmpbuf, sizeof(tmpbuf), format[i], pl);
661  strcat(outbuf, tmpbuf);
662  } else if (format[i] == '_') {
663  strcat(outbuf, " "); /* allow '_' to be used in place of spaces */
664  } else {
665  snprintf(tmpbuf, sizeof(tmpbuf), "%c", format[i]);
666  strcat(outbuf, tmpbuf);
667  }
668  }
670 }
671 
702 void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl) {
703  switch (letter) {
704  case 'N':
705  strlcpy(return_val, pl->ob->name, size);
706  break;
707 
708  case 't':
709  player_get_title(pl, return_val, size);
710  break;
711 
712  case 'c':
713  snprintf(return_val, size, "%u", pl->ob->count);
714  break;
715 
716  case 'n':
717  snprintf(return_val, size, "\n");
718  break;
719 
720  case 'h':
721  strlcpy(return_val, pl->peaceful ? "" : " <Hostile>", size);
722  break;
723 
724  case 'l':
725  snprintf(return_val, size, "%d", pl->ob->level);
726  break;
727 
728  case 'd':
729  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_WIZ) ? " <WIZ>" : ""), size);
730  break;
731 
732  case 'a':
733  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_AFK) ? " <AFK>" : ""), size);
734  break;
735 
736  case 'b':
737  strlcpy(return_val, (pl->socket.is_bot == 1) ? " <BOT>" : "", size);
738  break;
739 
740  case 'm':
741  // If path starts with .../var/crossfire/players/ then strip off the path
742  {
743  char *p = pl->ob->map->path;
744  if ( strncmp(p,settings.localdir,strlen(settings.localdir)) == 0 )
745  {
746  p += strlen(settings.localdir);
747  if ( *p == '/' ) ++p;
748  if ( strncmp(p,settings.playerdir,strlen(settings.playerdir)) == 0 )
749  {
750  p += strlen(settings.playerdir);
751  }
752  }
753  strlcpy(return_val, p, size);
754  }
755  break;
756 
757  case 'M':
758  strlcpy(return_val, pl->ob->map->name ? pl->ob->map->name : "Untitled", size);
759  break;
760 
761  case 'r':
762  strlcpy(return_val, get_name_of_region_for_map(pl->ob->map), size);
763  break;
764 
765  case 'R':
766  strlcpy(return_val, get_region_longname(get_region_by_map(pl->ob->map)), size);
767  break;
768 
769  case 'i':
770  strlcpy(return_val, pl->socket.host, size);
771  break;
772 
773  case '%':
774  snprintf(return_val, size, "%%");
775  break;
776 
777  case '_':
778  snprintf(return_val, size, "_");
779  break;
780  }
781 }
782 
791 void command_afk(object *op, const char *params) {
792  if (QUERY_FLAG(op, FLAG_AFK)) {
793  CLEAR_FLAG(op, FLAG_AFK);
795  i18n(op, "You are no longer AFK"));
796  } else {
797  SET_FLAG(op, FLAG_AFK);
799  i18n(op, "You are now AFK"));
800  }
801 }
802 
811 void command_malloc(object *op, const char *params) {
812  malloc_info(op);
813 }
814 
823 void command_mapinfo(object *op, const char *params) {
824  current_map_info(op);
825 }
826 
835 void command_whereami(object *op, const char *params) {
837 }
838 
847 void command_maps(object *op, const char *params) {
848  map_info(op, params);
849 }
850 
859 void command_strings(object *op, const char *params) {
860  char stats[HUGE_BUF];
861 
862  ss_dump_statistics(stats, sizeof(stats));
864  "[fixed]%s\n",
865  stats);
866 
868  ss_dump_table(SS_DUMP_TOTALS, stats, sizeof(stats)));
869 }
870 
879 void command_time(object *op, const char *params) {
880  time_info(op);
881 }
882 
891 void command_archs(object *op, const char *params) {
892  arch_info(op);
893 }
894 
903 void command_hiscore(object *op, const char *params) {
904  hiscore_display(op, op == NULL ? 9999 : 50, params);
905 }
906 
915 void command_debug(object *op, const char *params) {
916  int i;
917 
918  if (*params == '\0' || !sscanf(params, "%d", &i)) {
920  i18n(op, "Global debug level is %d."),
921  settings.debug);
922  return;
923  }
924  settings.debug = (enum LogLevel)FABS(i);
926  i18n(op, "Debug level set to %d."),
927  i);
928 }
929 
930 
939 void command_wizpass(object *op, const char *params) {
940  int i;
941 
942  if (!op)
943  return;
944 
945  if (*params == '\0')
946  i = (QUERY_FLAG(op, FLAG_WIZPASS)) ? 0 : 1;
947  else
948  i = onoff_value(params);
949 
950  if (i) {
952  i18n(op, "You will now walk through walls."));
953  SET_FLAG(op, FLAG_WIZPASS);
954  } else {
956  i18n(op, "You will now be stopped by walls."));
958  }
959 }
960 
969 void command_wizcast(object *op, const char *params) {
970  int i;
971 
972  if (!op)
973  return;
974 
975  if (*params == '\0')
976  i = (QUERY_FLAG(op, FLAG_WIZCAST)) ? 0 : 1;
977  else
978  i = onoff_value(params);
979 
980  if (i) {
982  i18n(op, "You can now cast spells anywhere."));
983  SET_FLAG(op, FLAG_WIZCAST);
984  } else {
986  i18n(op, "You now cannot cast spells in no-magic areas."));
988  }
989 }
990 
999 void command_dumpallobjects(object *op, const char *params) {
1000  object_dump_all();
1001 }
1002 
1011 void command_dumpfriendlyobjects(object *op, const char *params) {
1013 }
1014 
1023 void command_dumpallarchetypes(object *op, const char *params) {
1025 }
1026 
1035 void command_ssdumptable(object *op, const char *params) {
1036  ss_dump_table(SS_DUMP_TABLE, NULL, 0);
1037 }
1038 
1047 void command_dumpmap(object *op, const char *params) {
1048  if (op)
1049  dump_map(op->map);
1050 }
1051 
1060 void command_dumpallmaps(object *op, const char *params) {
1061  dump_all_maps();
1062 }
1063 
1072 void command_printlos(object *op, const char *params) {
1073  if (op)
1074  print_los(op);
1075 }
1076 
1077 
1086 void command_version(object *op, const char *params) {
1088  MSG_TYPE_ADMIN_VERSION, "Crossfire "FULL_VERSION);
1089 }
1090 
1099 void command_listen(object *op, const char *params) {
1100  int i;
1101 
1102  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1104  i18n(op, "Set listen to what (presently %d)?"),
1105  op->contr->listening);
1106  return;
1107  }
1108  if (i < 0) {
1110  i18n(op, "Verbose level should be positive."));
1111  return;
1112  }
1113  op->contr->listening = (char)i;
1115  i18n(op, "Your verbose level is now %d."),
1116  i);
1117 }
1118 
1130 void command_statistics(object *pl, const char *params) {
1131  char buf[MAX_BUF];
1132  uint32_t hours, minutes;
1133  uint64_t seconds; /* 64 bit to prevent overflows an intermediate results */
1134 
1135  if (!pl->contr)
1136  return;
1137  safe_strncpy(buf, i18n(pl, "[fixed] Experience: %"), sizeof(buf));
1138  strcat(buf, FMT64);
1140  buf,
1141  pl->stats.exp);
1142  safe_strncpy(buf, i18n(pl, "[fixed] Next Level: %"), sizeof(buf));
1143  strcat(buf, FMT64);
1145  buf,
1146  level_exp(pl->level+1, pl->expmul));
1147 
1149  i18n(pl, "[fixed]\nStat Nat/Real/Max"));
1150 
1152  i18n(pl, "[fixed]Str %2d/ %3d/%3d"),
1153  pl->contr->orig_stats.Str, pl->stats.Str, 20+pl->arch->clone.stats.Str);
1155  i18n(pl, "[fixed]Dex %2d/ %3d/%3d"),
1156  pl->contr->orig_stats.Dex, pl->stats.Dex, 20+pl->arch->clone.stats.Dex);
1158  i18n(pl, "[fixed]Con %2d/ %3d/%3d"),
1159  pl->contr->orig_stats.Con, pl->stats.Con, 20+pl->arch->clone.stats.Con);
1161  i18n(pl, "[fixed]Int %2d/ %3d/%3d"),
1162  pl->contr->orig_stats.Int, pl->stats.Int, 20+pl->arch->clone.stats.Int);
1164  i18n(pl, "[fixed]Wis %2d/ %3d/%3d"),
1165  pl->contr->orig_stats.Wis, pl->stats.Wis, 20+pl->arch->clone.stats.Wis);
1167  i18n(pl, "[fixed]Pow %2d/ %3d/%3d"),
1168  pl->contr->orig_stats.Pow, pl->stats.Pow, 20+pl->arch->clone.stats.Pow);
1170  i18n(pl, "[fixed]Cha %2d/ %3d/%3d"),
1171  pl->contr->orig_stats.Cha, pl->stats.Cha, 20+pl->arch->clone.stats.Cha);
1173  i18n(pl, "\nAttack Mode: %s"),
1174  i18n(pl, pl->contr->peaceful ? "Peaceful" : "Hostile"));
1178  float weap_speed = pl->weapon_speed; // This is the number of attacks per tick.
1179  if (weap_speed < 0.0f)
1180  weap_speed = 0.0f;
1181  if (weap_speed > 1.0f)
1182  weap_speed = 1.0f;
1183  // We will initially calculate the damage if every attack you perform hits.
1184  // This will serve as a baseline for future calculations
1185  float dps = (1000000.0f / max_time) * weap_speed * pl->stats.dam;
1186  // TODO: Account for opposing AC in calculations, make some sort of table/chart.
1187  // Then we round the floating-point.
1189  i18n(pl, "\n\nDam/Sec: %4d"), (int)(dps + 0.5f));
1190 
1191  /* max_time is in microseconds - thus divide by 1000000.
1192  * Need 64 bit values, as otherwise ticks_played * max_time
1193  * can easily overflow.
1194  * Note the message displayed here isn't really
1195  * perfect, since if max_time has been changed since the player started,
1196  * the time estimates use the current value. But I'm presuming that
1197  * max_time won't change very often. MSW 2009-12-01
1198  */
1199  seconds = (uint64_t)pl->contr->ticks_played * (uint64_t)max_time / 1000000;
1200  minutes = (uint32_t)seconds / 60;
1201  hours = minutes / 60;
1202  minutes = minutes % 60;
1203 
1205  "You have played this character for %u ticks, which amounts "
1206  "to %d hours and %d minutes.",
1207  pl->contr->ticks_played, hours, minutes);
1208 
1209 
1210  /* Can't think of anything else to print right now */
1211 }
1212 
1221 void command_fix_me(object *op, const char *params) {
1222  object_sum_weight(op);
1223  fix_object(op);
1224 }
1225 
1234 void command_players(object *op, const char *params) {
1235  char buf[MAX_BUF];
1236  char *t;
1237  DIR *dir;
1238 
1239  snprintf(buf, sizeof(buf), "%s/%s/", settings.localdir, settings.playerdir);
1240  t = buf+strlen(buf);
1241  if ((dir = opendir(buf)) != NULL) {
1242  const struct dirent *entry;
1243 
1244  while ((entry = readdir(dir)) != NULL) {
1245  /* skip '.' , '..' */
1246  if (!((entry->d_name[0] == '.' && entry->d_name[1] == '\0')
1247  || (entry->d_name[0] == '.' && entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) {
1248  struct stat st;
1249 
1250  strcpy(t, entry->d_name);
1251  if (stat(buf, &st) == 0) {
1252  /* This was not posix compatible
1253  * if ((st.st_mode & S_IFMT)==S_IFDIR) {
1254  */
1255  if (S_ISDIR(st.st_mode)) {
1256  struct tm *tm = localtime(&st.st_mtime);
1257 
1259  i18n(op, "[fixed]%s\t%04d %02d %02d %02d %02d %02d"),
1260  entry->d_name,
1261  1900+tm->tm_year,
1262  1+tm->tm_mon,
1263  tm->tm_mday,
1264  tm->tm_hour,
1265  tm->tm_min,
1266  tm->tm_sec);
1267  }
1268  }
1269  }
1270  }
1271  }
1272  closedir(dir);
1273 }
1274 
1283 void command_applymode(object *op, const char *params) {
1284  unapplymode unapply = op->contr->unapply;
1285  static const char *const types[] = {
1286  "nochoice",
1287  "never",
1288  "always"
1289  };
1290 
1291  if (*params == '\0') {
1293  i18n(op, "applymode is set to %s"),
1294  types[op->contr->unapply]);
1295  return;
1296  }
1297 
1298  if (!strcmp(params, "nochoice"))
1300  else if (!strcmp(params, "never"))
1301  op->contr->unapply = unapply_never;
1302  else if (!strcmp(params, "always"))
1303  op->contr->unapply = unapply_always;
1304  else {
1306  i18n(op, "applymode: Unknown options %s, valid options are nochoice, never, always"),
1307  params);
1308  return;
1309  }
1311  i18n(op, "applymode%s set to %s"),
1312  (unapply == op->contr->unapply ? "" : " now"),
1313  types[op->contr->unapply]);
1314 }
1315 
1324 void command_bowmode(object *op, const char *params) {
1325  bowtype_t oldtype = op->contr->bowtype;
1326  static const char *const types[] = {
1327  "normal",
1328  "threewide",
1329  "spreadshot",
1330  "firenorth",
1331  "firene",
1332  "fireeast",
1333  "firese",
1334  "firesouth",
1335  "firesw",
1336  "firewest",
1337  "firenw",
1338  "bestarrow"
1339  };
1340  char buf[MAX_BUF];
1341  int i, found;
1342 
1343  if (*params == '\0') {
1345  i18n(op, "bowmode is set to %s"),
1346  types[op->contr->bowtype]);
1347  return;
1348  }
1349 
1350  for (i = 0, found = 0; i <= bow_bestarrow; i++) {
1351  if (!strcmp(params, types[i])) {
1352  found++;
1353  op->contr->bowtype = i;
1354  break;
1355  }
1356  }
1357  if (!found) {
1358  snprintf(buf, sizeof(buf), "bowmode: Unknown options %s, valid options are:", params);
1359  for (i = 0; i <= bow_bestarrow; i++) {
1360  strcat(buf, " ");
1361  strcat(buf, types[i]);
1362  if (i < bow_nw)
1363  strcat(buf, ",");
1364  else
1365  strcat(buf, ".");
1366  }
1368  return;
1369  }
1371  i18n(op, "bowmode%s set to %s"),
1372  (oldtype == op->contr->bowtype ? "" : " now"),
1373  types[op->contr->bowtype]);
1374  return;
1375 }
1376 
1385 void command_unarmed_skill(object *op, const char *params) {
1386  object *skill;
1387  size_t i;
1388 
1389  if (*params == '\0') {
1391  "unarmed skill is set to %s",
1392  op->contr->unarmed_skill ? op->contr->unarmed_skill: "nothing");
1393  return;
1394  }
1395 
1396  /* find_skill_by_name() will ready any skill tools - which
1397  * is OK for us because no unarmed skills require skill tools,
1398  * but this could be an issue if you reuse this code for other skills.
1399  */
1400  skill = find_skill_by_name(op, params);
1401 
1402  if (!skill) {
1404  "You do not know any such skill called %s",
1405  params);
1406  return;
1407  }
1408  for (i = 0; i < sizeof(unarmed_skills); i++)
1409  if (skill->subtype == unarmed_skills[i])
1410  break;
1411  if (i == sizeof(unarmed_skills)) {
1413  "%s is not an unarmed skill!",
1414  skill->name);
1415  return;
1416 
1417  }
1418 
1419  if (op->contr->unarmed_skill)
1421 
1422  /* Taking actual skill name is better than taking params,
1423  * as params could be something more than an exact skill name.
1424  */
1425  op->contr->unarmed_skill = add_string(skill->name);
1426 
1428  "unarmed skill is now set to %s",
1429  op->contr->unarmed_skill);
1430 }
1431 
1432 
1441 void command_petmode(object *op, const char *params) {
1442  petmode_t oldtype = op->contr->petmode;
1443  static const char *const types[] = {
1444  "normal",
1445  "sad",
1446  "defend",
1447  "arena"
1448  };
1449 
1450  if (*params == '\0') {
1452  i18n(op, "petmode is set to %s"),
1453  types[op->contr->petmode]);
1454  return;
1455  }
1456 
1457  if (!strcmp(params, "normal"))
1458  op->contr->petmode = pet_normal;
1459  else if (!strcmp(params, "sad"))
1460  op->contr->petmode = pet_sad;
1461  else if (!strcmp(params, "defend"))
1462  op->contr->petmode = pet_defend;
1463  else if (!strcmp(params, "arena"))
1464  op->contr->petmode = pet_arena;
1465  else {
1467  i18n(op, "petmode: Unknown options %s, valid options are normal, sad (seek and destroy), defend, arena"),
1468  params);
1469  return;
1470  }
1472  i18n(op, "petmode%s set to %s"),
1473  (oldtype == op->contr->petmode ? "" : " now"),
1474  types[op->contr->petmode]);
1475 }
1476 
1485 void command_showpets(object *op, const char *params) {
1486  objectlink *obl, *next;
1487  int counter = 0, target = 0;
1488  int have_shown_pet = 0;
1489  if (*params != '\0')
1490  target = atoi(params);
1491 
1492  for (obl = first_friendly_object; obl != NULL; obl = next) {
1493  object *ob = obl->ob;
1494 
1495  next = obl->next;
1496  if (object_get_owner(ob) == op) {
1497  if (target == 0) {
1498  if (counter == 0)
1500  i18n(op, "Pets:"));
1502  i18n(op, "%d %s - level %d"),
1503  ++counter, ob->name, ob->level);
1504  } else if (!have_shown_pet && ++counter == target) {
1506  i18n(op, "[fixed]level %d %s"),
1507  ob->level, ob->name);
1509  i18n(op, "[fixed]%d/%d HP, %d/%d SP"),
1510  ob->stats.hp, ob->stats.maxhp, ob->stats.sp, ob->stats.maxsp);
1511 
1512  /* this is not a nice way to do this, it should be made to be more like the statistics command */
1514  i18n(op, "[fixed]Str %d"),
1515  ob->stats.Str);
1517  i18n(op, "[fixed]Dex %d"),
1518  ob->stats.Dex);
1520  i18n(op, "[fixed]Con %d"),
1521  ob->stats.Con);
1523  i18n(op, "[fixed]Int %d"),
1524  ob->stats.Int);
1526  i18n(op, "[fixed]Wis %d"),
1527  ob->stats.Wis);
1529  i18n(op, "[fixed]Cha %d"),
1530  ob->stats.Cha);
1532  i18n(op, "[fixed]Pow %d"),
1533  ob->stats.Pow);
1535  i18n(op, "[fixed]wc %d damage %d ac %d"),
1536  ob->stats.wc, ob->stats.dam, ob->stats.ac);
1537  have_shown_pet = 1;
1538  }
1539  }
1540  }
1541  if (counter == 0)
1543  i18n(op, "You have no pets."));
1544  else if (target != 0 && have_shown_pet == 0)
1546  i18n(op, "No such pet."));
1547 }
1548 
1557 void command_usekeys(object *op, const char *params) {
1558  usekeytype oldtype = op->contr->usekeys;
1559  static const char *const types[] = {
1560  "inventory",
1561  "keyrings",
1562  "containers"
1563  };
1564 
1565  if (*params == '\0') {
1567  i18n(op, "usekeys is set to %s"),
1568  types[op->contr->usekeys]);
1569  return;
1570  }
1571 
1572  if (!strcmp(params, "inventory"))
1573  op->contr->usekeys = key_inventory;
1574  else if (!strcmp(params, "keyrings"))
1575  op->contr->usekeys = keyrings;
1576  else if (!strcmp(params, "containers"))
1577  op->contr->usekeys = containers;
1578  else {
1580  i18n(op, "usekeys: Unknown option %s, valid options are inventory, keyrings, containers"),
1581  params);
1582  return;
1583  }
1585  i18n(op, "usekeys%s set to %s"),
1586  (oldtype == op->contr->usekeys ? "" : " now"),
1587  types[op->contr->usekeys]);
1588 }
1589 
1598 void command_resistances(object *op, const char *params) {
1599  int i;
1600  if (!op)
1601  return;
1602 
1603  for (i = 0; i < NROFATTACKS; i++) {
1604  if (i == ATNR_INTERNAL)
1605  continue;
1606 
1608  i18n(op, "[fixed]%-20s %+5d"),
1609  attacktype_desc[i], op->resist[i]);
1610  }
1611 
1612  /* If dragon player, let's display natural resistances */
1613  if (is_dragon_pl(op)) {
1614  int attack;
1615  object *tmp;
1616 
1617  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
1618  if (tmp != NULL) {
1620  i18n(op, "\nNatural skin resistances:"));
1621 
1622  for (attack = 0; attack < NROFATTACKS; attack++) {
1623  if (atnr_is_dragon_enabled(attack)) {
1625  i18n(op, "%s: %d"),
1626  change_resist_msg[attack], tmp->resist[attack]);
1627  }
1628  }
1629  }
1630  }
1631 }
1632 
1643 static void help_topics(object *op, int what) {
1644  DIR *dirp;
1645  struct dirent *de;
1646  char filename[MAX_BUF], line[HUGE_BUF];
1647  char suffix[MAX_BUF];
1648  int namelen;
1649  const char *language;
1650 
1651  language = i18n_get_language_code(op->contr->language);
1652  snprintf(suffix, sizeof(suffix), ".%s", language);
1653 
1654  switch (what) {
1655  case 1:
1656  snprintf(filename, sizeof(filename), "%s/wizhelp", settings.datadir);
1658  i18n(op, " Wiz commands:"));
1659  break;
1660 
1661  case 3:
1662  snprintf(filename, sizeof(filename), "%s/mischelp", settings.datadir);
1664  i18n(op, " Misc help:"));
1665  break;
1666 
1667  default:
1668  snprintf(filename, sizeof(filename), "%s/help", settings.datadir);
1670  i18n(op, " Commands:"));
1671  break;
1672  }
1673  if (!(dirp = opendir(filename)))
1674  return;
1675 
1676  line[0] = '\0';
1677  for (de = readdir(dirp); de; de = readdir(dirp)) {
1678  namelen = NAMLEN(de);
1679 
1680  if (namelen <= 2
1681  && *de->d_name == '.'
1682  && (namelen == 1 || de->d_name[1] == '.'))
1683  continue;
1684  if (strstr(de->d_name, suffix)) {
1685  strcat(line, strtok(de->d_name, "."));
1686  strcat(line, " ");
1687  }
1688  }
1690  line);
1691  closedir(dirp);
1692 }
1693 
1704 static void show_commands(object *op, int what) {
1705  char line[HUGE_BUF];
1706  int i, size;
1708 
1709  switch (what) {
1710  case 1:
1711  ap = WizCommands;
1712  size = WizCommandsSize;
1714  i18n(op, " Wiz commands:"));
1715  break;
1716 
1717  case 2:
1718  ap = CommunicationCommands;
1719  size = CommunicationCommandSize;
1721  i18n(op, " Communication commands:"));
1722  break;
1723 
1724  default:
1725  ap = Commands;
1726  size = CommandsSize;
1728  i18n(op, " Commands:"));
1729  break;
1730  }
1731 
1732  line[0] = '\0';
1733  for (i = 0; i < size; i++) {
1734  strcat(line, ap[i].name);
1735  strcat(line, " ");
1736  }
1738 }
1739 
1751 static int find_help_file(const char *name, const char *language, int wiz, char *path, int length) {
1752  struct stat st;
1753 
1754  snprintf(path, length, "%s/help/%s.%s", settings.datadir, name, language);
1755  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1756  return 1;
1757  }
1758 
1759  if (strcmp(language, "en")) {
1760  snprintf(path, length, "%s/help/%s.en", settings.datadir, name);
1761  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1762  return 1;
1763  }
1764  }
1765 
1766  if (!wiz)
1767  return 0;
1768 
1769  snprintf(path, length, "%s/wizhelp/%s.%s", settings.datadir, name, language);
1770  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1771  return 1;
1772  }
1773  if (strcmp(language, "en")) {
1774  snprintf(path, length, "%s/wizhelp/%s.en", settings.datadir, name);
1775  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1776  return 1;
1777  }
1778  }
1779 
1780  return 0;
1781 }
1782 
1791 void command_help(object *op, const char *params) {
1792  FILE *fp;
1793  char filename[MAX_BUF], line[MAX_BUF];
1794  int len;
1795  const char *language;
1796 
1797  /*
1798  * Main help page?
1799  */
1800  if (*params == '\0') {
1801  snprintf(filename, sizeof(filename), "%s/def_help", settings.datadir);
1802  if ((fp = fopen(filename, "r")) == NULL) {
1803  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1804  return;
1805  }
1806  while (fgets(line, MAX_BUF, fp)) {
1807  line[MAX_BUF-1] = '\0';
1808  len = strlen(line)-1;
1809  if (line[len] == '\n')
1810  line[len] = '\0';
1812  }
1813  fclose(fp);
1814  return;
1815  }
1816 
1817  /*
1818  * Topics list
1819  */
1820  if (!strcmp(params, "topics")) {
1821  help_topics(op, 3);
1822  help_topics(op, 0);
1823  if (QUERY_FLAG(op, FLAG_WIZ))
1824  help_topics(op, 1);
1825  return;
1826  }
1827 
1828  /*
1829  * Commands list
1830  */
1831  if (!strcmp(params, "commands")) {
1832  show_commands(op, 0);
1834  show_commands(op, 2); /* show comm commands */
1835  if (QUERY_FLAG(op, FLAG_WIZ)) {
1837  show_commands(op, 1);
1838  }
1839  return;
1840  }
1841 
1842  /*
1843  * User wants info about command
1844  */
1845  if (strchr(params, '.') || strchr(params, ' ') || strchr(params, '/')) {
1847  i18n(op, "Illegal characters in '%s'"),
1848  params);
1849  return;
1850  }
1851 
1852  language = i18n_get_language_code(op->contr->language);
1853 
1854  if (!find_help_file(params, language, QUERY_FLAG(op, FLAG_WIZ), filename, sizeof(filename))) {
1856  i18n(op, "No help available on '%s'"),
1857  params);
1858  return;
1859  }
1860 
1861  /*
1862  * Found that. Just cat it to screen.
1863  */
1864  if ((fp = fopen(filename, "r")) == NULL) {
1865  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1866  return;
1867  }
1868 
1870  i18n(op, "Help about '%s'"),
1871  params);
1872 
1873  while (fgets(line, MAX_BUF, fp)) {
1874  line[MAX_BUF-1] = '\0';
1875  len = strlen(line)-1;
1876  if (line[len] == '\n')
1877  line[len] = '\0';
1879  }
1880  fclose(fp);
1881 }
1882 
1893 int onoff_value(const char *line) {
1894  int i;
1895 
1896  if (sscanf(line, "%d", &i))
1897  return (i != 0);
1898 
1899  switch (line[0]) {
1900  case 'o':
1901  switch (line[1]) {
1902  case 'n':
1903  return 1; /* on */
1904  default:
1905  return 0; /* o[ff] */
1906  }
1907 
1908  case 'y': /* y[es] */
1909  case 'k': /* k[ylla] */
1910  case 's':
1911  case 'd':
1912  return 1;
1913 
1914  case 'n': /* n[o] */
1915  case 'e': /* e[i] */
1916  case 'u':
1917  default:
1918  return 0;
1919  }
1920 }
1921 
1927 void command_quit(object* op, const char* params) {
1928  draw_ext_info(
1930  i18n(op,
1931  "To leave the game, sleep in (apply) a bed to reality. To "
1932  "permenantly delete your character, use the 'delete' command."));
1933 }
1934 
1943 void command_delete(object *op, const char *params) {
1944  if (QUERY_FLAG(op, FLAG_WAS_WIZ)) {
1945  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_ADMIN_DM, "Can't quit when in DM mode.");
1946  return;
1947  }
1948 
1950  i18n(op, "Quitting will delete your character.\nAre you sure you want to delete your character (y/n):"));
1951 
1953 }
1954 
1963 void command_sound(object *op, const char *params) {
1964  if (!(op->contr->socket.sound&SND_MUTE)) {
1965  op->contr->socket.sound = op->contr->socket.sound|SND_MUTE;
1967  i18n(op, "Sounds are turned off."));
1968  } else {
1969  op->contr->socket.sound = op->contr->socket.sound&~SND_MUTE;
1971  i18n(op, "The sounds are enabled."));
1972  }
1973  return;
1974 }
1975 
1985 void receive_player_name(object *op) {
1986  if (!check_name(op->contr, op->contr->write_buf+1)) {
1987  get_name(op);
1988  return;
1989  }
1990  FREE_AND_COPY(op->name, op->contr->write_buf+1);
1991  FREE_AND_COPY(op->name_pl, op->contr->write_buf+1);
1993  op->contr->name_changed = 1;
1994  get_password(op);
1995 }
1996 
2003 void receive_player_password(object *op) {
2004  unsigned int pwd_len = strlen(op->contr->write_buf);
2005 
2006  if (pwd_len <= 1 || pwd_len > 17) {
2007  if (op->contr->state == ST_CHANGE_PASSWORD_OLD
2009  || op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
2011  i18n(op, "Password changed cancelled."));
2013  } else
2014  get_name(op);
2015  return;
2016  }
2017  /* To hide the password better */
2018  /* With currently clients, not sure if this is really the case - MSW */
2020 
2021  if (checkbanned(op->name, op->contr->socket.host)) {
2022  LOG(llevInfo, "Banned player tried to add: [%s@%s]\n", op->name, op->contr->socket.host);
2024  i18n(op, "You are not allowed to play."));
2025  get_name(op);
2026  return;
2027  }
2028 
2029  if (op->contr->state == ST_CONFIRM_PASSWORD) {
2030  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
2032  i18n(op, "The passwords did not match."));
2033  get_name(op);
2034  return;
2035  }
2036  LOG(llevInfo, "LOGIN: New player named %s from ip %s\n", op->name, op->contr->socket.host);
2037  display_motd(op);
2039  i18n(op, "\nWelcome, Brave New Warrior!\n"));
2040  roll_again(op);
2042  return;
2043  }
2044 
2045  if (op->contr->state == ST_CHANGE_PASSWORD_OLD) {
2046  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
2048  i18n(op, "You entered the wrong current password."));
2050  } else {
2051  send_query(&op->contr->socket, CS_QUERY_HIDEINPUT, i18n(op, "Please enter your new password, or blank to cancel:"));
2053  }
2054  return;
2055  }
2056 
2057  if (op->contr->state == ST_CHANGE_PASSWORD_NEW) {
2059  sizeof(op->contr->new_password));
2061  i18n(op, "Please confirm your new password, or blank to cancel:"));
2063  return;
2064  }
2065 
2066  if (op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
2067  if (!check_password(op->contr->write_buf+1, op->contr->new_password)) {
2069  i18n(op, "The new passwords don't match!"));
2070  } else {
2072  i18n(op, "Password changed."));
2073  strncpy(op->contr->password, op->contr->new_password, 13);
2074  }
2076  return;
2077  }
2078 
2080  sizeof(op->contr->password));
2082  check_login(op, TRUE);
2083 }
2084 
2095 void command_title(object *op, const char *params) {
2096  char buf[MAX_BUF];
2097 
2098  if (settings.set_title == FALSE) {
2100  i18n(op, "You cannot change your title."));
2101  return;
2102  }
2103 
2104  /* dragon players cannot change titles */
2105  if (is_dragon_pl(op)) {
2107  i18n(op, "Dragons cannot change titles."));
2108  return;
2109  }
2110 
2111  if (*params == '\0') {
2112  char tmp[MAX_BUF];
2113 
2114  player_get_title(op->contr, tmp, sizeof(tmp));
2115  snprintf(buf, sizeof(buf), i18n(op, "Your title is '%s'."), tmp);
2117  return;
2118  }
2119  if (strcmp(params, "clear") == 0 || strcmp(params, "default") == 0) {
2120  if (!player_has_own_title(op->contr))
2122  i18n(op, "Your title is the default title."));
2123  else
2125  i18n(op, "Title set to default."));
2126  player_set_own_title(op->contr, "");
2127  return;
2128  }
2129 
2130  if ((int)strlen(params) >= MAX_NAME) {
2132  i18n(op, "Title too long."));
2133  return;
2134  }
2135  player_set_own_title(op->contr, params);
2136 }
2137 
2146 void command_save(object *op, const char *params) {
2147  if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL)&P_NO_CLERIC) {
2149  i18n(op, "You can not save on unholy ground."));
2150  } else if (!op->stats.exp) {
2152  i18n(op, "You don't deserve to save yet."));
2153  } else {
2154  if (save_player(op, 1))
2156  i18n(op, "You have been saved."));
2157  else
2159  i18n(op, "SAVE FAILED!"));
2160  }
2161 }
2162 
2171 void command_peaceful(object *op, const char *params) {
2172  if ((op->contr->peaceful = !op->contr->peaceful))
2174  i18n(op, "You will not attack other players."));
2175  else
2177  i18n(op, "You will attack other players."));
2178 }
2179 
2188 void command_wimpy(object *op, const char *params) {
2189  int i;
2190 
2191  if (*params == '\0' || !sscanf(params, "%d", &i)) {
2193  i18n(op, "Your current wimpy level is %d."),
2194  op->run_away);
2195  return;
2196  }
2197 
2198  if (i < 0 || i > 100) {
2200  i18n(op, "Wimpy level should be between 1 and 100."),
2201  i);
2202  return;
2203  }
2204 
2206  i18n(op, "Your new wimpy level is %d."),
2207  i);
2208  op->run_away = i;
2209 }
2210 
2219 void command_brace(object *op, const char *params) {
2220  if (*params == '\0')
2221  op->contr->braced = !op->contr->braced;
2222  else
2223  op->contr->braced = onoff_value(params);
2224 
2225  if (op->contr->braced)
2227  i18n(op, "You are braced."));
2228  else
2230  i18n(op, "Not braced."));
2231 
2232  fix_object(op);
2233 }
2234 
2243 void command_kill_pets(object *op, const char *params) {
2244  objectlink *obl, *next;
2245  int counter = 0, removecount = 0;
2246 
2247  if (*params == '\0') {
2248  pets_terminate_all(op);
2250  i18n(op, "Your pets have been killed."));
2251  } else {
2252  int target = atoi(params);
2253  for (obl = first_friendly_object; obl != NULL; obl = next) {
2254  object *ob = obl->ob;
2255  next = obl->next;
2256  if (object_get_owner(ob) == op)
2257  if (++counter == target || (target == 0 && !strcasecmp(ob->name, params))) {
2258  if (!QUERY_FLAG(ob, FLAG_REMOVED))
2259  object_remove(ob);
2262  removecount++;
2263  }
2264  }
2265  if (removecount != 0)
2267  i18n(op, "Killed %d pets."),
2268  removecount);
2269  else
2271  i18n(op, "Couldn't find any suitable pets to kill."));
2272  }
2273 }
2274 
2283 void command_passwd(object *pl, const char *params) {
2284  /* If old client, this is the way you change your password. */
2285  if (pl->contr->socket.login_method < 1){
2286  send_query(&pl->contr->socket, CS_QUERY_HIDEINPUT, i18n(pl, "Password change.\nPlease enter your current password, or empty string to cancel."));
2287 
2289  }
2290  /* If new client (login_method = 2) or jxclient (login_method = 1), changing the password does nothing anyway, so error out */
2291  else{
2293  i18n(pl, "passwd is maintained for older clients that do not support the account system. Please use the 'Password' button in your character selection screen to change your password."));
2294  }
2295 }
2296 
2306 void do_harvest(object *pl, int dir, object *skill) {
2307  int16_t x, y;
2308  int count = 0, proba; /* Probability to get the item, 100 based. */
2309  int level, exp, check_exhaust = 0;
2310  object *found[10]; /* Found items that can be harvested. */
2311  mapstruct *map;
2312  object *item, *inv, *harvested;
2313  sstring trace, ttool, tspeed, race, tool, slevel, sexp;
2314  float speed;
2315 
2316  x = pl->x+freearr_x[dir];
2317  y = pl->y+freearr_y[dir];
2318  map = pl->map;
2319 
2320  if (!IS_PLAYER(pl))
2321  return;
2322 
2323  if (!map)
2324  return;
2325 
2326  if (get_map_flags(map, &map, x, y, &x, &y)&P_OUT_OF_MAP) {
2327  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2328  return;
2329  }
2330 
2331  if (!pl->chosen_skill || pl->chosen_skill->skill != skill->skill)
2332  return;
2333 
2334  trace = object_get_value(pl->chosen_skill, "harvest_race");
2335  ttool = object_get_value(pl->chosen_skill, "harvest_tool");
2336  tspeed = object_get_value(pl->chosen_skill, "harvest_speed");
2337  if (!trace || strcmp(trace, "") == 0 || !ttool || strcmp(ttool, "") == 0 || !tspeed || strcmp(tspeed, "") == 0) {
2338  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2339  LOG(llevError, "do_harvest: tool %s without harvest_[race|tool|speed]\n", pl->chosen_skill->name);
2340  return;
2341  }
2342 
2343  item = GET_MAP_OB(map, x, y);
2344  while (item && count < 10) {
2345  FOR_INV_PREPARE(item, inv) {
2346  if (object_get_value(inv, "harvestable") == NULL)
2347  continue;
2348  race = object_get_value(inv, "harvest_race");
2349  tool = object_get_value(inv, "harvest_tool");
2350  slevel = object_get_value(inv, "harvest_level");
2351  sexp = object_get_value(inv, "harvest_exp");
2352  if (race && (!slevel || !sexp)) {
2353  LOG(llevError, "do_harvest: item %s without harvest_[level|exp]\n", inv->name);
2354  continue;
2355  }
2356  if (race == trace && (!tool || tool == ttool))
2357  found[count++] = inv;
2358  } FOR_INV_FINISH();
2359  item = item->above;
2360  }
2361  if (count == 0) {
2362  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2363  return;
2364  }
2365 
2366  inv = found[rndm(0, count-1)];
2367  assert(inv);
2368  item = inv->env;
2369  assert(item);
2370 
2371  slevel = object_get_value(inv, "harvest_level");
2372  sexp = object_get_value(inv, "harvest_exp");
2373  level = atoi(slevel);
2374  exp = atoi(sexp);
2375 
2376  speed = atof(tspeed);
2377  if (speed < 0)
2378  speed = -speed*pl->speed;
2379  pl->speed_left -= speed;
2380 
2381 
2382  /* Now we found something to harvest, randomly try to get it. */
2383  if (level > skill->level+10) {
2384  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2385  return;
2386  }
2387 
2388  if (level >= skill->level)
2389  /* Up to 10 more levels, 1 to 11 percent probability. */
2390  proba = 10+skill->level-level;
2391  else if (skill->level <= level+10)
2392  proba = 10+(skill->level-level)*2;
2393  else
2394  proba = 30;
2395 
2396  if (proba <= random_roll(0, 100, pl, 1)) {
2397  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2398  return;
2399  }
2400 
2401  /* Check the new item can fit into inventory.
2402  * Fixes bug #3060474: fishing puts more fishes into inventory than you can carry. */
2403  if (((uint32_t)(pl->weight + pl->carrying + inv->weight)) > get_weight_limit(pl->stats.Str)) {
2404  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You are carrying too much to %s a %s.", skill->slaying, inv->name);
2405  return;
2406  }
2407 
2408  /* Ok, got it. */
2409  if (inv->nrof == 0) {
2410  harvested = object_new();
2411  object_copy_with_inv(inv, harvested);
2412  } else {
2413  if (count == 1 && inv->nrof == 1) {
2414  check_exhaust = 1;
2415  }
2416  harvested = object_split(inv, 1, NULL, 0);
2417  }
2418  object_set_value(harvested, "harvestable", NULL, 0);
2419  if (QUERY_FLAG(harvested, FLAG_MONSTER)) {
2420  int spot = object_find_free_spot(harvested, pl->map, pl->x, pl->y, 0, SIZEOFFREE);
2421  if (spot == -1) {
2422  /* Better luck next time...*/
2423  object_remove(harvested);
2424  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2425  return;
2426  }
2427  object_insert_in_map_at(harvested, pl->map, NULL, 0, pl->x+freearr_x[spot], pl->y+freearr_y[spot]);
2428  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s a %s!", skill->slaying, harvested->name);
2429  } else {
2430  harvested = object_insert_in_ob(harvested, pl);
2431  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s some %s", skill->slaying, harvested->name);
2432  }
2433 
2434  /* Get exp */
2435  change_exp(pl, exp, skill->name, SK_EXP_ADD_SKILL);
2436 
2437  if (check_exhaust) {
2438  sstring replacement = object_get_value(item, "harvest_exhaust_replacement");
2439  if (replacement) {
2440  if (replacement[0] != '-') {
2441  archetype *other = find_archetype(replacement);
2442  if (other) {
2443  object *final = object_create_arch(other);
2444  object_insert_in_map_at(final, map, item, INS_BELOW_ORIGINATOR, item->x, item->y);
2445  }
2446  }
2447  object_remove(item);
2449  }
2450  }
2451 
2452  return;
2453 }
#define MSG_TYPE_COMMAND_MAPS
Definition: newclient.h:500
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:316
uint8_t login_method
Definition: newserver.h:128
void command_petmode(object *op, const char *params)
Definition: c_misc.c:1441
char path[HUGE_BUF]
Definition: map.h:365
void command_save(object *op, const char *params)
Definition: c_misc.c:2146
void command_afk(object *op, const char *params)
Definition: c_misc.c:791
int8_t Int
Definition: living.h:36
#define NUM_BODY_LOCATIONS
Definition: object.h:13
Definition: player.h:92
archetype * find_archetype(const char *name)
Definition: arch.c:695
void command_malloc(object *op, const char *params)
Definition: c_misc.c:811
int8_t ac
Definition: living.h:38
void command_help(object *op, const char *params)
Definition: c_misc.c:1791
#define ST_GET_PARTY_PASSWORD
Definition: define.h:587
#define INS_BELOW_ORIGINATOR
Definition: object.h:572
void display_who_entry(object *op, player *pl, const char *format)
Definition: c_misc.c:646
void command_unarmed_skill(object *op, const char *params)
Definition: c_misc.c:1385
struct mapdef mapstruct
void command_who(object *op, const char *params)
Definition: c_misc.c:629
command_array_struct Commands[]
Definition: commands.c:36
void object_free(object *ob, int flags)
Definition: object.c:1411
const int WizCommandsSize
Definition: commands.c:268
Definition: player.h:39
void roll_again(object *op)
Definition: player.c:1113
int64_t level_exp(int level, double expmul)
Definition: living.c:1868
int check_name(player *me, const char *name)
Definition: login.c:163
void command_wizpass(object *op, const char *params)
Definition: c_misc.c:939
Definition: object.h:444
#define SET_FLAG(xyz, p)
Definition: define.h:223
void command_maps(object *op, const char *params)
Definition: c_misc.c:847
bool check_password(const char *typed, const char *crypted)
Definition: server.c:109
region * get_region_by_name(const char *region_name)
Definition: region.c:46
#define FABS(x)
Definition: define.h:22
uint32_t braced
Definition: player.h:124
#define MSG_TYPE_COMMAND_CONFIG
Definition: newclient.h:505
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
Definition: player.c:224
#define NDI_WHITE
Definition: newclient.h:222
EXTERN int num_animations
Definition: global.h:164
uint32_t name_changed
Definition: player.h:130
#define FLAG_USE_ARMOUR
Definition: define.h:296
void command_motd(object *op, const char *params)
Definition: c_misc.c:209
char who_wiz_format[MAX_BUF]
Definition: global.h:279
int region_is_child_of_region(const region *child, const region *r)
Definition: region.c:190
uint32_t map_size(mapstruct *m)
Definition: map.c:825
EXTERN objectlink * first_friendly_object
Definition: global.h:123
void object_copy_with_inv(const object *src_ob, object *dest_ob)
Definition: object.c:1008
int16_t players
Definition: map.h:344
void command_dumpallobjects(object *op, const char *params)
Definition: c_misc.c:999
unapplymode
Definition: player.h:62
int login_order
Definition: c_misc.c:530
int save_player(object *op, int flag)
Definition: login.c:212
uint32_t in_memory
Definition: map.h:345
const char * playerdir
Definition: global.h:250
#define MAP_ENTER_X(m)
Definition: map.h:85
void free_string(sstring str)
Definition: shstr.c:280
signed long object_sum_weight(object *op)
Definition: object.c:344
void command_brace(object *op, const char *params)
Definition: c_misc.c:2219
#define HUGE_BUF
Definition: define.h:37
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4299
#define SND_MUTE
Definition: sounds.h:14
#define SS_DUMP_TOTALS
Definition: shstr.h:47
#define ST_CHANGE_PASSWORD_CONFIRM
Definition: define.h:590
#define MAP_HEIGHT(m)
Definition: map.h:80
void command_kill_pets(object *op, const char *params)
Definition: c_misc.c:2243
char new_password[16]
Definition: player.h:177
object clone
Definition: object.h:472
struct treasureliststruct * next
Definition: treasure.h:89
socket_struct socket
Definition: player.h:94
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define ST_CONFIRM_PASSWORD
Definition: define.h:586
int object_count_active(void)
Definition: object.c:1612
const char * slaying
Definition: object.h:319
region * get_region_by_map(mapstruct *m)
Definition: region.c:74
DIR * opendir(const char *)
Definition: win32.c:37
void command_dumpallmaps(object *op, const char *params)
Definition: c_misc.c:1060
void command_dumpmap(object *op, const char *params)
Definition: c_misc.c:1047
void dump_all_archetypes(void)
Definition: arch.c:244
uint8_t subtype
Definition: object.h:340
#define FLAG_USE_WEAPON
Definition: define.h:297
void command_resistances(object *op, const char *params)
Definition: c_misc.c:1598
int checkbanned(const char *login, const char *host)
Definition: ban.c:32
int64_t exp
Definition: living.h:47
struct obj * above
Definition: object.h:288
void object_dump_all(void)
Definition: object.c:483
double expmul
Definition: object.h:397
#define ST_CHANGE_PASSWORD_NEW
Definition: define.h:589
int language
Definition: player.h:201
#define FLAG_AFK
Definition: define.h:377
#define TRUE
Definition: compat.h:10
player * find_player(const char *plname)
Definition: player.c:55
LogLevel debug
Definition: global.h:244
body_locations_struct body_locations[NUM_BODY_LOCATIONS]
Definition: item.c:54
#define FALSE
Definition: compat.h:11
void remove_friendly_object(object *op)
Definition: friend.c:56
int16_t sp
Definition: living.h:42
uint32_t get_weight_limit(int stat)
Definition: living.c:2356
#define SS_DUMP_TABLE
Definition: shstr.h:46
#define MSG_TYPE_COMMAND_STATISTICS
Definition: newclient.h:504
Definition: win32.h:110
#define safe_strncpy
Definition: compat.h:23
uint32_t hidden
Definition: player.h:132
char * partyname
Definition: party.h:14
void pets_terminate_all(object *owner)
Definition: pets.c:231
#define ST_ROLL_STAT
Definition: define.h:581
struct obj object
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:311
Definition: object.h:467
#define ST_PLAYING
Definition: define.h:579
void command_whereami(object *op, const char *params)
Definition: c_misc.c:835
char * host
Definition: newserver.h:100
const int CommunicationCommandSize
Definition: commands.c:201
void command_debug(object *op, const char *params)
Definition: c_misc.c:915
int16_t maxsp
Definition: living.h:43
int8_t Con
Definition: living.h:36
#define FLAG_REMOVED
Definition: define.h:232
int16_t hp
Definition: living.h:40
#define MAP_WHEN_RESET(m)
Definition: map.h:62
char namebuf[MAX_BUF]
Definition: c_misc.c:529
region * get_region_from_string(const char *name)
Definition: region.c:121
int nrofallocobjects
Definition: object.c:57
void command_dumpfriendlyobjects(object *op, const char *params)
Definition: c_misc.c:1011
short freearr_y[SIZEOFFREE]
Definition: object.c:71
partylist * party
Definition: player.h:186
void hiscore_display(object *op, int max, const char *match)
Definition: hiscore.c:388
void get_name(object *op)
Definition: player.c:855
void current_region_info(object *op)
Definition: c_misc.c:402
object * ob
Definition: object.h:445
uint32_t ticks_played
Definition: player.h:203
#define MSG_TYPE_ADMIN_DM
Definition: newclient.h:475
int rndm(int min, int max)
Definition: utils.c:162
void command_printlos(object *op, const char *params)
Definition: c_misc.c:1072
#define NAMLEN(dirent)
Definition: global.h:219
const char * get_region_longname(const region *r)
Definition: region.c:217
void command_fix_me(object *op, const char *params)
Definition: c_misc.c:1221
int player_has_own_title(const struct pl *pl)
Definition: player.c:239
char * name
Definition: map.h:328
#define MAP_IN_MEMORY
Definition: map.h:130
struct obj * chosen_skill
Definition: object.h:388
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4428
void object_free_drop_inventory(object *ob)
Definition: object.c:1391
int16_t y
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1935
#define NDI_RED
Definition: newclient.h:224
int16_t maxhp
Definition: living.h:41
char * name
Definition: map.h:278
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:532
#define MSG_TYPE_COMMAND
Definition: newclient.h:379
uint32_t sound
Definition: newserver.h:111
Definition: win32.h:120
struct artifactliststruct * next
Definition: artifact.h:29
object * object_new(void)
Definition: object.c:1070
const char * name_pl
Definition: object.h:315
usekeytype
Definition: player.h:52
void player_set_own_title(struct pl *pl, const char *title)
Definition: player.c:264
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2709
void send_query(socket_struct *ns, uint8_t flags, const char *text)
Definition: request.c:677
void command_players(object *op, const char *params)
Definition: c_misc.c:1234
float speed_left
Definition: object.h:329
unapplymode unapply
Definition: player.h:108
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:509
void command_wizcast(object *op, const char *params)
Definition: c_misc.c:969
signed short int16_t
Definition: win32.h:160
void command_passwd(object *pl, const char *params)
Definition: c_misc.c:2283
enum _petmode petmode_t
int32_t weight
Definition: object.h:366
static bool IS_PLAYER(object *op)
Definition: object.h:596
int8_t Wis
Definition: living.h:36
#define ST_CONFIRM_QUIT
Definition: define.h:583
void get_password(object *op)
Definition: player.c:867
struct mapdef * map
Definition: object.h:297
int is_dragon_pl(const object *op)
Definition: player.c:114
struct regiondef * next
Definition: map.h:277
void receive_player_password(object *op)
Definition: c_misc.c:2003
Definition: map.h:276
#define snprintf
Definition: win32.h:46
void player_set_state(player *pl, uint8_t state)
Definition: player.c:4530
#define MAP_TIMEOUT(m)
Definition: map.h:66
void dump_all_maps(void)
Definition: map.c:278
#define FOR_INV_FINISH()
Definition: define.h:715
char * msg
Definition: map.h:361
#define FMT64
Definition: compat.h:12
type_definition ** types
int16_t dam
Definition: living.h:46
void command_rules(object *op, const char *params)
Definition: c_misc.c:221
void command_applymode(object *op, const char *params)
Definition: c_misc.c:1283
int object_count_free(void)
Definition: object.c:1574
void do_harvest(object *pl, int dir, object *skill)
Definition: c_misc.c:2306
int32_t carrying
Definition: object.h:368
const char * name
Definition: object.h:311
living orig_stats
Definition: player.h:148
long seconds(void)
Definition: time.c:344
struct obj * env
Definition: object.h:293
void command_mapinfo(object *op, const char *params)
Definition: c_misc.c:823
#define ATNR_INTERNAL
Definition: attack.h:72
struct archt * more
Definition: object.h:471
static void show_commands(object *op, int what)
Definition: c_misc.c:1704
uint8_t state
Definition: player.h:118
#define CS_QUERY_SINGLECHAR
Definition: newclient.h:67
#define MSG_TYPE_COMMAND_WHO
Definition: newclient.h:499
uint32_t counter
Definition: map.h:294
uint32_t nrof
Definition: object.h:333
#define MAP_ENTER_Y(m)
Definition: map.h:87
uint8_t listening
Definition: player.h:120
int8_t Cha
Definition: living.h:36
EXTERN const char *const change_resist_msg[NROFATTACKS]
Definition: attack.h:135
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
Definition: map.h:251
EXTERN Animations * animations
Definition: global.h:163
struct pl * contr
Definition: object.h:276
char * ss_dump_table(int what, char *buf, size_t size)
Definition: shstr.c:354
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:585
void command_hiscore(object *op, const char *params)
Definition: c_misc.c:903
EXTERN treasurelist * first_treasurelist
Definition: global.h:120
void time_info(object *op)
Definition: time.c:294
char d_name[_MAX_FNAME+1]
Definition: win32.h:114
void command_listen(object *op, const char *params)
Definition: c_misc.c:1099
float speed
Definition: object.h:328
unsigned __int64 uint64_t
Definition: win32.h:167
struct regiondef * parent
Definition: map.h:286
void command_whereabouts(object *op, const char *params)
Definition: c_misc.c:490
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define MSG_TYPE_ADMIN_VERSION
Definition: newclient.h:479
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
EXTERN artifactlist * first_artifactlist
Definition: global.h:121
uint32_t is_bot
Definition: newserver.h:107
EXTERN const char *const attacktype_desc[NROFATTACKS]
Definition: attack.h:138
#define FLAG_WIZ
Definition: define.h:231
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Definition: living.c:2162
void command_language(object *op, const char *params)
Definition: c_misc.c:125
void command_news(object *op, const char *params)
Definition: c_misc.c:233
void dump_map(const mapstruct *m)
Definition: map.c:255
#define MAX_BUF
Definition: define.h:35
command_array_struct WizCommands[]
Definition: commands.c:204
void command_body(object *op, const char *params)
Definition: c_misc.c:168
LogLevel
Definition: logger.h:10
object * object_create_arch(archetype *at)
Definition: arch.c:736
char who_format[MAX_BUF]
Definition: global.h:278
#define MSG_TYPE_ADMIN
Definition: newclient.h:377
uint32_t peaceful
Definition: player.h:131
enum _bowtype bowtype_t
int16_t x
Definition: object.h:326
void command_wimpy(object *op, const char *params)
Definition: c_misc.c:2188
int nroffreeobjects
Definition: object.c:56
const char * skill
Definition: object.h:321
int8_t wc
Definition: living.h:37
unsigned short uint16_t
Definition: win32.h:163
void command_sound(object *op, const char *params)
Definition: c_misc.c:1963
void command_delete(object *op, const char *params)
Definition: c_misc.c:1943
uint16_t difficulty
Definition: map.h:343
int8_t Str
Definition: living.h:36
int16_t resist[NROFATTACKS]
Definition: object.h:342
object * ob
Definition: player.h:158
EXTERN long nrofartifacts
Definition: global.h:146
const char * sstring
Definition: global.h:40
unsigned int uint32_t
Definition: win32.h:162
const char * datadir
Definition: global.h:248
EXTERN long nrofallowedstr
Definition: global.h:147
void command_showpets(object *op, const char *params)
Definition: c_misc.c:1485
void set_map_reset_time(mapstruct *map)
Definition: map.c:2251
bowtype_t bowtype
Definition: player.h:101
void command_ssdumptable(object *op, const char *params)
Definition: c_misc.c:1035
int8_t body_info[NUM_BODY_LOCATIONS]
Definition: object.h:374
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2480
void print_los(object *op)
Definition: los.c:606
Definition: map.h:258
#define FREE_AND_COPY(sv, nv)
Definition: global.h:211
#define MSG_TYPE_COMMAND_MALLOC
Definition: newclient.h:502
static void malloc_info(object *op)
Definition: c_misc.c:243
void command_time(object *op, const char *params)
Definition: c_misc.c:879
const int CommandsSize
Definition: commands.c:128
const char * localdir
Definition: global.h:249
char password[16]
Definition: player.h:176
tag_t count
Definition: object.h:299
living stats
Definition: object.h:369
#define FLAG_WIZCAST
Definition: define.h:290
#define MSG_TYPE_LAST
Definition: newclient.h:396
int8_t Dex
Definition: living.h:36
void command_statistics(object *pl, const char *params)
Definition: c_misc.c:1130
struct archt * arch
Definition: object.h:414
sstring i18n_get_language_code(int language)
Definition: languages.c:122
struct oblnk * next
Definition: object.h:446
#define MAP_WIDTH(m)
Definition: map.h:78
void command_title(object *op, const char *params)
Definition: c_misc.c:2095
void check_login(object *op, int check_pass)
Definition: login.c:501
void command_strings(object *op, const char *params)
Definition: c_misc.c:859
struct Settings settings
Definition: init.c:39
void arch_info(object *op)
Definition: arch.c:198
#define SK_EXP_ADD_SKILL
Definition: skills.h:78
#define MSG_TYPE_COMMAND_INFO
Definition: newclient.h:506
struct archt * next
Definition: object.h:469
#define NROFATTACKS
Definition: attack.h:17
struct dirent * readdir(DIR *)
Definition: win32.c:75
void command_peaceful(object *op, const char *params)
Definition: c_misc.c:2171
uint32_t max_time
Definition: time.c:35
command_array_struct CommunicationCommands[]
Definition: commands.c:131
#define ST_CHANGE_PASSWORD_OLD
Definition: define.h:588
void ss_dump_statistics(char *buf, size_t size)
Definition: shstr.c:323
static void help_topics(object *op, int what)
Definition: c_misc.c:1643
int object_count_used(void)
Definition: object.c:1593
void send_news(const object *op)
Definition: player.c:202
#define MSG_TYPE_COMMAND_BODY
Definition: newclient.h:501
void send_rules(const object *op)
Definition: player.c:166
sstring add_string(const char *str)
Definition: shstr.c:124
const char * get_name_of_region_for_map(const mapstruct *m)
Definition: region.c:92
EXTERN player * first_player
Definition: global.h:117
void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl)
Definition: c_misc.c:702
struct pl * next
Definition: player.h:93
#define GET_MAP_OB(M, X, Y)
Definition: map.h:172
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
int i18n_find_language_by_code(const char *code)
Definition: languages.c:95
#define FLAG_MONSTER
Definition: define.h:245
#define MSG_TYPE_SKILL
Definition: newclient.h:383
int8_t Pow
Definition: living.h:36
int closedir(DIR *)
Definition: win32.c:108
char * strdup(const char *str)
Definition: porting.c:200
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:310
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Definition: utils.c:500
uint8_t set_title
Definition: global.h:267
petmode_t petmode
Definition: player.h:102
#define NDI_UNIQUE
Definition: newclient.h:245
#define S_ISDIR(x)
Definition: win32.h:69
#define MSG_SUBTYPE_NONE
Definition: newclient.h:398
usekeytype usekeys
Definition: player.h:107
Definition: player.h:46
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
#define CS_QUERY_HIDEINPUT
Definition: newclient.h:68
void receive_player_name(object *op)
Definition: c_misc.c:1985
#define FLAG_WAS_WIZ
Definition: define.h:234
EXTERN region * first_region
Definition: global.h:119
void command_archs(object *op, const char *params)
Definition: c_misc.c:891
#define MAX_NAME
Definition: define.h:41
uint8_t run_away
Definition: object.h:386
#define FULL_VERSION
Definition: version.h:6
struct mapdef * next
Definition: map.h:326
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3433
void command_dumpallarchetypes(object *op, const char *params)
Definition: c_misc.c:1023
void map_info(object *op, const char *search)
Definition: c_misc.c:45
void dump_friendly_objects(void)
Definition: friend.c:100
void command_quit(object *op, const char *params)
Definition: c_misc.c:1927
Definition: map.h:325
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
char write_buf[MAX_BUF]
Definition: player.h:174
void command_usekeys(object *op, const char *params)
Definition: c_misc.c:1557
void command_bowmode(object *op, const char *params)
Definition: c_misc.c:1324
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Definition: object.c:4221
int onoff_value(const char *line)
Definition: c_misc.c:1893
#define FLAG_WIZPASS
Definition: define.h:315
const char * unarmed_skill
Definition: player.h:202
#define S_ISREG(x)
Definition: win32.h:70
int16_t level
Definition: object.h:352
char const * newhash(char const *password)
void fix_object(object *op)
Definition: living.c:1120
const char * i18n(const object *who, const char *code)
Definition: languages.c:69
float weapon_speed
Definition: object.h:330
void list_players(object *op, region *reg, partylist *party)
Definition: c_misc.c:556
EXTERN mapstruct * first_map
Definition: global.h:118
EXTERN archetype * first_archetype
Definition: global.h:122
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.c:192
char * longname
Definition: map.h:291
void command_version(object *op, const char *params)
Definition: c_misc.c:1086
object * object_get_owner(object *op)
Definition: object.c:592
const char * name
Definition: object.h:468
static int find_help_file(const char *name, const char *language, int wiz, char *path, int length)
Definition: c_misc.c:1751
#define P_NO_CLERIC
Definition: map.h:238
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:366
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:708
void object_remove(object *op)
Definition: object.c:1668
const char * get_region_msg(const region *r)
Definition: region.c:238
void i18n_list_languages(object *who)
Definition: languages.c:132
int8_t body_used[NUM_BODY_LOCATIONS]
Definition: object.h:375
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
Definition: object.h:224
void current_map_info(object *op)
Definition: c_misc.c:424
static int name_cmp(const chars_names *c1, const chars_names *c2)
Definition: c_misc.c:542
void display_motd(const object *op)
Definition: player.c:135
EXTERN long nroftreasures
Definition: global.h:145