Crossfire Server, Trunk  R21246
c_misc.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
20 #define WANT_UNARMED_SKILLS
21 
22 #include "global.h"
23 
24 #include <assert.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 
30 #undef SS_STATISTICS
31 #include "loader.h"
32 #include "shstr.h"
33 #include "sounds.h"
34 #include "sproto.h"
35 #include "version.h"
36 
45 void map_info(object *op, const char *search) {
46  if (QUERY_FLAG(op, FLAG_WIZ)) {
48  i18n(op, "[fixed]Path Reset In (HH:MM:SS) Pl IM TO"));
49  } else {
51  i18n(op, "[fixed]Path Reset In (HH:MM)"));
52  }
53 
54  for (mapstruct *m = first_map; m != NULL; m = m->next) {
55  if (*search != '\0' && strstr(m->path, search) == NULL)
56  continue; /* Skip unwanted maps */
57 
58  /* Print out the last 26 characters of the map name... */
59  char map_path[MAX_BUF];
60  if (strlen(m->path) <= 26) {
61  strcpy(map_path, m->path);
62  } else {
63  safe_strncpy(map_path, m->path + strlen(m->path) - 26, sizeof(map_path));
64  }
65 
66  const uint32_t ttr = MAP_WHEN_RESET(m) - seconds();
67  const uint32_t hh = (ttr%86400)/3600, mm = (ttr%3600)/60, ss = ttr%60;
68  if (QUERY_FLAG(op, FLAG_WIZ)) {
71  i18n(op, "[fixed]%-26.26s %02d:%02d:%02d %2d %2d %4d"),
72  map_path, hh, mm, ss, m->players, m->in_memory, m->timeout);
73  } else {
76  i18n(op, "[fixed]%-26.26s %02d:%02d"), map_path, hh, mm);
77  }
78  }
79 }
80 
89 void command_language(object *op, const char *params) {
90  int language = -1;
91 
92  if (!op->contr)
93  return;
94 
95  if (*params == '\0' || (!strcmp(params, ""))) {
97  i18n(op, "Your current language is set to: English."));
99  i18n(op, "Available languages:"));
101  return;
102  }
103 
104  language = i18n_find_language_by_code(params);
105 
106  /* Error out if unknown language. */
107  if (language == -1) {
109  i18n(op, "Unknown language."));
110  return;
111  }
112 
113  op->contr->language = language;
114 
116  i18n(op, "Your current language is set to English."));
117 }
118 
132 void command_body(object *op, const char *params) {
133  int i;
134 
135  /* Too hard to try and make a header that lines everything up, so just
136  * give a description.
137  */
139  i18n(op, "The first column is the name of the body location."));
140 
142  i18n(op, "The second column is how many of those locations your body has."));
143 
145  i18n(op, "The third column is how many slots in that location are available."));
146 
147  for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
148  /* really debugging - normally body_used should not be set to anything
149  * if body_info isn't also set.
150  */
151  if (op->body_info[i] || op->body_used[i]) {
153  i18n(op, "[fixed]%-30s %5d %5d"),
154  i18n(op, body_locations[i].use_name), op->body_info[i], op->body_used[i]);
155  }
156  }
157  if (!QUERY_FLAG(op, FLAG_USE_ARMOUR))
159  i18n(op, "You are not allowed to wear armor."));
160  if (!QUERY_FLAG(op, FLAG_USE_WEAPON))
162  i18n(op, "You are not allowed to use weapons."));
163 }
164 
173 void command_motd(object *op, const char *params) {
174  display_motd(op);
175 }
176 
185 void command_rules(object *op, const char *params) {
186  send_rules(op);
187 }
188 
197 void command_news(object *op, const char *params) {
198  send_news(op);
199 }
200 
207 static void malloc_info(object *op) {
208  int ob_used = object_count_used(), ob_free = object_count_free(), players, nrofmaps;
209  int nrm = 0, mapmem = 0, anr, anims, sum_alloc = 0, sum_used = 0, i, tlnr, alnr;
210  treasurelist *tl;
211  player *pl;
212  mapstruct *m;
213  archetype *at;
214  artifactlist *al;
215 
216  for (tl = first_treasurelist, tlnr = 0; tl != NULL; tl = tl->next, tlnr++)
217  ;
218  for (al = first_artifactlist, alnr = 0; al != NULL; al = al->next, alnr++)
219  ;
220 
221  for (at = first_archetype, anr = 0, anims = 0; at != NULL; at = at->more == NULL ? at->next : at->more, anr++)
222  ;
223 
224  for (i = 1; i < num_animations; i++)
225  anims += animations[i].num_animations;
226 
227  for (pl = first_player, players = 0; pl != NULL; pl = pl->next, players++)
228  ;
229 
230  for (m = first_map, nrofmaps = 0; m != NULL; m = m->next, nrofmaps++)
231  if (m->in_memory == MAP_IN_MEMORY) {
232  mapmem += map_size(m) * (sizeof(object *) + sizeof(MapSpace));
233  nrm++;
234  }
235 
237  i18n(op, "Sizeof: object=%d player=%d map=%d"),
238  sizeof(object), sizeof(player), sizeof(mapstruct));
239 
241  i18n(op, "[fixed]Objects:"));
242 
244  i18n(op, "[fixed]%6d used"), ob_used);
245 
246  if (ob_used != nrofallocobjects - nroffreeobjects) {
248  i18n(op, "[fixed] (used list mismatch: %d)"),
250  }
251 
253  i18n(op, "[fixed]%6d free (%.2f%% of %d allocated)"),
254  ob_free, (float)ob_free / nrofallocobjects * 100, nrofallocobjects);
255 
256  if (ob_free != nroffreeobjects) {
258  i18n(op, "[fixed] (free list mismatch: %d)"),
260  }
261 
263  i18n(op, "[fixed]%6d on active list"),
265 
266  i = (ob_used*sizeof(object));
267  sum_used += i;
268  sum_alloc += i;
269 
271  i18n(op, "[fixed] object total: %11d"), i);
272 
273  i = (ob_free*sizeof(object));
274  sum_alloc += i;
275 
277  i18n(op, "[fixed]%4d players: %8d"),
278  players, i = (players*sizeof(player)));
279 
280  sum_alloc += i;
281  sum_used += i;
282 
284  i18n(op, "[fixed]%4d maps allocated: %8d"),
285  nrofmaps, i = (nrofmaps*sizeof(mapstruct)));
286 
287  sum_alloc += i;
288  sum_used += nrm*sizeof(mapstruct);
289 
291  i18n(op, "[fixed]%4d maps in memory: %8d"),
292  nrm, mapmem);
293 
294  sum_alloc += mapmem;
295  sum_used += mapmem;
296 
298  i18n(op, "[fixed]%4d archetypes: %8d"),
299  anr, i = (anr*sizeof(archetype)));
300 
301  sum_alloc += i;
302  sum_used += i;
303 
305  i18n(op, "[fixed]%4d animations: %8d"),
306  anims, i = (anims*sizeof(uint16_t)));
307 
308  sum_alloc += i;
309  sum_used += i;
310 
312  i18n(op, "[fixed]%4d treasurelists %8d"),
313  tlnr, i = (tlnr*sizeof(treasurelist)));
314 
315  sum_alloc += i;
316  sum_used += i;
317 
319  i18n(op, "[fixed]%4ld treasures %8d"),
320  nroftreasures, i = (nroftreasures*sizeof(treasure)));
321 
322  sum_alloc += i;
323  sum_used += i;
324 
326  i18n(op, "[fixed]%4ld artifacts %8d"),
327  nrofartifacts, i = (nrofartifacts*sizeof(artifact)));
328 
329  sum_alloc += i;
330  sum_used += i;
331 
333  i18n(op, "[fixed]%4ld artifacts strngs %8d"),
334  nrofallowedstr, i = (nrofallowedstr*sizeof(linked_char)));
335 
336  sum_alloc += i;
337  sum_used += i;
338 
340  i18n(op, "[fixed]%4d artifactlists %8d"),
341  alnr, i = (alnr*sizeof(artifactlist)));
342 
343  sum_alloc += i;
344  sum_used += i;
345 
347  i18n(op, "[fixed]Total space allocated:%8d"),
348  sum_alloc);
349 
351  i18n(op, "[fixed]Total space used: %8d"),
352  sum_used);
353 }
354 
366 void current_region_info(object *op) {
367  /*
368  * Ok I /suppose/ I should write a seperate function for this, but it isn't
369  * going to be /that/ slow, and won't get called much
370  */
372 
373  /* This should only be possible if regions are not operating on this server. */
374  if (!r)
375  return;
376 
378  i18n(op, "You are in %s.\n%s"),
380 }
381 
388 void current_map_info(object *op) {
389  mapstruct *m = op->map;
390 
391  if (!m)
392  return;
393 
395  "%s (%s) in %s",
397 
398  if (QUERY_FLAG(op, FLAG_WIZ)) {
400  i18n(op, "players:%d difficulty:%d size:%dx%d start:%dx%d timeout %d"),
401  m->players, m->difficulty,
402  MAP_WIDTH(m), MAP_HEIGHT(m),
403  MAP_ENTER_X(m), MAP_ENTER_Y(m),
404  MAP_TIMEOUT(m));
405  }
406  if (m->msg)
408 }
409 
410 #ifdef DEBUG_MALLOC_LEVEL
411 
419 void command_malloc_verify(object *op, char *parms) {
420  extern int malloc_verify(void);
421 
422  if (!malloc_verify())
424  i18n(op, "Heap is corrupted."));
425  else
427  i18n(op, "Heap checks out OK."));
428 
429  return 1;
430 }
431 #endif
432 
443 void command_whereabouts(object *op, const char *params) {
444  region *reg;
445  player *pl;
446 
447  /*
448  * reset the counter on the region, then use it to store the number of
449  * players there.
450  * I don't know how thread-safe this would be, I suspect not very....
451  */
452  for (reg = first_region; reg != NULL; reg = reg->next) {
453  reg->counter = 0;
454  }
455  for (pl = first_player; pl != NULL; pl = pl->next)
456  if (pl->ob->map != NULL)
457  get_region_by_map(pl->ob->map)->counter++;
458 
459  /* we only want to print out by places with a 'longname' field...*/
460  for (reg = first_region; reg != NULL; reg = reg->next) {
461  if (reg->longname == NULL && reg->counter > 0) {
462  if (reg->parent != NULL) {
463  reg->parent->counter += reg->counter;
464  reg->counter = 0;
465  } else /*uh oh, we shouldn't be here. */
466  LOG(llevError, "command_whereabouts() Region %s with no longname has no parent\n", reg->name);
467  }
468  }
470  i18n(op, "In the world currently there are:"));
471 
472  for (reg = first_region; reg != NULL; reg = reg->next)
473  if (reg->counter > 0) {
475  i18n(op, "%u players in %s"),
476  reg->counter, get_region_longname(reg));
477  }
478 }
479 
481 typedef struct {
482  char namebuf[MAX_BUF];
484 } chars_names;
485 
495 static int name_cmp(const chars_names *c1, const chars_names *c2) {
496  return strcasecmp(c1->namebuf, c2->namebuf);
497 }
498 
509 void list_players(object *op, region *reg, partylist *party) {
510  player *pl;
511  uint16_t i;
512  char *format;
513  int num_players = 0, num_wiz = 0, num_afk = 0, num_bot = 0;
514  chars_names *chars = NULL;
515 
516  if (op == NULL || QUERY_FLAG(op, FLAG_WIZ))
517  format = settings.who_wiz_format;
518  else
519  format = settings.who_format;
520 
521  for (pl = first_player; pl != NULL; pl = pl->next) {
522  if (pl->ob->map == NULL)
523  continue;
524  if (pl->hidden && !QUERY_FLAG(op, FLAG_WIZ))
525  continue;
526 
527  if (reg && !region_is_child_of_region(get_region_by_map(pl->ob->map), reg))
528  continue;
529  if (party && pl->party != party)
530  continue;
531 
532  if (pl->state == ST_PLAYING || pl->state == ST_GET_PARTY_PASSWORD) {
533  num_players++;
534  chars = (chars_names *)realloc(chars, num_players*sizeof(chars_names));
535  if (chars == NULL) {
537  i18n(op, "who failed - out of memory!"));
538  return;
539  }
540  sprintf(chars[num_players-1].namebuf, "%s", pl->ob->name);
541  chars[num_players-1].login_order = num_players;
542 
543  /* Check for WIZ's & AFK's*/
544  if (QUERY_FLAG(pl->ob, FLAG_WIZ))
545  num_wiz++;
546 
547  if (QUERY_FLAG(pl->ob, FLAG_AFK))
548  num_afk++;
549 
550  if (pl->socket.is_bot)
551  num_bot++;
552  }
553  }
554  if (first_player != (player *)NULL) {
555  if (reg == NULL && party == NULL)
557  i18n(op, "Total Players (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
558  num_players, num_wiz, num_afk, num_bot);
559  else if (party == NULL)
561  i18n(op, "Total Players in %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
562  reg->longname ? reg->longname : reg->name, num_players, num_wiz, num_afk, num_bot);
563  else
565  i18n(op, "Total Players in party %s (%d) -- WIZ(%d) AFK(%d) BOT(%d)"),
566  party->partyname, num_players, num_wiz, num_afk, num_bot);
567  }
568  qsort(chars, num_players, sizeof(chars_names), (int (*)(const void *, const void *))name_cmp);
569  for (i = 0; i < num_players; i++)
570  display_who_entry(op, find_player(chars[i].namebuf), format);
571  free(chars);
572 }
573 
582 void command_who(object *op, const char *params) {
583  region *reg;
584 
585  reg = get_region_from_string(params);
586  list_players(op, reg, NULL);
587 }
588 
599 void display_who_entry(object *op, player *pl, const char *format) {
600  char tmpbuf[MAX_BUF];
601  char outbuf[MAX_BUF];
602  size_t i;
603 
604  strcpy(outbuf, "[fixed]");
605 
606  if (pl == NULL) {
607  LOG(llevError, "display_who_entry(): I was passed a null player\n");
608  return;
609  }
610  for (i = 0; i <= strlen(format); i++) {
611  if (format[i] == '%') {
612  i++;
613  get_who_escape_code_value(tmpbuf, sizeof(tmpbuf), format[i], pl);
614  strcat(outbuf, tmpbuf);
615  } else if (format[i] == '_') {
616  strcat(outbuf, " "); /* allow '_' to be used in place of spaces */
617  } else {
618  snprintf(tmpbuf, sizeof(tmpbuf), "%c", format[i]);
619  strcat(outbuf, tmpbuf);
620  }
621  }
623 }
624 
655 void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl) {
656  switch (letter) {
657  case 'N':
658  strlcpy(return_val, pl->ob->name, size);
659  break;
660 
661  case 't':
662  player_get_title(pl, return_val, size);
663  break;
664 
665  case 'c':
666  snprintf(return_val, size, "%u", pl->ob->count);
667  break;
668 
669  case 'n':
670  snprintf(return_val, size, "\n");
671  break;
672 
673  case 'h':
674  strlcpy(return_val, pl->peaceful ? "" : " <Hostile>", size);
675  break;
676 
677  case 'l':
678  snprintf(return_val, size, "%d", pl->ob->level);
679  break;
680 
681  case 'd':
682  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_WIZ) ? " <WIZ>" : ""), size);
683  break;
684 
685  case 'a':
686  strlcpy(return_val, (QUERY_FLAG(pl->ob, FLAG_AFK) ? " <AFK>" : ""), size);
687  break;
688 
689  case 'b':
690  strlcpy(return_val, (pl->socket.is_bot == 1) ? " <BOT>" : "", size);
691  break;
692 
693  case 'm':
694  strlcpy(return_val, pl->ob->map->path, size);
695  break;
696 
697  case 'M':
698  strlcpy(return_val, pl->ob->map->name ? pl->ob->map->name : "Untitled", size);
699  break;
700 
701  case 'r':
702  strlcpy(return_val, get_name_of_region_for_map(pl->ob->map), size);
703  break;
704 
705  case 'R':
706  strlcpy(return_val, get_region_longname(get_region_by_map(pl->ob->map)), size);
707  break;
708 
709  case 'i':
710  strlcpy(return_val, pl->socket.host, size);
711  break;
712 
713  case '%':
714  snprintf(return_val, size, "%%");
715  break;
716 
717  case '_':
718  snprintf(return_val, size, "_");
719  break;
720  }
721 }
722 
731 void command_afk(object *op, const char *params) {
732  if (QUERY_FLAG(op, FLAG_AFK)) {
733  CLEAR_FLAG(op, FLAG_AFK);
735  i18n(op, "You are no longer AFK"));
736  } else {
737  SET_FLAG(op, FLAG_AFK);
739  i18n(op, "You are now AFK"));
740  }
741 }
742 
751 void command_malloc(object *op, const char *params) {
752  malloc_info(op);
753 }
754 
763 void command_mapinfo(object *op, const char *params) {
764  current_map_info(op);
765 }
766 
775 void command_whereami(object *op, const char *params) {
777 }
778 
787 void command_maps(object *op, const char *params) {
788  map_info(op, params);
789 }
790 
799 void command_strings(object *op, const char *params) {
800  char stats[HUGE_BUF];
801 
802  ss_dump_statistics(stats, sizeof(stats));
804  "[fixed]%s\n",
805  stats);
806 
808  ss_dump_table(SS_DUMP_TOTALS, stats, sizeof(stats)));
809 }
810 
819 void command_time(object *op, const char *params) {
820  time_info(op);
821 }
822 
831 void command_archs(object *op, const char *params) {
832  arch_info(op);
833 }
834 
843 void command_hiscore(object *op, const char *params) {
844  hiscore_display(op, op == NULL ? 9999 : 50, params);
845 }
846 
855 void command_debug(object *op, const char *params) {
856  int i;
857 
858  if (*params == '\0' || !sscanf(params, "%d", &i)) {
860  i18n(op, "Global debug level is %d."),
861  settings.debug);
862  return;
863  }
864  settings.debug = (enum LogLevel)FABS(i);
866  i18n(op, "Debug level set to %d."),
867  i);
868 }
869 
870 
879 void command_wizpass(object *op, const char *params) {
880  int i;
881 
882  if (!op)
883  return;
884 
885  if (*params == '\0')
886  i = (QUERY_FLAG(op, FLAG_WIZPASS)) ? 0 : 1;
887  else
888  i = onoff_value(params);
889 
890  if (i) {
892  i18n(op, "You will now walk through walls."));
893  SET_FLAG(op, FLAG_WIZPASS);
894  } else {
896  i18n(op, "You will now be stopped by walls."));
898  }
899 }
900 
909 void command_wizcast(object *op, const char *params) {
910  int i;
911 
912  if (!op)
913  return;
914 
915  if (*params == '\0')
916  i = (QUERY_FLAG(op, FLAG_WIZCAST)) ? 0 : 1;
917  else
918  i = onoff_value(params);
919 
920  if (i) {
922  i18n(op, "You can now cast spells anywhere."));
923  SET_FLAG(op, FLAG_WIZCAST);
924  } else {
926  i18n(op, "You now cannot cast spells in no-magic areas."));
928  }
929 }
930 
939 void command_dumpallobjects(object *op, const char *params) {
940  object_dump_all();
941 }
942 
951 void command_dumpfriendlyobjects(object *op, const char *params) {
953 }
954 
963 void command_dumpallarchetypes(object *op, const char *params) {
965 }
966 
975 void command_ssdumptable(object *op, const char *params) {
976  ss_dump_table(SS_DUMP_TABLE, NULL, 0);
977 }
978 
987 void command_dumpmap(object *op, const char *params) {
988  if (op)
989  dump_map(op->map);
990 }
991 
1000 void command_dumpallmaps(object *op, const char *params) {
1001  dump_all_maps();
1002 }
1003 
1012 void command_printlos(object *op, const char *params) {
1013  if (op)
1014  print_los(op);
1015 }
1016 
1017 
1026 void command_version(object *op, const char *params) {
1028  MSG_TYPE_ADMIN_VERSION, "Crossfire "FULL_VERSION);
1029 }
1030 
1039 void command_listen(object *op, const char *params) {
1040  int i;
1041 
1042  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1044  i18n(op, "Set listen to what (presently %d)?"),
1045  op->contr->listening);
1046  return;
1047  }
1048  if (i < 0) {
1050  i18n(op, "Verbose level should be positive."));
1051  return;
1052  }
1053  op->contr->listening = (char)i;
1055  i18n(op, "Your verbose level is now %d."),
1056  i);
1057 }
1058 
1070 void command_statistics(object *pl, const char *params) {
1071  char buf[MAX_BUF];
1072  uint32_t hours, minutes;
1073  uint64_t seconds; /* 64 bit to prevent overflows an intermediate results */
1074 
1075  if (!pl->contr)
1076  return;
1077  safe_strncpy(buf, i18n(pl, "[fixed] Experience: %"), sizeof(buf));
1078  strcat(buf, FMT64);
1080  buf,
1081  pl->stats.exp);
1082  safe_strncpy(buf, i18n(pl, "[fixed] Next Level: %"), sizeof(buf));
1083  strcat(buf, FMT64);
1085  buf,
1086  level_exp(pl->level+1, pl->expmul));
1087 
1089  i18n(pl, "[fixed]\nStat Nat/Real/Max"));
1090 
1092  i18n(pl, "[fixed]Str %2d/ %3d/%3d"),
1093  pl->contr->orig_stats.Str, pl->stats.Str, 20+pl->arch->clone.stats.Str);
1095  i18n(pl, "[fixed]Dex %2d/ %3d/%3d"),
1096  pl->contr->orig_stats.Dex, pl->stats.Dex, 20+pl->arch->clone.stats.Dex);
1098  i18n(pl, "[fixed]Con %2d/ %3d/%3d"),
1099  pl->contr->orig_stats.Con, pl->stats.Con, 20+pl->arch->clone.stats.Con);
1101  i18n(pl, "[fixed]Int %2d/ %3d/%3d"),
1102  pl->contr->orig_stats.Int, pl->stats.Int, 20+pl->arch->clone.stats.Int);
1104  i18n(pl, "[fixed]Wis %2d/ %3d/%3d"),
1105  pl->contr->orig_stats.Wis, pl->stats.Wis, 20+pl->arch->clone.stats.Wis);
1107  i18n(pl, "[fixed]Pow %2d/ %3d/%3d"),
1108  pl->contr->orig_stats.Pow, pl->stats.Pow, 20+pl->arch->clone.stats.Pow);
1110  i18n(pl, "[fixed]Cha %2d/ %3d/%3d"),
1111  pl->contr->orig_stats.Cha, pl->stats.Cha, 20+pl->arch->clone.stats.Cha);
1113  i18n(pl, "\nAttack Mode: %s"),
1114  i18n(pl, pl->contr->peaceful ? "Peaceful" : "Hostile"));
1118  float weap_speed = pl->weapon_speed; // This is the number of attacks per tick.
1119  if (weap_speed < 0.0f)
1120  weap_speed = 0.0f;
1121  if (weap_speed > 1.0f)
1122  weap_speed = 1.0f;
1123  // We will initially calculate the damage if every attack you perform hits.
1124  // This will serve as a baseline for future calculations
1125  float dps = (1000000.0f / max_time) * weap_speed * pl->stats.dam;
1126  // TODO: Account for opposing AC in calculations, make some sort of table/chart.
1127  // Then we round the floating-point.
1129  i18n(pl, "\n\nDam/Sec: %4d"), (int)(dps + 0.5f));
1130 
1131  /* max_time is in microseconds - thus divide by 1000000.
1132  * Need 64 bit values, as otherwise ticks_played * max_time
1133  * can easily overflow.
1134  * Note the message displayed here isn't really
1135  * perfect, since if max_time has been changed since the player started,
1136  * the time estimates use the current value. But I'm presuming that
1137  * max_time won't change very often. MSW 2009-12-01
1138  */
1139  seconds = (uint64_t)pl->contr->ticks_played * (uint64_t)max_time / 1000000;
1140  minutes = (uint32_t)seconds / 60;
1141  hours = minutes / 60;
1142  minutes = minutes % 60;
1143 
1145  "You have played this character for %u ticks, which amounts "
1146  "to %d hours and %d minutes.",
1147  pl->contr->ticks_played, hours, minutes);
1148 
1149 
1150  /* Can't think of anything else to print right now */
1151 }
1152 
1161 void command_fix_me(object *op, const char *params) {
1162  object_sum_weight(op);
1163  fix_object(op);
1164 }
1165 
1174 void command_players(object *op, const char *params) {
1175  char buf[MAX_BUF];
1176  char *t;
1177  DIR *dir;
1178 
1179  snprintf(buf, sizeof(buf), "%s/%s/", settings.localdir, settings.playerdir);
1180  t = buf+strlen(buf);
1181  if ((dir = opendir(buf)) != NULL) {
1182  const struct dirent *entry;
1183 
1184  while ((entry = readdir(dir)) != NULL) {
1185  /* skip '.' , '..' */
1186  if (!((entry->d_name[0] == '.' && entry->d_name[1] == '\0')
1187  || (entry->d_name[0] == '.' && entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) {
1188  struct stat st;
1189 
1190  strcpy(t, entry->d_name);
1191  if (stat(buf, &st) == 0) {
1192  /* This was not posix compatible
1193  * if ((st.st_mode & S_IFMT)==S_IFDIR) {
1194  */
1195  if (S_ISDIR(st.st_mode)) {
1196  struct tm *tm = localtime(&st.st_mtime);
1197 
1199  i18n(op, "[fixed]%s\t%04d %02d %02d %02d %02d %02d"),
1200  entry->d_name,
1201  1900+tm->tm_year,
1202  1+tm->tm_mon,
1203  tm->tm_mday,
1204  tm->tm_hour,
1205  tm->tm_min,
1206  tm->tm_sec);
1207  }
1208  }
1209  }
1210  }
1211  }
1212  closedir(dir);
1213 }
1214 
1223 void command_applymode(object *op, const char *params) {
1224  unapplymode unapply = op->contr->unapply;
1225  static const char *const types[] = {
1226  "nochoice",
1227  "never",
1228  "always"
1229  };
1230 
1231  if (*params == '\0') {
1233  i18n(op, "applymode is set to %s"),
1234  types[op->contr->unapply]);
1235  return;
1236  }
1237 
1238  if (!strcmp(params, "nochoice"))
1240  else if (!strcmp(params, "never"))
1241  op->contr->unapply = unapply_never;
1242  else if (!strcmp(params, "always"))
1243  op->contr->unapply = unapply_always;
1244  else {
1246  i18n(op, "applymode: Unknown options %s, valid options are nochoice, never, always"),
1247  params);
1248  return;
1249  }
1251  i18n(op, "applymode%s set to %s"),
1252  (unapply == op->contr->unapply ? "" : " now"),
1253  types[op->contr->unapply]);
1254 }
1255 
1264 void command_bowmode(object *op, const char *params) {
1265  bowtype_t oldtype = op->contr->bowtype;
1266  static const char *const types[] = {
1267  "normal",
1268  "threewide",
1269  "spreadshot",
1270  "firenorth",
1271  "firene",
1272  "fireeast",
1273  "firese",
1274  "firesouth",
1275  "firesw",
1276  "firewest",
1277  "firenw",
1278  "bestarrow"
1279  };
1280  char buf[MAX_BUF];
1281  int i, found;
1282 
1283  if (*params == '\0') {
1285  i18n(op, "bowmode is set to %s"),
1286  types[op->contr->bowtype]);
1287  return;
1288  }
1289 
1290  for (i = 0, found = 0; i <= bow_bestarrow; i++) {
1291  if (!strcmp(params, types[i])) {
1292  found++;
1293  op->contr->bowtype = i;
1294  break;
1295  }
1296  }
1297  if (!found) {
1298  snprintf(buf, sizeof(buf), "bowmode: Unknown options %s, valid options are:", params);
1299  for (i = 0; i <= bow_bestarrow; i++) {
1300  strcat(buf, " ");
1301  strcat(buf, types[i]);
1302  if (i < bow_nw)
1303  strcat(buf, ",");
1304  else
1305  strcat(buf, ".");
1306  }
1308  return;
1309  }
1311  i18n(op, "bowmode%s set to %s"),
1312  (oldtype == op->contr->bowtype ? "" : " now"),
1313  types[op->contr->bowtype]);
1314  return;
1315 }
1316 
1325 void command_unarmed_skill(object *op, const char *params) {
1326  object *skill;
1327  size_t i;
1328 
1329  if (*params == '\0') {
1331  "unarmed skill is set to %s",
1332  op->contr->unarmed_skill ? op->contr->unarmed_skill: "nothing");
1333  return;
1334  }
1335 
1336  /* find_skill_by_name() will ready any skill tools - which
1337  * is OK for us because no unarmed skills require skill tools,
1338  * but this could be an issue if you reuse this code for other skills.
1339  */
1340  skill = find_skill_by_name(op, params);
1341 
1342  if (!skill) {
1344  "You do not know any such skill called %s",
1345  params);
1346  return;
1347  }
1348  for (i = 0; i < sizeof(unarmed_skills); i++)
1349  if (skill->subtype == unarmed_skills[i])
1350  break;
1351  if (i == sizeof(unarmed_skills)) {
1353  "%s is not an unarmed skill!",
1354  skill->name);
1355  return;
1356 
1357  }
1358 
1359  if (op->contr->unarmed_skill)
1361 
1362  /* Taking actual skill name is better than taking params,
1363  * as params could be something more than an exact skill name.
1364  */
1365  op->contr->unarmed_skill = add_string(skill->name);
1366 
1368  "unarmed skill is now set to %s",
1369  op->contr->unarmed_skill);
1370 }
1371 
1372 
1381 void command_petmode(object *op, const char *params) {
1382  petmode_t oldtype = op->contr->petmode;
1383  static const char *const types[] = {
1384  "normal",
1385  "sad",
1386  "defend",
1387  "arena"
1388  };
1389 
1390  if (*params == '\0') {
1392  i18n(op, "petmode is set to %s"),
1393  types[op->contr->petmode]);
1394  return;
1395  }
1396 
1397  if (!strcmp(params, "normal"))
1398  op->contr->petmode = pet_normal;
1399  else if (!strcmp(params, "sad"))
1400  op->contr->petmode = pet_sad;
1401  else if (!strcmp(params, "defend"))
1402  op->contr->petmode = pet_defend;
1403  else if (!strcmp(params, "arena"))
1404  op->contr->petmode = pet_arena;
1405  else {
1407  i18n(op, "petmode: Unknown options %s, valid options are normal, sad (seek and destroy), defend, arena"),
1408  params);
1409  return;
1410  }
1412  i18n(op, "petmode%s set to %s"),
1413  (oldtype == op->contr->petmode ? "" : " now"),
1414  types[op->contr->petmode]);
1415 }
1416 
1425 void command_showpets(object *op, const char *params) {
1426  objectlink *obl, *next;
1427  int counter = 0, target = 0;
1428  int have_shown_pet = 0;
1429  if (*params != '\0')
1430  target = atoi(params);
1431 
1432  for (obl = first_friendly_object; obl != NULL; obl = next) {
1433  object *ob = obl->ob;
1434 
1435  next = obl->next;
1436  if (object_get_owner(ob) == op) {
1437  if (target == 0) {
1438  if (counter == 0)
1440  i18n(op, "Pets:"));
1442  i18n(op, "%d %s - level %d"),
1443  ++counter, ob->name, ob->level);
1444  } else if (!have_shown_pet && ++counter == target) {
1446  i18n(op, "[fixed]level %d %s"),
1447  ob->level, ob->name);
1449  i18n(op, "[fixed]%d/%d HP, %d/%d SP"),
1450  ob->stats.hp, ob->stats.maxhp, ob->stats.sp, ob->stats.maxsp);
1451 
1452  /* this is not a nice way to do this, it should be made to be more like the statistics command */
1454  i18n(op, "[fixed]Str %d"),
1455  ob->stats.Str);
1457  i18n(op, "[fixed]Dex %d"),
1458  ob->stats.Dex);
1460  i18n(op, "[fixed]Con %d"),
1461  ob->stats.Con);
1463  i18n(op, "[fixed]Int %d"),
1464  ob->stats.Int);
1466  i18n(op, "[fixed]Wis %d"),
1467  ob->stats.Wis);
1469  i18n(op, "[fixed]Cha %d"),
1470  ob->stats.Cha);
1472  i18n(op, "[fixed]Pow %d"),
1473  ob->stats.Pow);
1475  i18n(op, "[fixed]wc %d damage %d ac %d"),
1476  ob->stats.wc, ob->stats.dam, ob->stats.ac);
1477  have_shown_pet = 1;
1478  }
1479  }
1480  }
1481  if (counter == 0)
1483  i18n(op, "You have no pets."));
1484  else if (target != 0 && have_shown_pet == 0)
1486  i18n(op, "No such pet."));
1487 }
1488 
1497 void command_usekeys(object *op, const char *params) {
1498  usekeytype oldtype = op->contr->usekeys;
1499  static const char *const types[] = {
1500  "inventory",
1501  "keyrings",
1502  "containers"
1503  };
1504 
1505  if (*params == '\0') {
1507  i18n(op, "usekeys is set to %s"),
1508  types[op->contr->usekeys]);
1509  return;
1510  }
1511 
1512  if (!strcmp(params, "inventory"))
1513  op->contr->usekeys = key_inventory;
1514  else if (!strcmp(params, "keyrings"))
1515  op->contr->usekeys = keyrings;
1516  else if (!strcmp(params, "containers"))
1517  op->contr->usekeys = containers;
1518  else {
1520  i18n(op, "usekeys: Unknown option %s, valid options are inventory, keyrings, containers"),
1521  params);
1522  return;
1523  }
1525  i18n(op, "usekeys%s set to %s"),
1526  (oldtype == op->contr->usekeys ? "" : " now"),
1527  types[op->contr->usekeys]);
1528 }
1529 
1538 void command_resistances(object *op, const char *params) {
1539  int i;
1540  if (!op)
1541  return;
1542 
1543  for (i = 0; i < NROFATTACKS; i++) {
1544  if (i == ATNR_INTERNAL)
1545  continue;
1546 
1548  i18n(op, "[fixed]%-20s %+5d"),
1549  attacktype_desc[i], op->resist[i]);
1550  }
1551 
1552  /* If dragon player, let's display natural resistances */
1553  if (is_dragon_pl(op)) {
1554  int attack;
1555  object *tmp;
1556 
1557  tmp = object_find_by_type_and_arch_name(op, FORCE, "dragon_skin_force");
1558  if (tmp != NULL) {
1560  i18n(op, "\nNatural skin resistances:"));
1561 
1562  for (attack = 0; attack < NROFATTACKS; attack++) {
1563  if (atnr_is_dragon_enabled(attack)) {
1565  i18n(op, "%s: %d"),
1566  change_resist_msg[attack], tmp->resist[attack]);
1567  }
1568  }
1569  }
1570  }
1571 }
1572 
1583 static void help_topics(object *op, int what) {
1584  DIR *dirp;
1585  struct dirent *de;
1586  char filename[MAX_BUF], line[HUGE_BUF];
1587  char suffix[MAX_BUF];
1588  int namelen;
1589  const char *language;
1590 
1591  language = i18n_get_language_code(op->contr->language);
1592  snprintf(suffix, sizeof(suffix), ".%s", language);
1593 
1594  switch (what) {
1595  case 1:
1596  snprintf(filename, sizeof(filename), "%s/wizhelp", settings.datadir);
1598  i18n(op, " Wiz commands:"));
1599  break;
1600 
1601  case 3:
1602  snprintf(filename, sizeof(filename), "%s/mischelp", settings.datadir);
1604  i18n(op, " Misc help:"));
1605  break;
1606 
1607  default:
1608  snprintf(filename, sizeof(filename), "%s/help", settings.datadir);
1610  i18n(op, " Commands:"));
1611  break;
1612  }
1613  if (!(dirp = opendir(filename)))
1614  return;
1615 
1616  line[0] = '\0';
1617  for (de = readdir(dirp); de; de = readdir(dirp)) {
1618  namelen = NAMLEN(de);
1619 
1620  if (namelen <= 2
1621  && *de->d_name == '.'
1622  && (namelen == 1 || de->d_name[1] == '.'))
1623  continue;
1624  if (strstr(de->d_name, suffix)) {
1625  strcat(line, strtok(de->d_name, "."));
1626  strcat(line, " ");
1627  }
1628  }
1630  line);
1631  closedir(dirp);
1632 }
1633 
1644 static void show_commands(object *op, int what) {
1645  char line[HUGE_BUF];
1646  int i, size;
1648 
1649  switch (what) {
1650  case 1:
1651  ap = WizCommands;
1652  size = WizCommandsSize;
1654  i18n(op, " Wiz commands:"));
1655  break;
1656 
1657  case 2:
1658  ap = CommunicationCommands;
1659  size = CommunicationCommandSize;
1661  i18n(op, " Communication commands:"));
1662  break;
1663 
1664  default:
1665  ap = Commands;
1666  size = CommandsSize;
1668  i18n(op, " Commands:"));
1669  break;
1670  }
1671 
1672  line[0] = '\0';
1673  for (i = 0; i < size; i++) {
1674  strcat(line, ap[i].name);
1675  strcat(line, " ");
1676  }
1678 }
1679 
1691 static int find_help_file(const char *name, const char *language, int wiz, char *path, int length) {
1692  struct stat st;
1693 
1694  snprintf(path, length, "%s/help/%s.%s", settings.datadir, name, language);
1695  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1696  return 1;
1697  }
1698 
1699  if (strcmp(language, "en")) {
1700  snprintf(path, length, "%s/help/%s.en", settings.datadir, name);
1701  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1702  return 1;
1703  }
1704  }
1705 
1706  if (!wiz)
1707  return 0;
1708 
1709  snprintf(path, length, "%s/wizhelp/%s.%s", settings.datadir, name, language);
1710  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1711  return 1;
1712  }
1713  if (strcmp(language, "en")) {
1714  snprintf(path, length, "%s/wizhelp/%s.en", settings.datadir, name);
1715  if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
1716  return 1;
1717  }
1718  }
1719 
1720  return 0;
1721 }
1722 
1731 void command_help(object *op, const char *params) {
1732  FILE *fp;
1733  char filename[MAX_BUF], line[MAX_BUF];
1734  int len;
1735  const char *language;
1736 
1737  /*
1738  * Main help page?
1739  */
1740  if (*params == '\0') {
1741  snprintf(filename, sizeof(filename), "%s/def_help", settings.datadir);
1742  if ((fp = fopen(filename, "r")) == NULL) {
1743  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1744  return;
1745  }
1746  while (fgets(line, MAX_BUF, fp)) {
1747  line[MAX_BUF-1] = '\0';
1748  len = strlen(line)-1;
1749  if (line[len] == '\n')
1750  line[len] = '\0';
1752  }
1753  fclose(fp);
1754  return;
1755  }
1756 
1757  /*
1758  * Topics list
1759  */
1760  if (!strcmp(params, "topics")) {
1761  help_topics(op, 3);
1762  help_topics(op, 0);
1763  if (QUERY_FLAG(op, FLAG_WIZ))
1764  help_topics(op, 1);
1765  return;
1766  }
1767 
1768  /*
1769  * Commands list
1770  */
1771  if (!strcmp(params, "commands")) {
1772  show_commands(op, 0);
1774  show_commands(op, 2); /* show comm commands */
1775  if (QUERY_FLAG(op, FLAG_WIZ)) {
1777  show_commands(op, 1);
1778  }
1779  return;
1780  }
1781 
1782  /*
1783  * User wants info about command
1784  */
1785  if (strchr(params, '.') || strchr(params, ' ') || strchr(params, '/')) {
1787  i18n(op, "Illegal characters in '%s'"),
1788  params);
1789  return;
1790  }
1791 
1792  language = i18n_get_language_code(op->contr->language);
1793 
1794  if (!find_help_file(params, language, QUERY_FLAG(op, FLAG_WIZ), filename, sizeof(filename))) {
1796  i18n(op, "No help available on '%s'"),
1797  params);
1798  return;
1799  }
1800 
1801  /*
1802  * Found that. Just cat it to screen.
1803  */
1804  if ((fp = fopen(filename, "r")) == NULL) {
1805  LOG(llevError, "Cannot open help file %s: %s\n", filename, strerror(errno));
1806  return;
1807  }
1808 
1810  i18n(op, "Help about '%s'"),
1811  params);
1812 
1813  while (fgets(line, MAX_BUF, fp)) {
1814  line[MAX_BUF-1] = '\0';
1815  len = strlen(line)-1;
1816  if (line[len] == '\n')
1817  line[len] = '\0';
1819  }
1820  fclose(fp);
1821 }
1822 
1833 int onoff_value(const char *line) {
1834  int i;
1835 
1836  if (sscanf(line, "%d", &i))
1837  return (i != 0);
1838 
1839  switch (line[0]) {
1840  case 'o':
1841  switch (line[1]) {
1842  case 'n':
1843  return 1; /* on */
1844  default:
1845  return 0; /* o[ff] */
1846  }
1847 
1848  case 'y': /* y[es] */
1849  case 'k': /* k[ylla] */
1850  case 's':
1851  case 'd':
1852  return 1;
1853 
1854  case 'n': /* n[o] */
1855  case 'e': /* e[i] */
1856  case 'u':
1857  default:
1858  return 0;
1859  }
1860 }
1861 
1867 void command_quit(object* op, const char* params) {
1868  draw_ext_info(
1870  i18n(op,
1871  "To leave the game, sleep in (apply) a bed to reality. To "
1872  "permenantly delete your character, use the 'delete' command."));
1873 }
1874 
1883 void command_delete(object *op, const char *params) {
1884  if (QUERY_FLAG(op, FLAG_WAS_WIZ)) {
1885  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_ADMIN_DM, "Can't quit when in DM mode.");
1886  return;
1887  }
1888 
1890  i18n(op, "Quitting will delete your character.\nAre you sure you want to delete your character (y/n):"));
1891 
1893 }
1894 
1903 void command_sound(object *op, const char *params) {
1904  if (!(op->contr->socket.sound&SND_MUTE)) {
1905  op->contr->socket.sound = op->contr->socket.sound|SND_MUTE;
1907  i18n(op, "Sounds are turned off."));
1908  } else {
1909  op->contr->socket.sound = op->contr->socket.sound&~SND_MUTE;
1911  i18n(op, "The sounds are enabled."));
1912  }
1913  return;
1914 }
1915 
1925 void receive_player_name(object *op) {
1926  if (!check_name(op->contr, op->contr->write_buf+1)) {
1927  get_name(op);
1928  return;
1929  }
1930  FREE_AND_COPY(op->name, op->contr->write_buf+1);
1931  FREE_AND_COPY(op->name_pl, op->contr->write_buf+1);
1933  op->contr->name_changed = 1;
1934  get_password(op);
1935 }
1936 
1943 void receive_player_password(object *op) {
1944  unsigned int pwd_len = strlen(op->contr->write_buf);
1945 
1946  if (pwd_len <= 1 || pwd_len > 17) {
1947  if (op->contr->state == ST_CHANGE_PASSWORD_OLD
1949  || op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
1951  i18n(op, "Password changed cancelled."));
1953  } else
1954  get_name(op);
1955  return;
1956  }
1957  /* To hide the password better */
1958  /* With currently clients, not sure if this is really the case - MSW */
1960 
1961  if (checkbanned(op->name, op->contr->socket.host)) {
1962  LOG(llevInfo, "Banned player tried to add: [%s@%s]\n", op->name, op->contr->socket.host);
1964  i18n(op, "You are not allowed to play."));
1965  get_name(op);
1966  return;
1967  }
1968 
1969  if (op->contr->state == ST_CONFIRM_PASSWORD) {
1970  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
1972  i18n(op, "The passwords did not match."));
1973  get_name(op);
1974  return;
1975  }
1976  LOG(llevInfo, "LOGIN: New player named %s from ip %s\n", op->name, op->contr->socket.host);
1977  display_motd(op);
1979  i18n(op, "\nWelcome, Brave New Warrior!\n"));
1980  roll_again(op);
1982  return;
1983  }
1984 
1985  if (op->contr->state == ST_CHANGE_PASSWORD_OLD) {
1986  if (!check_password(op->contr->write_buf+1, op->contr->password)) {
1988  i18n(op, "You entered the wrong current password."));
1990  } else {
1991  send_query(&op->contr->socket, CS_QUERY_HIDEINPUT, i18n(op, "Please enter your new password, or blank to cancel:"));
1993  }
1994  return;
1995  }
1996 
1997  if (op->contr->state == ST_CHANGE_PASSWORD_NEW) {
1999  sizeof(op->contr->new_password));
2001  i18n(op, "Please confirm your new password, or blank to cancel:"));
2003  return;
2004  }
2005 
2006  if (op->contr->state == ST_CHANGE_PASSWORD_CONFIRM) {
2007  if (!check_password(op->contr->write_buf+1, op->contr->new_password)) {
2009  i18n(op, "The new passwords don't match!"));
2010  } else {
2012  i18n(op, "Password changed."));
2013  strncpy(op->contr->password, op->contr->new_password, 13);
2014  }
2016  return;
2017  }
2018 
2020  sizeof(op->contr->password));
2022  check_login(op, TRUE);
2023 }
2024 
2035 void command_title(object *op, const char *params) {
2036  char buf[MAX_BUF];
2037 
2038  if (settings.set_title == FALSE) {
2040  i18n(op, "You cannot change your title."));
2041  return;
2042  }
2043 
2044  /* dragon players cannot change titles */
2045  if (is_dragon_pl(op)) {
2047  i18n(op, "Dragons cannot change titles."));
2048  return;
2049  }
2050 
2051  if (*params == '\0') {
2052  char tmp[MAX_BUF];
2053 
2054  player_get_title(op->contr, tmp, sizeof(tmp));
2055  snprintf(buf, sizeof(buf), i18n(op, "Your title is '%s'."), tmp);
2057  return;
2058  }
2059  if (strcmp(params, "clear") == 0 || strcmp(params, "default") == 0) {
2060  if (!player_has_own_title(op->contr))
2062  i18n(op, "Your title is the default title."));
2063  else
2065  i18n(op, "Title set to default."));
2066  player_set_own_title(op->contr, "");
2067  return;
2068  }
2069 
2070  if ((int)strlen(params) >= MAX_NAME) {
2072  i18n(op, "Title too long."));
2073  return;
2074  }
2075  player_set_own_title(op->contr, params);
2076 }
2077 
2086 void command_save(object *op, const char *params) {
2087  if (get_map_flags(op->map, NULL, op->x, op->y, NULL, NULL)&P_NO_CLERIC) {
2089  i18n(op, "You can not save on unholy ground."));
2090  } else if (!op->stats.exp) {
2092  i18n(op, "You don't deserve to save yet."));
2093  } else {
2094  if (save_player(op, 1))
2096  i18n(op, "You have been saved."));
2097  else
2099  i18n(op, "SAVE FAILED!"));
2100  }
2101 }
2102 
2111 void command_peaceful(object *op, const char *params) {
2112  if ((op->contr->peaceful = !op->contr->peaceful))
2114  i18n(op, "You will not attack other players."));
2115  else
2117  i18n(op, "You will attack other players."));
2118 }
2119 
2128 void command_wimpy(object *op, const char *params) {
2129  int i;
2130 
2131  if (*params == '\0' || !sscanf(params, "%d", &i)) {
2133  i18n(op, "Your current wimpy level is %d."),
2134  op->run_away);
2135  return;
2136  }
2137 
2138  if (i < 0 || i > 100) {
2140  i18n(op, "Wimpy level should be between 1 and 100."),
2141  i);
2142  return;
2143  }
2144 
2146  i18n(op, "Your new wimpy level is %d."),
2147  i);
2148  op->run_away = i;
2149 }
2150 
2159 void command_brace(object *op, const char *params) {
2160  if (*params == '\0')
2161  op->contr->braced = !op->contr->braced;
2162  else
2163  op->contr->braced = onoff_value(params);
2164 
2165  if (op->contr->braced)
2167  i18n(op, "You are braced."));
2168  else
2170  i18n(op, "Not braced."));
2171 
2172  fix_object(op);
2173 }
2174 
2183 void command_kill_pets(object *op, const char *params) {
2184  objectlink *obl, *next;
2185  int counter = 0, removecount = 0;
2186 
2187  if (*params == '\0') {
2188  pets_terminate_all(op);
2190  i18n(op, "Your pets have been killed."));
2191  } else {
2192  int target = atoi(params);
2193  for (obl = first_friendly_object; obl != NULL; obl = next) {
2194  object *ob = obl->ob;
2195  next = obl->next;
2196  if (object_get_owner(ob) == op)
2197  if (++counter == target || (target == 0 && !strcasecmp(ob->name, params))) {
2198  if (!QUERY_FLAG(ob, FLAG_REMOVED))
2199  object_remove(ob);
2202  removecount++;
2203  }
2204  }
2205  if (removecount != 0)
2207  i18n(op, "Killed %d pets."),
2208  removecount);
2209  else
2211  i18n(op, "Couldn't find any suitable pets to kill."));
2212  }
2213 }
2214 
2223 void command_passwd(object *pl, const char *params) {
2224  /* If old client, this is the way you change your password. */
2225  if (pl->contr->socket.login_method < 1){
2226  send_query(&pl->contr->socket, CS_QUERY_HIDEINPUT, i18n(pl, "Password change.\nPlease enter your current password, or empty string to cancel."));
2227 
2229  }
2230  /* If new client (login_method = 2) or jxclient (login_method = 1), changing the password does nothing anyway, so error out */
2231  else{
2233  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."));
2234  }
2235 }
2236 
2246 void do_harvest(object *pl, int dir, object *skill) {
2247  int16_t x, y;
2248  int count = 0, proba; /* Probability to get the item, 100 based. */
2249  int level, exp;
2250  object *found[10]; /* Found items that can be harvested. */
2251  mapstruct *map;
2252  object *item, *inv;
2253  sstring trace, ttool, tspeed, race, tool, slevel, sexp;
2254  float speed;
2255 
2256  x = pl->x+freearr_x[dir];
2257  y = pl->y+freearr_y[dir];
2258  map = pl->map;
2259 
2260  if (!IS_PLAYER(pl))
2261  return;
2262 
2263  if (!map)
2264  return;
2265 
2266  if (get_map_flags(map, &map, x, y, &x, &y)&P_OUT_OF_MAP) {
2267  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2268  return;
2269  }
2270 
2271  if (!pl->chosen_skill || pl->chosen_skill->skill != skill->skill)
2272  return;
2273 
2274  trace = object_get_value(pl->chosen_skill, "harvest_race");
2275  ttool = object_get_value(pl->chosen_skill, "harvest_tool");
2276  tspeed = object_get_value(pl->chosen_skill, "harvest_speed");
2277  if (!trace || strcmp(trace, "") == 0 || !ttool || strcmp(ttool, "") == 0 || !tspeed || strcmp(tspeed, "") == 0) {
2278  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2279  LOG(llevError, "do_harvest: tool %s without harvest_[race|tool|speed]\n", pl->chosen_skill->name);
2280  return;
2281  }
2282 
2283  item = GET_MAP_OB(map, x, y);
2284  while (item && count < 10) {
2285  FOR_INV_PREPARE(item, inv) {
2286  if (object_get_value(inv, "harvestable") == NULL)
2287  continue;
2288  race = object_get_value(inv, "harvest_race");
2289  tool = object_get_value(inv, "harvest_tool");
2290  slevel = object_get_value(inv, "harvest_level");
2291  sexp = object_get_value(inv, "harvest_exp");
2292  if (race && (!slevel || !sexp)) {
2293  LOG(llevError, "do_harvest: item %s without harvest_[level|exp]\n", inv->name);
2294  continue;
2295  }
2296  if (race == trace && (!tool || tool == ttool))
2297  found[count++] = inv;
2298  } FOR_INV_FINISH();
2299  item = item->above;
2300  }
2301  if (count == 0) {
2302  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You can't %s anything here.", skill->slaying);
2303  return;
2304  }
2305 
2306  inv = found[rndm(0, count-1)];
2307  assert(inv);
2308 
2309  slevel = object_get_value(inv, "harvest_level");
2310  sexp = object_get_value(inv, "harvest_exp");
2311  level = atoi(slevel);
2312  exp = atoi(sexp);
2313 
2314  speed = atof(tspeed);
2315  if (speed < 0)
2316  speed = -speed*pl->speed;
2317  pl->speed_left -= speed;
2318 
2319 
2320  /* Now we found something to harvest, randomly try to get it. */
2321  if (level > skill->level+10) {
2322  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2323  return;
2324  }
2325 
2326  if (level >= skill->level)
2327  /* Up to 10 more levels, 1 to 11 percent probability. */
2328  proba = 10+skill->level-level;
2329  else if (skill->level <= level+10)
2330  proba = 10+(skill->level-level)*2;
2331  else
2332  proba = 30;
2333 
2334  if (proba <= random_roll(0, 100, pl, 1)) {
2335  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2336  return;
2337  }
2338 
2339  /* Check the new item can fit into inventory.
2340  * Fixes bug #3060474: fishing puts more fishes into inventory than you can carry. */
2341  if (((uint32_t)(pl->weight + pl->carrying + inv->weight)) > get_weight_limit(pl->stats.Str)) {
2342  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);
2343  return;
2344  }
2345 
2346  /* Ok, got it. */
2347  item = object_new();
2348  object_copy_with_inv(inv, item);
2349  object_set_value(item, "harvestable", NULL, 0);
2350  if (QUERY_FLAG(item, FLAG_MONSTER)) {
2351  int spot = object_find_free_spot(item, pl->map, pl->x, pl->y, 0, SIZEOFFREE);
2352  if (spot == -1) {
2353  /* Better luck next time...*/
2354  object_remove(item);
2355  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You fail to %s anything.", skill->slaying);
2356  return;
2357  }
2358  object_insert_in_map_at(item, pl->map, NULL, 0, pl->x+freearr_x[spot], pl->y+freearr_y[spot]);
2359  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s a %s!", skill->slaying, item->name);
2360  } else {
2361  item = object_insert_in_ob(item, pl);
2362  draw_ext_info_format(NDI_WHITE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_FAILURE, "You %s some %s", skill->slaying, item->name);
2363  }
2364 
2365  /* Get exp */
2366  change_exp(pl, exp, skill->name, SK_EXP_ADD_SKILL);
2367 
2368  return;
2369 }
#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:315
uint8_t login_method
Definition: newserver.h:128
void command_petmode(object *op, const char *params)
Definition: c_misc.c:1381
char path[HUGE_BUF]
Definition: map.h:365
void command_save(object *op, const char *params)
Definition: c_misc.c:2086
void command_afk(object *op, const char *params)
Definition: c_misc.c:731
int8_t Int
Definition: living.h:36
#define NUM_BODY_LOCATIONS
Definition: object.h:13
Definition: player.h:92
void command_malloc(object *op, const char *params)
Definition: c_misc.c:751
int8_t ac
Definition: living.h:38
void command_help(object *op, const char *params)
Definition: c_misc.c:1731
#define ST_GET_PARTY_PASSWORD
Definition: define.h:587
void display_who_entry(object *op, player *pl, const char *format)
Definition: c_misc.c:599
void command_unarmed_skill(object *op, const char *params)
Definition: c_misc.c:1325
struct mapdef mapstruct
void command_who(object *op, const char *params)
Definition: c_misc.c:582
command_array_struct Commands[]
Definition: commands.c:36
const int WizCommandsSize
Definition: commands.c:267
Definition: player.h:39
void roll_again(object *op)
Definition: player.c:1113
int64_t level_exp(int level, double expmul)
Definition: living.c:1847
int check_name(player *me, const char *name)
Definition: login.c:163
void command_wizpass(object *op, const char *params)
Definition: c_misc.c:879
Definition: object.h:442
#define SET_FLAG(xyz, p)
Definition: define.h:223
void command_maps(object *op, const char *params)
Definition: c_misc.c:787
bool check_password(const char *typed, const char *crypted)
Definition: server.c:107
region * get_region_by_name(const char *region_name)
Definition: region.c:46
#define FABS(x)
Definition: define.h:22
uint32_t braced
Definition: player.h:124
#define MSG_TYPE_COMMAND_CONFIG
Definition: newclient.h:505
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
Definition: player.c:224
#define NDI_WHITE
Definition: newclient.h:222
EXTERN int num_animations
Definition: global.h:164
uint32_t name_changed
Definition: player.h:130
#define FLAG_USE_ARMOUR
Definition: define.h:296
void command_motd(object *op, const char *params)
Definition: c_misc.c:173
char who_wiz_format[MAX_BUF]
Definition: global.h:273
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:819
EXTERN objectlink * first_friendly_object
Definition: global.h:123
void object_copy_with_inv(const object *src_ob, object *dest_ob)
Definition: object.c:1006
int16_t players
Definition: map.h:344
void command_dumpallobjects(object *op, const char *params)
Definition: c_misc.c:939
unapplymode
Definition: player.h:62
int login_order
Definition: c_misc.c:483
int save_player(object *op, int flag)
Definition: login.c:212
uint32_t in_memory
Definition: map.h:345
const char * playerdir
Definition: global.h:244
#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:342
void command_brace(object *op, const char *params)
Definition: c_misc.c:2159
#define HUGE_BUF
Definition: define.h:37
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4266
#define SND_MUTE
Definition: sounds.h:14
#define SS_DUMP_TOTALS
Definition: shstr.h:47
#define ST_CHANGE_PASSWORD_CONFIRM
Definition: define.h:590
#define MAP_HEIGHT(m)
Definition: map.h:80
void command_kill_pets(object *op, const char *params)
Definition: c_misc.c:2183
char new_password[16]
Definition: player.h:177
object clone
Definition: object.h:470
struct treasureliststruct * next
Definition: treasure.h:89
socket_struct socket
Definition: player.h:94
short freearr_x[SIZEOFFREE]
Definition: object.c:65
#define ST_CONFIRM_PASSWORD
Definition: define.h:586
int object_count_active(void)
Definition: object.c:1610
const char * slaying
Definition: object.h:319
region * get_region_by_map(mapstruct *m)
Definition: region.c:74
DIR * opendir(const char *)
Definition: win32.c:37
void command_dumpallmaps(object *op, const char *params)
Definition: c_misc.c:1000
void command_dumpmap(object *op, const char *params)
Definition: c_misc.c:987
void dump_all_archetypes(void)
Definition: arch.c:244
uint8_t subtype
Definition: object.h:339
#define FLAG_USE_WEAPON
Definition: define.h:297
void command_resistances(object *op, const char *params)
Definition: c_misc.c:1538
int checkbanned(const char *login, const char *host)
Definition: ban.c:32
int64_t exp
Definition: living.h:47
struct obj * above
Definition: object.h:288
void object_dump_all(void)
Definition: object.c:481
double expmul
Definition: object.h:395
#define ST_CHANGE_PASSWORD_NEW
Definition: define.h:589
int language
Definition: player.h:201
#define FLAG_AFK
Definition: define.h:377
#define TRUE
Definition: compat.h:10
player * find_player(const char *plname)
Definition: player.c:55
LogLevel debug
Definition: global.h:238
body_locations_struct body_locations[NUM_BODY_LOCATIONS]
Definition: item.c:54
#define FALSE
Definition: compat.h:11
void remove_friendly_object(object *op)
Definition: friend.c:56
int16_t sp
Definition: living.h:42
uint32_t get_weight_limit(int stat)
Definition: living.c:2305
#define SS_DUMP_TABLE
Definition: shstr.h:46
#define MSG_TYPE_COMMAND_STATISTICS
Definition: newclient.h:504
Definition: win32.h:110
#define safe_strncpy
Definition: compat.h:23
uint32_t hidden
Definition: player.h:132
char * partyname
Definition: party.h:14
void pets_terminate_all(object *owner)
Definition: pets.c:231
#define ST_ROLL_STAT
Definition: define.h:581
struct obj object
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:310
Definition: object.h:465
#define ST_PLAYING
Definition: define.h:579
void command_whereami(object *op, const char *params)
Definition: c_misc.c:775
char * host
Definition: newserver.h:100
const int CommunicationCommandSize
Definition: commands.c:200
void command_debug(object *op, const char *params)
Definition: c_misc.c:855
int16_t maxsp
Definition: living.h:43
int8_t Con
Definition: living.h:36
#define FLAG_REMOVED
Definition: define.h:232
int16_t hp
Definition: living.h:40
#define MAP_WHEN_RESET(m)
Definition: map.h:62
char namebuf[MAX_BUF]
Definition: c_misc.c:482
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:951
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:387
void get_name(object *op)
Definition: player.c:855
void current_region_info(object *op)
Definition: c_misc.c:366
object * ob
Definition: object.h:443
uint32_t ticks_played
Definition: player.h:203
#define MSG_TYPE_ADMIN_DM
Definition: newclient.h:475
int rndm(int min, int max)
Definition: utils.c:162
void command_printlos(object *op, const char *params)
Definition: c_misc.c:1012
#define NAMLEN(dirent)
Definition: global.h:219
const char * get_region_longname(const region *r)
Definition: region.c:217
void command_fix_me(object *op, const char *params)
Definition: c_misc.c:1161
int player_has_own_title(const struct pl *pl)
Definition: player.c:239
char * name
Definition: map.h:328
#define MAP_IN_MEMORY
Definition: map.h:130
struct obj * chosen_skill
Definition: object.h:386
int object_set_value(object *op, const char *key, const char *value, int add_key)
Definition: object.c:4395
void object_free_drop_inventory(object *ob)
Definition: object.c:1389
int16_t y
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1933
#define NDI_RED
Definition: newclient.h:224
int16_t maxhp
Definition: living.h:41
char * name
Definition: map.h:278
#define MSG_TYPE_COMMAND
Definition: newclient.h:379
uint32_t sound
Definition: newserver.h:111
Definition: win32.h:120
struct artifactliststruct * next
Definition: artifact.h:29
object * object_new(void)
Definition: object.c:1068
const char * name_pl
Definition: object.h:315
usekeytype
Definition: player.h:52
void player_set_own_title(struct pl *pl, const char *title)
Definition: player.c:264
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2707
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:1174
float speed_left
Definition: object.h:329
unapplymode unapply
Definition: player.h:108
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:509
void command_wizcast(object *op, const char *params)
Definition: c_misc.c:909
signed short int16_t
Definition: win32.h:160
void command_passwd(object *pl, const char *params)
Definition: c_misc.c:2223
enum _petmode petmode_t
int32_t weight
Definition: object.h:365
static bool IS_PLAYER(object *op)
Definition: object.h:594
int8_t Wis
Definition: living.h:36
#define ST_CONFIRM_QUIT
Definition: define.h:583
void get_password(object *op)
Definition: player.c:867
struct mapdef * map
Definition: object.h:297
int is_dragon_pl(const object *op)
Definition: player.c:114
struct regiondef * next
Definition: map.h:277
void receive_player_password(object *op)
Definition: c_misc.c:1943
Definition: map.h:276
#define snprintf
Definition: win32.h:46
void player_set_state(player *pl, uint8_t state)
Definition: player.c:4467
#define MAP_TIMEOUT(m)
Definition: map.h:66
void dump_all_maps(void)
Definition: map.c:278
#define FOR_INV_FINISH()
Definition: define.h:714
char * msg
Definition: map.h:361
#define FMT64
Definition: compat.h:12
type_definition ** types
int16_t dam
Definition: living.h:46
void command_rules(object *op, const char *params)
Definition: c_misc.c:185
void command_applymode(object *op, const char *params)
Definition: c_misc.c:1223
int object_count_free(void)
Definition: object.c:1572
void do_harvest(object *pl, int dir, object *skill)
Definition: c_misc.c:2246
int32_t carrying
Definition: object.h:367
const char * name
Definition: object.h:311
living orig_stats
Definition: player.h:148
long seconds(void)
Definition: time.c:344
void command_mapinfo(object *op, const char *params)
Definition: c_misc.c:763
#define ATNR_INTERNAL
Definition: attack.h:72
struct archt * more
Definition: object.h:469
static void show_commands(object *op, int what)
Definition: c_misc.c:1644
uint8_t state
Definition: player.h:118
#define CS_QUERY_SINGLECHAR
Definition: newclient.h:67
#define MSG_TYPE_COMMAND_WHO
Definition: newclient.h:499
uint32_t counter
Definition: map.h:294
#define MAP_ENTER_Y(m)
Definition: map.h:87
uint8_t listening
Definition: player.h:120
int8_t Cha
Definition: living.h:36
EXTERN const char *const change_resist_msg[NROFATTACKS]
Definition: attack.h:135
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
Definition: map.h:251
EXTERN Animations * animations
Definition: global.h:163
struct pl * contr
Definition: object.h:276
char * ss_dump_table(int what, char *buf, size_t size)
Definition: shstr.c:354
#define MSG_TYPE_SKILL_FAILURE
Definition: newclient.h:585
void command_hiscore(object *op, const char *params)
Definition: c_misc.c:843
EXTERN treasurelist * first_treasurelist
Definition: global.h:120
void time_info(object *op)
Definition: time.c:294
char d_name[_MAX_FNAME+1]
Definition: win32.h:114
void command_listen(object *op, const char *params)
Definition: c_misc.c:1039
float speed
Definition: object.h:328
unsigned __int64 uint64_t
Definition: win32.h:167
struct regiondef * parent
Definition: map.h:286
void command_whereabouts(object *op, const char *params)
Definition: c_misc.c:443
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define MSG_TYPE_ADMIN_VERSION
Definition: newclient.h:479
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
EXTERN artifactlist * first_artifactlist
Definition: global.h:121
uint32_t is_bot
Definition: newserver.h:107
EXTERN const char *const attacktype_desc[NROFATTACKS]
Definition: attack.h:138
#define FLAG_WIZ
Definition: define.h:231
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Definition: living.c:2126
void command_language(object *op, const char *params)
Definition: c_misc.c:89
void command_news(object *op, const char *params)
Definition: c_misc.c:197
void dump_map(const mapstruct *m)
Definition: map.c:255
#define MAX_BUF
Definition: define.h:35
command_array_struct WizCommands[]
Definition: commands.c:203
void command_body(object *op, const char *params)
Definition: c_misc.c:132
LogLevel
Definition: logger.h:10
char who_format[MAX_BUF]
Definition: global.h:272
#define MSG_TYPE_ADMIN
Definition: newclient.h:377
uint32_t peaceful
Definition: player.h:131
enum _bowtype bowtype_t
int16_t x
Definition: object.h:326
void command_wimpy(object *op, const char *params)
Definition: c_misc.c:2128
int nroffreeobjects
Definition: object.c:56
const char * skill
Definition: object.h:321
int8_t wc
Definition: living.h:37
unsigned short uint16_t
Definition: win32.h:163
void command_sound(object *op, const char *params)
Definition: c_misc.c:1903
void command_delete(object *op, const char *params)
Definition: c_misc.c:1883
uint16_t difficulty
Definition: map.h:343
int8_t Str
Definition: living.h:36
int16_t resist[NROFATTACKS]
Definition: object.h:341
object * ob
Definition: player.h:158
EXTERN long nrofartifacts
Definition: global.h:146
const char * sstring
Definition: global.h:40
unsigned int uint32_t
Definition: win32.h:162
const char * datadir
Definition: global.h:242
EXTERN long nrofallowedstr
Definition: global.h:147
void command_showpets(object *op, const char *params)
Definition: c_misc.c:1425
bowtype_t bowtype
Definition: player.h:101
void command_ssdumptable(object *op, const char *params)
Definition: c_misc.c:975
int8_t body_info[NUM_BODY_LOCATIONS]
Definition: object.h:372
void print_los(object *op)
Definition: los.c:606
Definition: map.h:258
#define FREE_AND_COPY(sv, nv)
Definition: global.h:211
#define MSG_TYPE_COMMAND_MALLOC
Definition: newclient.h:502
static void malloc_info(object *op)
Definition: c_misc.c:207
void command_time(object *op, const char *params)
Definition: c_misc.c:819
const int CommandsSize
Definition: commands.c:127
const char * localdir
Definition: global.h:243
char password[16]
Definition: player.h:176
tag_t count
Definition: object.h:299
living stats
Definition: object.h:368
#define FLAG_WIZCAST
Definition: define.h:290
#define MSG_TYPE_LAST
Definition: newclient.h:396
int8_t Dex
Definition: living.h:36
void command_statistics(object *pl, const char *params)
Definition: c_misc.c:1070
struct archt * arch
Definition: object.h:412
sstring i18n_get_language_code(int language)
Definition: languages.c:122
struct oblnk * next
Definition: object.h:444
#define MAP_WIDTH(m)
Definition: map.h:78
void command_title(object *op, const char *params)
Definition: c_misc.c:2035
void check_login(object *op, int check_pass)
Definition: login.c:501
void command_strings(object *op, const char *params)
Definition: c_misc.c:799
struct Settings settings
Definition: init.c:40
void arch_info(object *op)
Definition: arch.c:198
#define SK_EXP_ADD_SKILL
Definition: skills.h:78
#define MSG_TYPE_COMMAND_INFO
Definition: newclient.h:506
struct archt * next
Definition: object.h:467
#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:2111
uint32_t max_time
Definition: time.c:35
command_array_struct CommunicationCommands[]
Definition: commands.c:130
#define ST_CHANGE_PASSWORD_OLD
Definition: define.h:588
void ss_dump_statistics(char *buf, size_t size)
Definition: shstr.c:323
static void help_topics(object *op, int what)
Definition: c_misc.c:1583
int object_count_used(void)
Definition: object.c:1591
void send_news(const object *op)
Definition: player.c:202
#define MSG_TYPE_COMMAND_BODY
Definition: newclient.h:501
void send_rules(const object *op)
Definition: player.c:166
sstring add_string(const char *str)
Definition: shstr.c:124
const char * get_name_of_region_for_map(const mapstruct *m)
Definition: region.c:92
EXTERN player * first_player
Definition: global.h:117
void get_who_escape_code_value(char *return_val, int size, const char letter, player *pl)
Definition: c_misc.c:655
struct pl * next
Definition: player.h:93
#define GET_MAP_OB(M, X, Y)
Definition: map.h:172
int strcasecmp(const char *s1, const char *s2)
Definition: porting.c:256
int i18n_find_language_by_code(const char *code)
Definition: languages.c:95
#define FLAG_MONSTER
Definition: define.h:245
#define MSG_TYPE_SKILL
Definition: newclient.h:383
int8_t Pow
Definition: living.h:36
int closedir(DIR *)
Definition: win32.c:108
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.c:310
uint8_t set_title
Definition: global.h:261
petmode_t petmode
Definition: player.h:102
#define NDI_UNIQUE
Definition: newclient.h:245
#define S_ISDIR(x)
Definition: win32.h:69
#define MSG_SUBTYPE_NONE
Definition: newclient.h:398
usekeytype usekeys
Definition: player.h:107
Definition: player.h:46
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
#define CS_QUERY_HIDEINPUT
Definition: newclient.h:68
void receive_player_name(object *op)
Definition: c_misc.c:1925
#define FLAG_WAS_WIZ
Definition: define.h:234
EXTERN region * first_region
Definition: global.h:119
void command_archs(object *op, const char *params)
Definition: c_misc.c:831
#define MAX_NAME
Definition: define.h:41
uint8_t run_away
Definition: object.h:384
#define FULL_VERSION
Definition: version.h:6
struct mapdef * next
Definition: map.h:326
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3432
void command_dumpallarchetypes(object *op, const char *params)
Definition: c_misc.c:963
void map_info(object *op, const char *search)
Definition: c_misc.c:45
void dump_friendly_objects(void)
Definition: friend.c:100
void command_quit(object *op, const char *params)
Definition: c_misc.c:1867
Definition: map.h:325
int random_roll(int min, int max, const object *op, int goodbad)
Definition: utils.c:42
char write_buf[MAX_BUF]
Definition: player.h:174
void command_usekeys(object *op, const char *params)
Definition: c_misc.c:1497
void command_bowmode(object *op, const char *params)
Definition: c_misc.c:1264
object * object_find_by_type_and_arch_name(const object *who, int type, const char *name)
Definition: object.c:4188
int onoff_value(const char *line)
Definition: c_misc.c:1833
#define FLAG_WIZPASS
Definition: define.h:315
const char * unarmed_skill
Definition: player.h:202
#define S_ISREG(x)
Definition: win32.h:70
int16_t level
Definition: object.h:351
char const * newhash(char const *password)
void fix_object(object *op)
Definition: living.c:1119
const char * i18n(const object *who, const char *code)
Definition: languages.c:69
float weapon_speed
Definition: object.h:330
void list_players(object *op, region *reg, partylist *party)
Definition: c_misc.c:509
EXTERN mapstruct * first_map
Definition: global.h:118
EXTERN archetype * first_archetype
Definition: global.h:122
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.c:191
char * longname
Definition: map.h:291
void command_version(object *op, const char *params)
Definition: c_misc.c:1026
object * object_get_owner(object *op)
Definition: object.c:590
const char * name
Definition: object.h:466
static int find_help_file(const char *name, const char *language, int wiz, char *path, int length)
Definition: c_misc.c:1691
#define P_NO_CLERIC
Definition: map.h:238
size_t strlcpy(char *dst, const char *src, size_t size)
Definition: porting.c:366
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:707
void object_remove(object *op)
Definition: object.c:1666
const char * get_region_msg(const region *r)
Definition: region.c:238
void i18n_list_languages(object *who)
Definition: languages.c:132
int8_t body_used[NUM_BODY_LOCATIONS]
Definition: object.h:373
int atnr_is_dragon_enabled(int attacknr)
Definition: player.c:95
Definition: object.h:224
void current_map_info(object *op)
Definition: c_misc.c:388
static int name_cmp(const chars_names *c1, const chars_names *c2)
Definition: c_misc.c:495
void display_motd(const object *op)
Definition: player.c:135
EXTERN long nroftreasures
Definition: global.h:145