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));
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 
1432 void command_possess(object *op, const char *params) {
1433  object *victim;
1434  player *pl;
1435  int i;
1436  char buf[MAX_BUF];
1437 
1438  victim = NULL;
1439  if (*params != '\0') {
1440  if (sscanf(params, "%d", &i))
1441  victim = object_find_by_tag_global(i);
1442  else if (sscanf(params, "%s", buf))
1443  victim = object_find_by_name_global(buf);
1444  }
1445  if (victim == NULL) {
1447  "Patch what object (nr)?");
1448  return;
1449  }
1450 
1451  if (victim == op) {
1453  "As insane as you are, I cannot allow you to possess yourself.");
1454  return;
1455  }
1456 
1457  /* make the switch */
1458  pl = op->contr;
1459  victim->contr = pl;
1460  pl->ob = victim;
1461  victim->type = PLAYER;
1462  SET_FLAG(victim, FLAG_WIZ);
1463 
1464  /* basic patchup */
1465  /* The use of hard coded values is terrible. Note
1466  * that really, to be fair, this shouldn't get changed at
1467  * all - if you are possessing a kobold, you should have the
1468  * same limitations. As it is, as more body locations are added,
1469  * this will give this player more locations than perhaps
1470  * they should be allowed.
1471  */
1472  for (i = 0; i < NUM_BODY_LOCATIONS; i++)
1473  if (i == 1 || i == 6 || i == 8 || i == 9)
1474  victim->body_info[i] = 2;
1475  else
1476  victim->body_info[i] = 1;
1477 
1478  esrv_new_player(pl, 80); /* just pick a weight, we don't care */
1479  esrv_send_inventory(victim, victim);
1480 
1481  fix_object(victim);
1482 
1483  do_some_living(victim);
1484 }
1485 
1493 void command_patch(object *op, const char *params) {
1494  const char *arg, *arg2;
1495  object *tmp;
1496 
1497  tmp = get_dm_object(op->contr, &params, NULL);
1498  if (!tmp)
1499  /* Player already informed of failure */
1500  return;
1501 
1502  /* params set to first value by get_dm_default */
1503  arg = params;
1504  if (*arg == '\0') {
1506  "Patch what values?");
1507  return;
1508  }
1509 
1510  if ((arg2 = strchr(arg, ' ')))
1511  arg2++;
1512  if (settings.real_wiz == FALSE)
1513  SET_FLAG(tmp, FLAG_WAS_WIZ); /* To avoid cheating */
1514  if (set_variable(tmp, arg) == -1)
1516  "Unknown variable %s",
1517  arg);
1518  else {
1520  "(%s#%d)->%s=%s",
1521  tmp->name, tmp->count, arg, arg2);
1522  }
1523 }
1524 
1525 static void reset_faces_sent(struct socket_struct *socket) {
1526  free(socket->faces_sent);
1527  socket->faces_sent = static_cast<uint8_t *>(calloc(sizeof(socket->faces_sent[0]), get_faces_count()));
1528  socket->faces_sent_len = get_faces_count();
1529 }
1530 
1531 void command_recollect(object *op, const char *params) {
1532  (void)op;
1533  (void)params;
1534  load_assets();
1535 
1536  // To prevent negative speeds from sneaking through, we need to finalize the archetypes.
1537  // Negative speeds on monsters are caught and changed to .005-ish, so we need to make
1538  // sure they're right now rather than later.
1540 
1541  // Clear sent faces for connected sockets so that clients see new faces.
1542  for (int i = 0; i < socket_info.allocated_sockets; i++) {
1543  /*
1544  if (init_sockets[i].status == Ns_Add) {
1545  reset_faces_sent(&init_sockets[i]);
1546  }
1547  */
1548  }
1549 
1550  player *next;
1551  for (player *pl = first_player; pl != NULL; pl = next) {
1552  reset_faces_sent(pl->socket);
1553  next = pl->next;
1554  }
1555 }
1556 
1565 void command_remove(object *op, const char *params) {
1566  object *tmp;
1567  int from;
1568 
1569  tmp = get_dm_object(op->contr, &params, &from);
1570  if (!tmp) {
1572  "Remove what object (nr)?");
1573  return;
1574  }
1575 
1576  if (tmp->type == PLAYER) {
1578  "Unable to remove a player!");
1579  return;
1580  }
1581 
1582  if (QUERY_FLAG(tmp, FLAG_REMOVED)) {
1583  char name[MAX_BUF];
1584 
1585  query_name(tmp, name, MAX_BUF);
1587  "%s is already removed!",
1588  name);
1589  return;
1590  }
1591 
1592  if (from != STACK_FROM_STACK)
1593  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1594  dm_stack_pop(op->contr);
1595 
1596  /* Always work on the head - otherwise object will get in odd state */
1597  tmp = HEAD(tmp);
1598  if (tmp->speed != 0) {
1599  tmp->speed = 0;
1600  object_update_speed(tmp);
1601  }
1602  object_remove(tmp);
1603 }
1604 
1612 void command_free(object *op, const char *params) {
1613  object *tmp;
1614  int from;
1615 
1616  tmp = get_dm_object(op->contr, &params, &from);
1617 
1618  if (!tmp) {
1620  "Free what object (nr)?");
1621  return;
1622  }
1623 
1624  if (from != STACK_FROM_STACK)
1625  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1626  dm_stack_pop(op->contr);
1627 
1628  tmp = HEAD(tmp);
1629  if (!QUERY_FLAG(tmp, FLAG_REMOVED)) {
1631  "Warning: item was not removed, will do so now.");
1632  object_remove(tmp);
1633  }
1634 
1636 }
1637 
1638 void command_accountpasswd(object *op, const char *params) {
1639  char account_name[MAX_BUF], newpw[MAX_BUF];
1640  // Password may contain spaces, so use %[^\n] format string.
1641  if (sscanf(params, "%s %[^\n]", account_name, newpw) != 2) {
1643  "Usage: accountpasswd ACCOUNT PASSWORD");
1644  return;
1645  }
1646 
1647  int ret = account_change_password(account_name, NULL, newpw);
1648  switch (ret) {
1649  case 0:
1651  "Updated account password.");
1652  return;
1653  case 1:
1655  "Invalid characters in new password.");
1656  return;
1657  case 2:
1659  "Invalid characters in new password.");
1660  return;
1661  default:
1663  "Error changing password.");
1664  return;
1665  }
1666 }
1667 
1676 void command_addexp(object *op, const char *params) {
1677  char buf[MAX_BUF], skill[MAX_BUF];
1678  int i, q;
1679  object *skillob = NULL;
1680  player *pl;
1681 
1682  skill[0] = '\0';
1683  if ((*params == '\0')
1684  || (strlen(params) > MAX_BUF)
1685  || ((q = sscanf(params, "%s %d %[^\r\n]", buf, &i, skill)) < 2)) {
1687  "Usage: addexp player quantity [skill].");
1688  return;
1689  }
1690 
1691  for (pl = first_player; pl != NULL; pl = pl->next)
1692  if (!strncmp(pl->ob->name, buf, MAX_NAME))
1693  break;
1694 
1695  if (pl == NULL) {
1697  "No such player.");
1698  return;
1699  }
1700 
1701  if (q >= 3) {
1702  skillob = find_skill_by_name(pl->ob, skill);
1703  if (!skillob) {
1705  "Unable to find skill %s in %s",
1706  skill, buf);
1707  return;
1708  }
1709 
1710  i = check_exp_adjust(skillob, i);
1711  skillob->stats.exp += i;
1712  calc_perm_exp(skillob);
1713  player_lvl_adj(pl->ob, skillob);
1714  }
1715 
1716  pl->ob->stats.exp += i;
1717  calc_perm_exp(pl->ob);
1718  player_lvl_adj(pl->ob, NULL);
1719 
1720  if (settings.real_wiz == FALSE)
1721  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1722 }
1723 
1732 void command_speed(object *op, const char *params) {
1733  int i;
1734 
1735  if (*params == '\0' || !sscanf(params, "%d", &i)) {
1737  "Current speed is %d",
1738  tick_duration);
1739  return;
1740  }
1741 
1742  set_tick_duration(i);
1743  reset_sleep();
1745  "The speed is changed to %d.",
1746  i);
1747 }
1748 
1749 /**************************************************************************/
1750 /* Mods made by Tyler Van Gorder, May 10-13, 1992. */
1751 /* CSUChico : tvangod@cscihp.ecst.csuchico.edu */
1752 /**************************************************************************/
1753 
1762 void command_stats(object *op, const char *params) {
1763  player *pl;
1764 
1765  if (*params == '\0') {
1767  "Who?");
1768  return;
1769  }
1770 
1771  pl = find_player_partial_name(params);
1772  if (pl == NULL) {
1774  "No such player.");
1775  return;
1776  }
1777 
1779  "[Fixed]Statistics for %s:", pl->ob->name);
1780 
1782  "[fixed]Str : %-2d H.P. : %-4d MAX : %d",
1783  pl->ob->stats.Str, pl->ob->stats.hp, pl->ob->stats.maxhp);
1784 
1786  "[fixed]Dex : %-2d S.P. : %-4d MAX : %d",
1787  pl->ob->stats.Dex, pl->ob->stats.sp, pl->ob->stats.maxsp);
1788 
1790  "[fixed]Con : %-2d AC : %-4d WC : %d",
1791  pl->ob->stats.Con, pl->ob->stats.ac, pl->ob->stats.wc);
1792 
1794  "[fixed]Int : %-2d Damage : %d",
1795  pl->ob->stats.Int, pl->ob->stats.dam);
1796 
1798  "[fixed]Wis : %-2d EXP : %" FMT64,
1799  pl->ob->stats.Wis, pl->ob->stats.exp);
1800 
1802  "[fixed]Pow : %-2d Grace : %d",
1803  pl->ob->stats.Pow, pl->ob->stats.grace);
1804 
1806  "[fixed]Cha : %-2d Food : %d",
1807  pl->ob->stats.Cha, pl->ob->stats.food);
1808 }
1809 
1819 void command_abil(object *op, const char *params) {
1820  char thing[20], thing2[20];
1821  int iii;
1822  player *pl;
1823 
1824  iii = 0;
1825  thing[0] = '\0';
1826  thing2[0] = '\0';
1827  if (*params == '\0'
1828  || sscanf(params, "%s %s %d", thing, thing2, &iii) != 3
1829  || thing[0] == '\0') {
1831  "Who?");
1832  return;
1833  }
1834 
1835  if (thing2[0] == '\0') {
1837  "You can't change that.");
1838  return;
1839  }
1840 
1841  if (iii < MIN_STAT || iii > settings.max_stat) {
1843  "Illegal range of stat.\n");
1844  return;
1845  }
1846 
1847  for (pl = first_player; pl != NULL; pl = pl->next) {
1848  if (!strcmp(pl->ob->name, thing)) {
1849  if (settings.real_wiz == FALSE)
1850  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1851  if (!strcmp("str", thing2))
1852  pl->ob->stats.Str = iii, pl->orig_stats.Str = iii;
1853  if (!strcmp("dex", thing2))
1854  pl->ob->stats.Dex = iii, pl->orig_stats.Dex = iii;
1855  if (!strcmp("con", thing2))
1856  pl->ob->stats.Con = iii, pl->orig_stats.Con = iii;
1857  if (!strcmp("wis", thing2))
1858  pl->ob->stats.Wis = iii, pl->orig_stats.Wis = iii;
1859  if (!strcmp("cha", thing2))
1860  pl->ob->stats.Cha = iii, pl->orig_stats.Cha = iii;
1861  if (!strcmp("int", thing2))
1862  pl->ob->stats.Int = iii, pl->orig_stats.Int = iii;
1863  if (!strcmp("pow", thing2))
1864  pl->ob->stats.Pow = iii, pl->orig_stats.Pow = iii;
1866  "%s has been altered.",
1867  pl->ob->name);
1868  fix_object(pl->ob);
1869  return;
1870  }
1871  }
1872 
1874  "No such player.");
1875 }
1876 
1885 void command_reset(object *op, const char *params) {
1886  mapstruct *m;
1887  object *dummy = NULL, *tmp = NULL;
1888  char path[HUGE_BUF];
1889  const char *space, *confirmation = NULL;
1890  int res = 0;
1891 
1892  if (*params == '\0') {
1894  MSG_TYPE_COMMAND_ERROR, "Which map should be reset?");
1895  return;
1896  }
1897 
1898  space = strchr(params, ' ');
1899  if (space != NULL) {
1900  confirmation = params;
1901  params = space + 1;
1902  }
1903 
1904  /* Use the DM's map if the current map was given. */
1905  if (strcmp(params, ".") == 0) {
1906  strlcpy(path, op->map->path, sizeof(path));
1907  } else {
1908  path_combine_and_normalize(op->map->path, params, path, sizeof(path));
1909  }
1910 
1911  m = has_been_loaded(path);
1912  if (m == NULL) {
1914  MSG_TYPE_COMMAND_ERROR, "No such map.");
1915  return;
1916  }
1917 
1918  if (confirmation) {
1919  if (m->unique && (op->map == m)) {
1922  "Cannot reset a unique player map while on it. Use "
1923  "'reset full-reset %s' while standing somewhere else.",
1924  m->path);
1925  return;
1926  }
1927 
1928  if (strncmp("full-reset", confirmation, strlen("full-reset"))) {
1930  MSG_TYPE_COMMAND_ERROR, "Confirm using 'full-reset'.");
1931  return;
1932  }
1933  }
1934 
1935  /* Forbid using reset on our own map when we're in a transport, as
1936  * it has the displeasant effect of crashing the server.
1937  * - gros, July 25th 2006 */
1938  if ((op->contr && op->contr->transport) && (op->map == m)) {
1940  "You need to disembark first.");
1941  return;
1942  }
1943 
1944  strlcpy(path, m->path, sizeof(path));
1945 
1946  sstring reset_group = m->reset_group;
1947  m->reset_group = NULL;
1948 
1949  if (m->in_memory != MAP_SWAPPED) {
1950  if (m->in_memory != MAP_IN_MEMORY) {
1951  LOG(llevError, "Tried to swap out map which was not in memory.\n");
1952  m->reset_group = reset_group;
1953  return;
1954  }
1955 
1956  /*
1957  * Only attempt to remove the player that is doing the reset, and not other
1958  * players or wiz's.
1959  */
1960  if (op->map == m) {
1961  if (strncmp(m->path, "/random/", 8) == 0) {
1962  /* This is not a very satisfying solution - it would be much better
1963  * to recreate a random map with the same seed value as the old one.
1964  * Unfortunately, I think recreating the map would require some
1965  * knowledge about its 'parent', which appears very non-trivial to
1966  * me.
1967  * On the other hand, this should prevent the freeze that this
1968  * situation caused. - gros, 26th July 2006.
1969  */
1971  "You cannot reset a random map when inside it.");
1972  m->reset_group = reset_group;
1973  return;
1974  }
1975 
1976  dummy = object_new();
1977  dummy->map = NULL;
1978  EXIT_X(dummy) = op->x;
1979  EXIT_Y(dummy) = op->y;
1980  EXIT_PATH(dummy) = add_string(op->map->path);
1981  object_remove(op);
1982  op->map = NULL;
1983  tmp = op;
1984  }
1985  res = swap_map(m);
1986  }
1987 
1988  if (res < 0 || m->in_memory != MAP_SWAPPED) {
1989  player *pl;
1990  int playercount = 0;
1991 
1992  /* Need to re-insert player if swap failed for some reason */
1993  if (tmp) {
1994  object_insert_in_map_at(op, m, NULL, 0, op->x, op->y);
1996  }
1997 
1998  if (res < 0 && res != SAVE_ERROR_PLAYER) {
1999  /* no need to warn if player on map, code below checks that. */
2001  "Reset failed, error code: %d.", res);
2002  /* If we somehow (AFAIK this is only possible by DM intervention anyway) get
2003  * on a non-uniquely-loaded unique map (such as by a DM using goto onto a
2004  * unique map template or by creating an exit to a unique map template
2005  * without specifying in that exit that the map is unique), we need to re-insert
2006  * the player without calling enter_exit(), since we trip an assertion failure there.
2007  * If we reach here and tmp is defined, we have already re-inserted the player,
2008  * so we just need to bail.
2009  * -- Neila Hawkins 2023-12-13
2010  */
2011  if (res == SAVE_ERROR_UCREATION) {
2012  m->reset_group = reset_group;
2013  return;
2014  }
2015  }
2016  else {
2018  "Reset failed, couldn't swap map, the following players are on it:");
2019  for (pl = first_player; pl != NULL; pl = pl->next) {
2020  if (pl->ob->map == m && pl->ob != op) {
2022  pl->ob->name);
2023  playercount++;
2024  }
2025  }
2026  if (!playercount)
2028  "hmm, I don't see any other players on this map, something else is the problem.");
2029  m->reset_group = reset_group;
2030  return;
2031  }
2032  }
2033 
2034  FREE_AND_CLEAR_STR_IF(reset_group);
2035 
2036  /* Here, map reset succeeded. */
2037 
2038  if (m && m->in_memory == MAP_SWAPPED) {
2039  if (confirmation) {
2041  LOG(llevDebug, "DM %s fully resetting map %s.\n", op->name, m->path);
2042  } else
2043  LOG(llevDebug, "DM %s resetting map %s.\n", op->name, m->path);
2044 
2045  /* setting this effectively causes an immediate reload */
2046  m->reset_time = 1;
2047  flush_old_maps();
2048  }
2049 
2050  /* Display the appropriate success message. */
2051  if (confirmation) {
2053  MSG_TYPE_COMMAND_DM, "Fully resetting map %s.", path);
2054  } else {
2056  MSG_TYPE_COMMAND_DM, "Resetting map %s.", path);
2057  }
2058 
2059  if (tmp) {
2060  enter_exit(tmp, dummy);
2062  }
2063 
2064  /* Remind the DM how to fully reset the map. */
2065  if (confirmation == NULL) {
2068  "Use 'reset full-reset %s' to fully reset the map.", params);
2069  }
2070 }
2071 
2080 void command_nowiz(object *op, const char *params) { /* 'noadm' is alias */
2081  (void)params;
2082  CLEAR_FLAG(op, FLAG_WIZ);
2083  CLEAR_FLAG(op, FLAG_WIZPASS);
2084  CLEAR_FLAG(op, FLAG_WIZCAST);
2085 
2086  if (settings.real_wiz == TRUE)
2087  CLEAR_FLAG(op, FLAG_WAS_WIZ);
2088  if (op->contr->hidden) {
2089  unhide(op);
2090  } else
2092  "The Dungeon Master is gone...");
2093 
2094  update_los(op);
2095 }
2096 
2117 static int checkdm(object *op, const char *pl_name, const char *pl_passwd, const char *pl_host) {
2118  FILE *dmfile;
2119  char buf[MAX_BUF];
2120  char line_buf[160], name[160], passwd[160], host[160];
2121 
2122 #ifdef RESTRICTIVE_DM
2123  *pl_name = op->name ? op->name : "*";
2124 #else
2125  (void)op;
2126 #endif
2127 
2128  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, DMFILE);
2129  if ((dmfile = fopen(buf, "r")) == NULL) {
2130  LOG(llevDebug, "Could not find DM file.\n");
2131  return 0;
2132  }
2133 
2134  while (fgets(line_buf, 160, dmfile) != NULL) {
2135  // Skip empty lines as well as commented ones.
2136  if (line_buf[0] == '#' || line_buf[0] == '\n')
2137  continue;
2138  if (sscanf(line_buf, "%[^:]:%[^:]:%s\n", name, passwd, host) != 3) {
2139  LOG(llevError, "Warning - malformed dm file entry: %s\n", line_buf);
2140  } else if ((!strcmp(name, "*") || (pl_name && !strcmp(pl_name, name)))
2141  && (!strcmp(passwd, "*") || !strcmp(passwd, pl_passwd))
2142  && (!strcmp(host, "*") || !strcmp(host, pl_host))) {
2143  fclose(dmfile);
2144  return (1);
2145  }
2146  }
2147  fclose(dmfile);
2148  return (0);
2149 }
2150 
2165 static int do_wizard_dm(object *op, const char *params, int silent) {
2166  if (!op->contr)
2167  return 0;
2168 
2169  if (QUERY_FLAG(op, FLAG_WIZ)) {
2171  "You are already the Dungeon Master!");
2172  return 0;
2173  }
2174 
2175  if (checkdm(op, op->name, (*params != '\0' ? params : "*"), op->contr->socket->host)) {
2176  SET_FLAG(op, FLAG_WIZ);
2177  SET_FLAG(op, FLAG_WAS_WIZ);
2178  SET_FLAG(op, FLAG_WIZPASS);
2179  SET_FLAG(op, FLAG_WIZCAST);
2181  "Ok, you are the Dungeon Master!");
2182  /*
2183  * Remove setting flying here - that won't work, because next
2184  * fix_object() is called that will get cleared - proper solution
2185  * is probably something like a wiz_force which gives that and any
2186  * other desired abilities.
2187  */
2188  clear_los(op->contr);
2189 
2190  if (!silent)
2193  "The Dungeon Master has arrived!");
2194 
2195  return 1;
2196  }
2197 
2199  "Sorry Pal, I don't think so.");
2200  return 0;
2201 }
2202 
2214 void command_dm(object *op, const char *params) {
2215  do_wizard_dm(op, params, 0);
2216 }
2217 
2226 void command_invisible(object *op, const char *params) {
2227  (void)params;
2228  if (op) {
2229  op->invisible += 100;
2232  "You turn invisible.");
2233  }
2234 }
2235 
2253 static object *get_spell_by_name(object *op, const char *spell_name) {
2254  archetype *found;
2255  int conflict_found;
2256  size_t spell_name_length;
2257 
2258  /* First check for full name matches. */
2259  conflict_found = 0;
2260  found = NULL;
2261  getManager()->archetypes()->each([&] (auto ar) {
2262  if (ar->clone.type != SPELL)
2263  return;
2264 
2265  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2266  return;
2267 
2268  if (strcmp(ar->clone.name, spell_name) != 0)
2269  return;
2270 
2271  if (found != NULL) {
2272  if (!conflict_found) {
2273  conflict_found = 1;
2275  "More than one archetype matches the spell name %s:",
2276  spell_name);
2278  "- %s",
2279  found->name);
2280  }
2282  "- %s",
2283  ar->name);
2284  return;
2285  }
2286 
2287  found = ar;
2288  });
2289 
2290  /* No match if more more than one archetype matches. */
2291  if (conflict_found)
2292  return NULL;
2293 
2294  /* Return if exactly one archetype matches. */
2295  if (found != NULL)
2296  return arch_to_object(found);
2297 
2298  /* No full match found: now check for partial matches. */
2299  spell_name_length = strlen(spell_name);
2300  conflict_found = 0;
2301  found = NULL;
2302 
2303  getManager()->archetypes()->each([&] (auto ar) {
2304  if (ar->clone.type != SPELL)
2305  return;
2306 
2307  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2308  return;
2309 
2310  if (strncmp(ar->clone.name, spell_name, spell_name_length) != 0)
2311  return;
2312 
2313  if (found != NULL) {
2314  if (!conflict_found) {
2315  conflict_found = 1;
2317  "More than one spell matches %s:",
2318  spell_name);
2320  "- %s",
2321  found->clone.name);
2322  }
2324  "- %s",
2325  ar->clone.name);
2326  return;
2327  }
2328 
2329  found = ar;
2330  });
2331 
2332  /* No match if more more than one archetype matches. */
2333  if (conflict_found)
2334  return NULL;
2335 
2336  /* Return if exactly one archetype matches. */
2337  if (found != NULL)
2338  return arch_to_object(found);
2339 
2340  /* No spell found: just print an error message. */
2342  "The spell %s does not exist.",
2343  spell_name);
2344  return NULL;
2345 }
2346 
2357 static void command_learn_spell_or_prayer(object *op, const char *params, int special_prayer) {
2358  object *tmp;
2359 
2360  if (op->contr == NULL || *params == '\0') {
2362  "Which spell do you want to learn?");
2363  return;
2364  }
2365 
2366  tmp = get_spell_by_name(op, params);
2367  if (tmp == NULL) {
2368  return;
2369  }
2370 
2371  if (check_spell_known(op, tmp->name)) {
2373  "You already know the spell %s.",
2374  tmp->name);
2375  return;
2376  }
2377 
2378  do_learn_spell(op, tmp, special_prayer);
2380 }
2381 
2390 void command_learn_spell(object *op, const char *params) {
2391  command_learn_spell_or_prayer(op, params, 0);
2392 }
2393 
2402 void command_learn_special_prayer(object *op, const char *params) {
2403  command_learn_spell_or_prayer(op, params, 1);
2404 }
2405 
2415 void command_forget_spell(object *op, const char *params) {
2416  object *spell;
2417 
2418  if (op->contr == NULL || *params == '\0') {
2420  "Which spell do you want to forget?");
2421  return;
2422  }
2423 
2424  spell = lookup_spell_by_name(op, params);
2425  if (spell == NULL) {
2427  "You do not know the spell %s.",
2428  params);
2429  return;
2430  }
2431 
2432  do_forget_spell(op, spell->name);
2433 }
2434 
2443 void command_listplugins(object *op, const char *params) {
2444  (void)params;
2446 }
2447 
2458 void command_loadplugin(object *op, const char *params) {
2459  char buf[MAX_BUF];
2460 
2461  if (*params == '\0') {
2463  "Load which plugin?");
2464  return;
2465  }
2466 
2467  snprintf(buf, sizeof(buf), LIBDIR"/plugins/%s", params);
2468  LOG(llevDebug, "Requested plugin file is %s\n", buf);
2469  if (plugins_init_plugin(buf) == 0) {
2470  LOG(llevInfo, "DM %s loaded plugin %s\n", op->name, params);
2472  "Plugin %s successfully loaded.",
2473  params);
2474  } else
2476  "Could not load plugin %s.",
2477  params);
2478 }
2479 
2490 void command_unloadplugin(object *op, const char *params) {
2491  if (*params == '\0') {
2493  "Remove which plugin?");
2494  return;
2495  }
2496 
2497  if (plugins_remove_plugin(params) == 0) {
2498  LOG(llevInfo, "DM %s unloaded plugin %s\n", op->name, params);
2500  "Plugin %s successfully removed.",
2501  params);
2502  init_signals(); // Restore our signal handlers, some plugins (Python) mess with them
2503  } else
2505  "Could not remove plugin %s.",
2506  params);
2507 }
2508 
2519 void command_dmhide(object *op, const char *params) {
2520  if (!do_wizard_dm(op, params, 1))
2521  return;
2522 
2523  do_wizard_hide(op, 1);
2524 }
2525 
2534 void command_stack_pop(object *op, const char *params) {
2535  (void)params;
2536  dm_stack_pop(op->contr);
2537 }
2538 
2547 void command_stack_push(object *op, const char *params) {
2548  object *ob;
2549  int from;
2550  ob = get_dm_object(op->contr, &params, &from);
2551 
2552  if (ob && from != STACK_FROM_NUMBER)
2553  /* Object was from stack, need to push it again */
2554  dm_stack_push(op->contr, ob->count);
2555 }
2556 
2565 void command_stack_list(object *op, const char *params) {
2566  int item;
2567  object *display;
2568  player *pl = op->contr;
2569  (void)params;
2570 
2572  "Item stack contents:");
2573 
2574  for (item = 0; item < pl->stack_position; item++) {
2575  display = object_find_by_tag_global(pl->stack_items[item]);
2576  if (display)
2578  " %d : %s [%d]",
2579  item, display->name, display->count);
2580  else
2581  /* Item was freed */
2583  " %d : (lost item: %d)",
2584  item, pl->stack_items[item]);
2585  }
2586 }
2587 
2596 void command_stack_clear(object *op, const char *params) {
2597  (void)params;
2598  op->contr->stack_position = 0;
2600  "Item stack cleared.");
2601 }
2602 
2622 void command_diff(object *op, const char *params) {
2623  object *left, *right;
2624  char *diff;
2625  StringBuffer *sb;
2626  int left_from, right_from;
2627 
2628  left = get_dm_object(op->contr, &params, &left_from);
2629  if (!left) {
2631  "Compare to what item?");
2632  return;
2633  }
2634 
2635  if (left_from == STACK_FROM_NUMBER)
2636  /* Item was stacked, remove it else right will be the same... */
2637  dm_stack_pop(op->contr);
2638 
2639  right = get_dm_object(op->contr, &params, &right_from);
2640 
2641  if (!right) {
2643  "Compare what item?");
2644  return;
2645  }
2646 
2648  "Item difference:");
2649 
2650  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2651  /*
2652  * Special case: both items were taken from stack top.
2653  * Override the behaviour, taking left as item just below top, if exists.
2654  * See function description for why.
2655  * Besides, if we don't do anything, compare an item to itself, not really useful.
2656  */
2657  if (op->contr->stack_position > 1) {
2659  if (left)
2661  "(Note: first item taken from undertop)");
2662  else
2663  /* Stupid case: item under top was freed, fallback to stack top */
2664  left = right;
2665  }
2666  }
2667 
2668  sb = stringbuffer_new();
2669  get_ob_diff(sb, left, right);
2670  diff = stringbuffer_finish(sb);
2671  if (*diff == '\0') {
2672  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DM, "Objects are the same.");
2673  } else {
2675  }
2676  free(diff);
2677 }
2678 
2686 void command_insert_into(object *op, const char *params) {
2687  object *left, *right, *inserted;
2688  int left_from, right_from;
2689  char what[MAX_BUF], where[MAX_BUF];
2690 
2691  left = get_dm_object(op->contr, &params, &left_from);
2692  if (!left) {
2694  "Insert into what object?");
2695  return;
2696  }
2697 
2698  if (left_from == STACK_FROM_NUMBER)
2699  /* Item was stacked, remove it else right will be the same... */
2700  dm_stack_pop(op->contr);
2701 
2702  right = get_dm_object(op->contr, &params, &right_from);
2703 
2704  if (!right) {
2706  "Insert what item?");
2707  return;
2708  }
2709 
2710  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2711  /*
2712  * Special case: both items were taken from stack top.
2713  * Override the behaviour, taking left as item just below top, if exists.
2714  * See function description for why.
2715  * Besides, can't insert an item into itself.
2716  */
2717  if (op->contr->stack_position > 1) {
2719  if (left)
2721  "(Note: item to insert into taken from undertop)");
2722  else
2723  /* Stupid case: item under top was freed, fallback to stack top */
2724  left = right;
2725  }
2726  }
2727 
2728  if (left == right) {
2730  "Can't insert an object into itself!");
2731  return;
2732  }
2733 
2734  if (right->type == PLAYER) {
2736  "Can't insert a player into something!");
2737  return;
2738  }
2739 
2740  if (!QUERY_FLAG(right, FLAG_REMOVED))
2741  object_remove(right);
2742  inserted = object_insert_in_ob(right, left);
2743  if (left->type == PLAYER) {
2744  if (inserted != right)
2745  /* item was merged, so updating name and such. */
2746  esrv_update_item(UPD_WEIGHT|UPD_NAME|UPD_NROF, left, inserted);
2747  }
2748  query_name(inserted, what, MAX_BUF);
2749  query_name(left, where, MAX_BUF);
2751  "Inserted %s in %s",
2752  what, where);
2753 }
2754 
2763 void command_style_map_info(object *op, const char *params) {
2764  extern mapstruct *styles;
2765  mapstruct *mp;
2766  int maps_used = 0, mapmem = 0, objects_used = 0, x, y;
2767  (void)params;
2768 
2769  for (mp = styles; mp != NULL; mp = mp->next) {
2770  maps_used++;
2771  mapmem += map_size(mp) * (sizeof(object *)+sizeof(MapSpace))+sizeof(mapstruct);
2772  for (x = 0; x < MAP_WIDTH(mp); x++) {
2773  for (y = 0; y < MAP_HEIGHT(mp); y++) {
2774  FOR_MAP_PREPARE(mp, x, y, tmp)
2775  objects_used++;
2776  FOR_MAP_FINISH();
2777  }
2778  }
2779  }
2781  "[fixed]Style maps loaded: %d",
2782  maps_used);
2784  "[fixed]Memory used, not");
2786  "[fixed]including objects: %d",
2787  mapmem);
2789  "[fixed]Style objects: %d",
2790  objects_used);
2792  "[fixed]Mem for objects: %lu",
2793  (unsigned long)(objects_used*sizeof(object)));
2794 }
2795 
2796 bool can_follow(object* op, player* other) {
2797  // Only allow follow from same party.
2798  return (other->ob->contr->party != NULL) && (op->contr->party == other->ob->contr->party);
2799 }
2800 
2809 void command_follow(object *op, const char *params) {
2810  player *other;
2811 
2812  if (*params == '\0') {
2813  if (op->contr->followed_player != NULL) {
2816  }
2817  return;
2818  }
2819 
2820  other = find_player_partial_name(params);
2821  if (!other) {
2822  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "No such player or ambiguous name.");
2823  return;
2824  }
2825  if (other == op->contr) {
2826  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "You can't follow yourself.");
2827  return;
2828  }
2829 
2830  // Players trying to 'follow' are subject to additional checks.
2831  if (!QUERY_FLAG(op, FLAG_WIZ)) {
2832  if (!can_follow(op, other)) {
2835  "You can only follow members in the same party.");
2836  return;
2837  }
2838  rv_vector rv;
2839  if (!get_rangevector(op, other->ob, &rv, 0) || rv.distance > 1) {
2840  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "You need to go to them first!");
2841  return;
2842  }
2844  }
2845 
2846  if (op->contr->followed_player)
2848 
2849  op->contr->followed_player = add_string(other->ob->name);
2851 }
2852 
2853 void command_purge_quest(object *op, const char * param) {
2854  (void)param;
2855  free_quest();
2856  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Purged quest state.");
2857 }
2858 
2859 void command_purge_quest_definitions(object *op, const char * param) {
2860  (void)param;
2862  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Purged quests definitions.");
2863 }
2864 
2865 void do_dump(object *who, object *what) {
2866  StringBuffer *sb;
2867  char *diff;
2868 
2869  sb = stringbuffer_new();
2870  object_dump(what, sb);
2871  diff = stringbuffer_finish(sb);
2873  free(diff);
2874 
2875  /* Let's push that item on the dm's stack */
2876  dm_stack_push(who->contr, what->count);
2877 }
2878 
2887 void command_dumpbelow(object *op, const char *params) {
2888  (void)params;
2889  if (op && op->below) {
2890  do_dump(op, op->below);
2891  }
2892 }
2893 
2902 void command_dumpabove(object *op, const char *params) {
2903  (void)params;
2904  if (op && op->above) {
2905  do_dump(op, op->above);
2906  }
2907 }
2908 
2914 void command_settings(object *op, const char *ignored) {
2915  (void)ignored;
2916  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "Server settings:");
2917 
2919 
2920  if (settings.not_permadeth) {
2921  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * death is not permanent");
2922  } else if (settings.resurrection) {
2923  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * permanent death, resurrection is enabled");
2924  } else {
2925  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * permanent death, resurrection is NOT enabled");
2926  }
2927 
2928  if (settings.set_title) {
2929  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can set their title");
2930  } else {
2931  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't set their title");
2932  }
2933 
2936  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");
2937  } else {
2938  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");
2939  }
2940  } else {
2941  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * too much equipment can't lead to spell failure");
2942  }
2943 
2944  if (settings.casting_time) {
2945  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * casting takes time");
2946  } else {
2947  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * casting is immediate");
2948  }
2949 
2952 
2954 
2956  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't steal from other players");
2957  } else {
2958  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can steal from other players");
2959  }
2960 
2962  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can create portals from their apartments");
2963  } else {
2964  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't create portals from their apartments");
2965  }
2966 
2968  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can write spells they are denied");
2969  } else {
2970  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, " * players can't write spells they are denied");
2971  }
2972 }
Settings::casting_time
uint8_t casting_time
It takes awhile to cast a spell.
Definition: global.h:272
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
command_possess
void command_possess(object *op, const char *params)
DM can possess a monster.
Definition: c_wiz.cpp:1432
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
UP_OBJ_FACE
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:533
player::stack_items
tag_t * stack_items
Item stack for patch/dump/...
Definition: player.h:217
PLAYER
@ PLAYER
Definition: object.h:112
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:106
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:666
FREE_AND_CLEAR_STR_IF
#define FREE_AND_CLEAR_STR_IF(xyz)
Definition: global.h:202
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:545
first_player
player * first_player
First player.
Definition: init.cpp:106
settings
struct Settings settings
Server 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:618
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:724
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
NUM_BODY_LOCATIONS
#define NUM_BODY_LOCATIONS
Number of body locations.
Definition: object.h:15
MSG_TYPE_COMMAND_SUCCESS
#define MSG_TYPE_COMMAND_SUCCESS
Successful result from command.
Definition: newclient.h:533
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:2763
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:333
WAND
@ WAND
Definition: object.h:225
MSG_TYPE_ADMIN_PLAYER
#define MSG_TYPE_ADMIN_PLAYER
Player coming/going/death.
Definition: newclient.h:499
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
SHUTDOWN_IDLE
@ SHUTDOWN_IDLE
Definition: commands.h:44
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
reset_faces_sent
static void reset_faces_sent(struct socket_struct *socket)
Definition: c_wiz.cpp:1525
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:1493
player
One player.
Definition: player.h:105
Settings::resurrection
uint8_t resurrection
Ressurection possible w/ permadeth on.
Definition: global.h:268
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
plugins_remove_plugin
int plugins_remove_plugin(const char *id)
Unload the specified plugin.
Definition: plugins.cpp:454
plugins_init_plugin
int plugins_init_plugin(const char *libfile)
Try to load the specified plugin.
Definition: plugins.cpp:373
Settings::set_title
uint8_t set_title
Players can set thier title.
Definition: global.h:267
AssetsManager.h
do_learn_spell
void do_learn_spell(object *op, object *spell, int special_prayer)
Actually makes op learn spell.
Definition: apply.cpp:484
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:89
Socket_Info::allocated_sockets
int allocated_sockets
Number of allocated items in init_sockets.
Definition: newserver.h:144
flush_old_maps
void flush_old_maps(void)
Reset maps that need to, remove their swap file.
Definition: swap.cpp:291
esrv_new_player
void esrv_new_player(player *pl, uint32_t weight)
Tells the client that here is a player it should start using.
Definition: request.cpp:1008
FALSE
#define FALSE
Definition: compat.h:14
Settings::not_permadeth
uint8_t not_permadeth
If true, death is non-permament.
Definition: global.h:264
command_speed
void command_speed(object *op, const char *params)
Changes the server speed.
Definition: c_wiz.cpp:1732
Settings::permanent_exp_ratio
uint8_t permanent_exp_ratio
How much exp should be 'permenant' and unable to be lost.
Definition: global.h:260
esrv_send_inventory
void esrv_send_inventory(object *pl, object *op)
Sends inventory of a container.
Definition: item.cpp:316
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:2165
command_learn_spell
void command_learn_spell(object *op, const char *params)
Wizard wants to learn a regular spell.
Definition: c_wiz.cpp:2390
Settings::datadir
const char * datadir
Read only data files.
Definition: global.h:250
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:334
UPD_WEIGHT
#define UPD_WEIGHT
Definition: newclient.h:319
player::no_shout
uint32_t no_shout
if True, player is *not *able to use shout command.
Definition: player.h:148
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
if
if(!(yy_init))
Definition: loader.cpp:36428
object_set_enemy
void object_set_enemy(object *op, object *enemy)
Sets the enemy of an object.
Definition: object.cpp:915
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:433
living::Dex
int8_t Dex
Definition: living.h:36
FLAG_OBJ_ORIGINAL
#define FLAG_OBJ_ORIGINAL
NEVER SET THIS.
Definition: define.h:357
object::x
int16_t x
Definition: object.h:335
player::ob
object * ob
The object representing the player.
Definition: player.h:177
player::transport
object * transport
Transport the player is in.
Definition: player.h:214
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
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:296
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:293
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:2853
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
unhide
static void unhide(object *op)
Definition: c_wiz.cpp:333
do_dump
void do_dump(object *who, object *what)
Definition: c_wiz.cpp:2865
object::count
tag_t count
Unique object number for this object.
Definition: object.h:307
FLAG_WIZCAST
#define FLAG_WIZCAST
The wizard can cast spells in no-magic area.
Definition: define.h:289
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:1192
command_invisible
void command_invisible(object *op, const char *params)
Wizard wants to become invisible.
Definition: c_wiz.cpp:2226
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:248
player::hidden
uint32_t hidden
If True, player (DM) is hidden from view.
Definition: player.h:147
UPD_NROF
#define UPD_NROF
Definition: newclient.h:324
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:479
command_addexp
void command_addexp(object *op, const char *params)
This adds exp to a player.
Definition: c_wiz.cpp:1676
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:2443
skills.h
MSG_TYPE_COMMAND_ERROR
#define MSG_TYPE_COMMAND_ERROR
Bad syntax/can't use command.
Definition: newclient.h:532
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:727
mapstruct::path
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:355
buf
StringBuffer * buf
Definition: readable.cpp:1565
set_tick_duration
void set_tick_duration(long t)
Sets the tick duration.
Definition: time.cpp:209
getManager
AssetsManager * getManager()
Definition: assets.cpp:304
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:2857
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:407
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:249
SAVE_MODE_OVERLAY
#define SAVE_MODE_OVERLAY
Map is persisted as an overlay.
Definition: map.h:118
Settings::worldmaptilesx
uint32_t worldmaptilesx
Number of tiles wide the worldmap is.
Definition: global.h:295
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
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
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:2402
Ns_Dead
@ Ns_Dead
Definition: newserver.h:67
command_remove
void command_remove(object *op, const char *params)
Remove an object from its position.
Definition: c_wiz.cpp:1565
map_remove_unique_files
void map_remove_unique_files(const mapstruct *map)
Remove files containing the map's unique items.
Definition: map.cpp:2651
MSG_TYPE_ADMIN_DM
#define MSG_TYPE_ADMIN_DM
DM related admin actions.
Definition: newclient.h:500
MSG_TYPE_COMMAND_DEBUG
#define MSG_TYPE_COMMAND_DEBUG
Various debug type commands.
Definition: newclient.h:531
ASSETS_QUESTS
#define ASSETS_QUESTS
Definition: assets.h:30
Settings::spell_encumbrance
uint8_t spell_encumbrance
Encumbrance effects spells.
Definition: global.h:270
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
m
static event_registration m
Definition: citylife.cpp:422
clear_los
void clear_los(player *pl)
Clears/initialises the los-array associated to the player controlling the object.
Definition: los.cpp:270
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Map is fully loaded.
Definition: map.h:126
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:1560
object_update
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.cpp:1434
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:810
command_setgod
void command_setgod(object *op, const char *params)
Sets the god for some objects.
Definition: c_wiz.cpp:418
FLAG_WAS_WIZ
#define FLAG_WAS_WIZ
Player was once a wiz.
Definition: define.h:234
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:261
command_reset
void command_reset(object *op, const char *params)
Resets a map.
Definition: c_wiz.cpp:1885
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:588
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:277
player::followed_player
sstring followed_player
Player the DM is following.
Definition: player.h:218
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:538
command_purge_quest_definitions
void command_purge_quest_definitions(object *op, const char *param)
Definition: c_wiz.cpp:2859
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:645
Settings::worldmapstarty
uint32_t worldmapstarty
Starting y tile for the worldmap.
Definition: global.h:294
add_string
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.cpp:124
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:891
shutdown_s::type
enum shutdown_type type
Definition: commands.h:48
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:2214
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:2306
socket_struct::host
char * host
Which host it is connected from (ip address).
Definition: newserver.h:100
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:1819
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:2887
command_diff
void command_diff(object *op, const char *params)
Get a diff of specified items.
Definition: c_wiz.cpp:2622
object_update_speed
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.cpp:1349
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:860
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
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
FLAG_WIZPASS
#define FLAG_WIZPASS
The wizard can go through walls.
Definition: define.h:314
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:1592
command_dumpabove
void command_dumpabove(object *op, const char *params)
Player wants to dump object above her.
Definition: c_wiz.cpp:2902
Settings::item_power_factor
float item_power_factor
See note in setings file.
Definition: global.h:305
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:2686
living::food
int32_t food
How much food in stomach.
Definition: living.h:48
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Monster doesn't attack players.
Definition: define.h:272
assets_finish_archetypes_for_play
void assets_finish_archetypes_for_play()
Definition: assets.cpp:508
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:249
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:256
living::Int
int8_t Int
Definition: living.h:36
MSG_SUBTYPE_NONE
#define MSG_SUBTYPE_NONE
Definition: newclient.h:423
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:1323
Settings::death_penalty_level
uint8_t death_penalty_level
How many levels worth of exp may be lost on one death.
Definition: global.h:262
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:2100
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
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
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:211
MAP_WIDTH
#define MAP_WIDTH(m)
Map width.
Definition: map.h:73
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:435
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:1273
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:167
path
pluglist shows those as well as a short text describing each the list will simply appear empty The keyword for the Python plugin is Python plugout< keyword > Unloads a given identified by its _keyword_ So if you want to unload the Python you need to do plugout Python plugin< libname > Loads a given whose _filename_ is libname So in the case of you d have to do a plugin cfpython so Note that all filenames are relative to the default plugin path(SHARE/plugins). Console messages. ----------------- When Crossfire starts
monster_check_apply_all
void monster_check_apply_all(object *monster)
Calls monster_check_apply() for all inventory objects.
Definition: monster.cpp:1999
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
SAVE_ERROR_UCREATION
#define SAVE_ERROR_UCREATION
Couldn't create the file for unique objects.
Definition: map.h:141
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:200
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:271
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:534
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:717
load_assets
void load_assets(void)
Definition: init.cpp:310
ST_PLAYING
#define ST_PLAYING
Usual state.
Definition: define.h:535
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:2415
FLAG_REMOVED
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
Settings::allow_denied_spells_writing
int allow_denied_spells_writing
If set, players can write spells they can't cast.
Definition: global.h:317
command_nowiz
void command_nowiz(object *op, const char *params)
Steps down from wizard mode.
Definition: c_wiz.cpp:2080
FLAG_WIZ
#define FLAG_WIZ
Object has special privilegies.
Definition: define.h:231
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:2458
llevInfo
@ llevInfo
Information.
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:265
EVENT_MUZZLE
#define EVENT_MUZZLE
A player was Muzzled (no_shout set).
Definition: events.h:52
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
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Will help players.
Definition: define.h:246
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:2357
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:2253
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:2796
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:1329
mapstruct
This is a game-map.
Definition: map.h:315
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:747
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:2914
living::Cha
int8_t Cha
Definition: living.h:36
NDI_ALL
#define NDI_ALL
Inform all players of this message.
Definition: newclient.h:266
socket_struct::status
enum Sock_Status status
Definition: newserver.h:90
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:39047
command_stats
void command_stats(object *op, const char *params)
Displays the statistics of a player.
Definition: c_wiz.cpp:1762
player::state
uint8_t state
Input state of the player (name, password, etc).
Definition: player.h:131
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:3559
command_dmhide
void command_dmhide(object *op, const char *params)
A players wants to become DM and hide.
Definition: c_wiz.cpp:2519
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.cpp:359
command_unloadplugin
void command_unloadplugin(object *op, const char *params)
Unloads the given plugin.
Definition: c_wiz.cpp:2490
Settings::max_stat
uint8_t max_stat
Maximum stat value - 255 should be sufficient.
Definition: global.h:326
rv_vector
This is used by get_rangevector to determine where the other creature is.
Definition: map.h:370
MAP_SWAPPED
#define MAP_SWAPPED
Map spaces have been saved to disk.
Definition: map.h:127
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:436
assets.h
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
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:95
command_follow
void command_follow(object *op, const char *params)
Follow a player, or stop following a player.
Definition: c_wiz.cpp:2809
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:75
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:251
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:4986
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:96
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:1361
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
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:2505
player::party
partylist * party
Party this player is part of.
Definition: player.h:203
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:2117
MSG_TYPE_COMMAND_MAPS
#define MSG_TYPE_COMMAND_MAPS
Definition: newclient.h:523
player::count
uint32_t count
Any numbers typed before a command.
Definition: player.h:122
object::body_info
int8_t body_info[NUM_BODY_LOCATIONS]
Body info as loaded from the file.
Definition: object.h:382
UPD_NAME
#define UPD_NAME
Definition: newclient.h:321
command_accountpasswd
void command_accountpasswd(object *op, const char *params)
Definition: c_wiz.cpp:1638
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:273
MSG_TYPE_COMMUNICATION_PARTY
#define MSG_TYPE_COMMUNICATION_PARTY
Party message.
Definition: newclient.h:630
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:1833
try_find_archetype
archetype * try_find_archetype(const char *name)
Definition: assets.cpp:269
inventory
void inventory(object *op, object *inv)
Prints object's inventory.
Definition: c_object.cpp:2167
do_forget_spell
void do_forget_spell(object *op, const char *spell)
Erases spell from player's inventory.
Definition: apply.cpp:525
command_kick2
static void command_kick2(object *op, const char *params)
Kicks a player from the server.
Definition: c_wiz.cpp:468
do_some_living
void do_some_living(object *op)
Regenerate hp/sp/gr, decreases food.
Definition: player.cpp:3293
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:1407
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:219
command_stack_push
void command_stack_push(object *op, const char *params)
Push specified item on stack.
Definition: c_wiz.cpp:2547
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:107
mapstruct::next
mapstruct * next
Next map, linked list.
Definition: map.h:316
assets_collect
void assets_collect(const char *datadir, int what)
Collect all assets from the specified directory and all its subdirectories.
Definition: assets.cpp:112
Settings::no_player_stealing
uint8_t no_player_stealing
If 1, can not steal from other players.
Definition: global.h:312
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:1612
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:413
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:292
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:1531
command_stack_pop
void command_stack_pop(object *op, const char *params)
Pop the stack top.
Definition: c_wiz.cpp:2534
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:313
find_artifactlist
artifactlist * find_artifactlist(int type)
Finds the artifact list for a certain item type.
Definition: artifact.cpp:574
MSG_TYPE_ADMIN
#define MSG_TYPE_ADMIN
Definition: newclient.h:405
rv_vector::distance
unsigned int distance
Distance, in squares.
Definition: map.h:371
SPELLBOOK
@ SPELLBOOK
Definition: object.h:208
EVENT_KICK
#define EVENT_KICK
A player was Kicked by a DM
Definition: events.h:43
living::hp
int16_t hp
Hit Points.
Definition: living.h:40
SAVE_ERROR_PLAYER
#define SAVE_ERROR_PLAYER
Player on map to save.
Definition: map.h:148
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:263
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:253
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:13
living::Con
int8_t Con
Definition: living.h:36
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Player knows full info about item.
Definition: define.h:261
command_stack_clear
void command_stack_clear(object *op, const char *params)
Empty DM item stack.
Definition: c_wiz.cpp:2596
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:2565
Settings::localdir
const char * localdir
Read/write data files.
Definition: global.h:251