Crossfire Server, Trunk
c_misc.cpp
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 <stdlib.h>
26 #include <string.h>
27 #include <sys/stat.h>
28 
29 #undef SS_STATISTICS
30 #include "loader.h"
31 #include "shstr.h"
32 #include "sounds.h"
33 #include "sproto.h"
34 #include "version.h"
35 
36 #include "assets.h"
37 #include "AssetsManager.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  "Maps matching search: '%s'", search);
56  }
57  if (QUERY_FLAG(op, FLAG_WIZ)) {
59  "[fixed]Path Reset In (HH:MM:SS) Pl IM TO");
60  } else {
62  "[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  "[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  "[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  "Your current language is set to: English.");
142  "Available languages:");
144  return;
145  }
146 
148 
149  /* Error out if unknown language. */
150  if (language == -1) {
152  "Unknown language.");
153  return;
154  }
155 
156  op->contr->language = language;
157 
159  "Your current language is set to English.");
160 }
161 
175 void command_body(object *op, const char *params) {
176  int i;
177  (void)params;
178 
179  /* Too hard to try and make a header that lines everything up, so just
180  * give a description.
181  */
183  "The first column is the name of the body location.");
184 
186  "The second column is how many of those locations your body has.");
187 
189  "The third column is how many slots in that location are available.");
190 
191  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
192  /* really debugging - normally body_used should not be set to anything
193  * if body_info isn't also set.
194  */
195  if (op->body_info[i] || op->body_used[i]) {
197  "[fixed]%-30s %5d %5d",
198  i18n(op, body_locations[i].use_name), op->body_info[i], op->body_used[i]);
199  }
200  }
203  "You are not allowed to wear armor.");
206  "You are not allowed to use weapons.");
207 }
208 
217 void command_motd(object *op, const char *params) {
218  (void)params;
219  display_motd(op);
220 }
221 
230 void command_rules(object *op, const char *params) {
231  (void)params;
232  send_rules(op);
233 }
234 
243 void command_news(object *op, const char *params) {
244  (void)params;
245  send_news(op);
246 }
247 
254 static void malloc_info(object *op) {
255  int ob_used = object_count_used(), ob_free = object_count_free(), players, nrofmaps;
256  int nrm = 0, mapmem = 0, anr, anims, sum_alloc = 0, sum_used = 0, i, alnr;
257  player *pl;
258  mapstruct *m;
259  artifactlist *al;
260 
261  for (al = first_artifactlist, alnr = 0; al != NULL; al = al->next, alnr++)
262  ;
263 
264  anr = getManager()->archetypes()->count();
265 
266  anims = getManager()->animations()->count();
267 
268  for (pl = first_player, players = 0; pl != NULL; pl = pl->next, players++)
269  ;
270 
271  for (m = first_map, nrofmaps = 0; m != NULL; m = m->next, nrofmaps++)
272  if (m->in_memory == MAP_IN_MEMORY) {
273  mapmem += map_size(m) * (sizeof(object *) + sizeof(MapSpace));
274  nrm++;
275  }
276 
278  "Sizeof: object=%zu player=%zu map=%zu",
279  sizeof(object), sizeof(player), sizeof(mapstruct));
280 
282  "[fixed]Objects:");
283 
285  "[fixed]%6d used", ob_used);
286 
287  if (ob_used != nrofallocobjects - nroffreeobjects) {
289  "[fixed] (used list mismatch: %d)",
291  }
292 
294  "[fixed]%6d free (%.2f%% of %d allocated)",
295  ob_free, (float)ob_free / nrofallocobjects * 100, nrofallocobjects);
296 
297  if (ob_free != nroffreeobjects) {
299  "[fixed] (free list mismatch: %d)",
301  }
302 
304  "[fixed]%6d on active list",
306 
307  i = (ob_used*sizeof(object));
308  sum_used += i;
309  sum_alloc += i;
310 
312  "[fixed] object total: %11d", i);
313 
314  i = (ob_free*sizeof(object));
315  sum_alloc += i;
316 
318  "[fixed]%4d players: %8d",
319  players, i = (players*sizeof(player)));
320 
321  sum_alloc += i;
322  sum_used += i;
323 
325  "[fixed]%4d maps allocated: %8d",
326  nrofmaps, i = (nrofmaps*sizeof(mapstruct)));
327 
328  sum_alloc += i;
329  sum_used += nrm*sizeof(mapstruct);
330 
332  "[fixed]%4d maps in memory: %8d",
333  nrm, mapmem);
334 
335  sum_alloc += mapmem;
336  sum_used += mapmem;
337 
339  "[fixed]%4d archetypes: %8d",
340  anr, i = (anr*sizeof(archetype)));
341 
342  sum_alloc += i;
343  sum_used += i;
344 
346  "[fixed]%4d animations: %8d",
347  anims, i = (anims*sizeof(uint16_t)));
348 
349  sum_alloc += i;
350  sum_used += i;
351 
353  "[fixed]%4zu treasurelists %8d",
355 
356  sum_alloc += i;
357  sum_used += i;
358 
360  "[fixed]%4ld treasures %8d",
362 
363  sum_alloc += i;
364  sum_used += i;
365 
367  "[fixed]%4ld artifacts %8d",
368  nrofartifacts, i = (nrofartifacts*sizeof(artifact)));
369 
370  sum_alloc += i;
371  sum_used += i;
372 
374  "[fixed]%4ld artifacts strngs %8d",
375  nrofallowedstr, i = (nrofallowedstr*sizeof(linked_char)));
376 
377  sum_alloc += i;
378  sum_used += i;
379 
381  "[fixed]%4d artifactlists %8d",
382  alnr, i = (alnr*sizeof(artifactlist)));
383 
384  sum_alloc += i;
385  sum_used += i;
386 
388  "[fixed]Total space allocated:%8d",
389  sum_alloc);
390 
392  "[fixed]Total space used: %8d",
393  sum_used);
394 }
395 
407 static void current_region_info(object *op) {
408  /*
409  * Ok I /suppose/ I should write a seperate function for this, but it isn't
410  * going to be /that/ slow, and won't get called much
411  */
413 
414  /* This should only be possible if regions are not operating on this server. */
415  if (!r)
416  return;
417 
419  "You are in %s.\n%s",
421 }
422 
429 static void current_map_info(object *op) {
430  mapstruct *m = op->map;
431 
432  if (!m)
433  return;
434 
436  "%s (%s) in %s",
437  m->name, m->path, get_region_longname(get_region_by_map(m)));
438 
439  if (QUERY_FLAG(op, FLAG_WIZ)) {
441  "players:%d difficulty:%d size:%dx%d start:%dx%d timeout %d reset_group: %s",
442  m->players, m->difficulty,
443  MAP_WIDTH(m), MAP_HEIGHT(m),
445  MAP_TIMEOUT(m), m->reset_group ? m->reset_group : "(none)");
446  }
447  if (m->msg)
449 }
450 
451 #ifdef DEBUG_MALLOC_LEVEL
452 
460 void command_malloc_verify(object *op, char *parms) {
461  extern int malloc_verify(void);
462 
463  if (!malloc_verify())
465  "Heap is corrupted.");
466  else
468  "Heap checks out OK.");
469 
470  return 1;
471 }
472 #endif
473 
484 void command_whereabouts(object *op, const char *params) {
485  region *reg;
486  player *pl;
487  (void)params;
488 
489  /*
490  * reset the counter on the region, then use it to store the number of
491  * players there.
492  * I don't know how thread-safe this would be, I suspect not very....
493  */
494  for (reg = first_region; reg != NULL; reg = reg->next) {
495  reg->counter = 0;
496  }
497  for (pl = first_player; pl != NULL; pl = pl->next)
498  if (pl->ob->map != NULL)
500 
501  /* we only want to print out by places with a 'longname' field...*/
502  for (reg = first_region; reg != NULL; reg = reg->next) {
503  if (reg->longname == NULL && reg->counter > 0) {
504  if (reg->parent != NULL) {
505  reg->parent->counter += reg->counter;
506  reg->counter = 0;
507  } else /*uh oh, we shouldn't be here. */
508  LOG(llevError, "command_whereabouts() Region %s with no longname has no parent\n", reg->name);
509  }
510  }
512  "In the world currently there are:");
513 
514  for (reg = first_region; reg != NULL; reg = reg->next)
515  if (reg->counter > 0) {
517  "%u players in %s",
518  reg->counter, get_region_longname(reg));
519  }
520 }
521 
523 typedef struct {
524  char namebuf[MAX_BUF];
526 } chars_names;
527 
537 static int name_cmp(const chars_names *c1, const chars_names *c2) {
538  return strcasecmp(c1->namebuf, c2->namebuf);
539 }
540 
551 void list_players(object *op, region *reg, partylist *party) {
552  player *pl;
553  uint16_t i;
554  char *format;
555  int num_players = 0, num_wiz = 0, num_afk = 0, num_bot = 0;
556  chars_names *chars = NULL;
557 
558  if (op == NULL || QUERY_FLAG(op, FLAG_WIZ))
559  format = settings.who_wiz_format;
560  else
561  format = settings.who_format;
562 
563  for (pl = first_player; pl != NULL; pl = pl->next) {
564  if (pl->ob->map == NULL)
565  continue;
566  if (pl->hidden && !QUERY_FLAG(op, FLAG_WIZ))
567  continue;
568 
569  if (reg && !region_is_child_of_region(get_region_by_map(pl->ob->map), reg))
570  continue;
571  if (party && pl->party != party)
572  continue;
573 
574  if (pl->state == ST_PLAYING || pl->state == ST_GET_PARTY_PASSWORD) {
575  num_players++;
576  chars = (chars_names *)realloc(chars, num_players*sizeof(chars_names));
577  if (chars == NULL) {
579  "who failed - out of memory!");
580  return;
581  }
582  sprintf(chars[num_players-1].namebuf, "%s", pl->ob->name);
583  chars[num_players-1].login_order = num_players;
584 
585  /* Check for WIZ's & AFK's*/
586  if (QUERY_FLAG(pl->ob, FLAG_WIZ))
587  num_wiz++;
588 
589  if (QUERY_FLAG(pl->ob, FLAG_AFK))
590  num_afk++;
591 
592  if (pl->socket->is_bot)
593  num_bot++;
594  }
595  }
596  if (first_player != (player *)NULL) {
597  if (reg == NULL && party == NULL)
599  "Total Players (%d) -- WIZ(%d) AFK(%d) BOT(%d)",
600  num_players, num_wiz, num_afk, num_bot);
601  else if (party == NULL)
603  "Total Players in %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)",
604  reg->longname ? reg->longname : reg->name, num_players, num_wiz, num_afk, num_bot);
605  else
607  "Total Players in party %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)",
608  party->partyname, num_players, num_wiz, num_afk, num_bot);
609  }
610  qsort(chars, num_players, sizeof(chars_names), (int (*)(const void *, const void *))name_cmp);
611  for (i = 0; i < num_players; i++)
612  display_who_entry(op, find_player(chars[i].namebuf), format);
613  free(chars);
614 }
615 
624 void command_who(object *op, const char *params) {
625  region *reg;
626 
628  list_players(op, reg, NULL);
629 }
630 
641 static void display_who_entry(object *op, player *pl, const char *format) {
642  char tmpbuf[MAX_BUF];
643  char outbuf[MAX_BUF];
644  size_t i;
645 
646  strcpy(outbuf, "[fixed]");
647 
648  if (pl == NULL) {
649  LOG(llevError, "display_who_entry(): I was passed a null player\n");
650  return;
651  }
652  for (i = 0; i <= strlen(format); i++) {
653  if (format[i] == '%') {
654  i++;
655  get_who_escape_code_value(tmpbuf, sizeof(tmpbuf), format[i], pl);
656  strcat(outbuf, tmpbuf);
657  } else if (format[i] == '_') {
658  strcat(outbuf, " "); /* allow '_' to be used in place of spaces */
659  } else {
660  snprintf(tmpbuf, sizeof(tmpbuf), "%c", format[i]);
661  strcat(outbuf, tmpbuf);
662  }
663  }
665 }
666 
697 static void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl) {
698  switch (letter) {
699  case 'N':
700  strlcpy(return_val, pl->ob->name, size);
701  break;
702 
703  case 't':
704  player_get_title(pl, return_val, size);
705  break;
706 
707  case 'c':
708  snprintf(return_val, size, "%u", pl->ob->count);
709  break;
710 
711  case 'n':
712  snprintf(return_val, size, "\n");
713  break;
714 
715  case 'h':
716  strlcpy(return_val, pl->peaceful ? "" : " <Hostile>", size);
717  break;
718 
719  case 'l':
720  snprintf(return_val, size, "%d", pl->ob->level);
721  break;
722 
723  case 'd':
724  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_WIZ) ? " <WIZ>" : ""), size);
725  break;
726 
727  case 'a':
728  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_AFK) ? " <AFK>" : ""), size);
729  break;
730 
731  case 'b':
732  strlcpy(return_val, (pl->socket->is_bot == 1) ? " <BOT>" : "", size);
733  break;
734 
735  case 'm':
736  strlcpy(return_val, pl->ob->map->path, size);
737  break;
738 
739  case 'M':
740  strlcpy(return_val, pl->ob->map->name ? pl->ob->map->name : "Untitled", size);
741  break;
742 
743  case 'r':
744  strlcpy(return_val, get_name_of_region_for_map(pl->ob->map), size);
745  break;
746 
747  case 'R':
748  strlcpy(return_val, get_region_longname(get_region_by_map(pl->ob->map)), size);
749  break;
750 
751  case 'i':
752  strlcpy(return_val, pl->socket->host, size);
753  break;
754 
755  case '%':
756  snprintf(return_val, size, "%%");
757  break;
758 
759  case '_':
760  snprintf(return_val, size, "_");
761  break;
762 
763  default:
764  return_val[0] = '\0';
765  }
766 }
767 
776 void command_afk(object *op, const char *params) {
777  (void)params;
778  if (QUERY_FLAG(op, FLAG_AFK)) {
781  "You are no longer AFK");
782  } else {
783  SET_FLAG(op, FLAG_AFK);
785  "You are now AFK");
786  }
787 }
788 
797 void command_malloc(object *op, const char *params) {
798  (void)params;
799  malloc_info(op);
800 }
801 
810 void command_mapinfo(object *op, const char *params) {
811  (void)params;
813 }
814 
823 void command_whereami(object *op, const char *params) {
824  (void)params;
826 }
827 
836 void command_maps(object *op, const char *params) {
837  map_info(op, params);
838 }
839 
848 void command_strings(object *op, const char *params) {
849  char stats[HUGE_BUF];
850  (void)params;
851 
852  ss_dump_statistics(stats, sizeof(stats));
854  "[fixed]%s\n",
855  stats);
856 
858  ss_dump_table(SS_DUMP_TOTALS, stats, sizeof(stats)));
859 }
860 
869 void command_time(object *op, const char *params) {
870  (void)params;
871  time_info(op);
872 }
873 
882 void command_hiscore(object *op, const char *params) {
883  hiscore_display(op, op == NULL ? 9999 : 50, params);
884 }
885 
894 void command_debug(object *op, const char *params) {
895  int i;
896 
897  if (*params == '\0' || !sscanf(params, "%d", &i)) {
899  "Global debug level is %d.",
900  settings.debug);
901  return;
902  }
903  settings.debug = (enum LogLevel)FABS(i);
905  "Debug level set to %d.",
906  i);
907 }
908 
909 
918 void command_wizpass(object *op, const char *params) {
919  int i;
920 
921  if (!op)
922  return;
923 
924  if (*params == '\0')
925  i = (QUERY_FLAG(op, FLAG_WIZPASS)) ? 0 : 1;
926  else
927  i = onoff_value(params);
928 
929  if (i) {
931  "You will now walk through walls.");
933  } else {
935  "You will now be stopped by walls.");
937  }
938 }
939 
948 void command_wizcast(object *op, const char *params) {
949  int i;
950 
951  if (!op)
952  return;
953 
954  if (*params == '\0')
955  i = (QUERY_FLAG(op, FLAG_WIZCAST)) ? 0 : 1;
956  else
957  i = onoff_value(params);
958 
959  if (i) {
961  "You can now cast spells anywhere.");
963  } else {
965  "You now cannot cast spells in no-magic areas.");
967  }
968 }
969 
978 void command_dumpallobjects(object *op, const char *params) {
979  (void)op;
980  (void)params;
981  object_dump_all();
982 }
983 
992 void command_dumpfriendlyobjects(object *op, const char *params) {
993  (void)op;
994  (void)params;
996 }
997 
1006 void command_dumpallarchetypes(object *op, const char *params) {
1007  (void)op;
1008  (void)params;
1010 }
1011 
1020 void command_ssdumptable(object *op, const char *params) {
1021  (void)op;
1022  (void)params;
1023  ss_dump_table(SS_DUMP_TABLE, NULL, 0);
1024 }
1025 
1034 void command_dumpmap(object *op, const char *params) {
1035  (void)params;
1036  if (op)
1037  dump_map(op->map);
1038 }
1039 
1048 void command_dumpallmaps(object *op, const char *params) {
1049  (void)op;
1050  (void)params;
1051  dump_all_maps();
1052 }
1053 
1062 void command_printlos(object *op, const char *params) {
1063  (void)params;
1064  if (op)
1065  print_los(op);
1066 }
1067 
1068 
1077 void command_version(object *op, const char *params) {
1078  (void)params;
1080  MSG_TYPE_ADMIN_VERSION, "Crossfire " FULL_VERSION);
1081 }
1082 
1091 void command_listen(object *op, const char *params) {
1092  int i;
1093 
1094  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1096  "Set listen to what (presently %d)?",
1097  op->contr->listening);
1098  return;
1099  }
1100  if (i < 0) {
1102  "Verbose level should be positive.");
1103  return;
1104  }
1105  op->contr->listening = (char)i;
1107  "Your verbose level is now %d.",
1108  i);
1109 }
1110 
1122 void command_statistics(object *pl, const char *params) {
1123  char buf[MAX_BUF];
1124  uint32_t hours, minutes;
1125  uint64_t seconds; /* 64 bit to prevent overflows an intermediate results */
1126  (void)params;
1127 
1128  if (!pl->contr)
1129  return;
1130  safe_strncpy(buf, i18n(pl, "[fixed] Experience: %"), sizeof(buf));
1131  strcat(buf, FMT64);
1133  buf,
1134  pl->stats.exp);
1135  safe_strncpy(buf, i18n(pl, "[fixed] Next Level: %"), sizeof(buf));
1136  strcat(buf, FMT64);
1138  buf,
1139  level_exp(pl->level+1, pl->expmul));
1140 
1142  "[fixed]\nStat Nat/Real/Max");
1143 
1145  "[fixed]Str %2d/ %3d/%3d",
1146  pl->contr->orig_stats.Str, pl->stats.Str, 20+pl->arch->clone.stats.Str);
1148  "[fixed]Dex %2d/ %3d/%3d",
1149  pl->contr->orig_stats.Dex, pl->stats.Dex, 20+pl->arch->clone.stats.Dex);
1151  "[fixed]Con %2d/ %3d/%3d",
1152  pl->contr->orig_stats.Con, pl->stats.Con, 20+pl->arch->clone.stats.Con);
1154  "[fixed]Int %2d/ %3d/%3d",
1155  pl->contr->orig_stats.Int, pl->stats.Int, 20+pl->arch->clone.stats.Int);
1157  "[fixed]Wis %2d/ %3d/%3d",
1158  pl->contr->orig_stats.Wis, pl->stats.Wis, 20+pl->arch->clone.stats.Wis);
1160  "[fixed]Pow %2d/ %3d/%3d",
1161  pl->contr->orig_stats.Pow, pl->stats.Pow, 20+pl->arch->clone.stats.Pow);
1163  "[fixed]Cha %2d/ %3d/%3d",
1164  pl->contr->orig_stats.Cha, pl->stats.Cha, 20+pl->arch->clone.stats.Cha);
1166  "\nAttack Mode: %s",
1167  i18n(pl, pl->contr->peaceful ? "Peaceful" : "Hostile"));
1171  float weap_speed = pl->weapon_speed; // This is the number of attacks per tick.
1172  if (weap_speed < 0.0f)
1173  weap_speed = 0.0f;
1174  if (weap_speed > 1.0f)
1175  weap_speed = 1.0f;
1176  // We will initially calculate the damage if every attack you perform hits.
1177  // This will serve as a baseline for future calculations
1178  float dps = (1000000.0f / tick_duration) * weap_speed * pl->stats.dam;
1179  // TODO: Account for opposing AC in calculations, make some sort of table/chart.
1180  // Then we round the floating-point.
1182  "\n\nDam/Sec: %4d", (int)(dps + 0.5f));
1183 
1184  /* max_time is in microseconds - thus divide by 1000000.
1185  * Need 64 bit values, as otherwise ticks_played * max_time
1186  * can easily overflow.
1187  * Note the message displayed here isn't really
1188  * perfect, since if max_time has been changed since the player started,
1189  * the time estimates use the current value. But I'm presuming that
1190  * max_time won't change very often. MSW 2009-12-01
1191  */
1192  seconds = (uint64_t)pl->contr->ticks_played * (uint64_t)tick_duration / 1000000;
1193  minutes = (uint32_t)seconds / 60;
1194  hours = minutes / 60;
1195  minutes = minutes % 60;
1196 
1198  "You have played this character for %u ticks, which amounts "
1199  "to %d hours and %d minutes.",
1200  pl->contr->ticks_played, hours, minutes);
1201 
1202 
1203  /* Can't think of anything else to print right now */
1204 }
1205 
1214 void command_fix_me(object *op, const char *params) {
1215  (void)params;
1217  fix_object(op);
1218 }
1219 
1228 void command_players(object *op, const char *params) {
1229  char buf[MAX_BUF];
1230  char *t;
1231  DIR *dir;
1232  (void)params;
1233 
1234  snprintf(buf, sizeof(buf), "%s/%s/", settings.localdir, settings.playerdir);
1235  t = buf+strlen(buf);
1236  if ((dir = opendir(buf)) != NULL) {
1237  const struct dirent *entry;
1238 
1239  while ((entry = readdir(dir)) != NULL) {
1240  /* skip '.' , '..' */
1241  if (!((entry->d_name[0] == '.' && entry->d_name[1] == '\0')
1242  || (entry->d_name[0] == '.' && entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) {
1243  struct stat st;
1244 
1245  strcpy(t, entry->d_name);
1246  if (stat(buf, &st) == 0) {
1247  /* This was not posix compatible
1248  * if ((st.st_mode & S_IFMT)==S_IFDIR) {
1249  */
1250  if (S_ISDIR(st.st_mode)) {
1251  struct tm *tm = localtime(&st.st_mtime);
1252 
1254  "[fixed]%s\t%04d %02d %02d %02d %02d %02d",
1255  entry->d_name,
1256  1900+tm->tm_year,
1257  1+tm->tm_mon,
1258  tm->tm_mday,
1259  tm->tm_hour,
1260  tm->tm_min,
1261  tm->tm_sec);
1262  }
1263  }
1264  }
1265  }
1266  closedir(dir);
1267  }
1268 }
1269 
1278 void command_applymode(object *op, const char *params) {
1279  unapplymode unapply = op->contr->unapply;
1280  static const char *const types[] = {
1281  "nochoice",
1282  "never",
1283  "always"
1284  };
1285 
1286  if (*params == '\0') {
1288  "applymode is set to %s",
1289  types[op->contr->unapply]);
1290  return;
1291  }
1292 
1293  if (!strcmp(params, "nochoice"))
1294  op->contr->unapply = unapply_nochoice;
1295  else if (!strcmp(params, "never"))
1296  op->contr->unapply = unapply_never;
1297  else if (!strcmp(params, "always"))
1298  op->contr->unapply = unapply_always;
1299  else {
1301  "applymode: Unknown options %s, valid options are nochoice, never, always",
1302  params);
1303  return;
1304  }
1306  "applymode%s set to %s",
1307  (unapply == op->contr->unapply ? "" : " now"),
1308  types[op->contr->unapply]);
1309 }
1310 
1319 void command_bowmode(object *op, const char *params) {
1320  bowtype_t oldtype = op->contr->bowtype;
1321  static const char *const types[] = {
1322  "normal",
1323  "threewide",
1324  "spreadshot",
1325  "firenorth",
1326  "firene",
1327  "fireeast",
1328  "firese",
1329  "firesouth",
1330  "firesw",
1331  "firewest",
1332  "firenw",
1333  "bestarrow"
1334  };
1335  int i, found;
1336 
1337  if (*params == '\0') {
1339  "bowmode is set to %s",
1340  types[op->contr->bowtype]);
1341  return;
1342  }
1343 
1344  for (i = 0, found = 0; i <= bow_bestarrow; i++) {
1345  if (!strcmp(params, types[i])) {
1346  found++;
1347  op->contr->bowtype = static_cast<bowtype_t>(i);
1348  break;
1349  }
1350  }
1351  if (!found) {
1353  stringbuffer_append_printf(buf, "bowmode: Unknown options %s, valid options are:", params);
1354  for (i = 0; i <= bow_bestarrow; i++) {
1357  if (i < bow_nw)
1359  else
1361  }
1362  char *result = stringbuffer_finish(buf);
1364  free(result);
1365  return;
1366  }
1368  "bowmode%s set to %s",
1369  (oldtype == op->contr->bowtype ? "" : " now"),
1370  types[op->contr->bowtype]);
1371  return;
1372 }
1373 
1382 void command_unarmed_skill(object *op, const char *params) {
1383  object *skill;
1384  size_t i;
1385 
1386  if (*params == '\0') {
1388  "unarmed skill is set to %s",
1389  op->contr->unarmed_skill ? op->contr->unarmed_skill: "nothing");
1390  return;
1391  }
1392 
1393  /* find_skill_by_name() will ready any skill tools - which
1394  * is OK for us because no unarmed skills require skill tools,
1395  * but this could be an issue if you reuse this code for other skills.
1396  */
1397  skill = find_skill_by_name(op, params);
1398 
1399  if (!skill) {
1401  "You do not know any such skill called %s",
1402  params);
1403  return;
1404  }
1405  for (i = 0; i < sizeof(unarmed_skills); i++)
1406  if (skill->subtype == unarmed_skills[i])
1407  break;
1408  if (i == sizeof(unarmed_skills)) {
1410  "%s is not an unarmed skill!",
1411  skill->name);
1412  return;
1413 
1414  }
1415 
1416  if (op->contr->unarmed_skill)
1417  free_string(op->contr->unarmed_skill);
1418 
1419  /* Taking actual skill name is better than taking params,
1420  * as params could be something more than an exact skill name.
1421  */
1422  op->contr->unarmed_skill = add_string(skill->name);
1423 
1425  "unarmed skill is now set to %s",
1426  op->contr->unarmed_skill);
1427 }
1428 
1429 
1438 void command_petmode(object *op, const char *params) {
1439  petmode_t oldtype = op->contr->petmode;
1440  static const char *const types[] = {
1441  "normal",
1442  "sad",
1443  "defend",
1444  "arena"
1445  };
1446 
1447  if (*params == '\0') {
1449  "petmode is set to %s",
1450  types[op->contr->petmode]);
1451  return;
1452  }
1453 
1454  if (!strcmp(params, "normal"))
1455  op->contr->petmode = pet_normal;
1456  else if (!strcmp(params, "sad"))
1457  op->contr->petmode = pet_sad;
1458  else if (!strcmp(params, "defend"))
1459  op->contr->petmode = pet_defend;
1460  else if (!strcmp(params, "arena"))
1461  op->contr->petmode = pet_arena;
1462  else {
1464  "petmode: Unknown options %s, valid options are normal, sad (seek and destroy), defend, arena",
1465  params);
1466  return;
1467  }
1469  "petmode%s set to %s",
1470  (oldtype == op->contr->petmode ? "" : " now"),
1471  types[op->contr->petmode]);
1472 }
1473 
1482 void command_showpets(object *op, const char *params) {
1483  objectlink *obl, *list;
1484  int counter = 0, target = 0;
1485  int have_shown_pet = 0;
1486  if (*params != '\0')
1487  target = atoi(params);
1488 
1489  list = get_friends_of(op);
1490 
1491  for (obl = list; obl != NULL; obl = obl->next) {
1492  object *ob = obl->ob;
1493 
1494  if (target == 0) {
1495  if (counter == 0)
1497  "Pets:");
1499  "%d %s - level %d",
1500  ++counter, ob->name, ob->level);
1501  } else if (!have_shown_pet && ++counter == target) {
1503  "[fixed]level %d %s",
1504  ob->level, ob->name);
1506  "[fixed]%d/%d HP, %d/%d SP",
1507  ob->stats.hp, ob->stats.maxhp, ob->stats.sp, ob->stats.maxsp);
1508 
1509  /* this is not a nice way to do this, it should be made to be more like the statistics command */
1511  "[fixed]Str %d",
1512  ob->stats.Str);
1514  "[fixed]Dex %d",
1515  ob->stats.Dex);
1517  "[fixed]Con %d",
1518  ob->stats.Con);
1520  "[fixed]Int %d",
1521  ob->stats.Int);
1523  "[fixed]Wis %d",
1524  ob->stats.Wis);
1526  "[fixed]Cha %d",
1527  ob->stats.Cha);
1529  "[fixed]Pow %d",
1530  ob->stats.Pow);
1532  "[fixed]wc %d damage %d ac %d",
1533  ob->stats.wc, ob->stats.dam, ob->stats.ac);
1534  have_shown_pet = 1;
1535  }
1536  }
1537  if (list) {
1539  }
1540 
1541  if (counter == 0)
1543  "You have no pets.");
1544  else if (target != 0 && have_shown_pet == 0)
1546  "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  "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  "usekeys: Unknown option %s, valid options are inventory, keyrings, containers",
1581  params);
1582  return;
1583  }
1585  "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  (void)params;
1601  if (!op)
1602  return;
1603 
1604  for (i = 0; i < NROFATTACKS; i++) {
1605  if (i == ATNR_INTERNAL)
1606  continue;
1607 
1609  "[fixed]%-20s %+5d",
1610  attacktype_desc[i], op->resist[i]);
1611  }
1612 
1613  /* If dragon player, let's display natural resistances */
1614  if (is_dragon_pl(op)) {
1615  int attack;
1616  object *tmp;
1617 
1618  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
1619  if (tmp != NULL) {
1621  "\nNatural skin resistances:");
1622 
1623  for (attack = 0; attack < NROFATTACKS; attack++) {
1624  if (atnr_is_dragon_enabled(attack)) {
1626  "%s: %d",
1627  change_resist_msg[attack], tmp->resist[attack]);
1628  }
1629  }
1630  }
1631  }
1632 }
1633 
1644 static void help_topics(object *op, int what) {
1645  DIR *dirp;
1646  struct dirent *de;
1647  char filename[MAX_BUF], line[HUGE_BUF];
1648  char suffix[MAX_BUF];
1649  int namelen;
1650  const char *language;
1651 
1652  language = i18n_get_language_code(op->contr->language);
1653  snprintf(suffix, sizeof(suffix), ".%s", language);
1654 
1655  switch (what) {
1656  case 1:
1657  snprintf(filename, sizeof(filename), "%s/wizhelp", settings.datadir);
1659  " Wiz commands:");
1660  break;
1661 
1662  case 3:
1663  snprintf(filename, sizeof(filename), "%s/mischelp", settings.datadir);
1665  " Misc help:");
1666  break;
1667 
1668  default:
1669  snprintf(filename, sizeof(filename), "%s/help", settings.datadir);
1671  " Commands:");
1672  break;
1673  }
1674  if (!(dirp = opendir(filename)))
1675  return;
1676 
1677  line[0] = '\0';
1678  for (de = readdir(dirp); de; de = readdir(dirp)) {
1679  namelen = NAMLEN(de);
1680 
1681  if (namelen <= 2
1682  && *de->d_name == '.'
1683  && (namelen == 1 || de->d_name[1] == '.'))
1684  continue;
1685  if (strstr(de->d_name, suffix)) {
1686  strcat(line, strtok(de->d_name, "."));
1687  strcat(line, " ");
1688  }
1689  }
1691  line);
1692  closedir(dirp);
1693 }
1694 
1704 static int find_help_file_in(const char *dir, const char *name, const char *language, char *path, int length) {
1705  struct stat st;
1706 
1707  snprintf(path, length, "%s/%s/%s.%s", settings.datadir, dir, name, language);
1708  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1709  return 1;
1710  }
1711  return 0;
1712 }
1713 
1727 static int find_help_file(const char *name, const char *language, int wiz, char *path, int length) {
1728  if (wiz) {
1729  if (find_help_file_in("wizhelp", name, language, path, length))
1730  return 1;
1731  if (strcmp(language, "en") && find_help_file_in("wizhelp", name, "en", path, length))
1732  return 1;
1733  }
1734 
1735  if (find_help_file_in("help", name, language, path, length))
1736  return 1;
1737  if (strcmp(language, "en") && find_help_file_in("help", name, "en", path, length))
1738  return 1;
1739 
1740  return 0;
1741 }
1742 
1750 static void display_help_file(object *op, const char *filename) {
1751  BufferReader *br;
1752  const char *line;
1753 
1754  if ((br = bufferreader_init_from_file(NULL, filename, "Cannot open help file %s: %s\n", llevError)) == NULL) {
1755  return;
1756  }
1757 
1758  while ((line = bufferreader_next_line(br))) {
1760  }
1761 
1763 }
1764 
1773 void command_help(object *op, const char *params) {
1774  char filename[MAX_BUF];
1775  const char *language;
1776 
1777  /*
1778  * Main help page?
1779  */
1780  if (*params == '\0') {
1781  snprintf(filename, sizeof(filename), "%s/def_help", settings.datadir);
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")) {
1802  return;
1803  }
1804 
1805  /*
1806  * User wants info about command
1807  */
1808  if (strchr(params, '.') || strchr(params, ' ') || strchr(params, '/')) {
1810  "Illegal characters in '%s'",
1811  params);
1812  return;
1813  }
1814 
1815  language = i18n_get_language_code(op->contr->language);
1816 
1817  if (!find_help_file(params, language, QUERY_FLAG(op, FLAG_WIZ), filename, sizeof(filename))) {
1819  "No help available on '%s'",
1820  params);
1821  return;
1822  }
1823 
1824  /*
1825  * Found that. Just cat it to screen.
1826  */
1828 }
1829 
1840 static int onoff_value(const char *line) {
1841  int i;
1842 
1843  if (sscanf(line, "%d", &i))
1844  return (i != 0);
1845 
1846  switch (line[0]) {
1847  case 'o':
1848  switch (line[1]) {
1849  case 'n':
1850  return 1; /* on */
1851  default:
1852  return 0; /* o[ff] */
1853  }
1854 
1855  case 'y': /* y[es] */
1856  case 'k': /* k[ylla] */
1857  case 's':
1858  case 'd':
1859  return 1;
1860 
1861  case 'n': /* n[o] */
1862  case 'e': /* e[i] */
1863  case 'u':
1864  default:
1865  return 0;
1866  }
1867 }
1868 
1874 void command_quit(object* op, const char* params) {
1875  (void)params;
1876  draw_ext_info(
1878  "To leave the game, sleep in (apply) a bed to reality. To "
1879  "permenantly delete your character, use the 'delete' command.");
1880 }
1881 
1890 void command_delete(object *op, const char *params) {
1891  (void)params;
1892  if (QUERY_FLAG(op, FLAG_WIZ)) {
1893  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_ADMIN_DM, "Can't quit when in DM mode.");
1894  return;
1895  }
1896 
1897  send_query(op->contr->socket, CS_QUERY_SINGLECHAR,
1898  i18n(op, "Quitting will delete your character.\nAre you sure you want to delete your character (y/n):"));
1899 
1901 }
1902 
1911 void command_sound(object *op, const char *params) {
1912  (void)params;
1913  if (!(op->contr->socket->sound&SND_MUTE)) {
1914  op->contr->socket->sound = op->contr->socket->sound|SND_MUTE;
1916  "Sounds are turned off.");
1917  } else {
1918  op->contr->socket->sound = op->contr->socket->sound&~SND_MUTE;
1920  "The sounds are enabled.");
1921  }
1922  return;
1923 }
1924 
1936 void receive_player_name(object *op, const char *name) {
1937  if (!check_name(op->contr, name)) {
1938  get_name(op);
1939  return;
1940  }
1941  FREE_AND_COPY(op->name, name);
1942  FREE_AND_COPY(op->name_pl, name);
1944  op->contr->name_changed = 1;
1945  get_password(op);
1946 }
1947 
1956 void receive_player_password(object *op, const char *password) {
1957  unsigned int pwd_len = strlen(password);
1958 
1959  if (pwd_len == 0 || pwd_len > 16) {
1960  if (op->contr->state == ST_CHANGE_PASSWORD_OLD
1961  || op->contr->state == ST_CHANGE_PASSWORD_NEW
1962  || op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
1964  "Password changed cancelled.");
1965  player_set_state(op->contr, ST_PLAYING);
1966  } else
1967  get_name(op);
1968  return;
1969  }
1970  /* To hide the password better */
1971  /* With currently clients, not sure if this is really the case - MSW */
1973 
1974  if (checkbanned(op->name, op->contr->socket->host)) {
1975  LOG(llevInfo, "Banned player tried to add: [%s@%s]\n", op->name, op->contr->socket->host);
1977  "You are not allowed to play.");
1978  get_name(op);
1979  return;
1980  }
1981 
1982  if (op->contr->state == ST_CONFIRM_PASSWORD) {
1983  if (!check_password(password, op->contr->password)) {
1985  "The passwords did not match.");
1986  get_name(op);
1987  return;
1988  }
1989  LOG(llevInfo, "LOGIN: New player named %s from ip %s\n", op->name, op->contr->socket->host);
1990  display_motd(op);
1992  "\nWelcome, Brave New Warrior!\n");
1993  roll_again(op);
1994  player_set_state(op->contr, ST_ROLL_STAT);
1995  return;
1996  }
1997 
1998  if (op->contr->state == ST_CHANGE_PASSWORD_OLD) {
1999  if (!check_password(password, op->contr->password)) {
2001  "You entered the wrong current password.");
2002  player_set_state(op->contr, ST_PLAYING);
2003  } else {
2004  send_query(op->contr->socket, CS_QUERY_HIDEINPUT, i18n(op, "Please enter your new password, or blank to cancel:"));
2006  }
2007  return;
2008  }
2009 
2010  if (op->contr->state == ST_CHANGE_PASSWORD_NEW) {
2011  safe_strncpy(op->contr->new_password, newhash(password),
2012  sizeof(op->contr->new_password));
2013  send_query(op->contr->socket, CS_QUERY_HIDEINPUT,
2014  i18n(op, "Please confirm your new password, or blank to cancel:"));
2016  return;
2017  }
2018 
2019  if (op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
2020  if (!check_password(password, op->contr->new_password)) {
2022  "The new passwords don't match!");
2023  } else {
2025  "Password changed.");
2026  strncpy(op->contr->password, op->contr->new_password, 13);
2027  }
2028  player_set_state(op->contr, ST_PLAYING);
2029  return;
2030  }
2031 
2032  safe_strncpy(op->contr->password, newhash(password),
2033  sizeof(op->contr->password));
2034  player_set_state(op->contr, ST_ROLL_STAT);
2035  check_login(op, password);
2036 }
2037 
2048 void command_title(object *op, const char *params) {
2049  char buf[MAX_BUF];
2050 
2051  if (settings.set_title == FALSE) {
2053  "You cannot change your title.");
2054  return;
2055  }
2056 
2057  /* dragon players cannot change titles */
2058  if (is_dragon_pl(op)) {
2060  "Dragons cannot change titles.");
2061  return;
2062  }
2063 
2064  if (*params == '\0') {
2065  char tmp[MAX_BUF];
2066 
2067  player_get_title(op->contr, tmp, sizeof(tmp));
2068  snprintf(buf, sizeof(buf), "Your title is '%s'.", tmp);
2070  return;
2071  }
2072  if (strcmp(params, "clear") == 0 || strcmp(params, "default") == 0) {
2073  if (!player_has_own_title(op->contr))
2075  "Your title is the default title.");
2076  else
2078  "Title set to default.");
2079  player_set_own_title(op->contr, "");
2080  return;
2081  }
2082 
2083  if ((int)strlen(params) >= MAX_NAME) {
2085  "Title too long.");
2086  return;
2087  }
2088  player_set_own_title(op->contr, params);
2089 }
2090 
2099 void command_save(object *op, const char *params) {
2100  (void)params;
2101  if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL)&P_NO_CLERIC) {
2103  "You can not save on unholy ground.");
2104  } else if (!op->stats.exp) {
2106  "You don't deserve to save yet.");
2107  } else {
2108  if (save_player(op, 1))
2110  "You have been saved.");
2111  else
2113  "SAVE FAILED!");
2114  }
2115 }
2116 
2125 void command_peaceful(object *op, const char *params) {
2126  (void)params;
2127  if ((op->contr->peaceful = !op->contr->peaceful))
2129  "You will not attack other players.");
2130  else
2132  "You will attack other players.");
2133 }
2134 
2143 void command_wimpy(object *op, const char *params) {
2144  int i;
2145 
2146  if (*params == '\0' || !sscanf(params, "%d", &i)) {
2148  "Your current wimpy level is %d.",
2149  op->run_away);
2150  return;
2151  }
2152 
2153  if (i < 0 || i > 100) {
2155  "Wimpy level must be between 1 and 100.");
2156  return;
2157  }
2158 
2160  "Your new wimpy level is %d.",
2161  i);
2162  op->run_away = i;
2163 }
2164 
2173 void command_brace(object *op, const char *params) {
2174  if (*params == '\0')
2175  op->contr->braced = !op->contr->braced;
2176  else
2177  op->contr->braced = onoff_value(params);
2178 
2179  if (op->contr->braced)
2181  "You are braced.");
2182  else
2184  "Not braced.");
2185 
2186  fix_object(op);
2187 }
2188 
2197 void command_kill_pets(object *op, const char *params) {
2198  if (*params == '\0') {
2201  "Your pets have been killed.");
2202  } else {
2203  objectlink *obl, *list = get_friends_of(op);
2204  int counter = 0, removecount = 0;
2205  int target = atoi(params);
2206 
2207  for (obl = list; obl != NULL; obl = obl->next) {
2208  object *ob = obl->ob;
2209  if (object_get_owner(ob) == op) {
2210  if (++counter == target || (target == 0 && !strcasecmp(ob->name, params))) {
2211  if (!QUERY_FLAG(ob, FLAG_REMOVED))
2212  object_remove(ob);
2215  removecount++;
2216  }
2217  }
2218  }
2219  if (list) {
2221  }
2222  if (removecount != 0)
2224  "Killed %d pets.",
2225  removecount);
2226  else
2228  "Couldn't find any suitable pets to kill.");
2229  }
2230 }
2231 
2240 void command_passwd(object *pl, const char *params) {
2241  (void)params;
2242  /* If old client, this is the way you change your password. */
2243  if (pl->contr->socket->login_method < 1){
2244  send_query(pl->contr->socket, CS_QUERY_HIDEINPUT, i18n(pl, "Password change.\nPlease enter your current password, or empty string to cancel."));
2245 
2247  }
2248  /* If new client (login_method = 2) or jxclient (login_method = 1), changing the password does nothing anyway, so error out */
2249  else{
2251  "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.");
2252  }
2253 }
2254 
2264 void do_harvest(object *pl, int dir, object *skill) {
2265  int16_t x, y;
2266  int count = 0, proba; /* Probability to get the item, 100 based. */
2267  int level, exp, check_exhaust = 0;
2268  object *found[10]; /* Found items that can be harvested. */
2269  mapstruct *map;
2270  object *item, *inv, *harvested;
2271  sstring trace, ttool, tspeed, race, tool, slevel, sexp;
2272  float speed;
2273 
2274  x = pl->x+freearr_x[dir];
2275  y = pl->y+freearr_y[dir];
2276  map = pl->map;
2277 
2278  if (!IS_PLAYER(pl))
2279  return;
2280 
2281  if (!map)
2282  return;
2283 
2284  if (get_map_flags(map, &map, x, y, &x, &y)&P_OUT_OF_MAP) {
2285  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, i18n(pl, "You cannot %s here."), skill->slaying);
2286  return;
2287  }
2288 
2289  if (!pl->chosen_skill || pl->chosen_skill->skill != skill->skill)
2290  return;
2291 
2292  trace = object_get_value(pl->chosen_skill, "harvest_race");
2293  ttool = object_get_value(pl->chosen_skill, "harvest_tool");
2294  tspeed = object_get_value(pl->chosen_skill, "harvest_speed");
2295  if (!trace || strcmp(trace, "") == 0 || !ttool || strcmp(ttool, "") == 0 || !tspeed || strcmp(tspeed, "") == 0) {
2296  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, i18n(pl, "You start to %s, but change your mind."), skill->slaying);
2297  LOG(llevError, "do_harvest: tool %s without harvest_[race|tool|speed]\n", pl->chosen_skill->name);
2298  return;
2299  }
2300 
2301  item = GET_MAP_OB(map, x, y);
2302  while (item && count < 10) {
2304  if (object_value_set(inv, "harvestable") == false)
2305  continue;
2306  race = object_get_value(inv, "harvest_race");
2307  tool = object_get_value(inv, "harvest_tool");
2308  slevel = object_get_value(inv, "harvest_level");
2309  sexp = object_get_value(inv, "harvest_exp");
2310  if (race && (!slevel || !sexp)) {
2311  LOG(llevError, "do_harvest: item %s without harvest_[level|exp]\n", inv->name);
2312  continue;
2313  }
2314  if (race == trace && (!tool || tool == ttool))
2315  found[count++] = inv;
2316  } FOR_INV_FINISH();
2317  item = item->above;
2318  }
2319  if (count == 0) {
2320  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, i18n(pl, "You find nothing to %s here."), skill->slaying);
2321  return;
2322  }
2323 
2324  inv = found[rndm(0, count-1)];
2325  assert(inv);
2326  item = inv->env;
2327  assert(item);
2328 
2329  slevel = object_get_value(inv, "harvest_level");
2330  sexp = object_get_value(inv, "harvest_exp");
2331  level = atoi(slevel);
2332  exp = atoi(sexp);
2333 
2334  speed = atof(tspeed);
2335  if (speed < 0)
2336  speed = -speed*pl->speed;
2337  pl->speed_left -= speed;
2338 
2339 
2340  /* Now we found something to harvest, randomly try to get it. */
2341  if (level > skill->level+10) {
2342  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, i18n(pl, "You find something, but it is too difficult for you to %s."), skill->slaying);
2343  return;
2344  }
2345 
2346  if (level >= skill->level)
2347  /* Up to 10 more levels, 1 to 11 percent probability. */
2348  proba = 10+skill->level-level;
2349  else if (skill->level <= level+10)
2350  proba = 10+(skill->level-level)*2;
2351  else
2352  proba = 30;
2353 
2354  if (proba <= random_roll(0, 100, pl, 1)) {
2355  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, i18n(pl, "You find something, but fail to %s it."), skill->slaying);
2356  return;
2357  }
2358 
2359  /* Check the new item can fit into inventory.
2360  * Fixes bug #3060474: fishing puts more fishes into inventory than you can carry. */
2361  if (((uint32_t)(pl->weight + pl->carrying + inv->weight)) > get_weight_limit(pl->stats.Str)) {
2362  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);
2363  return;
2364  }
2365 
2366  /* Ok, got it. */
2367  if (inv->nrof == 0) {
2368  harvested = object_new();
2369  object_copy_with_inv(inv, harvested, true);
2370  } else {
2371  if (count == 1 && inv->nrof == 1) {
2372  check_exhaust = 1;
2373  }
2374  if ( inv->nrof == 1 ) {
2375  /* Avoid dumping object inventory like a dead monster if it has an inventory */
2376  object_remove(inv);
2377  harvested = inv;
2378  }
2379  else {
2380  harvested = object_split(inv, 1, NULL, 0);
2381  }
2382  }
2383  object_set_value(harvested, "harvestable", NULL, 0);
2384  if (QUERY_FLAG(harvested, FLAG_MONSTER)) {
2385  int spot = object_find_free_spot(harvested, pl->map, pl->x, pl->y, 0, SIZEOFFREE);
2386  if (spot == -1) {
2387  /* Better luck next time...*/
2388  object_remove(harvested);
2389  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2390  return;
2391  }
2392  object_insert_in_map_at(harvested, pl->map, NULL, 0, pl->x+freearr_x[spot], pl->y+freearr_y[spot]);
2393  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s a %s!", skill->slaying, harvested->name);
2394  } else {
2395  harvested = object_insert_in_ob(harvested, pl);
2396  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s some %s.", skill->slaying, harvested->name);
2397  }
2398 
2399  /* Get exp */
2400  change_exp(pl, exp, skill->name, SK_EXP_ADD_SKILL);
2401 
2402  if (check_exhaust) {
2403  sstring replacement = object_get_value(item, "harvest_exhaust_replacement");
2404  if (replacement) {
2405  if (replacement[0] != '-') {
2406  archetype *other = try_find_archetype(replacement);
2407  if (other) {
2408  object *final = object_create_arch(other);
2410  }
2411  }
2414  }
2415  }
2416 
2417  return;
2418 }
AssetsCollection::count
size_t count() const
Definition: AssetsCollection.h:80
object_value_set
bool object_value_set(const object *op, const char *const key)
Definition: object.cpp:4369
GET_MAP_OB
#define GET_MAP_OB(M, X, Y)
Definition: map.h:173
command_dumpallarchetypes
void command_dumpallarchetypes(object *op, const char *params)
Definition: c_misc.cpp:1006
object_get_owner
object * object_get_owner(object *op)
Definition: object.cpp:804
get_name_of_region_for_map
const char * get_name_of_region_for_map(const mapstruct *m)
Definition: region.cpp:92
global.h
make_face_from_files.anims
list anims
Definition: make_face_from_files.py:53
object
struct obj object
nrofartifacts
long nrofartifacts
Definition: init.cpp:116
first_player
player * first_player
Definition: init.cpp:106
ST_CHANGE_PASSWORD_OLD
#define ST_CHANGE_PASSWORD_OLD
Definition: define.h:550
settings
struct Settings settings
Definition: init.cpp:139
bow_nw
@ bow_nw
Definition: player.h:52
chars_names::login_order
int login_order
Definition: c_misc.cpp:525
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
remove_friendly_object
void remove_friendly_object(object *op)
Definition: friend.cpp:54
pets_terminate_all
void pets_terminate_all(object *owner)
Definition: pets.cpp:225
object_count_active
int object_count_active(void)
Definition: object.cpp:1783
i18n_find_language_by_code
int i18n_find_language_by_code(const char *code)
Definition: languages.cpp:81
NUM_BODY_LOCATIONS
#define NUM_BODY_LOCATIONS
Definition: object.h:13
ATNR_INTERNAL
#define ATNR_INTERNAL
Definition: attack.h:72
command_list
void command_list(object *pl, bool is_dm)
Definition: commands.cpp:391
name_cmp
static int name_cmp(const chars_names *c1, const chars_names *c2)
Definition: c_misc.cpp:537
first_region
region * first_region
Definition: init.cpp:108
llevError
@ llevError
Definition: logger.h:11
FABS
#define FABS(x)
Definition: define.h:22
hiscore_display
void hiscore_display(object *op, int max, const char *match)
Definition: hiscore.cpp:451
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
send_news
void send_news(const object *op)
Definition: player.cpp:204
player_has_own_title
int player_has_own_title(const struct pl *pl)
Definition: player.cpp:247
get_region_by_name
region * get_region_by_name(const char *region_name)
Definition: region.cpp:46
map_info
static void map_info(object *op, const char *search)
Definition: c_misc.cpp:52
ss_dump_statistics
void ss_dump_statistics(char *buf, size_t size)
Definition: shstr.cpp:323
dump_friendly_objects
void dump_friendly_objects(void)
Definition: friend.cpp:72
time_info
void time_info(object *op)
Definition: time.cpp:294
diamondslots.x
x
Definition: diamondslots.py:15
obj::count
tag_t count
Definition: object.h:305
obj::map
struct mapdef * map
Definition: object.h:303
MSG_TYPE_SKILL
#define MSG_TYPE_SKILL
Definition: newclient.h:407
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
receive_player_name
void receive_player_name(object *op, const char *name)
Definition: c_misc.cpp:1936
newhash
char const * newhash(char const *password)
Definition: server.cpp:101
Settings::set_title
uint8_t set_title
Definition: global.h:265
AssetsManager.h
command_dumpallobjects
void command_dumpallobjects(object *op, const char *params)
Definition: c_misc.cpp:978
pl::peaceful
uint32_t peaceful
Definition: player.h:146
types
type_definition ** types
Definition: gridarta-types-convert.c:56
stringbuffer_append_printf
void stringbuffer_append_printf(StringBuffer *sb, const char *format,...)
Definition: stringbuffer.cpp:138
liv::Str
int8_t Str
Definition: living.h:36
command_dumpallmaps
void command_dumpallmaps(object *op, const char *params)
Definition: c_misc.cpp:1048
FALSE
#define FALSE
Definition: compat.h:14
command_body
void command_body(object *op, const char *params)
Definition: c_misc.cpp:175
get_friends_of
objectlink * get_friends_of(const object *owner)
Definition: friend.cpp:119
region_is_child_of_region
int region_is_child_of_region(const region *child, const region *r)
Definition: region.cpp:187
Settings::datadir
const char * datadir
Definition: global.h:248
entry
Definition: entry.py:1
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
FULL_VERSION
#define FULL_VERSION
Definition: version.h:4
command_showpets
void command_showpets(object *op, const char *params)
Definition: c_misc.cpp:1482
pl
Definition: player.h:105
object_dump_all
void object_dump_all(void)
Definition: object.cpp:704
guildoracle.list
list
Definition: guildoracle.py:87
onoff_value
static int onoff_value(const char *line)
Definition: c_misc.cpp:1840
AssetsManager::animations
AllAnimations * animations()
Definition: AssetsManager.h:49
guildjoin.ob
ob
Definition: guildjoin.py:42
get_password
void get_password(object *op)
Definition: player.cpp:872
player_get_title
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
Definition: player.cpp:232
commongive.inv
inv
Definition: commongive.py:28
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
command_statistics
void command_statistics(object *pl, const char *params)
Definition: c_misc.cpp:1122
map_path
void map_path(const char *map, int flags, char *pathname, size_t bufsize)
Definition: map.cpp:1199
CS_QUERY_SINGLECHAR
#define CS_QUERY_SINGLECHAR
Definition: newclient.h:67
bufferreader_destroy
void bufferreader_destroy(BufferReader *br)
Definition: bufferreader.cpp:40
pl::ob
object * ob
Definition: player.h:176
socket_struct::is_bot
uint32_t is_bot
Definition: newserver.h:107
command_hiscore
void command_hiscore(object *op, const char *params)
Definition: c_misc.cpp:882
MSG_TYPE_LAST
#define MSG_TYPE_LAST
Definition: newclient.h:418
bowtype_t
enum _bowtype bowtype_t
FLAG_WIZCAST
#define FLAG_WIZCAST
Definition: define.h:289
command_kill_pets
void command_kill_pets(object *op, const char *params)
Definition: c_misc.cpp:2197
fix_object
void fix_object(object *op)
Definition: living.cpp:1125
Ice.tmp
int tmp
Definition: Ice.py:207
NDI_RED
#define NDI_RED
Definition: newclient.h:245
dump_map
void dump_map(const mapstruct *m)
Definition: map.cpp:246
command_rules
void command_rules(object *op, const char *params)
Definition: c_misc.cpp:230
guildbuy.players
list players
Definition: guildbuy.py:17
player_set_own_title
void player_set_own_title(struct pl *pl, const char *title)
Definition: player.cpp:272
command_ssdumptable
void command_ssdumptable(object *op, const char *params)
Definition: c_misc.cpp:1020
object_copy_with_inv
void object_copy_with_inv(const object *src_ob, object *dest_ob, bool update_speed)
Definition: object.cpp:1208
unapply_always
@ unapply_always
Definition: player.h:78
NROFATTACKS
#define NROFATTACKS
Definition: attack.h:17
i18n_get_language_code
sstring i18n_get_language_code(int language)
Definition: languages.cpp:108
rndm
int rndm(int min, int max)
Definition: utils.cpp:162
give.parms
parms
Definition: give.py:28
npc_dialog.filename
filename
Definition: npc_dialog.py:99
MSG_TYPE_COMMAND_ERROR
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:529
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.cpp:4339
buf
StringBuffer * buf
Definition: readable.cpp:1611
version.h
getManager
AssetsManager * getManager()
Definition: assets.cpp:309
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2851
get_region_longname
const char * get_region_longname(const region *r)
Definition: region.cpp:214
HUGE_BUF
#define HUGE_BUF
Definition: define.h:37
treasurestruct
Definition: treasure.h:63
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Definition: newclient.h:404
shstr.h
party_struct::partyname
char * partyname
Definition: party.h:14
linked_char
Definition: global.h:89
archt
Definition: object.h:472
help_topics
static void help_topics(object *op, int what)
Definition: c_misc.cpp:1644
MSG_TYPE_ADMIN_DM
#define MSG_TYPE_ADMIN_DM
Definition: newclient.h:497
obj::slaying
sstring slaying
Definition: object.h:325
command_debug
void command_debug(object *op, const char *params)
Definition: c_misc.cpp:894
regiondef::next
struct regiondef * next
Definition: map.h:276
command_time
void command_time(object *op, const char *params)
Definition: c_misc.cpp:869
m
static event_registration m
Definition: citylife.cpp:425
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Definition: map.h:131
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1560
bufferreader_init_from_file
BufferReader * bufferreader_init_from_file(BufferReader *br, const char *filepath, const char *failureMessage, LogLevel failureLevel)
Definition: bufferreader.cpp:65
pl::next
struct pl * next
Definition: player.h:106
command_news
void command_news(object *op, const char *params)
Definition: c_misc.cpp:243
FMT64
#define FMT64
Definition: compat.h:16
opendir
DIR * opendir(const char *)
is_valid_types_gen.line
line
Definition: is_valid_types_gen.py:34
map_size
uint32_t map_size(mapstruct *m)
Definition: map.cpp:825
disinfect.map
map
Definition: disinfect.py:4
nrofallowedstr
long nrofallowedstr
Definition: init.cpp:117
oblnk::next
struct oblnk * next
Definition: object.h:451
Settings::debug
LogLevel debug
Definition: global.h:243
send_rules
void send_rules(const object *op)
Definition: player.cpp:168
obj::name
sstring name
Definition: object.h:317
display_who_entry
static void display_who_entry(object *op, player *pl, const char *format)
Definition: c_misc.cpp:641
current_region_info
static void current_region_info(object *op)
Definition: c_misc.cpp:407
pl::state
uint8_t state
Definition: player.h:131
freearr_y
short freearr_y[SIZEOFFREE]
Definition: object.cpp:305
rotate-tower.result
bool result
Definition: rotate-tower.py:13
bow_bestarrow
@ bow_bestarrow
Definition: player.h:53
ST_CHANGE_PASSWORD_CONFIRM
#define ST_CHANGE_PASSWORD_CONFIRM
Definition: define.h:552
command_malloc
void command_malloc(object *op, const char *params)
Definition: c_misc.cpp:797
SS_DUMP_TABLE
#define SS_DUMP_TABLE
Definition: shstr.h:46
check_login
void check_login(object *op, const char *password)
Definition: login.cpp:511
pet_normal
@ pet_normal
Definition: player.h:58
list_players
void list_players(object *op, region *reg, partylist *party)
Definition: c_misc.cpp:551
unapplymode
unapplymode
Definition: player.h:75
split_string
size_t split_string(char *str, char *array[], size_t array_size, char sep)
Definition: utils.cpp:483
command_dumpfriendlyobjects
void command_dumpfriendlyobjects(object *op, const char *params)
Definition: c_misc.cpp:992
regiondef::counter
uint32_t counter
Definition: map.h:286
command_language
void command_language(object *op, const char *params)
Definition: c_misc.cpp:132
command_petmode
void command_petmode(object *op, const char *params)
Definition: c_misc.cpp:1438
petmode_t
enum _petmode petmode_t
MSG_TYPE_COMMAND_INFO
#define MSG_TYPE_COMMAND_INFO
Definition: newclient.h:526
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
liv::Cha
int8_t Cha
Definition: living.h:36
object_count_free
int object_count_free(void)
Definition: object.cpp:1751
first_map
mapstruct * first_map
Definition: init.cpp:107
get_region_msg
const char * get_region_msg(const region *r)
Definition: region.cpp:235
display_motd
void display_motd(const object *op)
Definition: player.cpp:137
pet_defend
@ pet_defend
Definition: player.h:60
MAP_WHEN_RESET
#define MAP_WHEN_RESET(m)
Definition: map.h:62
readdir
struct dirent * readdir(DIR *)
MSG_TYPE_COMMAND_MALLOC
#define MSG_TYPE_COMMAND_MALLOC
Definition: newclient.h:522
python_init.path
path
Definition: python_init.py:8
socket_struct::host
char * host
Definition: newserver.h:100
command_passwd
void command_passwd(object *pl, const char *params)
Definition: c_misc.cpp:2240
FLAG_AFK
#define FLAG_AFK
Definition: define.h:368
MSG_TYPE_COMMAND_STATISTICS
#define MSG_TYPE_COMMAND_STATISTICS
Definition: newclient.h:524
change_resist_msg
const char *const change_resist_msg[NROFATTACKS]
Definition: init.cpp:70
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Definition: global.h:204
regiondef::name
char * name
Definition: map.h:277
artifactliststruct::next
struct artifactliststruct * next
Definition: artifact.h:29
object_create_arch
object * object_create_arch(archetype *at)
Definition: arch.cpp:299
do_harvest
void do_harvest(object *pl, int dir, object *skill)
Definition: c_misc.cpp:2264
command_quit
void command_quit(object *op, const char *params)
Definition: c_misc.cpp:1874
FLAG_WIZPASS
#define FLAG_WIZPASS
Definition: define.h:314
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1592
find_help_file_in
static int find_help_file_in(const char *dir, const char *name, const char *language, char *path, int length)
Definition: c_misc.cpp:1704
artifactliststruct
Definition: artifact.h:26
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
MAX_NAME
#define MAX_NAME
Definition: define.h:41
ST_CHANGE_PASSWORD_NEW
#define ST_CHANGE_PASSWORD_NEW
Definition: define.h:551
INS_BELOW_ORIGINATOR
#define INS_BELOW_ORIGINATOR
Definition: object.h:573
command_applymode
void command_applymode(object *op, const char *params)
Definition: c_misc.cpp:1278
change_exp
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Definition: living.cpp:2166
sstring
const typedef char * sstring
Definition: global.h:43
disinfect.count
int count
Definition: disinfect.py:7
push.match
bool match
Definition: push.py:61
level_exp
int64_t level_exp(int level, double expmul)
Definition: living.cpp:1872
body_locations
body_locations_struct body_locations[NUM_BODY_LOCATIONS]
Definition: item.cpp:54
liv::Con
int8_t Con
Definition: living.h:36
display_help_file
static void display_help_file(object *op, const char *filename)
Definition: c_misc.cpp:1750
FLAG_USE_WEAPON
#define FLAG_USE_WEAPON
Definition: define.h:296
sproto.h
command_strings
void command_strings(object *op, const char *params)
Definition: c_misc.cpp:848
ss_dump_table
char * ss_dump_table(int what, char *buf, size_t size)
Definition: shstr.cpp:354
SND_MUTE
#define SND_MUTE
Definition: sounds.h:14
nrofallocobjects
int nrofallocobjects
Definition: object.cpp:291
stringbuffer_append_string
void stringbuffer_append_string(StringBuffer *sb, const char *str)
Definition: stringbuffer.cpp:95
chars_names::namebuf
char namebuf[MAX_BUF]
Definition: c_misc.cpp:524
MapSpace
Definition: map.h:257
mapdef
Definition: map.h:317
random_roll
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.cpp:42
command_usekeys
void command_usekeys(object *op, const char *params)
Definition: c_misc.cpp:1557
command_whereabouts
void command_whereabouts(object *op, const char *params)
Definition: c_misc.cpp:484
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:420
command_afk
void command_afk(object *op, const char *params)
Definition: c_misc.cpp:776
command_sound
void command_sound(object *op, const char *params)
Definition: c_misc.cpp:1911
liv::Int
int8_t Int
Definition: living.h:36
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
command_save
void command_save(object *op, const char *params)
Definition: c_misc.cpp:2099
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.cpp:2098
command_resistances
void command_resistances(object *op, const char *params)
Definition: c_misc.cpp:1598
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
party_struct
Definition: party.h:10
key_inventory
@ key_inventory
Definition: player.h:66
find_skill_by_name
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.cpp:202
seconds
long seconds(void)
Definition: time.cpp:344
mapdef::name
char * name
Definition: map.h:320
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:78
SIZEOFFREE
#define SIZEOFFREE
Definition: define.h:155
P_OUT_OF_MAP
#define P_OUT_OF_MAP
Definition: map.h:250
AssetsManager::archetypes
Archetypes * archetypes()
Definition: AssetsManager.h:44
MAX_BUF
#define MAX_BUF
Definition: define.h:35
artifactstruct
Definition: artifact.h:14
receive_player_password
void receive_player_password(object *op, const char *password)
Definition: c_misc.cpp:1956
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.cpp:222
NAMLEN
#define NAMLEN(dirent)
Definition: global.h:211
checkbanned
int checkbanned(const char *login, const char *host)
Definition: ban.cpp:32
object_new
object * object_new(void)
Definition: object.cpp:1273
command_printlos
void command_printlos(object *op, const char *params)
Definition: c_misc.cpp:1062
set_map_reset_time
void set_map_reset_time(mapstruct *map)
Definition: map.cpp:2255
get_weight_limit
uint32_t get_weight_limit(int stat)
Definition: living.cpp:2360
nroffreeobjects
int nroffreeobjects
Definition: object.cpp:290
free_string
void free_string(sstring str)
Definition: shstr.cpp:280
Settings::playerdir
const char * playerdir
Definition: global.h:250
IS_PLAYER
static bool IS_PLAYER(object *op)
Definition: object.h:598
StringBuffer
Definition: stringbuffer.cpp:25
print_los
void print_los(object *op)
Definition: los.cpp:606
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
command_delete
void command_delete(object *op, const char *params)
Definition: c_misc.cpp:1890
ST_PLAYING
#define ST_PLAYING
Definition: define.h:541
sounds.h
FLAG_REMOVED
#define FLAG_REMOVED
Definition: define.h:232
command_version
void command_version(object *op, const char *params)
Definition: c_misc.cpp:1077
FLAG_WIZ
#define FLAG_WIZ
Definition: define.h:231
llevInfo
@ llevInfo
Definition: logger.h:12
dirent
#define dirent
Definition: xdir.h:12
command_players
void command_players(object *op, const char *params)
Definition: c_misc.cpp:1228
Floor.t
t
Definition: Floor.py:62
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:262
regiondef::parent
struct regiondef * parent
Definition: map.h:278
attacktype_desc
const char *const attacktype_desc[NROFATTACKS]
Definition: init.cpp:40
chars_names
Definition: c_misc.cpp:523
MSG_TYPE_SKILL_FAILURE
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:590
object_count_used
int object_count_used(void)
Definition: object.cpp:1767
command_dumpmap
void command_dumpmap(object *op, const char *params)
Definition: c_misc.cpp:1034
Settings::who_wiz_format
char who_wiz_format[MAX_BUF]
Definition: global.h:277
is_dragon_pl
int is_dragon_pl(const object *op)
Definition: player.cpp:122
ST_CONFIRM_PASSWORD
#define ST_CONFIRM_PASSWORD
Definition: define.h:548
command_maps
void command_maps(object *op, const char *params)
Definition: c_misc.cpp:836
liv::Dex
int8_t Dex
Definition: living.h:36
unapply_nochoice
@ unapply_nochoice
Definition: player.h:76
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.cpp:301
FLAG_USE_ARMOUR
#define FLAG_USE_ARMOUR
Definition: define.h:295
item
Definition: item.py:1
liv::Wis
int8_t Wis
Definition: living.h:36
MSG_TYPE_COMMAND_BODY
#define MSG_TYPE_COMMAND_BODY
Definition: newclient.h:521
roll_again
void roll_again(object *op)
Definition: player.cpp:1121
command_motd
void command_motd(object *op, const char *params)
Definition: c_misc.cpp:217
give.op
op
Definition: give.py:33
assets_number_of_treasurelists
size_t assets_number_of_treasurelists()
Definition: assets.cpp:262
pet_sad
@ pet_sad
Definition: player.h:59
i18n_list_languages
void i18n_list_languages(object *who)
Definition: languages.cpp:118
object_split
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.cpp:2631
pet_arena
@ pet_arena
Definition: player.h:61
command_brace
void command_brace(object *op, const char *params)
Definition: c_misc.cpp:2173
object_find_free_spot
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.cpp:3552
command_title
void command_title(object *op, const char *params)
Definition: c_misc.cpp:2048
roll-o-matic.params
params
Definition: roll-o-matic.py:193
diamondslots.y
y
Definition: diamondslots.py:16
NDI_WHITE
#define NDI_WHITE
Definition: newclient.h:243
oblnk::ob
object * ob
Definition: object.h:450
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
pl::hidden
uint32_t hidden
Definition: player.h:147
get_region_from_string
region * get_region_from_string(const char *name)
Definition: region.cpp:121
tick_duration
uint32_t tick_duration
Definition: time.cpp:35
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:80
MAP_ENTER_Y
#define MAP_ENTER_Y(m)
Definition: map.h:87
MSG_TYPE_COMMAND_CONFIG
#define MSG_TYPE_COMMAND_CONFIG
Definition: newclient.h:525
atnr_is_dragon_enabled
int atnr_is_dragon_enabled(int attacknr)
Definition: player.cpp:103
obj::subtype
uint8_t subtype
Definition: object.h:347
command_who
void command_who(object *op, const char *params)
Definition: c_misc.cpp:624
object_find_by_type_and_arch_name
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Definition: object.cpp:4270
level
int level
Definition: readable.cpp:1609
first_artifactlist
artifactlist * first_artifactlist
Definition: init.cpp:109
containers
@ containers
Definition: player.h:68
keyrings
@ keyrings
Definition: player.h:67
MSG_TYPE_COMMAND_MAPS
#define MSG_TYPE_COMMAND_MAPS
Definition: newclient.h:520
strcasecmp
int strcasecmp(const char *s1, const char *s2)
malloc_info
static void malloc_info(object *op)
Definition: c_misc.cpp:254
find_help_file
static int find_help_file(const char *name, const char *language, int wiz, char *path, int length)
Definition: c_misc.cpp:1727
command_whereami
void command_whereami(object *op, const char *params)
Definition: c_misc.cpp:823
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.cpp:74
obj::skill
sstring skill
Definition: object.h:327
command_help
void command_help(object *op, const char *params)
Definition: c_misc.cpp:1773
loader.h
command_bowmode
void command_bowmode(object *op, const char *params)
Definition: c_misc.cpp:1319
save_player
int save_player(object *op, int flag)
Definition: login.cpp:230
ST_GET_PARTY_PASSWORD
#define ST_GET_PARTY_PASSWORD
Definition: define.h:549
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.cpp:308
command_wizpass
void command_wizpass(object *op, const char *params)
Definition: c_misc.cpp:918
pl::ticks_played
uint32_t ticks_played
Definition: player.h:221
current_map_info
static void current_map_info(object *op)
Definition: c_misc.cpp:429
MAP_ENTER_X
#define MAP_ENTER_X(m)
Definition: map.h:85
object_remove
void object_remove(object *op)
Definition: object.cpp:1833
player_set_state
void player_set_state(player *pl, uint8_t state)
Definition: player.cpp:4432
try_find_archetype
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:274
get_who_escape_code_value
static void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl)
Definition: c_misc.cpp:697
object_sum_weight
signed long object_sum_weight(object *op)
Definition: object.cpp:568
check_password
bool check_password(const char *typed, const char *crypted)
Definition: server.cpp:114
SS_DUMP_TOTALS
#define SS_DUMP_TOTALS
Definition: shstr.h:47
socket_struct::login_method
uint8_t login_method
Definition: newserver.h:128
P_NO_CLERIC
#define P_NO_CLERIC
Definition: map.h:239
ST_CONFIRM_QUIT
#define ST_CONFIRM_QUIT
Definition: define.h:545
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:533
command_wimpy
void command_wimpy(object *op, const char *params)
Definition: c_misc.cpp:2143
SK_EXP_ADD_SKILL
#define SK_EXP_ADD_SKILL
Definition: skills.h:78
say.item
dictionary item
Definition: say.py:149
MSG_TYPE_ADMIN_VERSION
#define MSG_TYPE_ADMIN_VERSION
Definition: newclient.h:501
unapply_never
@ unapply_never
Definition: player.h:77
LogLevel
LogLevel
Definition: logger.h:10
object_set_value
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.cpp:4492
command_unarmed_skill
void command_unarmed_skill(object *op, const char *params)
Definition: c_misc.cpp:1382
freearr_x
short freearr_x[SIZEOFFREE]
Definition: object.cpp:299
oblnk
Definition: object.h:449
mapdef::path
char path[HUGE_BUF]
Definition: map.h:358
MAP_TIMEOUT
#define MAP_TIMEOUT(m)
Definition: map.h:66
pl::party
partylist * party
Definition: player.h:202
TRUE
#define TRUE
Definition: compat.h:11
ST_ROLL_STAT
#define ST_ROLL_STAT
Definition: define.h:543
check_name
int check_name(player *me, const char *name)
Definition: login.cpp:181
closedir
int closedir(DIR *)
MSG_TYPE_COMMAND_WHO
#define MSG_TYPE_COMMAND_WHO
Definition: newclient.h:519
pl::socket
socket_struct * socket
Definition: player.h:107
regiondef::longname
char * longname
Definition: map.h:283
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
command_wizcast
void command_wizcast(object *op, const char *params)
Definition: c_misc.cpp:948
BufferReader
Definition: bufferreader.cpp:21
send_query
void send_query(socket_struct *ns, uint8_t flags, const char *text)
Definition: request.cpp:680
command_peaceful
void command_peaceful(object *op, const char *params)
Definition: c_misc.cpp:2125
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:402
mapstruct
struct mapdef mapstruct
command_mapinfo
void command_mapinfo(object *op, const char *params)
Definition: c_misc.cpp:810
Settings::who_format
char who_format[MAX_BUF]
Definition: global.h:276
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
FORCE
@ FORCE
Definition: object.h:227
usekeytype
usekeytype
Definition: player.h:65
liv::Pow
int8_t Pow
Definition: living.h:36
command_listen
void command_listen(object *op, const char *params)
Definition: c_misc.cpp:1091
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
dump_all_maps
void dump_all_maps(void)
Definition: map.cpp:269
obj::level
int16_t level
Definition: object.h:359
command_fix_me
void command_fix_me(object *op, const char *params)
Definition: c_misc.cpp:1214
dump_all_archetypes
void dump_all_archetypes(void)
Definition: arch.cpp:150
assets_number_of_treasures
size_t assets_number_of_treasures()
Definition: assets.cpp:259
pl::orig_stats
living orig_stats
Definition: player.h:166
treasureliststruct
Definition: treasure.h:85
i18n
const char * i18n(const object *who, const char *code)
Definition: languages.cpp:55
give.name
name
Definition: give.py:27
castle_read.suffix
string suffix
Definition: castle_read.py:30
get_name
void get_name(object *op)
Definition: player.cpp:861
bufferreader_next_line
char * bufferreader_next_line(BufferReader *br)
Definition: bufferreader.cpp:102
CS_QUERY_HIDEINPUT
#define CS_QUERY_HIDEINPUT
Definition: newclient.h:68
find_player
player * find_player(const char *plname)
Definition: player.cpp:57
level
Definition: level.py:1
Settings::localdir
const char * localdir
Definition: global.h:249
regiondef
Definition: map.h:275