Crossfire Server, Trunk  1.75.0
c_wiz.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 #include "global.h"
21 
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26 
27 #include "sproto.h"
28 #include "spells.h"
29 #include "treasure.h"
30 #include "skills.h"
31 #include "assets.h"
32 #include "AssetsManager.h"
33 
34 /* Defines for DM item stack **/
35 #define STACK_SIZE 50
37 enum {
42 };
43 
45 
60 static player *get_other_player_from_name(object *op, const char *name) {
61  player *pl;
62 
63  if (!name)
64  return NULL;
65 
66  for (pl = first_player; pl != NULL; pl = pl->next)
67  if (!strncmp(pl->ob->name, name, MAX_NAME))
68  break;
69 
70  if (pl == NULL) {
72  "No such player.");
73  return NULL;
74  }
75 
76  if (pl->ob == op) {
78  "You can't do that to yourself.");
79  return NULL;
80  }
81  if (pl->state != ST_PLAYING) {
83  "That player is in no state for that right now.");
84  return NULL;
85  }
86  return pl;
87 }
88 
95 static void dm_stack_pop(player *pl) {
96  if (!pl->stack_items || !pl->stack_position) {
98  "Empty stack!");
99  return;
100  }
101 
102  pl->stack_position--;
104  "Popped item from stack, %d left.",
105  pl->stack_position);
106 }
107 
120 static object *dm_stack_peek(player *pl) {
121  object *ob;
122 
123  if (!pl->stack_position) {
125  "Empty stack!");
126  return NULL;
127  }
128 
130  if (!ob) {
132  "Stacked item was removed!");
133  dm_stack_pop(pl);
134  return NULL;
135  }
136 
137  return ob;
138 }
139 
150 static void dm_stack_push(player *pl, tag_t item) {
151  if (!pl->stack_items) {
152  pl->stack_items = (tag_t *)malloc(sizeof(tag_t)*STACK_SIZE);
153  memset(pl->stack_items, 0, sizeof(tag_t)*STACK_SIZE);
154  }
155 
156  if (pl->stack_position == STACK_SIZE) {
158  "Item stack full!");
159  return;
160  }
161 
162  pl->stack_items[pl->stack_position] = item;
164  "Item stacked as %d.",
165  pl->stack_position);
166  pl->stack_position++;
167 }
168 
196 static object *get_dm_object(player *pl, const char **params, int *from) {
197  int item_tag, item_position;
198  object *ob;
199 
200  if (!pl)
201  return NULL;
202 
203  if (**params == '\0') {
204  if (from)
205  *from = STACK_FROM_TOP;
206  /* No parameter => get stack item */
207  return dm_stack_peek(pl);
208  }
209 
210  /* Let's clean white spaces */
211  while (**params == ' ')
212  (*params)++;
213 
214  /* Next case: number => item tag */
215  if (sscanf(*params, "%d", &item_tag)) {
216  /* Move parameter to next item */
217  while (isdigit(**params))
218  (*params)++;
219 
220  /* And skip blanks, too */
221  while (**params == ' ')
222  (*params)++;
223 
224  /* Get item */
225  ob = object_find_by_tag_global(item_tag);
226  if (!ob) {
227  if (from)
228  *from = STACK_FROM_NONE;
230  "No such item %d!",
231  item_tag);
232  return NULL;
233  }
234 
235  /* Got one, let's push it on stack */
236  dm_stack_push(pl, item_tag);
237  if (from)
238  *from = STACK_FROM_NUMBER;
239  return ob;
240  }
241 
242  /* Next case: $number => stack item */
243  if (sscanf(*params, "$%d", &item_position)) {
244  /* Move parameter to next item */
245  (*params)++;
246 
247  while (isdigit(**params))
248  (*params)++;
249  while (**params == ' ')
250  (*params)++;
251 
252  if (item_position >= pl->stack_position) {
253  if (from)
254  *from = STACK_FROM_NONE;
256  "No such stack item %d!",
257  item_position);
258  return NULL;
259  }
260 
261  ob = object_find_by_tag_global(pl->stack_items[item_position]);
262  if (!ob) {
263  if (from)
264  *from = STACK_FROM_NONE;
266  "Stack item %d was removed.",
267  item_position);
268  return NULL;
269  }
270 
271  if (from)
272  *from = item_position < pl->stack_position-1 ? STACK_FROM_STACK : STACK_FROM_TOP;
273  return ob;
274  }
275 
276  /* Next case: 'me' => return pl->ob */
277  if (!strncmp(*params, "me", 2)) {
278  if (from)
279  *from = STACK_FROM_NUMBER;
280  dm_stack_push(pl, pl->ob->count);
281 
282  /* Skip to next token */
283  (*params) += 2;
284  while (**params == ' ')
285  (*params)++;
286 
287  return pl->ob;
288  }
289 
290  /* Last case: get stack top */
291  if (from)
292  *from = STACK_FROM_TOP;
293  return dm_stack_peek(pl);
294 }
295 
306 void command_loadtest(object *op, const char *params) {
307  uint32_t x, y;
308  char buf[1024];
309 
311  "loadtest will stress server through teleporting at different map places. "
312  "Use at your own risk. Very long loop used so server may have to be reset. "
313  "type loadtest TRUE to run");
315  "{%s}",
316  params);
317  if (*params == '\0')
318  return;
319  if (strncmp(params, "TRUE", 4))
320  return;
321 
323  "gogogo");
324 
325  for (x = 0; x < settings.worldmaptilesx; x++) {
326  for (y = 0; y < settings.worldmaptilesy; y++) {
327  snprintf(buf, sizeof(buf), "/world/world_%u_%u", x+settings.worldmapstartx, y+settings.worldmapstarty);
328  command_goto(op, buf);
329  }
330  }
331 }
332 
333 static void unhide(object* op) {
334  op->contr->hidden = 0;
335  op->invisible = 1;
336  op->map->players++;
338  "You are no longer hidden from other players");
341  "%s has entered the game.", op->name);
342 }
343 
352 static void do_wizard_hide(object *op, int silent_dm) {
353  if (op->contr->hidden) {
354  unhide(op);
355  if (!silent_dm) {
358  "The Dungeon Master has arrived!");
359  }
360  } else {
361  op->contr->hidden = 1;
363  "Other players will no longer see you.");
364  op->map->players--;
365  if (!silent_dm) {
368  "The Dungeon Master is gone...");
369  }
372  "%s leaves the game.",
373  op->name);
376  "%s left the game.",
377  op->name);
378  }
379 }
380 
389 void command_hide(object *op, const char *params) {
390  (void)params;
391  do_wizard_hide(op, 0);
392 }
393 
403 static object *find_object_both(const char *params) {
404  if (params[0] == '#')
405  return object_find_by_tag_global(atol(params+1));
406  else
407  return object_find_by_name_global(params);
408 }
409 
418 void command_setgod(object *op, const char *params) {
419  object *ob;
420  const object *god;
421  char *str;
422 
423  if (*params == '\0' || !(str = const_cast<char *>(strchr(params, ' ')))) {
425  "Usage: set_god player god");
426  return;
427  }
428 
429  /* kill the space, and set string to the next param */
430  *str++ = '\0';
431  if (!(ob = find_object_both(params))) {
433  "Set whose god - can not find object %s?",
434  params);
435  return;
436  }
437 
438  /*
439  * Perhaps this is overly restrictive? Should we perhaps be able
440  * to rebless altars and the like?
441  */
442  if (ob->type != PLAYER) {
444  "%s is not a player - can not change its god",
445  ob->name);
446  return;
447  }
448 
449  god = find_god(str);
450  if (god == NULL) {
452  "No such god %s.",
453  str);
454  return;
455  }
456 
457  become_follower(ob, god);
458 }
459 
468 static void command_kick2(object *op, const char *params) {
469  struct player *pl;
470 
471  for (pl = first_player; pl != NULL; pl = pl->next) {
472  if ((*params == '\0' || !strcmp(pl->ob->name, params)) && pl->ob != op) {
473  object *op = pl->ob;
474  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
475  events_execute_global_event(EVENT_KICK, op, *params == '\0' ? NULL : params);
476  }
478  "%s is kicked out of the game.",
479  op->name);
480 
481  // Saving/leaving/removing is handled on the next tick in do_server().
482  pl->socket->status = Ns_Dead;
483  }
484  }
485 }
486 
502 void command_banish(object *op, const char *params) {
503  player *pl;
504  FILE *banishfile;
505  char buf[MAX_BUF];
506  time_t now;
507 
508  if (*params == '\0') {
510  "Usage: banish <player>.");
511  return;
512  }
513 
514  pl = get_other_player_from_name(op, params);
515  if (!pl)
516  return;
517 
518  snprintf(buf, sizeof(buf), "%s/%s", settings.localdir, BANISHFILE);
519 
520  if ((banishfile = fopen(buf, "a")) == NULL) {
521  LOG(llevDebug, "Could not find file banish_file.\n");
523  "Could not find banish_file.");
524  return;
525  }
526 
527  now = time(NULL);
528  /*
529  * Record this as a comment - then we don't have to worry about changing
530  * the parsing code.
531  */
532  fprintf(banishfile, "# %s (%s) banned by %s at %s\n", pl->ob->name, pl->socket->host, op->name, ctime(&now));
533  fprintf(banishfile, "*@%s\n", pl->socket->host);
534  fclose(banishfile);
535 
536  LOG(llevDebug, "! %s banned %s from IP: %s.\n", op->name, pl->ob->name, pl->socket->host);
537 
539  "You banish %s",
540  pl->ob->name);
541 
543  "%s banishes %s from the land!",
544  op->name, pl->ob->name);
545  command_kick2(op, pl->ob->name);
546 }
547 
556 void command_kick(object *op, const char *params) {
557  command_kick2(op, params);
558 }
559 
568 void command_overlay_save(object *op, const char *params) {
569  (void)params;
570  if (!op)
571  return;
572 
573  if (save_map(op->map, SAVE_MODE_OVERLAY) < 0)
575  "Overlay save error!");
576  else
578  "Current map has been saved as an overlay.");
579 }
580 
589 void command_overlay_reset(object *op, const char *params) {
590  char filename[MAX_BUF];
591  struct stat stats;
592  (void)params;
593 
594  create_overlay_pathname(op->map->path, filename, MAX_BUF);
595  if (!stat(filename, &stats))
596  if (!unlink(filename))
598  "Overlay successfully removed.");
599  else
601  "Overlay couldn't be removed.");
602  else
604  "No overlay for current map.");
605 }
606 
615 void command_toggle_shout(object *op, const char *params) {
616  player *pl;
617 
618  if (*params == '\0') {
620  "Usage: toggle_shout <player>.");
621  return;
622  }
623 
624  pl = get_other_player_from_name(op, params);
625  if (!pl)
626  return;
627 
628  if (pl->ob->contr->no_shout == 0) {
629  pl->ob->contr->no_shout = 1;
630 
632  "You have been muzzled by the DM!");
634  "You muzzle %s.",
635  pl->ob->name);
636 
638 
639  return;
640  }
641 
642  pl->ob->contr->no_shout = 0;
644  "You are allowed to shout and chat again.");
646  "You remove %s's muzzle.",
647  pl->ob->name);
648 }
649 
658 void command_shutdown(object *op, const char *params) {
659  if (strlen(params) == 0) {
660  /* Give DM command help and display current shutdown status. */
661  command_help(op, "shutdown");
664  MSG_TYPE_COMMAND_DM, "No shutdown is currently scheduled.");
665  } else if (shutdown_state.type == SHUTDOWN_TIME) {
666  time_t time_left = shutdown_state.time - time(NULL);
668  MSG_TYPE_COMMAND_DM, "Shutdown scheduled in %lu minutes.", time_left/60);
669  } else if (shutdown_state.type == SHUTDOWN_IDLE) {
671  MSG_TYPE_COMMAND_DM, "Shutdown scheduled when there are no active players.");
672  }
673  } else if (strcmp(params, "cancel") == 0) {
676  MSG_TYPE_ADMIN_DM, "Server shutdown cancelled.");
677  LOG(llevInfo, "Server shutdown cancelled by %s.\n", op->name);
679  } else {
681  MSG_TYPE_COMMAND_ERROR, "No shutdown is pending.");
682  }
683  } else if (strncmp(params, "now", 3) == 0) {
684  /* Announce and shut down immediately. */
686  MSG_TYPE_ADMIN_DM, "This server is shutting down now!");
688  shutdown_state.time = time(NULL);
689  LOG(llevInfo, "Server shutdown initiated by %s.\n", op->name);
690  } else if (strcmp(params, "idle") == 0) {
692  MSG_TYPE_ADMIN_DM, "This server will shut down when all players leave.");
694  shutdown_state.time = 0;
696  LOG(llevInfo, "Server idle shutdown scheduled by %s.\n", op->name);
697  } else {
698  /* Schedule (but don't announce) a shutdown. */
699  int minutes = atoi(params);
700 
701  if (minutes > 0 && minutes <= 720) {
704  "Server will shut down in %d minutes.", minutes);
706  shutdown_state.time = time(NULL) + minutes * 60;
707  LOG(llevInfo, "Server shutdown scheduled in %d minutes by %s.\n", minutes, op->name);
708  } else {
711  "Please specify a reasonable time in minutes.");
712  }
713  }
714 }
715 
724 void command_goto(object *op, const char *params) {
725  if (!op)
726  return ;
727 
728  if (*params == '\0') {
730  "Go to what level?");
731  return;
732  }
733 
734  do_goto(op, params, -1, -1);
735 }
736 
745 void command_freeze(object *op, const char *params) {
746  int ticks;
747  player *pl;
748 
749  if (*params == '\0') {
751  "Usage: freeze [ticks] <player>.");
752  return;
753  }
754 
755  ticks = atoi(params);
756  if (ticks) {
757  while ((isdigit(*params) || isspace(*params)) && *params != 0)
758  params++;
759  if (*params == 0) {
761  "Usage: freeze [ticks] <player>.");
762  return;
763  }
764  } else
765  ticks = 100;
766 
767  pl = get_other_player_from_name(op, params);
768  if (!pl)
769  return;
770 
772  "You have been frozen by the DM!");
773 
775  "You freeze %s for %d ticks",
776  pl->ob->name, ticks);
777 
778  pl->ob->speed_left = -(pl->ob->speed*ticks);
779 }
780 
789 int player_arrest(object *who) {
790  object *dummy;
791  mapstruct *cur;
792  int x, y;
793 
794  if (who->type != PLAYER)
795  return -3;
796 
797  dummy = get_jail_exit(who);
798  if (!dummy) {
799  return -1;
800  }
801  cur = who->map;
802  x = who->x;
803  y = who->y;
804  enter_exit(who, dummy);
806 
807  if (cur == who->map && x == who->x && y == who->y)
808  return -2;
809 
810  return 0;
811 }
812 
821 void command_arrest(object *op, const char *params) {
822  player *pl;
823  int ret;
824 
825  if (!op)
826  return;
827  if (*params == '\0') {
829  "Usage: arrest <player>.");
830  return;
831  }
832  pl = get_other_player_from_name(op, params);
833  if (!pl)
834  return;
835 
836  ret = player_arrest(pl->ob);
837  if (ret == -1) {
838  /* we have nowhere to send the prisoner....*/
840  "Can't jail player, there is no map to hold them");
841  return;
842  }
843  if (ret == -2) {
844  /* something prevented jailing the player */
846  "Can't jail player, map loading issue or already in jail's position");
847  return;
848 
849  }
850 
852  "You have been arrested.");
854  "Jailed %s",
855  pl->ob->name);
856  LOG(llevInfo, "Player %s arrested by %s\n", pl->ob->name, op->name);
857 }
858 
866 void command_summon(object *op, const char *params) {
867  int i;
868  object *dummy;
869  player *pl;
870 
871  if (!op)
872  return;
873 
874  if (*params == '\0') {
876  "Usage: summon <player>.");
877  return;
878  }
879 
880  pl = get_other_player_from_name(op, params);
881  if (!pl)
882  return;
883 
884  i = object_find_free_spot(op, op->map, op->x, op->y, 1, 9);
885  if (i == -1) {
887  "Can not find a free spot to place summoned player.");
888  return;
889  }
890 
891  dummy = object_new();
892  EXIT_PATH(dummy) = add_string(op->map->path);
893  EXIT_X(dummy) = op->x+freearr_x[i];
894  EXIT_Y(dummy) = op->y+freearr_y[i];
895  enter_exit(pl->ob, dummy);
898  "You are summoned.");
900  "You summon %s",
901  pl->ob->name);
902 }
903 
907 void command_swap(object *op, const char *params) {
908  if (*params == '\0') {
910  return;
911  }
912 
913  char path[HUGE_BUF];
914  path_combine_and_normalize(op->map->path, params, path, sizeof(path));
915  mapstruct *m = has_been_loaded(path);
916  if (m == NULL || m->in_memory != MAP_IN_MEMORY) {
917  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR, "That map isn't in memory.");
918  return;
919  }
920  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS, "Marked map ready for swapping.");
921  m->timeout = 1; // not zero but one, see check_active_maps()
922 }
923 
932 /* mids 01/16/2002 */
933 void command_teleport(object *op, const char *params) {
934  int i;
935  object *dummy;
936  player *pl;
937 
938  if (!op)
939  return;
940 
941  if (*params == '\0') {
943  "Usage: teleport <player>.");
944  return;
945  }
946 
947  pl = find_player_partial_name(params);
948  if (!pl) {
950  "No such player or ambiguous name.");
951  return;
952  }
953 
954  i = object_find_free_spot(pl->ob, pl->ob->map, pl->ob->x, pl->ob->y, 1, 9);
955  if (i == -1) {
957  "Can not find a free spot to teleport to.");
958  return;
959  }
960 
961  dummy = object_new();
962  EXIT_PATH(dummy) = add_string(pl->ob->map->path);
963  EXIT_X(dummy) = pl->ob->x+freearr_x[i];
964  EXIT_Y(dummy) = pl->ob->y+freearr_y[i];
965  enter_exit(op, dummy);
967  if (!op->contr->hidden)
969  "You see a portal open.");
971  "You teleport to %s",
972  pl->ob->name);
973 }
974 
999 void command_create(object *op, const char *params) {
1000  object *tmp = NULL;
1001  uint32_t i;
1002  int magic, set_magic = 0, set_nrof = 0, gotquote, gotspace;
1003  uint32_t nrof;
1004  char *cp, *bp, *bp2, *bp3, *endline, cpy[MAX_BUF];
1005  archetype *at, *at_spell = NULL;
1006  const artifact *art = NULL;
1007 
1008  if (!op)
1009  return;
1010 
1011  if (*params == '\0') {
1013  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]");
1014  return;
1015  }
1016  safe_strncpy(cpy, params, sizeof(cpy));
1017  bp = cpy;
1018 
1019  /* We need to know where the line ends */
1020  endline = bp+strlen(bp);
1021 
1022  if (sscanf(bp, "%u ", &nrof)) {
1023  if ((bp = strchr(cpy, ' ')) == NULL) {
1025  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]");
1026  return;
1027  }
1028  bp++;
1029  set_nrof = 1;
1030  LOG(llevDebug, "%s creates: (%u) %s\n", op->name, nrof, bp);
1031  }
1032  if (sscanf(bp, "%d ", &magic)) {
1033  if ((bp = strchr(bp, ' ')) == NULL) {
1035  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]");
1036  return;
1037  }
1038  bp++;
1039  set_magic = 1;
1040  LOG(llevDebug, "%s creates: (%d) (%d) %s\n", op->name, nrof, magic, bp);
1041  }
1042  if ((cp = strstr(bp, " of ")) != NULL) {
1043  *cp = '\0';
1044  cp += 4;
1045  }
1046  for (bp2 = bp; *bp2; bp2++) {
1047  if (*bp2 == ' ') {
1048  *bp2 = '\0';
1049  bp2++;
1050  break;
1051  }
1052  }
1053 
1054  if ((at = try_find_archetype(bp)) == NULL) {
1056  "No such archetype.");
1057  return;
1058  }
1059 
1060  if (cp) {
1061  char spell_name[MAX_BUF], *fsp = NULL;
1062 
1063  /*
1064  * Try to find a spell object for this. Note that
1065  * we also set up spell_name which is only
1066  * the first word.
1067  */
1068 
1069  at_spell = try_find_archetype(cp);
1070  if (!at_spell || at_spell->clone.type != SPELL)
1071  at_spell = find_archetype_by_object_name(cp);
1072  if (!at_spell || at_spell->clone.type != SPELL) {
1073  safe_strncpy(spell_name, cp, sizeof(spell_name));
1074  fsp = strchr(spell_name, ' ');
1075  if (fsp) {
1076  *fsp = 0;
1077  fsp++;
1078  at_spell = try_find_archetype(spell_name);
1079 
1080  /* Got a spell, update the first string pointer */
1081  if (at_spell && at_spell->clone.type == SPELL)
1082  bp2 = cp+strlen(spell_name)+1;
1083  else
1084  at_spell = NULL;
1085  } else
1086  at_spell = NULL;
1087  }
1088 
1089  /* OK - we didn't find a spell - presume the 'of'
1090  * in this case means its an artifact.
1091  */
1092  if (!at_spell) {
1093  if (find_artifactlist(at->clone.type) == NULL) {
1095  "No artifact list for type %d\n",
1096  at->clone.type);
1097  } else {
1098  auto items = find_artifactlist(at->clone.type)->items;
1099  auto i = std::find_if(items.cbegin(), items.cend(),
1100  [&] (const auto art) { return !strcmp(art->item->name, cp) && legal_artifact_combination(&at->clone, art); });
1101  art = i == items.cend() ? nullptr : *i;
1102 
1103  if (!art) {
1105  "No such artifact ([%d] of %s)",
1106  at->clone.type, cp);
1107  }
1108  }
1109  LOG(llevDebug, "%s creates: (%d) (%d) (%s) of (%s)\n", op->name, set_nrof ? nrof : 0, set_magic ? magic : 0, bp, cp);
1110  }
1111  } /* if cp */
1112 
1113  /* rods and potions can get their spell from the artifact */
1114  if ((at->clone.type == ROD || at->clone.type == POTION) && !at_spell && (!art || !art->item->other_arch)) {
1116  "Unable to find spell %s for object that needs it, or it is of wrong type",
1117  cp);
1118  return;
1119  }
1120  if ((at->clone.type == WAND || at->clone.type == SCROLL || at->clone.type == SPELLBOOK)
1121  && !at_spell) {
1123  "Unable to find spell %s for object that needs it, or it is of wrong type",
1124  cp);
1125  return;
1126  }
1127 
1128  /*
1129  * Rather than have two different blocks with a lot of similar code,
1130  * just create one object, do all the processing, and then determine
1131  * if that one object should be inserted or if we need to make copies.
1132  */
1133  tmp = object_create_arch(at);
1134  if (settings.real_wiz == FALSE)
1135  SET_FLAG(tmp, FLAG_WAS_WIZ);
1136  if (set_magic)
1137  set_abs_magic(tmp, magic);
1138  if (art)
1139  give_artifact_abilities(tmp, art->item);
1140  if (!is_identifiable_type(tmp)) {
1141  SET_FLAG(tmp, FLAG_IDENTIFIED);
1143  }
1144 
1145  /*
1146  * This entire block here tries to find variable pairings,
1147  * eg, 'hp 4' or the like. The mess here is that values
1148  * can be quoted (eg "my cool sword"); So the basic logic
1149  * is we want to find two spaces, but if we got a quote,
1150  * any spaces there don't count.
1151  */
1152  while (*bp2 && bp2 <= endline) {
1153  gotspace = 0;
1154  gotquote = 0;
1155  /* find the first quote */
1156  for (bp3 = bp2; *bp3 && gotspace < 2 && gotquote < 2; bp3++) {
1157  /* Found a quote - now lets find the second one */
1158  if (*bp3 == '"') {
1159  *bp3 = ' ';
1160  bp2 = bp3+1; /* Update start of string */
1161  bp3++;
1162  gotquote++;
1163  while (*bp3) {
1164  if (*bp3 == '"') {
1165  *bp3 = '\0';
1166  gotquote++;
1167  } else
1168  bp3++;
1169  }
1170  } else if (*bp3 == ' ') {
1171  gotspace++;
1172  }
1173  }
1174 
1175  /*
1176  * If we got two spaces, send the second one to null.
1177  * if we've reached the end of the line, increase gotspace -
1178  * this is perfectly valid for the list entry listed.
1179  */
1180  if (gotspace == 2 || gotquote == 2) {
1181  bp3--; /* Undo the extra increment */
1182  *bp3 = '\0';
1183  } else if (*bp3 == '\0')
1184  gotspace++;
1185 
1186  if ((gotquote && gotquote != 2)
1187  || (gotspace != 2 && gotquote != 2)) {
1188  /*
1189  * Unfortunately, we've clobbered lots of values, so printing
1190  * out what we have probably isn't useful. Break out, because
1191  * trying to recover is probably won't get anything useful
1192  * anyways, and we'd be confused about end of line pointers
1193  * anyways.
1194  */
1196  "Malformed create line: %s",
1197  bp2);
1198  break;
1199  }
1200  /* bp2 should still point to the start of this line,
1201  * with bp3 pointing to the end
1202  */
1203  if (set_variable(tmp, bp2) == -1)
1205  "Unknown variable %s",
1206  bp2);
1207  else
1209  "(%s#%d)->%s",
1210  tmp->name, tmp->count, bp2);
1211  bp2 = bp3+1;
1212  }
1213 
1214  if (at->clone.nrof) {
1215  if (at_spell)
1216  object_insert_in_ob(arch_to_object(at_spell), tmp);
1217 
1218  if (set_nrof)
1219  tmp->nrof = nrof;
1220 
1221  if (at->clone.randomitems != NULL && !at_spell) {
1222  create_treasure(at->clone.randomitems, tmp, 0, op->map->difficulty, 0);
1223  if (QUERY_FLAG(tmp, FLAG_MONSTER)) {
1225  }
1226  }
1227 
1228  /* Multipart objects can't be in inventory, put'em on floor. */
1229  if (!tmp->more) {
1230  tmp = object_insert_in_ob(tmp, op);
1231  } else {
1232  object_insert_in_map_at(tmp, op->map, op, 0, op->x, op->y);
1233  }
1234 
1235  /* Let's put this created item on stack so dm can access it easily. */
1236  dm_stack_push(op->contr, tmp->count);
1237 
1238  return;
1239  }
1240 
1241  for (i = 0; i < (set_nrof ? nrof : 1); i++) {
1242  archetype *atmp;
1243  object *prev = NULL, *head = NULL, *dup;
1244 
1245  for (atmp = at; atmp != NULL; atmp = atmp->more) {
1246  dup = arch_to_object(atmp);
1247 
1248  if (at_spell)
1249  object_insert_in_ob(arch_to_object(at_spell), dup);
1250 
1251  /*
1252  * The head is what contains all the important bits,
1253  * so just copying it over should be fine.
1254  */
1255  if (head == NULL) {
1256  head = dup;
1257  object_copy(tmp, dup);
1258  }
1259  if (settings.real_wiz == FALSE)
1260  SET_FLAG(dup, FLAG_WAS_WIZ);
1261  dup->x = op->x+dup->arch->clone.x;
1262  dup->y = op->y+dup->arch->clone.y;
1263  dup->map = op->map;
1264 
1265  if (head != dup) {
1266  dup->head = head;
1267  prev->more = dup;
1268  }
1269  prev = dup;
1270  }
1271 
1272  if (QUERY_FLAG(head, FLAG_ALIVE)) {
1273  object *check = head;
1274  int size_x = 0;
1275  int size_y = 0;
1276 
1277  while (check) {
1278  size_x = MAX(size_x, check->arch->clone.x);
1279  size_y = MAX(size_y, check->arch->clone.y);
1280  check = check->more;
1281  }
1282 
1283  if (out_of_map(op->map, head->x+size_x, head->y+size_y)) {
1284  if (head->x < size_x || head->y < size_y) {
1285  dm_stack_pop(op->contr);
1288  "Object too big to insert in map, or wrong position.");
1290  return;
1291  }
1292 
1293  check = head;
1294  while (check) {
1295  check->x -= size_x;
1296  check->y -= size_y;
1297  check = check->more;
1298  }
1299  }
1300 
1301  object_insert_in_map_at(head, op->map, op, 0, head->x, head->y);
1302  } else
1303  head = object_insert_in_ob(head, op);
1304 
1305  /* Let's put this created item on stack so dm can access it easily. */
1306  /* Wonder if we really want to push all of these, but since
1307  * things like rods have nrof 0, we want to cover those.
1308  */
1309  dm_stack_push(op->contr, head->count);
1310 
1311  if (at->clone.randomitems != NULL && !at_spell) {
1312  create_treasure(at->clone.randomitems, head, 0, op->map->difficulty, 0);
1313  if (QUERY_FLAG(head, FLAG_MONSTER)) {
1315  }
1316  }
1317  }
1318 
1319  /* free the one we used to copy */
1321 }
1322 
1323 /*
1324  * Now follows dm-commands which are also acceptable from sockets
1325  */
1326 
1335 void command_inventory(object *op, const char *params) {
1336  object *tmp;
1337  int i;
1338 
1339  if (*params == '\0') {
1340  inventory(op, NULL);
1341  return;
1342  }
1343 
1344  if (!sscanf(params, "%d", &i) || (tmp = object_find_by_tag_global(i)) == NULL) {
1346  "Inventory of what object (nr)?");
1347  return;
1348  }
1349 
1350  inventory(op, tmp);
1351 }
1352 
1365 void command_skills(object *op, const char *params) {
1366  show_skills(op, *params == '\0' ? NULL : params);
1367 }
1368 
1377 void command_dump(object *op, const char *params) {
1378  object *tmp;
1379  StringBuffer *sb;
1380  char *diff;
1381 
1382  tmp = get_dm_object(op->contr, &params, NULL);
1383  if (!tmp)
1384  return;
1385 
1386  sb = stringbuffer_new();
1387  object_dump(tmp, sb);
1388  diff = stringbuffer_finish(sb);
1390  free(diff);
1391  if (QUERY_FLAG(tmp, FLAG_OBJ_ORIGINAL))
1393  "Object is marked original");
1394 }
1395 
1405 void command_mon_aggr(object *op, const char *params) {
1406  (void)params;
1407  if (op->enemy || !QUERY_FLAG(op, FLAG_UNAGGRESSIVE)) {
1408  object_set_enemy(op, NULL);
1411  "Aggression turned OFF");
1412  } else {
1416  "Aggression turned ON");
1417  }
1418 }
1419 
1427 void command_patch(object *op, const char *params) {
1428  const char *arg, *arg2;
1429  object *tmp;
1430 
1431  tmp = get_dm_object(op->contr, &params, NULL);
1432  if (!tmp)
1433  /* Player already informed of failure */
1434  return;
1435 
1436  /* params set to first value by get_dm_default */
1437  arg = params;
1438  if (*arg == '\0') {
1440  "Patch what values?");
1441  return;
1442  }
1443 
1444  if ((arg2 = strchr(arg, ' ')))
1445  arg2++;
1446  if (settings.real_wiz == FALSE)
1447  SET_FLAG(tmp, FLAG_WAS_WIZ); /* To avoid cheating */
1448  if (set_variable(tmp, arg) == -1)
1450  "Unknown variable %s",
1451  arg);
1452  else {
1454  "(%s#%d)->%s=%s",
1455  tmp->name, tmp->count, arg, arg2);
1456  }
1457 }
1458 
1459 static void reset_faces_sent(struct socket_struct *socket) {
1460  free(socket->faces_sent);
1461  socket->faces_sent = static_cast<uint8_t *>(calloc(sizeof(socket->faces_sent[0]), get_faces_count()));
1462  socket->faces_sent_len = get_faces_count();
1463 }
1464 
1465 void command_recollect(object *op, const char *params) {
1466  (void)op;
1467  (void)params;
1468  load_assets();
1469 
1470  // To prevent negative speeds from sneaking through, we need to finalize the archetypes.
1471  // Negative speeds on monsters are caught and changed to .005-ish, so we need to make
1472  // sure they're right now rather than later.
1474 
1475  // Clear sent faces for connected sockets so that clients see new faces.
1476  for (int i = 0; i < socket_info.allocated_sockets; i++) {
1477  /*
1478  if (init_sockets[i].status == Ns_Add) {
1479  reset_faces_sent(&init_sockets[i]);
1480  }
1481  */
1482  }
1483 
1484  player *next;
1485  for (player *pl = first_player; pl != NULL; pl = next) {
1486  reset_faces_sent(pl->socket);
1487  next = pl->next;
1488  }
1489 }
1490 
1499 void command_remove(object *op, const char *params) {
1500  object *tmp;
1501  int from;
1502 
1503  tmp = get_dm_object(op->contr, &params, &from);
1504  if (!tmp) {
1506  "Remove what object (nr)?");
1507  return;
1508  }
1509 
1510  if (tmp->type == PLAYER) {
1512  "Unable to remove a player!");
1513  return;
1514  }
1515 
1516  if (QUERY_FLAG(tmp, FLAG_REMOVED)) {
1517  char name[MAX_BUF];
1518 
1519  query_name(tmp, name, MAX_BUF);
1521  "%s is already removed!",
1522  name);
1523  return;
1524  }
1525 
1526  if (from != STACK_FROM_STACK)
1527  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1528  dm_stack_pop(op->contr);
1529 
1530  /* Always work on the head - otherwise object will get in odd state */
1531  tmp = HEAD(tmp);
1532  if (tmp->speed != 0) {
1533  tmp->speed = 0;
1534  object_update_speed(tmp);
1535  }
1536  object_remove(tmp);
1537 }
1538 
1546 void command_free(object *op, const char *params) {
1547  object *tmp;
1548  int from;
1549 
1550  tmp = get_dm_object(op->contr, &params, &from);
1551 
1552  if (!tmp) {
1554  "Free what object (nr)?");
1555  return;
1556  }
1557 
1558  if (from != STACK_FROM_STACK)
1559  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1560  dm_stack_pop(op->contr);
1561 
1562  tmp = HEAD(tmp);
1563  if (!QUERY_FLAG(tmp, FLAG_REMOVED)) {
1565  "Warning: item was not removed, will do so now.");
1566  object_remove(tmp);
1567  }
1568 
1570 }
1571 
1572 void command_accountpasswd(object *op, const char *params) {
1573  char account_name[MAX_BUF], newpw[MAX_BUF];
1574  // Password may contain spaces, so use %[^\n] format string.
1575  if (sscanf(params, "%s %[^\n]", account_name, newpw) != 2) {
1577  "Usage: accountpasswd ACCOUNT PASSWORD");
1578  return;
1579  }
1580 
1581  int ret = account_change_password(account_name, NULL, newpw);
1582  switch (ret) {
1583  case 0:
1585  "Updated account password.");
1586  return;
1587  case 1:
1589  "Invalid characters in new password.");
1590  return;
1591  case 2:
1593  "Invalid characters in new password.");
1594  return;
1595  default:
1597  "Error changing password.");
1598  return;
1599  }
1600 }
1601 
1610 void command_addexp(object *op, const char *params) {
1611  char buf[MAX_BUF], skill[MAX_BUF];
1612  int i, q;
1613  object *skillob = NULL;
1614  player *pl;
1615 
1616  skill[0] = '\0';
1617  if ((*params == '\0')
1618  || (strlen(params) > MAX_BUF)
1619  || ((q = sscanf(params, "%s %d %[^\r\n]", buf, &i, skill)) < 2)) {
1621  "Usage: addexp player quantity [skill].");
1622  return;
1623  }
1624 
1625  for (pl = first_player; pl != NULL; pl = pl->next)
1626  if (!strncmp(pl->ob->name, buf, MAX_NAME))
1627  break;
1628 
1629  if (pl == NULL) {
1631  "No such player.");
1632  return;
1633  }
1634 
1635  if (q >= 3) {
1636  skillob = find_skill_by_name(pl->ob, skill);
1637  if (!skillob) {
1639  "Unable to find skill %s in %s",
1640  skill, buf);
1641  return;
1642  }
1643 
1644  i = check_exp_adjust(skillob, i);
1645  skillob->stats.exp += i;
1646  calc_perm_exp(skillob);
1647  player_lvl_adj(pl->ob, skillob);
1648  }
1649 
1650  pl->ob->stats.exp += i;
1651  calc_perm_exp(pl->ob);
1652  player_lvl_adj(pl->ob, NULL);
1653 
1654  if (settings.real_wiz == FALSE)
1655  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1656 }
1657 
1666 void command_speed(object *op, const char *params) {
1667  int i;
1668 
1669  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1671  "Current speed is %d",
1672  tick_duration);
1673  return;
1674  }
1675 
1676  set_tick_duration(i);
1677  reset_sleep();
1679  "The speed is changed to %d.",
1680  i);
1681 }
1682 
1683 /**************************************************************************/
1684 /* Mods made by Tyler Van Gorder, May 10-13, 1992. */
1685 /* CSUChico : tvangod@cscihp.ecst.csuchico.edu */
1686 /**************************************************************************/
1687 
1696 void command_stats(object *op, const char *params) {
1697  player *pl;
1698 
1699  if (*params == '\0') {
1701  "Who?");
1702  return;
1703  }
1704 
1705  pl = find_player_partial_name(params);
1706  if (pl == NULL) {
1708  "No such player.");
1709  return;
1710  }
1711 
1713  "[Fixed]Statistics for %s:", pl->ob->name);
1714 
1716  "[fixed]Str : %-2d H.P. : %-4d MAX : %d",
1717  pl->ob->stats.Str, pl->ob->stats.hp, pl->ob->stats.maxhp);
1718 
1720  "[fixed]Dex : %-2d S.P. : %-4d MAX : %d",
1721  pl->ob->stats.Dex, pl->ob->stats.sp, pl->ob->stats.maxsp);
1722 
1724  "[fixed]Con : %-2d AC : %-4d WC : %d",
1725  pl->ob->stats.Con, pl->ob->stats.ac, pl->ob->stats.wc);
1726 
1728  "[fixed]Int : %-2d Damage : %d",
1729  pl->ob->stats.Int, pl->ob->stats.dam);
1730 
1732  "[fixed]Wis : %-2d EXP : %" FMT64,
1733  pl->ob->stats.Wis, pl->ob->stats.exp);
1734 
1736  "[fixed]Pow : %-2d Grace : %d",
1737  pl->ob->stats.Pow, pl->ob->stats.grace);
1738 
1740  "[fixed]Cha : %-2d Food : %d",
1741  pl->ob->stats.Cha, pl->ob->stats.food);
1742 }
1743 
1753 void command_abil(object *op, const char *params) {
1754  char thing[20], thing2[20];
1755  int iii;
1756  player *pl;
1757 
1758  iii = 0;
1759  thing[0] = '\0';
1760  thing2[0] = '\0';
1761  if (*params == '\0'
1762  || sscanf(params, "%s %s %d", thing, thing2, &iii) != 3
1763  || thing[0] == '\0') {
1765  "Who?");
1766  return;
1767  }
1768 
1769  if (thing2[0] == '\0') {
1771  "You can't change that.");
1772  return;
1773  }
1774 
1775  if (iii < MIN_STAT || iii > settings.max_stat) {
1777  "Illegal range of stat.\n");
1778  return;
1779  }
1780 
1781  for (pl = first_player; pl != NULL; pl = pl->next) {
1782  if (!strcmp(pl->ob->name, thing)) {
1783  if (settings.real_wiz == FALSE)
1784  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1785  if (!strcmp("str", thing2))
1786  pl->ob->stats.Str = iii, pl->orig_stats.Str = iii;
1787  if (!strcmp("dex", thing2))
1788  pl->ob->stats.Dex = iii, pl->orig_stats.Dex = iii;
1789  if (!strcmp("con", thing2))
1790  pl->ob->stats.Con = iii, pl->orig_stats.Con = iii;
1791  if (!strcmp("wis", thing2))
1792  pl->ob->stats.Wis = iii, pl->orig_stats.Wis = iii;
1793  if (!strcmp("cha", thing2))
1794  pl->ob->stats.Cha = iii, pl->orig_stats.Cha = iii;
1795  if (!strcmp("int", thing2))
1796  pl->ob->stats.Int = iii, pl->orig_stats.Int = iii;
1797  if (!strcmp("pow", thing2))
1798  pl->ob->stats.Pow = iii, pl->orig_stats.Pow = iii;
1800  "%s has been altered.",
1801  pl->ob->name);
1802  fix_object(pl->ob);
1803  return;
1804  }
1805  }
1806 
1808  "No such player.");
1809 }
1810 
1819 void command_reset(object *op, const char *params) {
1820  mapstruct *m;
1821  object *dummy = NULL, *tmp = NULL;
1822  char path[HUGE_BUF];
1823  const char *space, *confirmation = NULL;
1824  int res = 0;
1825 
1826  if (*params == '\0') {
1828  MSG_TYPE_COMMAND_ERROR, "Which map should be reset?");
1829  return;
1830  }
1831 
1832  space = strchr(params, ' ');
1833  if (space != NULL) {
1834  confirmation = params;
1835  params = space + 1;
1836  }
1837 
1838  /* Use the DM's map if the current map was given. */
1839  if (strcmp(params, ".") == 0) {
1840  strlcpy(path, op->map->path, sizeof(path));
1841  } else {
1842  path_combine_and_normalize(op->map->path, params, path, sizeof(path));
1843  }
1844 
1845  m = has_been_loaded(path);
1846  if (m == NULL) {
1848  MSG_TYPE_COMMAND_ERROR, "No such map.");
1849  return;
1850  }
1851 
1852  if (confirmation) {
1853  if (m->unique && (op->map == m)) {
1856  "Cannot reset a unique player map while on it. Use "
1857  "'reset full-reset %s' while standing somewhere else.",
1858  m->path);
1859  return;
1860  }
1861 
1862  if (strncmp("full-reset", confirmation, strlen("full-reset"))) {
1864  MSG_TYPE_COMMAND_ERROR, "Confirm using 'full-reset'.");
1865  return;
1866  }
1867  }
1868 
1869  /* Forbid using reset on our own map when we're in a transport, as
1870  * it has the displeasant effect of crashing the server.
1871  * - gros, July 25th 2006 */
1872  if ((op->contr && op->contr->transport) && (op->map == m)) {
1874  "You need to disembark first.");
1875  return;
1876  }
1877 
1878  strlcpy(path, m->path, sizeof(path));
1879 
1880  sstring reset_group = m->reset_group;
1881  m->reset_group = NULL;
1882 
1883  if (m->in_memory != MAP_SWAPPED) {
1884  if (m->in_memory != MAP_IN_MEMORY) {
1885  LOG(llevError, "Tried to swap out map which was not in memory.\n");
1886  m->reset_group = reset_group;
1887  return;
1888  }
1889 
1890  /*
1891  * Only attempt to remove the player that is doing the reset, and not other
1892  * players or wiz's.
1893  */
1894  if (op->map == m) {
1895  if (strncmp(m->path, "/random/", 8) == 0) {
1896  /* This is not a very satisfying solution - it would be much better
1897  * to recreate a random map with the same seed value as the old one.
1898  * Unfortunately, I think recreating the map would require some
1899  * knowledge about its 'parent', which appears very non-trivial to
1900  * me.
1901  * On the other hand, this should prevent the freeze that this
1902  * situation caused. - gros, 26th July 2006.
1903  */
1905  "You cannot reset a random map when inside it.");
1906  m->reset_group = reset_group;
1907  return;
1908  }
1909 
1910  dummy = object_new();
1911  dummy->map = NULL;
1912  EXIT_X(dummy) = op->x;
1913  EXIT_Y(dummy) = op->y;
1914  EXIT_PATH(dummy) = add_string(op->map->path);
1915  object_remove(op);
1916  op->map = NULL;
1917  tmp = op;
1918  }
1919  res = swap_map(m);
1920  }
1921 
1922  if (res < 0 || m->in_memory != MAP_SWAPPED) {
1923  player *pl;
1924  int playercount = 0;
1925 
1926  /* Need to re-insert player if swap failed for some reason */
1927  if (tmp) {
1928  object_insert_in_map_at(op, m, NULL, 0, op->x, op->y);
1930  }
1931 
1932  if (res < 0 && res != SAVE_ERROR_PLAYER) {
1933  /* no need to warn if player on map, code below checks that. */
1935  "Reset failed, error code: %d.", res);
1936  /* If we somehow (AFAIK this is only possible by DM intervention anyway) get
1937  * on a non-uniquely-loaded unique map (such as by a DM using goto onto a
1938  * unique map template or by creating an exit to a unique map template
1939  * without specifying in that exit that the map is unique), we need to re-insert
1940  * the player without calling enter_exit(), since we trip an assertion failure there.
1941  * If we reach here and tmp is defined, we have already re-inserted the player,
1942  * so we just need to bail.
1943  * -- Neila Hawkins 2023-12-13
1944  */
1945  if (res == SAVE_ERROR_UCREATION) {
1946  m->reset_group = reset_group;
1947  return;
1948  }
1949  }
1950  else {
1952  "Reset failed, couldn't swap map, the following players are on it:");
1953  for (pl = first_player; pl != NULL; pl = pl->next) {
1954  if (pl->ob->map == m && pl->ob != op) {
1956  pl->ob->name);
1957  playercount++;
1958  }
1959  }
1960  if (!playercount)
1962  "hmm, I don't see any other players on this map, something else is the problem.");
1963  m->reset_group = reset_group;
1964  return;
1965  }
1966  }
1967 
1968  FREE_AND_CLEAR_STR_IF(reset_group);
1969 
1970  /* Here, map reset succeeded. */
1971 
1972  if (m && m->in_memory == MAP_SWAPPED) {
1973  if (confirmation) {
1975  LOG(llevDebug, "DM %s fully resetting map %s.\n", op->name, m->path);
1976  } else
1977  LOG(llevDebug, "DM %s resetting map %s.\n", op->name, m->path);
1978 
1979  /* setting this effectively causes an immediate reload */
1980  m->reset_time = 1;
1981  flush_old_maps();
1982  }
1983 
1984  /* Display the appropriate success message. */
1985  if (confirmation) {
1987  MSG_TYPE_COMMAND_DM, "Fully resetting map %s.", path);
1988  } else {
1990  MSG_TYPE_COMMAND_DM, "Resetting map %s.", path);
1991  }
1992 
1993  if (tmp) {
1994  enter_exit(tmp, dummy);
1996  }
1997 
1998  /* Remind the DM how to fully reset the map. */
1999  if (confirmation == NULL) {
2002  "Use 'reset full-reset %s' to fully reset the map.", params);
2003  }
2004 }
2005 
2014 void command_nowiz(object *op, const char *params) { /* 'noadm' is alias */
2015  (void)params;
2016  CLEAR_FLAG(op, FLAG_WIZ);
2017  CLEAR_FLAG(op, FLAG_WIZPASS);
2018  CLEAR_FLAG(op, FLAG_WIZCAST);
2019 
2020  if (settings.real_wiz == TRUE)
2021  CLEAR_FLAG(op, FLAG_WAS_WIZ);
2022  if (op->contr->hidden) {
2023  unhide(op);
2024  } else
2026  "The Dungeon Master is gone...");
2027 
2028  update_los(op);
2029 }
2030 
2051 static int checkdm(object *op, const char *pl_name, const char *pl_passwd, const char *pl_host) {
2052  FILE *dmfile;
2053  char buf[MAX_BUF];
2054  char line_buf[160], name[160], passwd[160], host[160];
2055 
2056 #ifdef RESTRICTIVE_DM
2057  *pl_name = op->name ? op->name : "*";
2058 #else
2059  (void)op;
2060 #endif
2061 
2062  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, DMFILE);
2063  if ((dmfile = fopen(buf, "r")) == NULL) {
2064  LOG(llevDebug, "Could not find DM file.\n");
2065  return 0;
2066  }
2067 
2068  while (fgets(line_buf, 160, dmfile) != NULL) {
2069  // Skip empty lines as well as commented ones.
2070  if (line_buf[0] == '#' || line_buf[0] == '\n')
2071  continue;
2072  if (sscanf(line_buf, "%[^:]:%[^:]:%s\n", name, passwd, host) != 3) {
2073  LOG(llevError, "Warning - malformed dm file entry: %s\n", line_buf);
2074  } else if ((!strcmp(name, "*") || (pl_name && !strcmp(pl_name, name)))
2075  && (!strcmp(passwd, "*") || !strcmp(passwd, pl_passwd))
2076  && (!strcmp(host, "*") || !strcmp(host, pl_host))) {
2077  fclose(dmfile);
2078  return (1);
2079  }
2080  }
2081  fclose(dmfile);
2082  return (0);
2083 }
2084 
2099 static int do_wizard_dm(object *op, const char *params, int silent) {
2100  if (!op->contr)
2101  return 0;
2102 
2103  if (QUERY_FLAG(op, FLAG_WIZ)) {
2105  "You are already the Dungeon Master!");
2106  return 0;
2107  }
2108 
2109  if (checkdm(op, op->name, (*params != '\0' ? params : "*"), op->contr->socket->host)) {
2110  SET_FLAG(op, FLAG_WIZ);
2111  SET_FLAG(op, FLAG_WAS_WIZ);
2112  SET_FLAG(op, FLAG_WIZPASS);
2113  SET_FLAG(op, FLAG_WIZCAST);
2115  "Ok, you are the Dungeon Master!");
2116  /*
2117  * Remove setting flying here - that won't work, because next
2118  * fix_object() is called that will get cleared - proper solution
2119  * is probably something like a wiz_force which gives that and any
2120  * other desired abilities.
2121  */
2122  clear_los(op->contr);
2123 
2124  if (!silent)
2127  "The Dungeon Master has arrived!");
2128 
2129  return 1;
2130  }
2131 
2133  "Sorry Pal, I don't think so.");
2134  return 0;
2135 }
2136 
2148 void command_dm(object *op, const char *params) {
2149  do_wizard_dm(op, params, 0);
2150 }
2151 
2160 void command_invisible(object *op, const char *params) {
2161  (void)params;
2162  if (op) {
2163  op->invisible += 100;
2166  "You turn invisible.");
2167  }
2168 }
2169 
2187 static object *get_spell_by_name(object *op, const char *spell_name) {
2188  archetype *found;
2189  int conflict_found;
2190  size_t spell_name_length;
2191 
2192  /* First check for full name matches. */
2193  conflict_found = 0;
2194  found = NULL;
2195  getManager()->archetypes()->each([&] (auto ar) {
2196  if (ar->clone.type != SPELL)
2197  return;
2198 
2199  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2200  return;
2201 
2202  if (strcmp(ar->clone.name, spell_name) != 0)
2203  return;
2204 
2205  if (found != NULL) {
2206  if (!conflict_found) {
2207  conflict_found = 1;
2209  "More than one archetype matches the spell name %s:",
2210  spell_name);
2212  "- %s",
2213  found->name);
2214  }
2216  "- %s",
2217  ar->name);
2218  return;
2219  }
2220 
2221  found = ar;
2222  });
2223 
2224  /* No match if more more than one archetype matches. */
2225  if (conflict_found)
2226  return NULL;
2227 
2228  /* Return if exactly one archetype matches. */
2229  if (found != NULL)
2230  return arch_to_object(found);
2231 
2232  /* No full match found: now check for partial matches. */
2233  spell_name_length = strlen(spell_name);
2234  conflict_found = 0;
2235  found = NULL;
2236 
2237  getManager()->archetypes()->each([&] (auto ar) {
2238  if (ar->clone.type != SPELL)
2239  return;
2240 
2241  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2242  return;
2243 
2244  if (strncmp(ar->clone.name, spell_name, spell_name_length) != 0)
2245  return;
2246 
2247  if (found != NULL) {
2248  if (!conflict_found) {
2249  conflict_found = 1;
2251  "More than one spell matches %s:",
2252  spell_name);
2254  "- %s",
2255  found->clone.name);
2256  }
2258  "- %s",
2259  ar->clone.name);
2260  return;
2261  }
2262 
2263  found = ar;
2264  });
2265 
2266  /* No match if more more than one archetype matches. */
2267  if (conflict_found)
2268  return NULL;
2269 
2270  /* Return if exactly one archetype matches. */
2271  if (found != NULL)
2272  return arch_to_object(found);
2273 
2274  /* No spell found: just print an error message. */
2276  "The spell %s does not exist.",
2277  spell_name);
2278  return NULL;
2279 }
2280 
2291 static void command_learn_spell_or_prayer(object *op, const char *params, int special_prayer) {
2292  object *tmp;
2293 
2294  if (op->contr == NULL || *params == '\0') {
2296  "Which spell do you want to learn?");
2297  return;
2298  }
2299 
2300  tmp = get_spell_by_name(op, params);
2301  if (tmp == NULL) {
2302  return;
2303  }
2304 
2305  if (check_spell_known(op, tmp->name)) {
2307  "You already know the spell %s.",
2308  tmp->name);
2309  return;
2310  }
2311 
2312  do_learn_spell(op, tmp, special_prayer);
2314 }
2315 
2324 void command_learn_spell(object *op, const char *params) {
2325  command_learn_spell_or_prayer(op, params, 0);
2326 }
2327 
2336 void command_learn_special_prayer(object *op, const char *params) {
2337  command_learn_spell_or_prayer(op, params, 1);
2338 }
2339 
2349 void command_forget_spell(object *op, const char *params) {
2350  object *spell;
2351 
2352  if (op->contr == NULL || *params == '\0') {
2354  "Which spell do you want to forget?");
2355  return;
2356  }
2357 
2358  spell = lookup_spell_by_name(op, params);
2359  if (spell == NULL) {
2361  "You do not know the spell %s.",
2362  params);
2363  return;
2364  }
2365 
2366  do_forget_spell(op, spell->name);
2367 }
2368 
2377 void command_listplugins(object *op, const char *params) {
2378  (void)params;
2380 }
2381 
2392 void command_loadplugin(object *op, const char *params) {
2393  char buf[MAX_BUF];
2394 
2395  if (*params == '\0') {
2397  "Load which plugin?");
2398  return;
2399  }
2400 
2401  snprintf(buf, sizeof(buf), LIBDIR"/plugins/%s", params);
2402  LOG(llevDebug, "Requested plugin file is %s\n", buf);
2403  if (plugins_init_plugin(buf) == 0) {
2404  LOG(llevInfo, "DM %s loaded plugin %s\n", op->name, params);
2406  "Plugin %s successfully loaded.",
2407  params);
2408  } else
2410  "Could not load plugin %s.",
2411  params);
2412 }
2413 
2424 void command_unloadplugin(object *op, const char *params) {
2425  if (*params == '\0') {
2427  "Remove which plugin?");
2428  return;
2429  }
2430 
2431  if (plugins_remove_plugin(params) == 0) {
2432  LOG(llevInfo, "DM %s unloaded plugin %s\n", op->name, params);
2434  "Plugin %s successfully removed.",
2435  params);
2436  init_signals(); // Restore our signal handlers, some plugins (Python) mess with them
2437  } else
2439  "Could not remove plugin %s.",
2440  params);
2441 }
2442 
2453 void command_dmhide(object *op, const char *params) {
2454  if (!do_wizard_dm(op, params, 1))
2455  return;
2456 
2457  do_wizard_hide(op, 1);
2458 }
2459 
2468 void command_stack_pop(object *op, const char *params) {
2469  (void)params;
2470  dm_stack_pop(op->contr);
2471 }
2472 
2481 void command_stack_push(object *op, const char *params) {
2482  object *ob;
2483  int from;
2484  ob = get_dm_object(op->contr, &params, &from);
2485 
2486  if (ob && from != STACK_FROM_NUMBER)
2487  /* Object was from stack, need to push it again */
2488  dm_stack_push(op->contr, ob->count);
2489 }
2490 
2499 void command_stack_list(object *op, const char *params) {
2500  int item;
2501  object *display;
2502  player *pl = op->contr;
2503  (void)params;
2504 
2506  "Item stack contents:");
2507 
2508  for (item = 0; item < pl->stack_position; item++) {
2509  display = object_find_by_tag_global(pl->stack_items[item]);
2510  if (display)
2512  " %d : %s [%d]",
2513  item, display->name, display->count);
2514  else
2515  /* Item was freed */
2517  " %d : (lost item: %d)",
2518  item, pl->stack_items[item]);
2519  }
2520 }
2521 
2530 void command_stack_clear(object *op, const char *params) {
2531  (void)params;
2532  op->contr->stack_position = 0;
2534  "Item stack cleared.");
2535 }
2536 
2556 void command_diff(object *op, const char *params) {
2557  object *left, *right;
2558  char *diff;
2559  StringBuffer *sb;
2560  int left_from, right_from;
2561 
2562  left = get_dm_object(op->contr, &params, &left_from);
2563  if (!left) {
2565  "Compare to what item?");
2566  return;
2567  }
2568 
2569  if (left_from == STACK_FROM_NUMBER)
2570  /* Item was stacked, remove it else right will be the same... */
2571  dm_stack_pop(op->contr);
2572 
2573  right = get_dm_object(op->contr, &params, &right_from);
2574 
2575  if (!right) {
2577  "Compare what item?");
2578  return;
2579  }
2580 
2582  "Item difference:");
2583 
2584  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2585  /*
2586  * Special case: both items were taken from stack top.
2587  * Override the behaviour, taking left as item just below top, if exists.
2588  * See function description for why.
2589  * Besides, if we don't do anything, compare an item to itself, not really useful.
2590  */
2591  if (op->contr->stack_position > 1) {
2593  if (left)
2595  "(Note: first item taken from undertop)");
2596  else
2597  /* Stupid case: item under top was freed, fallback to stack top */
2598  left = right;
2599  }
2600  }
2601 
2602  sb = stringbuffer_new();
2603  get_ob_diff(sb, left, right);
2604  diff = stringbuffer_finish(sb);
2605  if (*diff == '\0') {
2606  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DM, "Objects are the same.");
2607  } else {
2609  }
2610  free(diff);
2611 }
2612 
2620 void command_insert_into(object *op, const char *params) {
2621  object *left, *right, *inserted;
2622  int left_from, right_from;
2623  char what[MAX_BUF], where[MAX_BUF];
2624 
2625  left = get_dm_object(op->contr, &params, &left_from);
2626  if (!left) {
2628  "Insert into what object?");
2629  return;
2630  }
2631 
2632  if (left_from == STACK_FROM_NUMBER)
2633  /* Item was stacked, remove it else right will be the same... */
2634  dm_stack_pop(op->contr);
2635 
2636  right = get_dm_object(op->contr, &params, &right_from);
2637 
2638  if (!right) {
2640  "Insert what item?");
2641  return;
2642  }
2643 
2644  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2645  /*
2646  * Special case: both items were taken from stack top.
2647  * Override the behaviour, taking left as item just below top, if exists.
2648  * See function description for why.
2649  * Besides, can't insert an item into itself.
2650  */
2651  if (op->contr->stack_position > 1) {
2653  if (left)
2655  "(Note: item to insert into taken from undertop)");
2656  else
2657  /* Stupid case: item under top was freed, fallback to stack top */
2658  left = right;
2659  }
2660  }
2661 
2662  if (left == right) {
2664  "Can't insert an object into itself!");
2665  return;
2666  }
2667 
2668  if (right->type == PLAYER) {
2670  "Can't insert a player into something!");
2671  return;
2672  }
2673 
2674  if (!QUERY_FLAG(right, FLAG_REMOVED))
2675  object_remove(right);
2676  inserted = object_insert_in_ob(right, left);
2677  if (left->type == PLAYER) {
2678  if (inserted != right)
2679  /* item was merged, so updating name and such. */
2680  esrv_update_item(UPD_WEIGHT|UPD_NAME|UPD_NROF, left, inserted);
2681  }
2682  query_name(inserted, what, MAX_BUF);
2683  query_name(left, where, MAX_BUF);
2685  "Inserted %s in %s",
2686  what, where);
2687 }
2688 
2697 void command_style_map_info(object *op, const char *params) {
2698  extern mapstruct *styles;
2699  mapstruct *mp;
2700  int maps_used = 0, mapmem = 0, objects_used = 0, x, y;
2701  (void)params;
2702 
2703  for (mp = styles; mp != NULL; mp = mp->next) {
2704  maps_used++;
2705  mapmem += map_size(mp) * (sizeof(object *)+sizeof(MapSpace))+sizeof(mapstruct);
2706  for (x = 0; x < MAP_WIDTH(mp); x++) {
2707  for (y = 0; y < MAP_HEIGHT(mp); y++) {
2708  FOR_MAP_PREPARE(mp, x, y, tmp)
2709  objects_used++;
2710  FOR_MAP_FINISH();
2711  }
2712  }
2713  }
2715  "[fixed]Style maps loaded: %d",
2716  maps_used);
2718  "[fixed]Memory used, not");
2720  "[fixed]including objects: %d",
2721  mapmem);
2723  "[fixed]Style objects: %d",
2724  objects_used);
2726  "[fixed]Mem for objects: %lu",
2727  (unsigned long)(objects_used*sizeof(object)));
2728 }
2729 
2730 bool can_follow(object* op, player* other) {
2731  // Only allow follow from same party.
2732  return (other->ob->contr->party != NULL) && (op->contr->party == other->ob->contr->party);
2733 }
2734 
2743 void command_follow(object *op, const char *params) {
2744  player *other;
2745 
2746  if (*params == '\0') {
2747  if (op->contr->followed_player != NULL) {
2750  }
2751  return;
2752  }
2753 
2754  other = find_player_partial_name(params);
2755  if (!other) {
2756  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "No such player or ambiguous name.");
2757  return;
2758  }
2759  if (other == op->contr) {
2760  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "You can't follow yourself.");
2761  return;
2762  }
2763 
2764  // Players trying to 'follow' are subject to additional checks.
2765  if (!QUERY_FLAG(op, FLAG_WIZ)) {
2766  if (!can_follow(op, other)) {
2769  "You can only follow members in the same party.");
2770  return;
2771  }
2772  rv_vector rv;
2773  if (!get_rangevector(op, other->ob, &rv, 0) || rv.distance > 1) {
2774  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "You need to go to them first!");
2775  return;
2776  }
2778  }
2779 
2780  if (op->contr->followed_player)
2782 
2783  op->contr->followed_player = add_string(other->ob->name);
2785 }
2786 
2787 void command_purge_quest(object *op, const char * param) {
2788  (void)param;
2789  free_quest();
2790  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Purged quest state.");
2791 }
2792 
2793 void command_purge_quest_definitions(object *op, const char * param) {
2794  (void)param;
2796  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Purged quests definitions.");
2797 }
2798 
2799 void do_dump(object *who, object *what) {
2800  StringBuffer *sb;
2801  char *diff;
2802 
2803  sb = stringbuffer_new();
2804  object_dump(what, sb);
2805  diff = stringbuffer_finish(sb);
2807  free(diff);
2808 
2809  /* Let's push that item on the dm's stack */
2810  dm_stack_push(who->contr, what->count);
2811 }
2812 
2821 void command_dumpbelow(object *op, const char *params) {
2822  (void)params;
2823  if (op && op->below) {
2824  do_dump(op, op->below);
2825  }
2826 }
2827 
2836 void command_dumpabove(object *op, const char *params) {
2837  (void)params;
2838  if (op && op->above) {
2839  do_dump(op, op->above);
2840  }
2841 }
2842 
2848 void command_settings(object *op, const char *ignored) {
2849  (void)ignored;
2850  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Server settings:");
2851 
2853 
2854  if (settings.not_permadeth) {
2855  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * death is not permanent");
2856  } else if (settings.resurrection) {
2857  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * permanent death, resurrection is enabled");
2858  } else {
2859  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * permanent death, resurrection is NOT enabled");
2860  }
2861 
2862  if (settings.set_title) {
2863  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can set their title");
2864  } else {
2865  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't set their title");
2866  }
2867 
2870  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * too much equipment can lead to spell failure and ill effects");
2871  } else {
2872  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * too much equipment can lead to spell failure but no ill effects");
2873  }
2874  } else {
2875  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * too much equipment can't lead to spell failure");
2876  }
2877 
2878  if (settings.casting_time) {
2879  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * casting takes time");
2880  } else {
2881  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * casting is immediate");
2882  }
2883 
2886 
2888 
2890  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't steal from other players");
2891  } else {
2892  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can steal from other players");
2893  }
2894 
2896  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can create portals from their apartments");
2897  } else {
2898  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't create portals from their apartments");
2899  }
2900 
2902  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can write spells they are denied");
2903  } else {
2904  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't write spells they are denied");
2905  }
2906 }
Settings::casting_time
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:275
get_other_player_from_name
static player * get_other_player_from_name(object *op, const char *name)
Enough of the DM functions seem to need this that I broke it out to a separate function.
Definition: c_wiz.cpp:60
command_overlay_reset
void command_overlay_reset(object *op, const char *params)
Removes the overlay for op's current map.
Definition: c_wiz.cpp:589
STACK_FROM_NONE
@ STACK_FROM_NONE
Item was not found.
Definition: c_wiz.cpp:38
living::exp
int64_t exp
Experience.
Definition: living.h:47
player::stack_items
tag_t * stack_items
Item stack for patch/dump/...
Definition: player.h:219
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:108
set_magic
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Sets a random magical bonus in the given object based upon the given difficulty, and the given max po...
Definition: treasure.cpp:693
FREE_AND_CLEAR_STR_IF
#define FREE_AND_CLEAR_STR_IF(xyz)
Definition: global.h:206
global.h
first_player
player * first_player
First player.
Definition: init.cpp:106
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
set_abs_magic
void set_abs_magic(object *op, int magic)
Sets magical bonus in an object, and recalculates the effect on the armour variable,...
Definition: treasure.cpp:645
STACK_SIZE
#define STACK_SIZE
Stack size, static.
Definition: c_wiz.cpp:35
safe_strncpy
#define safe_strncpy
Definition: compat.h:27
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
Definition: define.h:714
STACK_FROM_NUMBER
@ STACK_FROM_NUMBER
Item is a number (may be top)
Definition: c_wiz.cpp:41
living::maxhp
int16_t maxhp
Max hit points.
Definition: living.h:41
command_overlay_save
void command_overlay_save(object *op, const char *params)
Saves the op's map as an overlay - objects are persisted.
Definition: c_wiz.cpp:568
MSG_TYPE_COMMAND_SUCCESS
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:534
command_style_map_info
void command_style_map_info(object *op, const char *params)
Displays information about styles loaded for random maps.
Definition: c_wiz.cpp:2697
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:338
WAND
@ WAND
Definition: object.h:225
MSG_TYPE_ADMIN_PLAYER
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
Definition: newclient.h:500
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:82
SHUTDOWN_IDLE
@ SHUTDOWN_IDLE
Definition: commands.h:44
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:369
reset_faces_sent
static void reset_faces_sent(struct socket_struct *socket)
Definition: c_wiz.cpp:1459
archetype::more
archetype * more
Next part of a linked object.
Definition: object.h:486
command_patch
void command_patch(object *op, const char *params)
Wizard wants to altar an object.
Definition: c_wiz.cpp:1427
player
One player.
Definition: player.h:107
Settings::resurrection
uint8_t resurrection
Ressurection possible w/ permadeth on.
Definition: global.h:271
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:371
plugins_remove_plugin
int plugins_remove_plugin(const char *id)
Unload the specified plugin.
Definition: plugins.cpp:455
plugins_init_plugin
int plugins_init_plugin(const char *libfile)
Try to load the specified plugin.
Definition: plugins.cpp:374
Settings::set_title
uint8_t set_title
Players can set thier title.
Definition: global.h:270
AssetsManager.h
do_learn_spell
void do_learn_spell(object *op, object *spell, int special_prayer)
Actually makes op learn spell.
Definition: apply.cpp:146
command_shutdown
void command_shutdown(object *op, const char *params)
Totally shutdowns the server.
Definition: c_wiz.cpp:658
has_been_loaded
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.cpp:79
socket_struct
Socket structure, represents a client-server connection.
Definition: newserver.h:93
Socket_Info::allocated_sockets
int allocated_sockets
Number of allocated items in init_sockets.
Definition: newserver.h:149
flush_old_maps
void flush_old_maps(void)
Reset maps that need to, remove their swap file.
Definition: swap.cpp:291
FALSE
#define FALSE
Definition: compat.h:14
Settings::not_permadeth
uint8_t not_permadeth
If true, death is non-permament.
Definition: global.h:267
command_speed
void command_speed(object *op, const char *params)
Changes the server speed.
Definition: c_wiz.cpp:1666
Settings::permanent_exp_ratio
uint8_t permanent_exp_ratio
How much exp should be 'permenant' and unable to be lost.
Definition: global.h:263
do_wizard_dm
static int do_wizard_dm(object *op, const char *params, int silent)
Actually changes a player to wizard.
Definition: c_wiz.cpp:2099
command_learn_spell
void command_learn_spell(object *op, const char *params)
Wizard wants to learn a regular spell.
Definition: c_wiz.cpp:2324
Settings::datadir
const char * datadir
Read only data files.
Definition: global.h:253
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:233
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
Definition: stringbuffer.cpp:57
mapstruct::players
int16_t players
How many players are on this level right now.
Definition: map.h:339
UPD_WEIGHT
#define UPD_WEIGHT
Definition: newclient.h:320
player::no_shout
uint32_t no_shout
if True, player is *not *able to use shout command.
Definition: player.h:150
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
if
if(!(yy_init))
Definition: loader.cpp:36440
object_set_enemy
void object_set_enemy(object *op, object *enemy)
Sets the enemy of an object.
Definition: object.cpp:900
artifactlist::items
std::vector< artifact * > items
Artifacts for this type.
Definition: artifact.h:28
object::invisible
int16_t invisible
How much longer the object will be invis.
Definition: object.h:370
dm_stack_pop
static void dm_stack_pop(player *pl)
Remove an item from the wizard's item stack.
Definition: c_wiz.cpp:95
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:424
living::Dex
int8_t Dex
Definition: living.h:36
object::x
int16_t x
Definition: object.h:335
player::ob
object * ob
The object representing the player.
Definition: player.h:179
player::transport
object * transport
Transport the player is in.
Definition: player.h:216
object::speed_left
float speed_left
How much speed is left to spend this round.
Definition: object.h:338
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Fixes the given object, giving it the abilities and titles it should have due to the second artifact-...
Definition: artifact.cpp:230
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Map is fully loaded.
Definition: map.h:131
socket_info
Socket_Info socket_info
Socket information.
Definition: init.cpp:52
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
command_arrest
void command_arrest(object *op, const char *params)
Wizard jails player.
Definition: c_wiz.cpp:821
Settings::worldmaptilesy
uint32_t worldmaptilesy
Number of tiles high the worldmap is.
Definition: global.h:299
command_teleport
void command_teleport(object *op, const char *params)
Teleport next to target player.
Definition: c_wiz.cpp:933
command_mon_aggr
void command_mon_aggr(object *op, const char *params)
When DM is possessing a monster, flip aggression on and off, to allow better motion.
Definition: c_wiz.cpp:1405
artifact::item
object * item
Special values of the artifact.
Definition: artifact.h:15
dm_stack_push
static void dm_stack_push(player *pl, tag_t item)
Push specified item on player stack.
Definition: c_wiz.cpp:150
check_exp_adjust
int64_t check_exp_adjust(const object *op, int64_t exp)
Returns the maximum experience the object can gain or lose.
Definition: living.cpp:2102
Settings::worldmapstartx
uint32_t worldmapstartx
Starting x tile for the worldmap.
Definition: global.h:296
time
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long time
Definition: arch-handbook.txt:206
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_purge_quest
void command_purge_quest(object *op, const char *param)
Definition: c_wiz.cpp:2787
calc_perm_exp
void calc_perm_exp(object *op)
Ensure that the permanent experience requirements in an exp object are met.
Definition: living.cpp:1914
FLAG_WIZ
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:218
unhide
static void unhide(object *op)
Definition: c_wiz.cpp:333
do_dump
void do_dump(object *who, object *what)
Definition: c_wiz.cpp:2799
object::count
tag_t count
Unique object number for this object.
Definition: object.h:307
object_copy
void object_copy(const object *src_ob, object *dest_ob)
Copy object first frees everything allocated by the second object, and then copies the contents of th...
Definition: object.cpp:1177
command_invisible
void command_invisible(object *op, const char *params)
Wizard wants to become invisible.
Definition: c_wiz.cpp:2160
ST_PLAYING
#define ST_PLAYING
Usual state.
Definition: define.h:525
fix_object
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.cpp:1132
command_banish
void command_banish(object *op, const char *params)
Add player's IP to ban_file and kick them off the server.
Definition: c_wiz.cpp:502
NDI_RED
#define NDI_RED
Definition: newclient.h:249
player::hidden
uint32_t hidden
If True, player (DM) is hidden from view.
Definition: player.h:149
UPD_NROF
#define UPD_NROF
Definition: newclient.h:325
object::enemy
object * enemy
Monster/player to follow even if not closest.
Definition: object.h:391
plugins_display_list
void plugins_display_list(object *op)
Displays a list of loaded plugins (keystrings and description) in the game log window.
Definition: plugins.cpp:480
command_addexp
void command_addexp(object *op, const char *params)
This adds exp to a player.
Definition: c_wiz.cpp:1610
command_listplugins
void command_listplugins(object *op, const char *params)
Lists all plugins currently loaded with their IDs and full names.
Definition: c_wiz.cpp:2377
skills.h
MSG_TYPE_COMMAND_ERROR
#define MSG_TYPE_COMMAND_ERROR
Bad syntax/can't use command.
Definition: newclient.h:533
object_find_by_tag_global
object * object_find_by_tag_global(tag_t i)
Returns the object which has the count-variable equal to the argument.
Definition: object.cpp:712
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:361
buf
StringBuffer * buf
Definition: readable.cpp:1564
EVENT_KICK
#define EVENT_KICK
A player was Kicked by a DM
Definition: events.h:56
set_tick_duration
void set_tick_duration(long t)
Sets the tick duration.
Definition: time.cpp:209
getManager
AssetsManager * getManager()
Definition: assets.cpp:309
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.cpp:2842
object::above
object * above
Pointer to the object stacked above this one.
Definition: object.h:296
HUGE_BUF
#define HUGE_BUF
Used for messages - some can be quite long.
Definition: define.h:37
MAX
#define MAX(x, y)
Definition: compat.h:24
MSG_TYPE_COMMAND
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:408
SAVE_ERROR_PLAYER
#define SAVE_ERROR_PLAYER
Player on map to save.
Definition: map.h:153
find_god
const object * find_god(const char *name)
Returns a god's object from its name.
Definition: holy.cpp:317
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
NDI_ORANGE
#define NDI_ORANGE
Definition: newclient.h:250
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:219
Settings::worldmaptilesx
uint32_t worldmaptilesx
Number of tiles wide the worldmap is.
Definition: global.h:298
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
command_learn_special_prayer
void command_learn_special_prayer(object *op, const char *params)
Wizard wants to learn a god-given spell.
Definition: c_wiz.cpp:2336
Ns_Dead
@ Ns_Dead
Definition: newserver.h:71
command_remove
void command_remove(object *op, const char *params)
Remove an object from its position.
Definition: c_wiz.cpp:1499
map_remove_unique_files
void map_remove_unique_files(const mapstruct *map)
Remove files containing the map's unique items.
Definition: map.cpp:2677
MSG_TYPE_ADMIN_DM
#define MSG_TYPE_ADMIN_DM
DM related admin actions.
Definition: newclient.h:501
MSG_TYPE_COMMAND_DEBUG
#define MSG_TYPE_COMMAND_DEBUG
Various debug type commands.
Definition: newclient.h:532
ASSETS_QUESTS
#define ASSETS_QUESTS
Definition: assets.h:30
Settings::spell_encumbrance
uint8_t spell_encumbrance
Encumbrance effects spells.
Definition: global.h:273
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:217
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:424
clear_los
void clear_los(player *pl)
Clears/initialises the los-array associated to the player controlling the object.
Definition: los.cpp:270
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.cpp:76
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1545
object_update
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.cpp:1419
shutdown_s::time
time_t time
When using SHUTDOWN_TIME, time of shutdown.
Definition: commands.h:49
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
FMT64
#define FMT64
Definition: compat.h:16
command_toggle_shout
void command_toggle_shout(object *op, const char *params)
A simple toggle for the no_shout field.
Definition: c_wiz.cpp:615
map_size
uint32_t map_size(mapstruct *m)
Calculate map size without intermediate sign extension.
Definition: map.cpp:816
command_setgod
void command_setgod(object *op, const char *params)
Sets the god for some objects.
Definition: c_wiz.cpp:418
freearr_y
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.cpp:305
command_create
void command_create(object *op, const char *params)
Wizard wants to create an object.
Definition: c_wiz.cpp:999
Settings::death_penalty_ratio
uint8_t death_penalty_ratio
Hhow much exp should be lost at death.
Definition: global.h:264
command_reset
void command_reset(object *op, const char *params)
Resets a map.
Definition: c_wiz.cpp:1819
do_wizard_hide
static void do_wizard_hide(object *op, int silent_dm)
Actually hides or unhides specified player (obviously a DM).
Definition: c_wiz.cpp:352
query_name
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.cpp:593
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
POTION
@ POTION
Definition: object.h:116
command_summon
void command_summon(object *op, const char *params)
Summons player near DM.
Definition: c_wiz.cpp:866
Settings::set_friendly_fire
uint16_t set_friendly_fire
Percent of damage done by peaceful player vs player damage.
Definition: global.h:280
player::followed_player
sstring followed_player
Player the DM is following.
Definition: player.h:220
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Combines the 2 paths.
Definition: path.cpp:172
MSG_TYPE_COMMAND_DM
#define MSG_TYPE_COMMAND_DM
DM related commands.
Definition: newclient.h:539
command_purge_quest_definitions
void command_purge_quest_definitions(object *op, const char *param)
Definition: c_wiz.cpp:2793
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
STACK_FROM_TOP
@ STACK_FROM_TOP
Item is stack top.
Definition: c_wiz.cpp:39
object_dump
void object_dump(const object *op, StringBuffer *sb)
Dumps an object.
Definition: object.cpp:630
Settings::worldmapstarty
uint32_t worldmapstarty
Starting y tile for the worldmap.
Definition: global.h:297
add_string
sstring add_string(const char *str)
Share a string.
Definition: shstr.cpp:137
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:232
HEAD
#define HEAD(op)
Returns the head part of an object.
Definition: object.h:607
ROD
@ ROD
Definition: object.h:114
free_quest
void free_quest(void)
Free all quest status structures.
Definition: quest.cpp:895
shutdown_s::type
enum shutdown_type type
Definition: commands.h:48
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Monster doesn't attack players.
Definition: define.h:259
object::below
object * below
Pointer to the object stacked below this one.
Definition: object.h:295
command_dm
void command_dm(object *op, const char *params)
Actual command to perhaps become dm.
Definition: c_wiz.cpp:2148
out_of_map
int out_of_map(mapstruct *m, int x, int y)
Return 1 if coordinates X and Y are out of the map M, taking into account tiling.
Definition: map.cpp:2332
socket_struct::host
char * host
Which host it is connected from (ip address).
Definition: newserver.h:104
shutdown_s
Definition: commands.h:47
command_abil
void command_abil(object *op, const char *params)
Changes an object's statistics.
Definition: c_wiz.cpp:1753
lookup_spell_by_name
object * lookup_spell_by_name(object *op, const char *spname)
Look at object 'op' and see if they know the spell spname.
Definition: spell_util.cpp:410
command_dumpbelow
void command_dumpbelow(object *op, const char *params)
Player wants to dump object below her.
Definition: c_wiz.cpp:2821
command_diff
void command_diff(object *op, const char *params)
Get a diff of specified items.
Definition: c_wiz.cpp:2556
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1334
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
command_inventory
void command_inventory(object *op, const char *params)
Shows the inventory or some item.
Definition: c_wiz.cpp:1335
do_goto
void do_goto(object *op, const char *name, int x, int y)
Definition: c_move.cpp:151
living::dam
int16_t dam
How much damage this object does when hitting.
Definition: living.h:46
command_swap
void command_swap(object *op, const char *params)
Mark a map as ready for swapping.
Definition: c_wiz.cpp:907
command_help
void command_help(object *op, const char *params)
Player is asking for some help.
Definition: c_misc.cpp:1772
shutdown_state
struct shutdown_s shutdown_state
Definition: c_wiz.cpp:44
show_skills
void show_skills(object *op, const char *search)
Displays a player's skill list, and some other non skill related info (god, max weapon improvements,...
Definition: skill_util.cpp:884
SAVE_MODE_OVERLAY
#define SAVE_MODE_OVERLAY
Map is persisted as an overlay.
Definition: map.h:123
command_skills
void command_skills(object *op, const char *params)
Player is asking for her skills.
Definition: c_wiz.cpp:1365
object_create_arch
object * object_create_arch(archetype *at)
Create a full object using the given archetype.
Definition: arch.cpp:296
SAVE_ERROR_UCREATION
#define SAVE_ERROR_UCREATION
Couldn't create the file for unique objects.
Definition: map.h:146
spell
with a maximum of six This is not so if you are wearing plate you receive no benefit Armour is additive with all the supplementry forms of which means that it lasts until the next semi permanent spell effect is cast upon the character spell
Definition: tome-of-magic.txt:44
player_lvl_adj
void player_lvl_adj(object *who, object *op)
For the new exp system.
Definition: living.cpp:1830
object_free
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects,...
Definition: object.cpp:1577
command_dumpabove
void command_dumpabove(object *op, const char *params)
Player wants to dump object above her.
Definition: c_wiz.cpp:2836
Settings::item_power_factor
float item_power_factor
See note in setings file.
Definition: global.h:306
MAX_NAME
#define MAX_NAME
Definition: define.h:41
DMFILE
#define DMFILE
File containing valid names that can be dm, one on each line.
Definition: config.h:369
command_insert_into
void command_insert_into(object *op, const char *params)
Puts an object into another.
Definition: c_wiz.cpp:2620
living::food
int32_t food
How much food in stomach.
Definition: living.h:48
assets_finish_archetypes_for_play
void assets_finish_archetypes_for_play()
Definition: assets.cpp:513
tag_t
uint32_t tag_t
Object tag, unique during the whole game.
Definition: object.h:14
archetype
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:483
Settings::confdir
const char * confdir
Configuration files.
Definition: global.h:252
sproto.h
living::sp
int16_t sp
Spell points.
Definition: living.h:42
AssetsCollection::each
void each(std::function< void(T *)> op)
Apply a function to each asset.
Definition: AssetsCollection.h:158
MapSpace
This structure contains all information related to one map square.
Definition: map.h:261
living::Int
int8_t Int
Definition: living.h:36
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:424
become_follower
int become_follower(object *op, const object *new_god)
This function is called whenever a player has switched to a new god.
Definition: gods.cpp:414
command_goto
void command_goto(object *op, const char *params)
Wizard teleports to a map.
Definition: c_wiz.cpp:724
init_signals
void init_signals()
Setup our signal handlers.
Definition: init.cpp:1368
Settings::death_penalty_level
uint8_t death_penalty_level
How many levels worth of exp may be lost on one death.
Definition: global.h:265
SHUTDOWN_NONE
@ SHUTDOWN_NONE
Definition: commands.h:42
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.cpp:2085
object::other_arch
struct archetype * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:425
find_skill_by_name
object * find_skill_by_name(object *who, const char *name)
This returns the skill pointer of the given name (the one that accumulates exp, has the level,...
Definition: skill_util.cpp:209
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:76
command_kick
void command_kick(object *op, const char *params)
Kicks a player from the server.
Definition: c_wiz.cpp:556
command_loadtest
void command_loadtest(object *op, const char *params)
This command will stress server.
Definition: c_wiz.cpp:306
AssetsManager::archetypes
Archetypes * archetypes()
Get archetypes.
Definition: AssetsManager.h:44
treasure.h
EXIT_X
#define EXIT_X(xyz)
Definition: define.h:426
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
strlcpy
size_t strlcpy(char *dst, const char *src, size_t size)
Portable implementation of strlcpy(3).
Definition: porting.cpp:222
object_new
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it.
Definition: object.cpp:1258
create_overlay_pathname
void create_overlay_pathname(const char *name, char *buf, size_t size)
Same as create_pathname(), but for the overlay maps.
Definition: map.cpp:125
player::orig_stats
living orig_stats
Permanent real stats of player.
Definition: player.h:169
monster_check_apply_all
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.cpp:2001
command_hide
void command_hide(object *op, const char *params)
Wizard 'hide' command.
Definition: c_wiz.cpp:389
living::wc
int8_t wc
Weapon Class, lower WC increases probability of hitting.
Definition: living.h:37
StringBuffer
A buffer that will be expanded as content is added to it.
Definition: stringbuffer.cpp:25
FREE_AND_CLEAR_STR
#define FREE_AND_CLEAR_STR(xyz)
Release the shared string, and set it to NULL.
Definition: global.h:204
command_freeze
void command_freeze(object *op, const char *params)
Freezes a player for a specified tick count, 100 by default.
Definition: c_wiz.cpp:745
Settings::spell_failure_effects
uint8_t spell_failure_effects
Nasty backlash to spell failures.
Definition: global.h:274
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
MSG_TYPE_COMMAND_FAILURE
#define MSG_TYPE_COMMAND_FAILURE
Failed result from command.
Definition: newclient.h:535
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
Definition: define.h:707
living::Wis
int8_t Wis
Definition: living.h:36
command_forget_spell
void command_forget_spell(object *op, const char *params)
Command for players to forget a spell.
Definition: c_wiz.cpp:2349
Settings::allow_denied_spells_writing
int allow_denied_spells_writing
If set, players can write spells they can't cast.
Definition: global.h:318
command_nowiz
void command_nowiz(object *op, const char *params)
Steps down from wizard mode.
Definition: c_wiz.cpp:2014
styles
mapstruct * styles
Loaded styles maps cache, to avoid having to load all the time.
Definition: style.cpp:122
swap_map
int swap_map(mapstruct *map)
Swaps a map to disk.
Definition: swap.cpp:136
command_loadplugin
void command_loadplugin(object *op, const char *params)
Loads the given plugin.
Definition: c_wiz.cpp:2392
llevInfo
@ llevInfo
Information.
Definition: logger.h:14
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:266
find_archetype_by_object_name
archetype * find_archetype_by_object_name(const char *name)
This function retrieves an archetype given the name that appears during the game (for example,...
Definition: arch.cpp:51
spells.h
get_jail_exit
object * get_jail_exit(object *op)
Returns an object which is an exit through which the player represented by op should be sent in order...
Definition: region.cpp:252
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
command_learn_spell_or_prayer
static void command_learn_spell_or_prayer(object *op, const char *params, int special_prayer)
Wizards wants to learn a spell.
Definition: c_wiz.cpp:2291
BANISHFILE
#define BANISHFILE
Definition: config.h:520
get_spell_by_name
static object * get_spell_by_name(object *op, const char *spell_name)
Returns spell object (from archetypes) by name.
Definition: c_wiz.cpp:2187
living::maxsp
int16_t maxsp
Max spell points.
Definition: living.h:43
can_follow
bool can_follow(object *op, player *other)
Definition: c_wiz.cpp:2730
is_identifiable_type
int is_identifiable_type(const object *op)
Return true if this item's type is one that cares about whether or not it's been identified – e....
Definition: item.cpp:1331
mapstruct
This is a game-map.
Definition: map.h:320
enter_exit
void enter_exit(object *op, object *exit_ob)
Tries to move 'op' to exit_ob.
Definition: server.cpp:727
object_find_by_name_global
object * object_find_by_name_global(const char *str)
Finds an object by name.
Definition: object.cpp:732
check_spell_known
object * check_spell_known(object *op, const char *name)
Checks to see if player knows the spell.
Definition: spell_util.cpp:394
find_object_both
static object * find_object_both(const char *params)
This finds and returns the object which matches the name or object number (specified via num #whateve...
Definition: c_wiz.cpp:403
SHUTDOWN_TIME
@ SHUTDOWN_TIME
Definition: commands.h:43
sstring
const typedef char * sstring
Definition: sstring.h:2
command_settings
void command_settings(object *op, const char *ignored)
Wizard wants to know some server settings, so display.
Definition: c_wiz.cpp:2848
living::Cha
int8_t Cha
Definition: living.h:36
NDI_ALL
#define NDI_ALL
Inform all players of this message.
Definition: newclient.h:267
socket_struct::status
enum Sock_Status status
Definition: newserver.h:94
set_variable
int set_variable(object *op, const char *buf)
This takes a buffer, scans it for variables, and sets those variables as appropriate in op.
Definition: loader.cpp:39060
command_stats
void command_stats(object *op, const char *params)
Displays the statistics of a player.
Definition: c_wiz.cpp:1696
player::state
uint8_t state
Input state of the player (name, password, etc).
Definition: player.h:133
command_dump
void command_dump(object *op, const char *params)
Dumps the difference between an object and its archetype.
Definition: c_wiz.cpp:1377
object_find_free_spot
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
object_find_free_spot(object, map, x, y, start, stop) will search for a spot at the given map and coo...
Definition: object.cpp:3544
command_dmhide
void command_dmhide(object *op, const char *params)
A players wants to become DM and hide.
Definition: c_wiz.cpp:2453
MAP_SWAPPED
#define MAP_SWAPPED
Map spaces have been saved to disk.
Definition: map.h:132
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.cpp:361
command_unloadplugin
void command_unloadplugin(object *op, const char *params)
Unloads the given plugin.
Definition: c_wiz.cpp:2424
Settings::max_stat
uint8_t max_stat
Maximum stat value - 255 should be sufficient.
Definition: global.h:327
rv_vector
This is used by get_rangevector to determine where the other creature is.
Definition: map.h:376
reset_sleep
void reset_sleep(void)
Initialise all variables used in the timing routines.
Definition: time.cpp:134
EXIT_Y
#define EXIT_Y(xyz)
Definition: define.h:427
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:370
player_arrest
int player_arrest(object *who)
Put a player into jail, taking into account cursed exits and player's region.
Definition: c_wiz.cpp:789
socket_struct::faces_sent_len
size_t faces_sent_len
This is the number of elements allocated in faces_sent[].
Definition: newserver.h:99
command_follow
void command_follow(object *op, const char *params)
Follow a player, or stop following a player.
Definition: c_wiz.cpp:2743
get_dm_object
static object * get_dm_object(player *pl, const char **params, int *from)
Checks 'params' for object code.
Definition: c_wiz.cpp:196
MAP_HEIGHT
#define MAP_HEIGHT(m)
Map height.
Definition: map.h:78
living::ac
int8_t ac
Armor Class, lower AC increases probability of not getting hit.
Definition: living.h:38
tick_duration
uint32_t tick_duration
Gloabal variables:
Definition: time.cpp:35
NDI_DK_ORANGE
#define NDI_DK_ORANGE
DarkOrange2.
Definition: newclient.h:252
get_ob_diff
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Returns a pointer to a static string which contains all variables which are different in the two give...
Definition: object.cpp:4971
find_player_partial_name
player * find_player_partial_name(const char *plname)
Find a player by a partial name.
Definition: player.cpp:114
account_change_password
int account_change_password(const char *account_name, const char *current_password, const char *new_password)
Change an account password.
Definition: account.cpp:627
socket_struct::faces_sent
uint8_t * faces_sent
This is a bitmap on sent face status.
Definition: newserver.h:100
arch_to_object
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
Definition: arch.cpp:227
object_give_identified_properties
void object_give_identified_properties(object *op)
Ensure op has all its "identified" properties set.
Definition: item.cpp:1363
stats
Player Stats effect how well a character can survie and interact inside the crossfire world This section discusses the various stats
Definition: stats.txt:2
UP_OBJ_FACE
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:533
get_rangevector
int get_rangevector(object *op1, const object *op2, rv_vector *retval, int flags)
From map.c This is used by get_player to determine where the other creature is.
Definition: map.cpp:2531
player::party
partylist * party
Party this player is part of.
Definition: player.h:205
checkdm
static int checkdm(object *op, const char *pl_name, const char *pl_passwd, const char *pl_host)
object *op is trying to become dm.
Definition: c_wiz.cpp:2051
MSG_TYPE_COMMAND_MAPS
#define MSG_TYPE_COMMAND_MAPS
Definition: newclient.h:524
player::count
uint32_t count
Any numbers typed before a command.
Definition: player.h:124
FLAG_WIZCAST
#define FLAG_WIZCAST
The wizard can cast spells in no-magic area.
Definition: define.h:276
UPD_NAME
#define UPD_NAME
Definition: newclient.h:322
command_accountpasswd
void command_accountpasswd(object *op, const char *params)
Definition: c_wiz.cpp:1572
object::randomitems
struct treasurelist * randomitems
Items to be generated.
Definition: object.h:395
Settings::real_wiz
uint8_t real_wiz
Use mud-like wizards.
Definition: global.h:276
FLAG_OBJ_ORIGINAL
#define FLAG_OBJ_ORIGINAL
NEVER SET THIS.
Definition: define.h:344
MSG_TYPE_COMMUNICATION_PARTY
#define MSG_TYPE_COMMUNICATION_PARTY
Party message.
Definition: newclient.h:631
skill
skill
Definition: arch-handbook.txt:585
object_remove
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to.
Definition: object.cpp:1818
try_find_archetype
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:274
inventory
void inventory(object *op, object *inv)
Prints object's inventory.
Definition: c_object.cpp:2117
do_forget_spell
void do_forget_spell(object *op, const char *spell)
Erases spell from player's inventory.
Definition: apply.cpp:187
command_kick2
static void command_kick2(object *op, const char *params)
Kicks a player from the server.
Definition: c_wiz.cpp:468
EVENT_MUZZLE
#define EVENT_MUZZLE
A player was Muzzled (no_shout set).
Definition: events.h:65
STACK_FROM_STACK
@ STACK_FROM_STACK
Item is somewhere in stack.
Definition: c_wiz.cpp:40
save_map
int save_map(mapstruct *m, int flag)
Saves a map to file.
Definition: map.cpp:1412
SCROLL
@ SCROLL
Definition: object.h:226
shutdown_s::next_warn
int next_warn
Definition: commands.h:51
object::nrof
uint32_t nrof
Number of objects.
Definition: object.h:342
player::stack_position
int stack_position
Current stack position, 0 for no item.
Definition: player.h:221
command_stack_push
void command_stack_push(object *op, const char *params)
Push specified item on stack.
Definition: c_wiz.cpp:2481
FLAG_WAS_WIZ
#define FLAG_WAS_WIZ
Player was once a wiz.
Definition: define.h:221
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:109
mapstruct::next
mapstruct * next
Next map, linked list.
Definition: map.h:321
assets_collect
void assets_collect(const char *datadir, int what)
Collect all assets from the specified directory and all its subdirectories.
Definition: assets.cpp:113
Settings::no_player_stealing
uint8_t no_player_stealing
If 1, can not steal from other players.
Definition: global.h:313
living::grace
int16_t grace
Grace.
Definition: living.h:44
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
artifact
This is one artifact, ie one special item.
Definition: artifact.h:14
command_free
void command_free(object *op, const char *params)
Totally free an object.
Definition: c_wiz.cpp:1546
object::more
object * more
Pointer to the rest of a large body of objects.
Definition: object.h:303
MSG_TYPE_COMMUNICATION
#define MSG_TYPE_COMMUNICATION
Communication between players.
Definition: newclient.h:414
load_assets
void load_assets(void)
Definition: assets.cpp:551
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Item is identifiable (e.g.
Definition: define.h:248
update_los
void update_los(object *op)
Recalculates the array which specifies what is visible for the given player-object.
Definition: los.cpp:509
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:297
freearr_x
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.cpp:299
TRUE
#define TRUE
Definition: compat.h:11
command_recollect
void command_recollect(object *op, const char *params)
Definition: c_wiz.cpp:1465
command_stack_pop
void command_stack_pop(object *op, const char *params)
Pop the stack top.
Definition: c_wiz.cpp:2468
SPELL
@ SPELL
Definition: object.h:219
living::Pow
int8_t Pow
Definition: living.h:36
Settings::create_home_portals
uint8_t create_home_portals
If 1, can create portals in unique maps (apartments)
Definition: global.h:314
FLAG_WIZPASS
#define FLAG_WIZPASS
The wizard can go through walls.
Definition: define.h:301
find_artifactlist
artifactlist * find_artifactlist(int type)
Finds the artifact list for a certain item type.
Definition: artifact.cpp:570
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:406
rv_vector::distance
unsigned int distance
Distance, in squares.
Definition: map.h:377
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
living::hp
int16_t hp
Hit Points.
Definition: living.h:40
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
Definition: treasure.cpp:290
dm_stack_peek
static object * dm_stack_peek(player *pl)
Get current stack top item for player.
Definition: c_wiz.cpp:120
NDI_LT_GREEN
#define NDI_LT_GREEN
DarkSeaGreen, which is actually paler than seagreen - also background color.
Definition: newclient.h:254
events_execute_global_event
void events_execute_global_event(int eventcode,...)
Execute a global event.
Definition: events.cpp:30
llevDebug
@ llevDebug
Only for debugging purposes.
Definition: logger.h:15
living::Con
int8_t Con
Definition: living.h:36
command_stack_clear
void command_stack_clear(object *op, const char *params)
Empty DM item stack.
Definition: c_wiz.cpp:2530
living::Str
int8_t Str
Definition: living.h:36
command_stack_list
void command_stack_list(object *op, const char *params)
Displays stack contents.
Definition: c_wiz.cpp:2499
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:254