Crossfire Server, Trunk  R22047
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 
37 #include "assets.h"
38 
39 /* Static declarations where needed (when ordering would be an issue) */
40 static void display_who_entry(object *op, player *pl, const char *format);
41 static void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl);
42 static int onoff_value(const char *line);
43 
52 static void map_info(object *op, const char *search) {
53  if ( *search != 0 ) {
55  i18n(op, "Maps matching search: '%s'"), search);
56  }
57  if (QUERY_FLAG(op, FLAG_WIZ)) {
59  i18n(op, "[fixed]Path Reset In (HH:MM:SS) Pl IM TO"));
60  } else {
62  i18n(op, "[fixed]Path Reset In (HH:MM)"));
63  }
64 
65  /* Allow a comma-separate list of search strings; more complicated because of the const */
66  char *to_be_freed = NULL;
67  char *search_array[64];
68  int search_array_count = 0;
69  if ( search[0] ) {
70  to_be_freed = strdup(search);
71  if ( !to_be_freed ) {
72  search_array[0] = to_be_freed;
73  search_array_count = 1;
74  } else {
75  search_array_count = split_string(to_be_freed,search_array,64,',');
76  }
77  }
78 
79  for (mapstruct *m = first_map; m != NULL; m = m->next) {
80  bool match = TRUE;
81  if ( search_array_count ) {
82  match = FALSE;
83  for (int i=0; i<search_array_count; ++i) {
84  if ( strstr(m->path,search_array[i]) ) {
85  match=TRUE;
86  break;
87  }
88  }
89  }
90  if ( !match ) continue; /* Skip unwanted maps */
91 
92  /* Print out the last 26 characters of the map name... */
93  char map_path[MAX_BUF];
94  if (strlen(m->path) <= 26) {
95  strcpy(map_path, m->path);
96  } else {
97  safe_strncpy(map_path, m->path + strlen(m->path) - 26, sizeof(map_path));
98  }
99 
100  uint32_t ttr = MAP_WHEN_RESET(m) - seconds() > 0 ? MAP_WHEN_RESET(m) - seconds() : 0;
101  if ( !m->reset_timeout && !m->unique ) set_map_reset_time(m);
102  if (m->players) {
103  ttr = (m->unique ? 0 : m->reset_timeout) + 300;
104  }
105  else if (m->timeout) {
106  ttr = (m->unique ? 0 : m->reset_timeout) + m->timeout;
107  }
108  const uint32_t hh = ttr/3600, mm = (ttr%3600)/60, ss = ttr%60;
109  if (QUERY_FLAG(op, FLAG_WIZ)) {
112  i18n(op, "[fixed]%-26.26s %2d:%02d:%02d %2d %2d %4d"),
113  map_path, hh, mm, ss, m->players, m->in_memory, m->timeout);
114  } else {
117  i18n(op, "[fixed]%-26.26s %2d:%02d%s"), map_path, hh, mm,
118  m->players ? " (in use)" : "");
119  }
120  }
121  if ( to_be_freed ) free( to_be_freed );
122 }
123 
132 void command_language(object *op, const char *params) {
133  int language = -1;
134 
135  if (!op->contr)
136  return;
137 
138  if (*params == '\0' || (!strcmp(params, ""))) {
140  i18n(op, "Your current language is set to: English."));
142  i18n(op, "Available languages:"));
144  return;
145  }
146 
147  language = i18n_find_language_by_code(params);
148 
149  /* Error out if unknown language. */
150  if (language == -1) {
152  i18n(op, "Unknown language."));
153  return;
154  }
155 
156  op->contr->language = language;
157 
159  i18n(op, "Your current language is set to English."));
160 }
161 
175 void command_body(object *op, const char *params) {
176  int i;
177 
178  /* Too hard to try and make a header that lines everything up, so just
179  * give a description.
180  */
182  i18n(op, "The first column is the name of the body location."));
183 
185  i18n(op, "The second column is how many of those locations your body has."));
186 
188  i18n(op, "The third column is how many slots in that location are available."));
189 
190  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
191  /* really debugging - normally body_used should not be set to anything
192  * if body_info isn't also set.
193  */
194  if (op->body_info[i] || op->body_used[i]) {
196  i18n(op, "[fixed]%-30s %5d %5d"),
197  i18n(op, body_locations[i].use_name), op->body_info[i], op->body_used[i]);
198  }
199  }
200  if (!QUERY_FLAG(op, FLAG_USE_ARMOUR))
202  i18n(op, "You are not allowed to wear armor."));
203  if (!QUERY_FLAG(op, FLAG_USE_WEAPON))
205  i18n(op, "You are not allowed to use weapons."));
206 }
207 
216 void command_motd(object *op, const char *params) {
217  display_motd(op);
218 }
219 
228 void command_rules(object *op, const char *params) {
229  send_rules(op);
230 }
231 
240 void command_news(object *op, const char *params) {
241  send_news(op);
242 }
243 
250 static void malloc_info(object *op) {
251  int ob_used = object_count_used(), ob_free = object_count_free(), players, nrofmaps;
252  int nrm = 0, mapmem = 0, anr, anims, sum_alloc = 0, sum_used = 0, i, alnr;
253  treasurelist *tl;
254  player *pl;
255  mapstruct *m;
256  archetype *at;
257  artifactlist *al;
258 
259  for (al = first_artifactlist, alnr = 0; al != NULL; al = al->next, alnr++)
260  ;
261 
263 
264  anims = assets_number_of_animations();
265 
266  for (pl = first_player, players = 0; pl != NULL; pl = pl->next, players++)
267  ;
268 
269  for (m = first_map, nrofmaps = 0; m != NULL; m = m->next, nrofmaps++)
270  if (m->in_memory == MAP_IN_MEMORY) {
271  mapmem += map_size(m) * (sizeof(object *) + sizeof(MapSpace));
272  nrm++;
273  }
274 
276  i18n(op, "Sizeof: object=%d player=%d map=%d"),
277  sizeof(object), sizeof(player), sizeof(mapstruct));
278 
280  i18n(op, "[fixed]Objects:"));
281 
283  i18n(op, "[fixed]%6d used"), ob_used);
284 
285  if (ob_used != nrofallocobjects - nroffreeobjects) {
287  i18n(op, "[fixed] (used list mismatch: %d)"),
289  }
290 
292  i18n(op, "[fixed]%6d free (%.2f%% of %d allocated)"),
293  ob_free, (float)ob_free / nrofallocobjects * 100, nrofallocobjects);
294 
295  if (ob_free != nroffreeobjects) {
297  i18n(op, "[fixed] (free list mismatch: %d)"),
299  }
300 
302  i18n(op, "[fixed]%6d on active list"),
304 
305  i = (ob_used*sizeof(object));
306  sum_used += i;
307  sum_alloc += i;
308 
310  i18n(op, "[fixed] object total: %11d"), i);
311 
312  i = (ob_free*sizeof(object));
313  sum_alloc += i;
314 
316  i18n(op, "[fixed]%4d players: %8d"),
317  players, i = (players*sizeof(player)));
318 
319  sum_alloc += i;
320  sum_used += i;
321 
323  i18n(op, "[fixed]%4d maps allocated: %8d"),
324  nrofmaps, i = (nrofmaps*sizeof(mapstruct)));
325 
326  sum_alloc += i;
327  sum_used += nrm*sizeof(mapstruct);
328 
330  i18n(op, "[fixed]%4d maps in memory: %8d"),
331  nrm, mapmem);
332 
333  sum_alloc += mapmem;
334  sum_used += mapmem;
335 
337  i18n(op, "[fixed]%4d archetypes: %8d"),
338  anr, i = (anr*sizeof(archetype)));
339 
340  sum_alloc += i;
341  sum_used += i;
342 
344  i18n(op, "[fixed]%4d animations: %8d"),
345  anims, i = (anims*sizeof(uint16_t)));
346 
347  sum_alloc += i;
348  sum_used += i;
349 
351  i18n(op, "[fixed]%4d treasurelists %8d"),
353 
354  sum_alloc += i;
355  sum_used += i;
356 
358  i18n(op, "[fixed]%4ld treasures %8d"),
360 
361  sum_alloc += i;
362  sum_used += i;
363 
365  i18n(op, "[fixed]%4ld artifacts %8d"),
366  nrofartifacts, i = (nrofartifacts*sizeof(artifact)));
367 
368  sum_alloc += i;
369  sum_used += i;
370 
372  i18n(op, "[fixed]%4ld artifacts strngs %8d"),
373  nrofallowedstr, i = (nrofallowedstr*sizeof(linked_char)));
374 
375  sum_alloc += i;
376  sum_used += i;
377 
379  i18n(op, "[fixed]%4d artifactlists %8d"),
380  alnr, i = (alnr*sizeof(artifactlist)));
381 
382  sum_alloc += i;
383  sum_used += i;
384 
386  i18n(op, "[fixed]Total space allocated:%8d"),
387  sum_alloc);
388 
390  i18n(op, "[fixed]Total space used: %8d"),
391  sum_used);
392 }
393 
405 static void current_region_info(object *op) {
406  /*
407  * Ok I /suppose/ I should write a seperate function for this, but it isn't
408  * going to be /that/ slow, and won't get called much
409  */
411 
412  /* This should only be possible if regions are not operating on this server. */
413  if (!r)
414  return;
415 
417  i18n(op, "You are in %s.\n%s"),
419 }
420 
427 static void current_map_info(object *op) {
428  mapstruct *m = op->map;
429 
430  if (!m)
431  return;
432 
434  "%s (%s) in %s",
436 
437  if (QUERY_FLAG(op, FLAG_WIZ)) {
439  i18n(op, "players:%d difficulty:%d size:%dx%d start:%dx%d timeout %d"),
440  m->players, m->difficulty,
441  MAP_WIDTH(m), MAP_HEIGHT(m),
442  MAP_ENTER_X(m), MAP_ENTER_Y(m),
443  MAP_TIMEOUT(m));
444  }
445  if (m->msg)
447 }
448 
449 #ifdef DEBUG_MALLOC_LEVEL
450 
458 void command_malloc_verify(object *op, char *parms) {
459  extern int malloc_verify(void);
460 
461  if (!malloc_verify())
463  i18n(op, "Heap is corrupted."));
464  else
466  i18n(op, "Heap checks out OK."));
467 
468  return 1;
469 }
470 #endif
471 
482 void command_whereabouts(object *op, const char *params) {
483  region *reg;
484  player *pl;
485 
486  /*
487  * reset the counter on the region, then use it to store the number of
488  * players there.
489  * I don't know how thread-safe this would be, I suspect not very....
490  */
491  for (reg = first_region; reg != NULL; reg = reg->next) {
492  reg->counter = 0;
493  }
494  for (pl = first_player; pl != NULL; pl = pl->next)
495  if (pl->ob->map != NULL)
496  get_region_by_map(pl->ob->map)->counter++;
497 
498  /* we only want to print out by places with a 'longname' field...*/
499  for (reg = first_region; reg != NULL; reg = reg->next) {
500  if (reg->longname == NULL && reg->counter > 0) {
501  if (reg->parent != NULL) {
502  reg->parent->counter += reg->counter;
503  reg->counter = 0;
504  } else /*uh oh, we shouldn't be here. */
505  LOG(llevError, "command_whereabouts() Region %s with no longname has no parent\n", reg->name);
506  }
507  }
509  i18n(op, "In the world currently there are:"));
510 
511  for (reg = first_region; reg != NULL; reg = reg->next)
512  if (reg->counter > 0) {
514  i18n(op, "%u players in %s"),
515  reg->counter, get_region_longname(reg));
516  }
517 }
518 
520 typedef struct {
521  char namebuf[MAX_BUF];
523 } chars_names;
524 
534 static int name_cmp(const chars_names *c1, const chars_names *c2) {
535  return strcasecmp(c1->namebuf, c2->namebuf);
536 }
537 
548 void list_players(object *op, region *reg, partylist *party) {
549  player *pl;
550  uint16_t i;
551  char *format;
552  int num_players = 0, num_wiz = 0, num_afk = 0, num_bot = 0;
553  chars_names *chars = NULL;
554 
555  if (op == NULL || QUERY_FLAG(op, FLAG_WIZ))
556  format = settings.who_wiz_format;
557  else
558  format = settings.who_format;
559 
560  for (pl = first_player; pl != NULL; pl = pl->next) {
561  if (pl->ob->map == NULL)
562  continue;
563  if (pl->hidden && !QUERY_FLAG(op, FLAG_WIZ))
564  continue;
565 
566  if (reg && !region_is_child_of_region(get_region_by_map(pl->ob->map), reg))
567  continue;
568  if (party && pl->party != party)
569  continue;
570 
571  if (pl->state == ST_PLAYING || pl->state == ST_GET_PARTY_PASSWORD) {
572  num_players++;
573  chars = (chars_names *)realloc(chars, num_players*sizeof(chars_names));
574  if (chars == NULL) {
576  i18n(op, "who failed - out of memory!"));
577  return;
578  }
579  sprintf(chars[num_players-1].namebuf, "%s", pl->ob->name);
580  chars[num_players-1].login_order = num_players;
581 
582  /* Check for WIZ's & AFK's*/
583  if (QUERY_FLAG(pl->ob, FLAG_WIZ))
584  num_wiz++;
585 
586  if (QUERY_FLAG(pl->ob, FLAG_AFK))
587  num_afk++;
588 
589  if (pl->socket.is_bot)
590  num_bot++;
591  }
592  }
593  if (first_player != (player *)NULL) {
594  if (reg == NULL && party == NULL)
596  i18n(op, "Total Players (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
597  num_players, num_wiz, num_afk, num_bot);
598  else if (party == NULL)
600  i18n(op, "Total Players in %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
601  reg->longname ? reg->longname : reg->name, num_players, num_wiz, num_afk, num_bot);
602  else
604  i18n(op, "Total Players in party %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
605  party->partyname, num_players, num_wiz, num_afk, num_bot);
606  }
607  qsort(chars, num_players, sizeof(chars_names), (int (*)(const void *, const void *))name_cmp);
608  for (i = 0; i < num_players; i++)
609  display_who_entry(op, find_player(chars[i].namebuf), format);
610  free(chars);
611 }
612 
621 void command_who(object *op, const char *params) {
622  region *reg;
623 
624  reg = get_region_from_string(params);
625  list_players(op, reg, NULL);
626 }
627 
638 static void display_who_entry(object *op, player *pl, const char *format) {
639  char tmpbuf[MAX_BUF];
640  char outbuf[MAX_BUF];
641  size_t i;
642 
643  strcpy(outbuf, "[fixed]");
644 
645  if (pl == NULL) {
646  LOG(llevError, "display_who_entry(): I was passed a null player\n");
647  return;
648  }
649  for (i = 0; i <= strlen(format); i++) {
650  if (format[i] == '%') {
651  i++;
652  get_who_escape_code_value(tmpbuf, sizeof(tmpbuf), format[i], pl);
653  strcat(outbuf, tmpbuf);
654  } else if (format[i] == '_') {
655  strcat(outbuf, " "); /* allow '_' to be used in place of spaces */
656  } else {
657  snprintf(tmpbuf, sizeof(tmpbuf), "%c", format[i]);
658  strcat(outbuf, tmpbuf);
659  }
660  }
662 }
663 
694 static void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl) {
695  switch (letter) {
696  case 'N':
697  strlcpy(return_val, pl->ob->name, size);
698  break;
699 
700  case 't':
701  player_get_title(pl, return_val, size);
702  break;
703 
704  case 'c':
705  snprintf(return_val, size, "%u", pl->ob->count);
706  break;
707 
708  case 'n':
709  snprintf(return_val, size, "\n");
710  break;
711 
712  case 'h':
713  strlcpy(return_val, pl->peaceful ? "" : " <Hostile>", size);
714  break;
715 
716  case 'l':
717  snprintf(return_val, size, "%d", pl->ob->level);
718  break;
719 
720  case 'd':
721  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_WIZ) ? " <WIZ>" : ""), size);
722  break;
723 
724  case 'a':
725  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_AFK) ? " <AFK>" : ""), size);
726  break;
727 
728  case 'b':
729  strlcpy(return_val, (pl->socket.is_bot == 1) ? " <BOT>" : "", size);
730  break;
731 
732  case 'm':
733  strlcpy(return_val, pl->ob->map->path, size);
734  break;
735 
736  case 'M':
737  strlcpy(return_val, pl->ob->map->name ? pl->ob->map->name : "Untitled", size);
738  break;
739 
740  case 'r':
741  strlcpy(return_val, get_name_of_region_for_map(pl->ob->map), size);
742  break;
743 
744  case 'R':
745  strlcpy(return_val, get_region_longname(get_region_by_map(pl->ob->map)), size);
746  break;
747 
748  case 'i':
749  strlcpy(return_val, pl->socket.host, size);
750  break;
751 
752  case '%':
753  snprintf(return_val, size, "%%");
754  break;
755 
756  case '_':
757  snprintf(return_val, size, "_");
758  break;
759  }
760 }
761 
770 void command_afk(object *op, const char *params) {
771  if (QUERY_FLAG(op, FLAG_AFK)) {
772  CLEAR_FLAG(op, FLAG_AFK);
774  i18n(op, "You are no longer AFK"));
775  } else {
776  SET_FLAG(op, FLAG_AFK);
778  i18n(op, "You are now AFK"));
779  }
780 }
781 
790 void command_malloc(object *op, const char *params) {
791  malloc_info(op);
792 }
793 
802 void command_mapinfo(object *op, const char *params) {
803  current_map_info(op);
804 }
805 
814 void command_whereami(object *op, const char *params) {
816 }
817 
826 void command_maps(object *op, const char *params) {
827  map_info(op, params);
828 }
829 
838 void command_strings(object *op, const char *params) {
839  char stats[HUGE_BUF];
840 
841  ss_dump_statistics(stats, sizeof(stats));
843  "[fixed]%s\n",
844  stats);
845 
847  ss_dump_table(SS_DUMP_TOTALS, stats, sizeof(stats)));
848 }
849 
858 void command_time(object *op, const char *params) {
859  time_info(op);
860 }
861 
870 void command_hiscore(object *op, const char *params) {
871  hiscore_display(op, op == NULL ? 9999 : 50, params);
872 }
873 
882 void command_debug(object *op, const char *params) {
883  int i;
884 
885  if (*params == '\0' || !sscanf(params, "%d", &i)) {
887  i18n(op, "Global debug level is %d."),
888  settings.debug);
889  return;
890  }
891  settings.debug = (enum LogLevel)FABS(i);
893  i18n(op, "Debug level set to %d."),
894  i);
895 }
896 
897 
906 void command_wizpass(object *op, const char *params) {
907  int i;
908 
909  if (!op)
910  return;
911 
912  if (*params == '\0')
913  i = (QUERY_FLAG(op, FLAG_WIZPASS)) ? 0 : 1;
914  else
915  i = onoff_value(params);
916 
917  if (i) {
919  i18n(op, "You will now walk through walls."));
920  SET_FLAG(op, FLAG_WIZPASS);
921  } else {
923  i18n(op, "You will now be stopped by walls."));
925  }
926 }
927 
936 void command_wizcast(object *op, const char *params) {
937  int i;
938 
939  if (!op)
940  return;
941 
942  if (*params == '\0')
943  i = (QUERY_FLAG(op, FLAG_WIZCAST)) ? 0 : 1;
944  else
945  i = onoff_value(params);
946 
947  if (i) {
949  i18n(op, "You can now cast spells anywhere."));
950  SET_FLAG(op, FLAG_WIZCAST);
951  } else {
953  i18n(op, "You now cannot cast spells in no-magic areas."));
955  }
956 }
957 
966 void command_dumpallobjects(object *op, const char *params) {
967  object_dump_all();
968 }
969 
978 void command_dumpfriendlyobjects(object *op, const char *params) {
980 }
981 
990 void command_dumpallarchetypes(object *op, const char *params) {
992 }
993 
1002 void command_ssdumptable(object *op, const char *params) {
1003  ss_dump_table(SS_DUMP_TABLE, NULL, 0);
1004 }
1005 
1014 void command_dumpmap(object *op, const char *params) {
1015  if (op)
1016  dump_map(op->map);
1017 }
1018 
1027 void command_dumpallmaps(object *op, const char *params) {
1028  dump_all_maps();
1029 }
1030 
1039 void command_printlos(object *op, const char *params) {
1040  if (op)
1041  print_los(op);
1042 }
1043 
1044 
1053 void command_version(object *op, const char *params) {
1055  MSG_TYPE_ADMIN_VERSION, "Crossfire "FULL_VERSION);
1056 }
1057 
1066 void command_listen(object *op, const char *params) {
1067  int i;
1068 
1069  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1071  i18n(op, "Set listen to what (presently %d)?"),
1072  op->contr->listening);
1073  return;
1074  }
1075  if (i < 0) {
1077  i18n(op, "Verbose level should be positive."));
1078  return;
1079  }
1080  op->contr->listening = (char)i;
1082  i18n(op, "Your verbose level is now %d."),
1083  i);
1084 }
1085 
1097 void command_statistics(object *pl, const char *params) {
1098  char buf[MAX_BUF];
1099  uint32_t hours, minutes;
1100  uint64_t seconds; /* 64 bit to prevent overflows an intermediate results */
1101 
1102  if (!pl->contr)
1103  return;
1104  safe_strncpy(buf, i18n(pl, "[fixed] Experience: %"), sizeof(buf));
1105  strcat(buf, FMT64);
1107  buf,
1108  pl->stats.exp);
1109  safe_strncpy(buf, i18n(pl, "[fixed] Next Level: %"), sizeof(buf));
1110  strcat(buf, FMT64);
1112  buf,
1113  level_exp(pl->level+1, pl->expmul));
1114 
1116  i18n(pl, "[fixed]\nStat Nat/Real/Max"));
1117 
1119  i18n(pl, "[fixed]Str %2d/ %3d/%3d"),
1120  pl->contr->orig_stats.Str, pl->stats.Str, 20+pl->arch->clone.stats.Str);
1122  i18n(pl, "[fixed]Dex %2d/ %3d/%3d"),
1123  pl->contr->orig_stats.Dex, pl->stats.Dex, 20+pl->arch->clone.stats.Dex);
1125  i18n(pl, "[fixed]Con %2d/ %3d/%3d"),
1126  pl->contr->orig_stats.Con, pl->stats.Con, 20+pl->arch->clone.stats.Con);
1128  i18n(pl, "[fixed]Int %2d/ %3d/%3d"),
1129  pl->contr->orig_stats.Int, pl->stats.Int, 20+pl->arch->clone.stats.Int);
1131  i18n(pl, "[fixed]Wis %2d/ %3d/%3d"),
1132  pl->contr->orig_stats.Wis, pl->stats.Wis, 20+pl->arch->clone.stats.Wis);
1134  i18n(pl, "[fixed]Pow %2d/ %3d/%3d"),
1135  pl->contr->orig_stats.Pow, pl->stats.Pow, 20+pl->arch->clone.stats.Pow);
1137  i18n(pl, "[fixed]Cha %2d/ %3d/%3d"),
1138  pl->contr->orig_stats.Cha, pl->stats.Cha, 20+pl->arch->clone.stats.Cha);
1140  i18n(pl, "\nAttack Mode: %s"),
1141  i18n(pl, pl->contr->peaceful ? "Peaceful" : "Hostile"));
1145  float weap_speed = pl->weapon_speed; // This is the number of attacks per tick.
1146  if (weap_speed < 0.0f)
1147  weap_speed = 0.0f;
1148  if (weap_speed > 1.0f)
1149  weap_speed = 1.0f;
1150  // We will initially calculate the damage if every attack you perform hits.
1151  // This will serve as a baseline for future calculations
1152  float dps = (1000000.0f / max_time) * weap_speed * pl->stats.dam;
1153  // TODO: Account for opposing AC in calculations, make some sort of table/chart.
1154  // Then we round the floating-point.
1156  i18n(pl, "\n\nDam/Sec: %4d"), (int)(dps + 0.5f));
1157 
1158  /* max_time is in microseconds - thus divide by 1000000.
1159  * Need 64 bit values, as otherwise ticks_played * max_time
1160  * can easily overflow.
1161  * Note the message displayed here isn't really
1162  * perfect, since if max_time has been changed since the player started,
1163  * the time estimates use the current value. But I'm presuming that
1164  * max_time won't change very often. MSW 2009-12-01
1165  */
1166  seconds = (uint64_t)pl->contr->ticks_played * (uint64_t)max_time / 1000000;
1167  minutes = (uint32_t)seconds / 60;
1168  hours = minutes / 60;
1169  minutes = minutes % 60;
1170 
1172  "You have played this character for %u ticks, which amounts "
1173  "to %d hours and %d minutes.",
1174  pl->contr->ticks_played, hours, minutes);
1175 
1176 
1177  /* Can't think of anything else to print right now */
1178 }
1179 
1188 void command_fix_me(object *op, const char *params) {
1189  object_sum_weight(op);
1190  fix_object(op);
1191 }
1192 
1201 void command_players(object *op, const char *params) {
1202  char buf[MAX_BUF];
1203  char *t;
1204  DIR *dir;
1205 
1206  snprintf(buf, sizeof(buf), "%s/%s/", settings.localdir, settings.playerdir);
1207  t = buf+strlen(buf);
1208  if ((dir = opendir(buf)) != NULL) {
1209  const struct dirent *entry;
1210 
1211  while ((entry = readdir(dir)) != NULL) {
1212  /* skip '.' , '..' */
1213  if (!((entry->d_name[0] == '.' && entry->d_name[1] == '\0')
1214  || (entry->d_name[0] == '.' && entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) {
1215  struct stat st;
1216 
1217  strcpy(t, entry->d_name);
1218  if (stat(buf, &st) == 0) {
1219  /* This was not posix compatible
1220  * if ((st.st_mode & S_IFMT)==S_IFDIR) {
1221  */
1222  if (S_ISDIR(st.st_mode)) {
1223  struct tm *tm = localtime(&st.st_mtime);
1224 
1226  i18n(op, "[fixed]%s\t%04d %02d %02d %02d %02d %02d"),
1227  entry->d_name,
1228  1900+tm->tm_year,
1229  1+tm->tm_mon,
1230  tm->tm_mday,
1231  tm->tm_hour,
1232  tm->tm_min,
1233  tm->tm_sec);
1234  }
1235  }
1236  }
1237  }
1238  }
1239  closedir(dir);
1240 }
1241 
1250 void command_applymode(object *op, const char *params) {
1251  unapplymode unapply = op->contr->unapply;
1252  static const char *const types[] = {
1253  "nochoice",
1254  "never",
1255  "always"
1256  };
1257 
1258  if (*params == '\0') {
1260  i18n(op, "applymode is set to %s"),
1261  types[op->contr->unapply]);
1262  return;
1263  }
1264 
1265  if (!strcmp(params, "nochoice"))
1266  op->contr->unapply = unapply_nochoice;
1267  else if (!strcmp(params, "never"))
1268  op->contr->unapply = unapply_never;
1269  else if (!strcmp(params, "always"))
1270  op->contr->unapply = unapply_always;
1271  else {
1273  i18n(op, "applymode: Unknown options %s, valid options are nochoice, never, always"),
1274  params);
1275  return;
1276  }
1278  i18n(op, "applymode%s set to %s"),
1279  (unapply == op->contr->unapply ? "" : " now"),
1280  types[op->contr->unapply]);
1281 }
1282 
1291 void command_bowmode(object *op, const char *params) {
1292  bowtype_t oldtype = op->contr->bowtype;
1293  static const char *const types[] = {
1294  "normal",
1295  "threewide",
1296  "spreadshot",
1297  "firenorth",
1298  "firene",
1299  "fireeast",
1300  "firese",
1301  "firesouth",
1302  "firesw",
1303  "firewest",
1304  "firenw",
1305  "bestarrow"
1306  };
1307  int i, found;
1308 
1309  if (*params == '\0') {
1311  i18n(op, "bowmode is set to %s"),
1312  types[op->contr->bowtype]);
1313  return;
1314  }
1315 
1316  for (i = 0, found = 0; i <= bow_bestarrow; i++) {
1317  if (!strcmp(params, types[i])) {
1318  found++;
1319  op->contr->bowtype = i;
1320  break;
1321  }
1322  }
1323  if (!found) {
1325  stringbuffer_append_printf(buf, "bowmode: Unknown options %s, valid options are:", params);
1326  for (i = 0; i <= bow_bestarrow; i++) {
1327  stringbuffer_append_string(buf, " ");
1328  stringbuffer_append_string(buf, types[i]);
1329  if (i < bow_nw)
1330  stringbuffer_append_string(buf, ",");
1331  else
1332  stringbuffer_append_string(buf, ".");
1333  }
1334  char *result = stringbuffer_finish(buf);
1336  free(result);
1337  return;
1338  }
1340  i18n(op, "bowmode%s set to %s"),
1341  (oldtype == op->contr->bowtype ? "" : " now"),
1342  types[op->contr->bowtype]);
1343  return;
1344 }
1345 
1354 void command_unarmed_skill(object *op, const char *params) {
1355  object *skill;
1356  size_t i;
1357 
1358  if (*params == '\0') {
1360  "unarmed skill is set to %s",
1361  op->contr->unarmed_skill ? op->contr->unarmed_skill: "nothing");
1362  return;
1363  }
1364 
1365  /* find_skill_by_name() will ready any skill tools - which
1366  * is OK for us because no unarmed skills require skill tools,
1367  * but this could be an issue if you reuse this code for other skills.
1368  */
1369  skill = find_skill_by_name(op, params);
1370 
1371  if (!skill) {
1373  "You do not know any such skill called %s",
1374  params);
1375  return;
1376  }
1377  for (i = 0; i < sizeof(unarmed_skills); i++)
1378  if (skill->subtype == unarmed_skills[i])
1379  break;
1380  if (i == sizeof(unarmed_skills)) {
1382  "%s is not an unarmed skill!",
1383  skill->name);
1384  return;
1385 
1386  }
1387 
1388  if (op->contr->unarmed_skill)
1389  free_string(op->contr->unarmed_skill);
1390 
1391  /* Taking actual skill name is better than taking params,
1392  * as params could be something more than an exact skill name.
1393  */
1394  op->contr->unarmed_skill = add_string(skill->name);
1395 
1397  "unarmed skill is now set to %s",
1398  op->contr->unarmed_skill);
1399 }
1400 
1401 
1410 void command_petmode(object *op, const char *params) {
1411  petmode_t oldtype = op->contr->petmode;
1412  static const char *const types[] = {
1413  "normal",
1414  "sad",
1415  "defend",
1416  "arena"
1417  };
1418 
1419  if (*params == '\0') {
1421  i18n(op, "petmode is set to %s"),
1422  types[op->contr->petmode]);
1423  return;
1424  }
1425 
1426  if (!strcmp(params, "normal"))
1427  op->contr->petmode = pet_normal;
1428  else if (!strcmp(params, "sad"))
1429  op->contr->petmode = pet_sad;
1430  else if (!strcmp(params, "defend"))
1431  op->contr->petmode = pet_defend;
1432  else if (!strcmp(params, "arena"))
1433  op->contr->petmode = pet_arena;
1434  else {
1436  i18n(op, "petmode: Unknown options %s, valid options are normal, sad (seek and destroy), defend, arena"),
1437  params);
1438  return;
1439  }
1441  i18n(op, "petmode%s set to %s"),
1442  (oldtype == op->contr->petmode ? "" : " now"),
1443  types[op->contr->petmode]);
1444 }
1445 
1454 void command_showpets(object *op, const char *params) {
1455  objectlink *obl, *next;
1456  int counter = 0, target = 0;
1457  int have_shown_pet = 0;
1458  if (*params != '\0')
1459  target = atoi(params);
1460 
1461  for (obl = first_friendly_object; obl != NULL; obl = next) {
1462  object *ob = obl->ob;
1463 
1464  next = obl->next;
1465  if (object_get_owner(ob) == op) {
1466  if (target == 0) {
1467  if (counter == 0)
1469  i18n(op, "Pets:"));
1471  i18n(op, "%d %s - level %d"),
1472  ++counter, ob->name, ob->level);
1473  } else if (!have_shown_pet && ++counter == target) {
1475  i18n(op, "[fixed]level %d %s"),
1476  ob->level, ob->name);
1478  i18n(op, "[fixed]%d/%d HP, %d/%d SP"),
1479  ob->stats.hp, ob->stats.maxhp, ob->stats.sp, ob->stats.maxsp);
1480 
1481  /* this is not a nice way to do this, it should be made to be more like the statistics command */
1483  i18n(op, "[fixed]Str %d"),
1484  ob->stats.Str);
1486  i18n(op, "[fixed]Dex %d"),
1487  ob->stats.Dex);
1489  i18n(op, "[fixed]Con %d"),
1490  ob->stats.Con);
1492  i18n(op, "[fixed]Int %d"),
1493  ob->stats.Int);
1495  i18n(op, "[fixed]Wis %d"),
1496  ob->stats.Wis);
1498  i18n(op, "[fixed]Cha %d"),
1499  ob->stats.Cha);
1501  i18n(op, "[fixed]Pow %d"),
1502  ob->stats.Pow);
1504  i18n(op, "[fixed]wc %d damage %d ac %d"),
1505  ob->stats.wc, ob->stats.dam, ob->stats.ac);
1506  have_shown_pet = 1;
1507  }
1508  }
1509  }
1510  if (counter == 0)
1512  i18n(op, "You have no pets."));
1513  else if (target != 0 && have_shown_pet == 0)
1515  i18n(op, "No such pet."));
1516 }
1517 
1526 void command_usekeys(object *op, const char *params) {
1527  usekeytype oldtype = op->contr->usekeys;
1528  static const char *const types[] = {
1529  "inventory",
1530  "keyrings",
1531  "containers"
1532  };
1533 
1534  if (*params == '\0') {
1536  i18n(op, "usekeys is set to %s"),
1537  types[op->contr->usekeys]);
1538  return;
1539  }
1540 
1541  if (!strcmp(params, "inventory"))
1542  op->contr->usekeys = key_inventory;
1543  else if (!strcmp(params, "keyrings"))
1544  op->contr->usekeys = keyrings;
1545  else if (!strcmp(params, "containers"))
1546  op->contr->usekeys = containers;
1547  else {
1549  i18n(op, "usekeys: Unknown option %s, valid options are inventory, keyrings, containers"),
1550  params);
1551  return;
1552  }
1554  i18n(op, "usekeys%s set to %s"),
1555  (oldtype == op->contr->usekeys ? "" : " now"),
1556  types[op->contr->usekeys]);
1557 }
1558 
1567 void command_resistances(object *op, const char *params) {
1568  int i;
1569  if (!op)
1570  return;
1571 
1572  for (i = 0; i < NROFATTACKS; i++) {
1573  if (i == ATNR_INTERNAL)
1574  continue;
1575 
1577  i18n(op, "[fixed]%-20s %+5d"),
1578  attacktype_desc[i], op->resist[i]);
1579  }
1580 
1581  /* If dragon player, let's display natural resistances */
1582  if (is_dragon_pl(op)) {
1583  int attack;
1584  object *tmp;
1585 
1586  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
1587  if (tmp != NULL) {
1589  i18n(op, "\nNatural skin resistances:"));
1590 
1591  for (attack = 0; attack < NROFATTACKS; attack++) {
1592  if (atnr_is_dragon_enabled(attack)) {
1594  i18n(op, "%s: %d"),
1595  change_resist_msg[attack], tmp->resist[attack]);
1596  }
1597  }
1598  }
1599  }
1600 }
1601 
1612 static void help_topics(object *op, int what) {
1613  DIR *dirp;
1614  struct dirent *de;
1615  char filename[MAX_BUF], line[HUGE_BUF];
1616  char suffix[MAX_BUF];
1617  int namelen;
1618  const char *language;
1619 
1620  language = i18n_get_language_code(op->contr->language);
1621  snprintf(suffix, sizeof(suffix), ".%s", language);
1622 
1623  switch (what) {
1624  case 1:
1625  snprintf(filename, sizeof(filename), "%s/wizhelp", settings.datadir);
1627  i18n(op, " Wiz commands:"));
1628  break;
1629 
1630  case 3:
1631  snprintf(filename, sizeof(filename), "%s/mischelp", settings.datadir);
1633  i18n(op, " Misc help:"));
1634  break;
1635 
1636  default:
1637  snprintf(filename, sizeof(filename), "%s/help", settings.datadir);
1639  i18n(op, " Commands:"));
1640  break;
1641  }
1642  if (!(dirp = opendir(filename)))
1643  return;
1644 
1645  line[0] = '\0';
1646  for (de = readdir(dirp); de; de = readdir(dirp)) {
1647  namelen = NAMLEN(de);
1648 
1649  if (namelen <= 2
1650  && *de->d_name == '.'
1651  && (namelen == 1 || de->d_name[1] == '.'))
1652  continue;
1653  if (strstr(de->d_name, suffix)) {
1654  strcat(line, strtok(de->d_name, "."));
1655  strcat(line, " ");
1656  }
1657  }
1659  line);
1660  closedir(dirp);
1661 }
1662 
1673 static void show_commands(object *op, int what) {
1674  char line[HUGE_BUF];
1675  int i, size;
1677 
1678  switch (what) {
1679  case 1:
1680  ap = WizCommands;
1681  size = WizCommandsSize;
1683  i18n(op, " Wiz commands:"));
1684  break;
1685 
1686  case 2:
1687  ap = CommunicationCommands;
1688  size = CommunicationCommandSize;
1690  i18n(op, " Communication commands:"));
1691  break;
1692 
1693  default:
1694  ap = Commands;
1695  size = CommandsSize;
1697  i18n(op, " Commands:"));
1698  break;
1699  }
1700 
1701  line[0] = '\0';
1702  for (i = 0; i < size; i++) {
1703  strcat(line, ap[i].name);
1704  strcat(line, " ");
1705  }
1707 }
1708 
1720 static int find_help_file(const char *name, const char *language, int wiz, char *path, int length) {
1721  struct stat st;
1722 
1723  snprintf(path, length, "%s/help/%s.%s", settings.datadir, name, language);
1724  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1725  return 1;
1726  }
1727 
1728  if (strcmp(language, "en")) {
1729  snprintf(path, length, "%s/help/%s.en", settings.datadir, name);
1730  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1731  return 1;
1732  }
1733  }
1734 
1735  if (!wiz)
1736  return 0;
1737 
1738  snprintf(path, length, "%s/wizhelp/%s.%s", settings.datadir, name, language);
1739  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1740  return 1;
1741  }
1742  if (strcmp(language, "en")) {
1743  snprintf(path, length, "%s/wizhelp/%s.en", settings.datadir, name);
1744  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1745  return 1;
1746  }
1747  }
1748 
1749  return 0;
1750 }
1751 
1760 void command_help(object *op, const char *params) {
1761  FILE *fp;
1762  char filename[MAX_BUF], line[MAX_BUF];
1763  int len;
1764  const char *language;
1765 
1766  /*
1767  * Main help page?
1768  */
1769  if (*params == '\0') {
1770  snprintf(filename, sizeof(filename), "%s/def_help", settings.datadir);
1771  if ((fp = fopen(filename, "r")) == NULL) {
1772  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1773  return;
1774  }
1775  while (fgets(line, MAX_BUF, fp)) {
1776  line[MAX_BUF-1] = '\0';
1777  len = strlen(line)-1;
1778  if (line[len] == '\n')
1779  line[len] = '\0';
1781  }
1782  fclose(fp);
1783  return;
1784  }
1785 
1786  /*
1787  * Topics list
1788  */
1789  if (!strcmp(params, "topics")) {
1790  help_topics(op, 3);
1791  help_topics(op, 0);
1792  if (QUERY_FLAG(op, FLAG_WIZ))
1793  help_topics(op, 1);
1794  return;
1795  }
1796 
1797  /*
1798  * Commands list
1799  */
1800  if (!strcmp(params, "commands")) {
1801  show_commands(op, 0);
1803  show_commands(op, 2); /* show comm commands */
1804  if (QUERY_FLAG(op, FLAG_WIZ)) {
1806  show_commands(op, 1);
1807  }
1808  return;
1809  }
1810 
1811  /*
1812  * User wants info about command
1813  */
1814  if (strchr(params, '.') || strchr(params, ' ') || strchr(params, '/')) {
1816  i18n(op, "Illegal characters in '%s'"),
1817  params);
1818  return;
1819  }
1820 
1821  language = i18n_get_language_code(op->contr->language);
1822 
1823  if (!find_help_file(params, language, QUERY_FLAG(op, FLAG_WIZ), filename, sizeof(filename))) {
1825  i18n(op, "No help available on '%s'"),
1826  params);
1827  return;
1828  }
1829 
1830  /*
1831  * Found that. Just cat it to screen.
1832  */
1833  if ((fp = fopen(filename, "r")) == NULL) {
1834  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1835  return;
1836  }
1837 
1839  i18n(op, "Help about '%s'"),
1840  params);
1841 
1842  while (fgets(line, MAX_BUF, fp)) {
1843  line[MAX_BUF-1] = '\0';
1844  len = strlen(line)-1;
1845  if (line[len] == '\n')
1846  line[len] = '\0';
1848  }
1849  fclose(fp);
1850 }
1851 
1862 static int onoff_value(const char *line) {
1863  int i;
1864 
1865  if (sscanf(line, "%d", &i))
1866  return (i != 0);
1867 
1868  switch (line[0]) {
1869  case 'o':
1870  switch (line[1]) {
1871  case 'n':
1872  return 1; /* on */
1873  default:
1874  return 0; /* o[ff] */
1875  }
1876 
1877  case 'y': /* y[es] */
1878  case 'k': /* k[ylla] */
1879  case 's':
1880  case 'd':
1881  return 1;
1882 
1883  case 'n': /* n[o] */
1884  case 'e': /* e[i] */
1885  case 'u':
1886  default:
1887  return 0;
1888  }
1889 }
1890 
1896 void command_quit(object* op, const char* params) {
1897  draw_ext_info(
1899  i18n(op,
1900  "To leave the game, sleep in (apply) a bed to reality. To "
1901  "permenantly delete your character, use the 'delete' command."));
1902 }
1903 
1912 void command_delete(object *op, const char *params) {
1913  if (QUERY_FLAG(op, FLAG_WAS_WIZ)) {
1914  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_ADMIN_DM, "Can't quit when in DM mode.");
1915  return;
1916  }
1917 
1918  send_query(&op->contr->socket, CS_QUERY_SINGLECHAR,
1919  i18n(op, "Quitting will delete your character.\nAre you sure you want to delete your character (y/n):"));
1920 
1921  player_set_state(op->contr, ST_CONFIRM_QUIT);
1922 }
1923 
1932 void command_sound(object *op, const char *params) {
1933  if (!(op->contr->socket.sound&SND_MUTE)) {
1934  op->contr->socket.sound = op->contr->socket.sound|SND_MUTE;
1936  i18n(op, "Sounds are turned off."));
1937  } else {
1938  op->contr->socket.sound = op->contr->socket.sound&~SND_MUTE;
1940  i18n(op, "The sounds are enabled."));
1941  }
1942  return;
1943 }
1944 
1954 void receive_player_name(object *op) {
1955  if (!check_name(op->contr, op->contr->write_buf+1)) {
1956  get_name(op);
1957  return;
1958  }
1959  FREE_AND_COPY(op->name, op->contr->write_buf+1);
1960  FREE_AND_COPY(op->name_pl, op->contr->write_buf+1);
1961  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_SUBTYPE_NONE, op->contr->write_buf);
1962  op->contr->name_changed = 1;
1963  get_password(op);
1964 }
1965 
1972 void receive_player_password(object *op) {
1973  unsigned int pwd_len = strlen(op->contr->write_buf);
1974 
1975  if (pwd_len <= 1 || pwd_len > 17) {
1976  if (op->contr->state == ST_CHANGE_PASSWORD_OLD
1977  || op->contr->state == ST_CHANGE_PASSWORD_NEW
1978  || op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
1980  i18n(op, "Password changed cancelled."));
1981  player_set_state(op->contr, ST_PLAYING);
1982  } else
1983  get_name(op);
1984  return;
1985  }
1986  /* To hide the password better */
1987  /* With currently clients, not sure if this is really the case - MSW */
1989 
1990  if (checkbanned(op->name, op->contr->socket.host)) {
1991  LOG(llevInfo, "Banned player tried to add: [%s@%s]\n", op->name, op->contr->socket.host);
1993  i18n(op, "You are not allowed to play."));
1994  get_name(op);
1995  return;
1996  }
1997 
1998  if (op->contr->state == ST_CONFIRM_PASSWORD) {
1999  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
2001  i18n(op, "The passwords did not match."));
2002  get_name(op);
2003  return;
2004  }
2005  LOG(llevInfo, "LOGIN: New player named %s from ip %s\n", op->name, op->contr->socket.host);
2006  display_motd(op);
2008  i18n(op, "\nWelcome, Brave New Warrior!\n"));
2009  roll_again(op);
2010  player_set_state(op->contr, ST_ROLL_STAT);
2011  return;
2012  }
2013 
2014  if (op->contr->state == ST_CHANGE_PASSWORD_OLD) {
2015  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
2017  i18n(op, "You entered the wrong current password."));
2018  player_set_state(op->contr, ST_PLAYING);
2019  } else {
2020  send_query(&op->contr->socket, CS_QUERY_HIDEINPUT, i18n(op, "Please enter your new password, or blank to cancel:"));
2022  }
2023  return;
2024  }
2025 
2026  if (op->contr->state == ST_CHANGE_PASSWORD_NEW) {
2027  safe_strncpy(op->contr->new_password, newhash(op->contr->write_buf+1),
2028  sizeof(op->contr->new_password));
2029  send_query(&op->contr->socket, CS_QUERY_HIDEINPUT,
2030  i18n(op, "Please confirm your new password, or blank to cancel:"));
2032  return;
2033  }
2034 
2035  if (op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
2036  if (!check_password(op->contr->write_buf+1, op->contr->new_password)) {
2038  i18n(op, "The new passwords don't match!"));
2039  } else {
2041  i18n(op, "Password changed."));
2042  strncpy(op->contr->password, op->contr->new_password, 13);
2043  }
2044  player_set_state(op->contr, ST_PLAYING);
2045  return;
2046  }
2047 
2048  safe_strncpy(op->contr->password, newhash(op->contr->write_buf+1),
2049  sizeof(op->contr->password));
2050  player_set_state(op->contr, ST_ROLL_STAT);
2051  check_login(op, TRUE);
2052 }
2053 
2064 void command_title(object *op, const char *params) {
2065  char buf[MAX_BUF];
2066 
2067  if (settings.set_title == FALSE) {
2069  i18n(op, "You cannot change your title."));
2070  return;
2071  }
2072 
2073  /* dragon players cannot change titles */
2074  if (is_dragon_pl(op)) {
2076  i18n(op, "Dragons cannot change titles."));
2077  return;
2078  }
2079 
2080  if (*params == '\0') {
2081  char tmp[MAX_BUF];
2082 
2083  player_get_title(op->contr, tmp, sizeof(tmp));
2084  snprintf(buf, sizeof(buf), i18n(op, "Your title is '%s'."), tmp);
2086  return;
2087  }
2088  if (strcmp(params, "clear") == 0 || strcmp(params, "default") == 0) {
2089  if (!player_has_own_title(op->contr))
2091  i18n(op, "Your title is the default title."));
2092  else
2094  i18n(op, "Title set to default."));
2095  player_set_own_title(op->contr, "");
2096  return;
2097  }
2098 
2099  if ((int)strlen(params) >= MAX_NAME) {
2101  i18n(op, "Title too long."));
2102  return;
2103  }
2104  player_set_own_title(op->contr, params);
2105 }
2106 
2115 void command_save(object *op, const char *params) {
2116  if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL)&P_NO_CLERIC) {
2118  i18n(op, "You can not save on unholy ground."));
2119  } else if (!op->stats.exp) {
2121  i18n(op, "You don't deserve to save yet."));
2122  } else {
2123  if (save_player(op, 1))
2125  i18n(op, "You have been saved."));
2126  else
2128  i18n(op, "SAVE FAILED!"));
2129  }
2130 }
2131 
2140 void command_peaceful(object *op, const char *params) {
2141  if ((op->contr->peaceful = !op->contr->peaceful))
2143  i18n(op, "You will not attack other players."));
2144  else
2146  i18n(op, "You will attack other players."));
2147 }
2148 
2157 void command_wimpy(object *op, const char *params) {
2158  int i;
2159 
2160  if (*params == '\0' || !sscanf(params, "%d", &i)) {
2162  i18n(op, "Your current wimpy level is %d."),
2163  op->run_away);
2164  return;
2165  }
2166 
2167  if (i < 0 || i > 100) {
2169  i18n(op, "Wimpy level should be between 1 and 100."),
2170  i);
2171  return;
2172  }
2173 
2175  i18n(op, "Your new wimpy level is %d."),
2176  i);
2177  op->run_away = i;
2178 }
2179 
2188 void command_brace(object *op, const char *params) {
2189  if (*params == '\0')
2190  op->contr->braced = !op->contr->braced;
2191  else
2192  op->contr->braced = onoff_value(params);
2193 
2194  if (op->contr->braced)
2196  i18n(op, "You are braced."));
2197  else
2199  i18n(op, "Not braced."));
2200 
2201  fix_object(op);
2202 }
2203 
2212 void command_kill_pets(object *op, const char *params) {
2213  objectlink *obl, *next;
2214  int counter = 0, removecount = 0;
2215 
2216  if (*params == '\0') {
2217  pets_terminate_all(op);
2219  i18n(op, "Your pets have been killed."));
2220  } else {
2221  int target = atoi(params);
2222  for (obl = first_friendly_object; obl != NULL; obl = next) {
2223  object *ob = obl->ob;
2224  next = obl->next;
2225  if (object_get_owner(ob) == op)
2226  if (++counter == target || (target == 0 && !strcasecmp(ob->name, params))) {
2227  if (!QUERY_FLAG(ob, FLAG_REMOVED))
2228  object_remove(ob);
2231  removecount++;
2232  }
2233  }
2234  if (removecount != 0)
2236  i18n(op, "Killed %d pets."),
2237  removecount);
2238  else
2240  i18n(op, "Couldn't find any suitable pets to kill."));
2241  }
2242 }
2243 
2252 void command_passwd(object *pl, const char *params) {
2253  /* If old client, this is the way you change your password. */
2254  if (pl->contr->socket.login_method < 1){
2255  send_query(&pl->contr->socket, CS_QUERY_HIDEINPUT, i18n(pl, "Password change.\nPlease enter your current password, or empty string to cancel."));
2256 
2258  }
2259  /* If new client (login_method = 2) or jxclient (login_method = 1), changing the password does nothing anyway, so error out */
2260  else{
2262  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."));
2263  }
2264 }
2265 
2275 void do_harvest(object *pl, int dir, object *skill) {
2276  int16_t x, y;
2277  int count = 0, proba; /* Probability to get the item, 100 based. */
2278  int level, exp, check_exhaust = 0;
2279  object *found[10]; /* Found items that can be harvested. */
2280  mapstruct *map;
2281  object *item, *inv, *harvested;
2282  sstring trace, ttool, tspeed, race, tool, slevel, sexp;
2283  float speed;
2284 
2285  x = pl->x+freearr_x[dir];
2286  y = pl->y+freearr_y[dir];
2287  map = pl->map;
2288 
2289  if (!IS_PLAYER(pl))
2290  return;
2291 
2292  if (!map)
2293  return;
2294 
2295  if (get_map_flags(map, &map, x, y, &x, &y)&P_OUT_OF_MAP) {
2296  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2297  return;
2298  }
2299 
2300  if (!pl->chosen_skill || pl->chosen_skill->skill != skill->skill)
2301  return;
2302 
2303  trace = object_get_value(pl->chosen_skill, "harvest_race");
2304  ttool = object_get_value(pl->chosen_skill, "harvest_tool");
2305  tspeed = object_get_value(pl->chosen_skill, "harvest_speed");
2306  if (!trace || strcmp(trace, "") == 0 || !ttool || strcmp(ttool, "") == 0 || !tspeed || strcmp(tspeed, "") == 0) {
2307  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2308  LOG(llevError, "do_harvest: tool %s without harvest_[race|tool|speed]\n", pl->chosen_skill->name);
2309  return;
2310  }
2311 
2312  item = GET_MAP_OB(map, x, y);
2313  while (item && count < 10) {
2314  FOR_INV_PREPARE(item, inv) {
2315  if (object_get_value(inv, "harvestable") == NULL)
2316  continue;
2317  race = object_get_value(inv, "harvest_race");
2318  tool = object_get_value(inv, "harvest_tool");
2319  slevel = object_get_value(inv, "harvest_level");
2320  sexp = object_get_value(inv, "harvest_exp");
2321  if (race && (!slevel || !sexp)) {
2322  LOG(llevError, "do_harvest: item %s without harvest_[level|exp]\n", inv->name);
2323  continue;
2324  }
2325  if (race == trace && (!tool || tool == ttool))
2326  found[count++] = inv;
2327  } FOR_INV_FINISH();
2328  item = item->above;
2329  }
2330  if (count == 0) {
2331  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2332  return;
2333  }
2334 
2335  inv = found[rndm(0, count-1)];
2336  assert(inv);
2337  item = inv->env;
2338  assert(item);
2339 
2340  slevel = object_get_value(inv, "harvest_level");
2341  sexp = object_get_value(inv, "harvest_exp");
2342  level = atoi(slevel);
2343  exp = atoi(sexp);
2344 
2345  speed = atof(tspeed);
2346  if (speed < 0)
2347  speed = -speed*pl->speed;
2348  pl->speed_left -= speed;
2349 
2350 
2351  /* Now we found something to harvest, randomly try to get it. */
2352  if (level > skill->level+10) {
2353  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2354  return;
2355  }
2356 
2357  if (level >= skill->level)
2358  /* Up to 10 more levels, 1 to 11 percent probability. */
2359  proba = 10+skill->level-level;
2360  else if (skill->level <= level+10)
2361  proba = 10+(skill->level-level)*2;
2362  else
2363  proba = 30;
2364 
2365  if (proba <= random_roll(0, 100, pl, 1)) {
2366  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2367  return;
2368  }
2369 
2370  /* Check the new item can fit into inventory.
2371  * Fixes bug #3060474: fishing puts more fishes into inventory than you can carry. */
2372  if (((uint32_t)(pl->weight + pl->carrying + inv->weight)) > get_weight_limit(pl->stats.Str)) {
2373  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);
2374  return;
2375  }
2376 
2377  /* Ok, got it. */
2378  if (inv->nrof == 0) {
2379  harvested = object_new();
2380  object_copy_with_inv(inv, harvested);
2381  } else {
2382  if (count == 1 && inv->nrof == 1) {
2383  check_exhaust = 1;
2384  }
2385  harvested = object_split(inv, 1, NULL, 0);
2386  }
2387  object_set_value(harvested, "harvestable", NULL, 0);
2388  if (QUERY_FLAG(harvested, FLAG_MONSTER)) {
2389  int spot = object_find_free_spot(harvested, pl->map, pl->x, pl->y, 0, SIZEOFFREE);
2390  if (spot == -1) {
2391  /* Better luck next time...*/
2392  object_remove(harvested);
2393  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2394  return;
2395  }
2396  object_insert_in_map_at(harvested, pl->map, NULL, 0, pl->x+freearr_x[spot], pl->y+freearr_y[spot]);
2397  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s a %s!", skill->slaying, harvested->name);
2398  } else {
2399  harvested = object_insert_in_ob(harvested, pl);
2400  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s some %s", skill->slaying, harvested->name);
2401  }
2402 
2403  /* Get exp */
2404  change_exp(pl, exp, skill->name, SK_EXP_ADD_SKILL);
2405 
2406  if (check_exhaust) {
2407  sstring replacement = object_get_value(item, "harvest_exhaust_replacement");
2408  if (replacement) {
2409  if (replacement[0] != '-') {
2410  archetype *other = try_find_archetype(replacement);
2411  if (other) {
2412  object *final = object_create_arch(other);
2413  object_insert_in_map_at(final, map, item, INS_BELOW_ORIGINATOR, item->x, item->y);
2414  }
2415  }
2416  object_remove(item);
2417  object_free(item, FREE_OBJ_FREE_INVENTORY);
2418  }
2419  }
2420 
2421  return;
2422 }
#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:313
void command_petmode(object *op, const char *params)
Definition: c_misc.c:1410
char path[HUGE_BUF]
Definition: map.h:366
void command_save(object *op, const char *params)
Definition: c_misc.c:2115
void command_afk(object *op, const char *params)
Definition: c_misc.c:770
Definition: player.h:92
void command_malloc(object *op, const char *params)
Definition: c_misc.c:790
void command_help(object *op, const char *params)
Definition: c_misc.c:1760
#define ST_GET_PARTY_PASSWORD
Definition: define.h:586
static void map_info(object *op, const char *search)
Definition: c_misc.c:52
void command_unarmed_skill(object *op, const char *params)
Definition: c_misc.c:1354
static int onoff_value(const char *line)
Definition: c_misc.c:1862
struct mapdef mapstruct
void command_who(object *op, const char *params)
Definition: c_misc.c:621
command_array_struct Commands[]
Definition: commands.c:36
void object_free(object *ob, int flags)
Definition: object.c:1348
const int WizCommandsSize
Definition: commands.c:267
Definition: player.h:39
void roll_again(object *op)
Definition: player.c:1120
int64_t level_exp(int level, double expmul)
Definition: living.c:1872
int check_name(player *me, const char *name)
Definition: login.c:163
void command_wizpass(object *op, const char *params)
Definition: c_misc.c:906
static void display_who_entry(object *op, player *pl, const char *format)
Definition: c_misc.c:638
#define SET_FLAG(xyz, p)
Definition: define.h:223
void command_maps(object *op, const char *params)
Definition: c_misc.c:826
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
StringBuffer * buf
Definition: readable.c:1591
#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
#define FLAG_USE_ARMOUR
Definition: define.h:296
void command_motd(object *op, const char *params)
Definition: c_misc.c:216
char who_wiz_format[MAX_BUF]
Definition: global.h:276
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:826
EXTERN objectlink * first_friendly_object
Definition: global.h:119
void object_copy_with_inv(const object *src_ob, object *dest_ob)
Definition: object.c:952
int16_t players
Definition: map.h:345
void command_dumpallobjects(object *op, const char *params)
Definition: c_misc.c:966
unapplymode
Definition: player.h:62
int login_order
Definition: c_misc.c:522
int save_player(object *op, int flag)
Definition: login.c:212
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
uint32_t in_memory
Definition: map.h:346
const char * playerdir
Definition: global.h:247
#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:338
void command_brace(object *op, const char *params)
Definition: c_misc.c:2188
#define HUGE_BUF
Definition: define.h:37
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4136
#define SND_MUTE
Definition: sounds.h:14
#define SS_DUMP_TOTALS
Definition: shstr.h:47
#define ST_CHANGE_PASSWORD_CONFIRM
Definition: define.h:589
#define MAP_HEIGHT(m)
Definition: map.h:80
void command_kill_pets(object *op, const char *params)
Definition: c_misc.c:2212
socket_struct socket
Definition: player.h:94
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define ST_CONFIRM_PASSWORD
Definition: define.h:585
int object_count_active(void)
Definition: object.c:1538
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:1027
void command_dumpmap(object *op, const char *params)
Definition: c_misc.c:1014
#define FLAG_USE_WEAPON
Definition: define.h:297
void command_resistances(object *op, const char *params)
Definition: c_misc.c:1567
int checkbanned(const char *login, const char *host)
Definition: ban.c:32
void dump_all_archetypes(void)
Definition: arch.cpp:152
void object_dump_all(void)
Definition: object.c:468
#define ST_CHANGE_PASSWORD_NEW
Definition: define.h:588
#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:241
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
uint32_t get_weight_limit(int stat)
Definition: living.c:2360
#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:225
#define ST_ROLL_STAT
Definition: define.h:580
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:308
#define ST_PLAYING
Definition: define.h:578
void command_whereami(object *op, const char *params)
Definition: c_misc.c:814
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:882
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:257
#define FLAG_REMOVED
Definition: define.h:232
#define MAP_WHEN_RESET(m)
Definition: map.h:62
char namebuf[MAX_BUF]
Definition: c_misc.c:521
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:978
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:445
void get_name(object *op)
Definition: player.c:861
#define MSG_TYPE_ADMIN_DM
Definition: newclient.h:475
int rndm(int min, int max)
Definition: utils.c:162
size_t assets_number_of_animations()
Definition: assets.cpp:261
void command_printlos(object *op, const char *params)
Definition: c_misc.c:1039
#define NAMLEN(dirent)
Definition: global.h:214
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:1188
int player_has_own_title(const struct pl *pl)
Definition: player.c:239
char * name
Definition: map.h:329
#define MAP_IN_MEMORY
Definition: map.h:131
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4259
void object_free_drop_inventory(object *ob)
Definition: object.c:1316
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1849
#define NDI_RED
Definition: newclient.h:224
char * name
Definition: map.h:279
#define MSG_TYPE_COMMAND
Definition: newclient.h:379
Definition: win32.h:120
struct artifactliststruct * next
Definition: artifact.h:29
object * object_new(void)
Definition: object.c:1011
usekeytype
Definition: player.h:52
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.c:95
static void current_region_info(object *op)
Definition: c_misc.c:405
size_t assets_number_of_treasurelists()
Definition: assets.cpp:241
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:2602
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:1201
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:509
void command_wizcast(object *op, const char *params)
Definition: c_misc.c:936
signed short int16_t
Definition: win32.h:160
void command_passwd(object *pl, const char *params)
Definition: c_misc.c:2252
enum _petmode petmode_t
#define ST_CONFIRM_QUIT
Definition: define.h:582
void get_password(object *op)
Definition: player.c:873
int is_dragon_pl(const object *op)
Definition: player.c:114
struct regiondef * next
Definition: map.h:278
void receive_player_password(object *op)
Definition: c_misc.c:1972
Definition: map.h:277
#define snprintf
Definition: win32.h:46
void player_set_state(player *pl, uint8_t state)
Definition: player.c:4427
int strcasecmp(const char *s1, const char *s2)
#define MAP_TIMEOUT(m)
Definition: map.h:66
void dump_all_maps(void)
Definition: map.c:279
#define FOR_INV_FINISH()
Definition: define.h:714
char * msg
Definition: map.h:362
#define FMT64
Definition: compat.h:12
type_definition ** types
void command_rules(object *op, const char *params)
Definition: c_misc.c:228
void command_applymode(object *op, const char *params)
Definition: c_misc.c:1250
int object_count_free(void)
Definition: object.c:1506
void do_harvest(object *pl, int dir, object *skill)
Definition: c_misc.c:2275
long seconds(void)
Definition: time.c:344
void command_mapinfo(object *op, const char *params)
Definition: c_misc.c:802
#define ATNR_INTERNAL
Definition: attack.h:72
size_t assets_number_of_archetypes()
Definition: assets.cpp:245
static void show_commands(object *op, int what)
Definition: c_misc.c:1673
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:295
#define MAP_ENTER_Y(m)
Definition: map.h:87
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:252
char * ss_dump_table(int what, char *buf, size_t size)
Definition: shstr.c:354
static void current_map_info(object *op)
Definition: c_misc.c:427
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:585
void command_hiscore(object *op, const char *params)
Definition: c_misc.c:870
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:1066
unsigned __int64 uint64_t
Definition: win32.h:167
struct regiondef * parent
Definition: map.h:287
void command_whereabouts(object *op, const char *params)
Definition: c_misc.c:482
#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:118
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:2166
void command_language(object *op, const char *params)
Definition: c_misc.c:132
void command_news(object *op, const char *params)
Definition: c_misc.c:240
void dump_map(const mapstruct *m)
Definition: map.c:256
#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:175
LogLevel
Definition: logger.h:10
char who_format[MAX_BUF]
Definition: global.h:275
#define MSG_TYPE_ADMIN
Definition: newclient.h:377
uint32_t peaceful
Definition: player.h:131
enum _bowtype bowtype_t
void command_wimpy(object *op, const char *params)
Definition: c_misc.c:2157
int nroffreeobjects
Definition: object.c:56
unsigned short uint16_t
Definition: win32.h:163
void command_sound(object *op, const char *params)
Definition: c_misc.c:1932
void command_delete(object *op, const char *params)
Definition: c_misc.c:1912
uint16_t difficulty
Definition: map.h:344
object * object_create_arch(archetype *at)
Definition: arch.cpp:301
object * ob
Definition: player.h:158
EXTERN long nrofartifacts
Definition: global.h:140
const char * sstring
Definition: global.h:40
unsigned int uint32_t
Definition: win32.h:162
const char * datadir
Definition: global.h:245
EXTERN long nrofallowedstr
Definition: global.h:141
void command_showpets(object *op, const char *params)
Definition: c_misc.c:1454
void set_map_reset_time(mapstruct *map)
Definition: map.c:2256
void command_ssdumptable(object *op, const char *params)
Definition: c_misc.c:1002
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.c:2382
void print_los(object *op)
Definition: los.c:606
Definition: map.h:259
#define FREE_AND_COPY(sv, nv)
Definition: global.h:204
#define MSG_TYPE_COMMAND_MALLOC
Definition: newclient.h:502
static void malloc_info(object *op)
Definition: c_misc.c:250
void command_time(object *op, const char *params)
Definition: c_misc.c:858
const int CommandsSize
Definition: commands.c:128
const char * localdir
Definition: global.h:246
#define FLAG_WIZCAST
Definition: define.h:290
#define MSG_TYPE_LAST
Definition: newclient.h:396
void command_statistics(object *pl, const char *params)
Definition: c_misc.c:1097
sstring i18n_get_language_code(int language)
Definition: languages.c:108
#define MAP_WIDTH(m)
Definition: map.h:78
void command_title(object *op, const char *params)
Definition: c_misc.c:2064
void check_login(object *op, int check_pass)
Definition: login.c:501
void command_strings(object *op, const char *params)
Definition: c_misc.c:838
struct Settings settings
Definition: init.c:39
#define SK_EXP_ADD_SKILL
Definition: skills.h:78
#define MSG_TYPE_COMMAND_INFO
Definition: newclient.h:506
#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:2140
uint32_t max_time
Definition: time.c:35
command_array_struct CommunicationCommands[]
Definition: commands.c:131
#define ST_CHANGE_PASSWORD_OLD
Definition: define.h:587
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:1612
int object_count_used(void)
Definition: object.c:1522
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:115
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.c:104
struct pl * next
Definition: player.h:93
#define GET_MAP_OB(M, X, Y)
Definition: map.h:173
int i18n_find_language_by_code(const char *code)
Definition: languages.c:81
#define FLAG_MONSTER
Definition: define.h:245
#define MSG_TYPE_SKILL
Definition: newclient.h:383
int closedir(DIR *)
Definition: win32.c:108
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:311
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:264
#define NDI_UNIQUE
Definition: newclient.h:245
#define S_ISDIR(x)
Definition: win32.h:69
#define MSG_SUBTYPE_NONE
Definition: newclient.h:398
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:1954
#define FLAG_WAS_WIZ
Definition: define.h:234
EXTERN region * first_region
Definition: global.h:117
#define MAX_NAME
Definition: define.h:41
#define FULL_VERSION
Definition: version.h:6
struct mapdef * next
Definition: map.h:327
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3291
void command_dumpallarchetypes(object *op, const char *params)
Definition: c_misc.c:990
void dump_friendly_objects(void)
Definition: friend.c:100
void command_quit(object *op, const char *params)
Definition: c_misc.c:1896
Definition: map.h:326
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
void command_usekeys(object *op, const char *params)
Definition: c_misc.c:1526
void command_bowmode(object *op, const char *params)
Definition: c_misc.c:1291
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Definition: object.c:4067
#define FLAG_WIZPASS
Definition: define.h:315
#define S_ISREG(x)
Definition: win32.h:70
char const * newhash(char const *password)
void fix_object(object *op)
Definition: living.c:1124
const char * i18n(const object *who, const char *code)
Definition: languages.c:55
void list_players(object *op, region *reg, partylist *party)
Definition: c_misc.c:548
EXTERN mapstruct * first_map
Definition: global.h:116
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.c:202
char * longname
Definition: map.h:292
void command_version(object *op, const char *params)
Definition: c_misc.c:1053
object * object_get_owner(object *op)
Definition: object.c:568
int level
Definition: readable.c:1589
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
static int find_help_file(const char *name, const char *language, int wiz, char *path, int length)
Definition: c_misc.c:1720
#define P_NO_CLERIC
Definition: map.h:239
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:370
size_t assets_number_of_treasures()
Definition: assets.cpp:238
static void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl)
Definition: c_misc.c:694
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
void object_remove(object *op)
Definition: object.c:1588
const char * get_region_msg(const region *r)
Definition: region.c:238
void i18n_list_languages(object *who)
Definition: languages.c:118
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
static int name_cmp(const chars_names *c1, const chars_names *c2)
Definition: c_misc.c:534
void display_motd(const object *op)
Definition: player.c:135