Crossfire Server, Branches 1.12  R18729
c_wiz.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_c_wiz_c =
3  * "$Id: c_wiz.c 13939 2010-09-29 19:21:57Z ryo_saeba $";
4  */
5 
6 /*
7  CrossFire, A Multiplayer game for X-windows
8 
9  Copyright (C) 2006 Mark Wedel & Crossfire Development Team
10  Copyright (C) 1992 Frank Tore Johansen
11 
12  This program is free software; you can redistribute it and/or modify
13  it under the terms of the GNU General Public License as published by
14  the Free Software Foundation; either version 2 of the License, or
15  (at your option) any later version.
16 
17  This program is distributed in the hope that it will be useful,
18  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  GNU General Public License for more details.
21 
22  You should have received a copy of the GNU General Public License
23  along with this program; if not, write to the Free Software
24  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 
26  The authors can be reached via e-mail at crossfire-devel@real-time.com
27 */
28 
35 #include <global.h>
36 #ifndef __CEXTRACT__
37 #include <sproto.h>
38 #endif
39 #include <spells.h>
40 #include <treasure.h>
41 #include <skills.h>
42 
43 /* Defines for DM item stack **/
44 #define STACK_SIZE 50
46 enum {
51 };
52 
67 static player *get_other_player_from_name(object *op, const char *name) {
68  player *pl;
69 
70  if (!name)
71  return NULL;
72 
73  for (pl = first_player; pl != NULL; pl = pl->next)
74  if (!strncmp(pl->ob->name, name, MAX_NAME))
75  break;
76 
77  if (pl == NULL) {
79  "No such player.", NULL);
80  return NULL;
81  }
82 
83  if (pl->ob == op) {
85  "You can't do that to yourself.", NULL);
86  return NULL;
87  }
88  if (pl->state != ST_PLAYING) {
90  "That player is in no state for that right now.", NULL);
91  return NULL;
92  }
93  return pl;
94 }
95 
108 int command_loadtest(object *op, char *params) {
109  uint32 x, y;
110  char buf[1024];
111 
113  "loadtest will stress server through teleporting at different map places. "
114  "Use at your own risk. Very long loop used so server may have to be reset. "
115  "type loadtest TRUE to run",
116  NULL);
118  "{%s}",
119  "{%s}",
120  params);
121  if (!params)
122  return 0;
123  if (strncmp(params, "TRUE", 4))
124  return 0;
125 
127  "gogogo", NULL);
128 
129  for (x = 0; x < settings.worldmaptilesx; x++) {
130  for (y = 0; y < settings.worldmaptilesy; y++) {
131  snprintf(buf, sizeof(buf), "/world/world_%u_%u", x+settings.worldmapstartx, y+settings.worldmapstarty);
132  command_goto(op, buf);
133  }
134  }
135 
136  return 0;
137 }
138 
147 void do_wizard_hide(object *op, int silent_dm) {
148  if (op->contr->hidden) {
149  op->contr->hidden = 0;
150  op->invisible = 1;
152  "You are no longer hidden from other players", NULL);
153  op->map->players++;
156  "%s has entered the game.",
157  "%s has entered the game.",
158  op->name);
159  if (!silent_dm) {
162  "The Dungeon Master has arrived!", NULL);
163  }
164  } else {
165  op->contr->hidden = 1;
167  "Other players will no longer see you.", NULL);
168  op->map->players--;
169  if (!silent_dm) {
172  "The Dungeon Master is gone..", NULL);
173  }
176  "%s leaves the game.",
177  "%s leaves the game.",
178  op->name);
181  "%s left the game.",
182  "%s left the game.",
183  op->name);
184  }
185 }
186 
197 int command_hide(object *op, char *params) {
198  do_wizard_hide(op, 0);
199  return 1;
200 }
201 
211 static object *find_object_both(char *params) {
212  if (!params)
213  return NULL;
214  if (params[0] == '#')
215  return find_object(atol(params+1));
216  else
217  return find_object_name(params);
218 }
219 
232 int command_setgod(object *op, char *params) {
233  object *ob;
234  const object *god;
235  char *str;
236 
237  if (!params || !(str = strchr(params, ' '))) {
239  "Usage: setgod object god", NULL);
240  return 0;
241  }
242 
243  /* kill the space, and set string to the next param */
244  *str++ = '\0';
245  if (!(ob = find_object_both(params))) {
247  "Set whose god - can not find object %s?",
248  "Set whose god - can not find object %s?",
249  params);
250  return 1;
251  }
252 
253  /*
254  * Perhaps this is overly restrictive? Should we perhaps be able
255  * to rebless altars and the like?
256  */
257  if (ob->type != PLAYER) {
259  "%s is not a player - can not change its god",
260  "%s is not a player - can not change its god",
261  ob->name);
262  return 1;
263  }
264 
265  god = find_god(str);
266  if (god == NULL) {
268  "No such god %s.",
269  "No such god %s.",
270  str);
271  return 1;
272  }
273 
274  become_follower(ob, god);
275  return 1;
276 }
277 
293 int command_banish(object *op, char *params) {
294  player *pl;
295  FILE *banishfile;
296  char buf[MAX_BUF];
297  time_t now;
298 
299  if (!params) {
301  "Usage: banish <player>.", NULL);
302  return 1;
303  }
304 
305  pl = get_other_player_from_name(op, params);
306  if (!pl)
307  return 1;
308 
309  snprintf(buf, sizeof(buf), "%s/%s", settings.localdir, BANISHFILE);
310 
311  if ((banishfile = fopen(buf, "a")) == NULL) {
312  LOG(llevDebug, "Could not find file banish_file.\n");
314  "Could not find banish_file.", NULL);
315  return 0;
316  }
317 
318  now = time(NULL);
319  /*
320  * Record this as a comment - then we don't have to worry about changing
321  * the parsing code.
322  */
323  fprintf(banishfile, "# %s (%s) banned by %s at %s\n", pl->ob->name, pl->socket.host, op->name, ctime(&now));
324  fprintf(banishfile, "*@%s\n", pl->socket.host);
325  fclose(banishfile);
326 
327  LOG(llevDebug, "! %s banned %s from IP: %s.\n", op->name, pl->ob->name, pl->socket.host);
328 
330  "You banish %s",
331  "You banish %s",
332  pl->ob->name);
333 
335  "%s banishes %s from the land!",
336  "%s banishes %s from the land!",
337  op->name, pl->ob->name);
338  command_kick(op, pl->ob->name);
339  return 1;
340 }
341 
352 int command_kick(object *op, const char *params) {
353  struct pl *pl;
354 
355  for (pl = first_player; pl != NULL; pl = pl->next) {
356  if ((params == NULL || !strcmp(pl->ob->name, params)) && pl->ob != op) {
357  object *op;
358  int removed = 0;
359 
360  op = pl->ob;
361  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
362  /* Avion : Here we handle the KICK global event */
363  execute_global_event(EVENT_KICK, op, params);
364  remove_ob(op);
365  removed = 1;
366  }
367  op->direction = 0;
369  "%s is kicked out of the game.",
370  "%s is kicked out of the game.",
371  op->name);
372  strcpy(op->contr->killer, "left");
373  check_score(op, 0); /* Always check score */
374 
375  /*
376  * not sure how the player would be freed, but did see
377  * a crash here - if that is the case, don't save the
378  * the player.
379  */
380  if (!removed && !QUERY_FLAG(op, FLAG_FREED)) {
381  (void)save_player(op, 0);
382  if (op->map)
383  op->map->players--;
384  }
385 #if MAP_MAXTIMEOUT
386  if (op->map)
387  op->map->timeout = MAP_TIMEOUT(op->map);
388 #endif
389  pl->socket.status = Ns_Dead;
390  }
391  }
392 
393  return 1;
394 }
395 
406 int command_overlay_save(object *op, char *params) {
407  if (!op)
408  return 0;
409 
410  if (save_map(op->map, SAVE_MODE_OVERLAY) < 0)
412  "Overlay save error!", NULL);
413  else
415  "Current map has been saved as an overlay.", NULL);
416 
417  return 1;
418 }
419 
430 int command_overlay_reset(object *op, char *params) {
431  char filename[MAX_BUF];
432  struct stat stats;
433 
434  create_overlay_pathname(op->map->path, filename, MAX_BUF);
435  if (!stat(filename, &stats))
436  if (!unlink(filename))
438  "Overlay successfully removed.", NULL);
439  else
441  "Overlay couldn't be removed.", NULL);
442  else
444  "No overlay for current map.", NULL);
445 
446  return 1;
447 }
448 
459 int command_toggle_shout(object *op, char *params) {
460  player *pl;
461 
462  if (!params) {
464  "Usage: toggle_shout <player>.", NULL);
465  return 1;
466  }
467 
468  pl = get_other_player_from_name(op, params);
469  if (!pl)
470  return 1;
471 
472  if (pl->ob->contr->no_shout == 0) {
473  pl->ob->contr->no_shout = 1;
474 
476  "You have been muzzled by the DM!", NULL);
478  "You muzzle %s.",
479  "You muzzle %s.",
480  pl->ob->name);
481 
482  /* Avion : Here we handle the MUZZLE global event */
483  execute_global_event(EVENT_MUZZLE, pl->ob, params);
484 
485  return 1;
486  } else {
487  pl->ob->contr->no_shout = 0;
489  "You are allowed to shout and chat again.", NULL);
491  "You remove %s's muzzle.",
492  "You remove %s's muzzle.",
493  pl->ob->name);
494  return 1;
495  }
496 }
497 
508 int command_shutdown(object *op, char *params) {
509  /*
510  * We need to give op - command_kick expects it. however, this means
511  * the op won't get kicked off, so we do it ourselves
512  */
513  command_kick(op, NULL);
514  check_score(op, 0); /* Always check score */
515  (void)save_player(op, 0);
516  play_again(op);
517  cleanup();
518  /* not reached */
519  return 1;
520 }
521 
532 int command_goto(object *op, char *params) {
533  char *name;
534  object *dummy;
535 
536  if (!op)
537  return 0;
538 
539  if (params == NULL) {
541  "Go to what level?", NULL);
542  return 1;
543  }
544 
545  name = params;
546  dummy = get_object();
547  dummy->map = op->map;
548  EXIT_PATH(dummy) = add_string(name);
549  dummy->name = add_string(name);
550 
551  enter_exit(op, dummy);
552  free_object(dummy);
554  "Difficulty: %d.",
555  "Difficulty: %d.",
556  op->map->difficulty);
557 
558  return 1;
559 }
560 
571 int command_freeze(object *op, char *params) {
572  int ticks;
573  player *pl;
574 
575  if (!params) {
577  "Usage: freeze [ticks] <player>.", NULL);
578  return 1;
579  }
580 
581  ticks = atoi(params);
582  if (ticks) {
583  while ((isdigit(*params) || isspace(*params)) && *params != 0)
584  params++;
585  if (*params == 0) {
587  "Usage: freeze [ticks] <player>.", NULL);
588  return 1;
589  }
590  } else
591  ticks = 100;
592 
593  pl = get_other_player_from_name(op, params);
594  if (!pl)
595  return 1;
596 
598  "You have been frozen by the DM!", NULL);
599 
601  "You freeze %s for %d ticks",
602  "You freeze %s for %d ticks",
603  pl->ob->name, ticks);
604 
605  pl->ob->speed_left = -(pl->ob->speed*ticks);
606  return 0;
607 }
608 
619 int command_arrest(object *op, char *params) {
620  object *dummy;
621  player *pl;
622 
623  if (!op)
624  return 0;
625  if (params == NULL) {
627  "Usage: arrest <player>.", NULL);
628  return 1;
629  }
630  pl = get_other_player_from_name(op, params);
631  if (!pl)
632  return 1;
633  dummy = get_jail_exit(pl->ob);
634  if (!dummy) {
635  /* we have nowhere to send the prisoner....*/
637  "Can't jail player, there is no map to hold them", NULL);
638  return 0;
639  }
640  enter_exit(pl->ob, dummy);
641  free_object(dummy);
643  "You have been arrested.", NULL);
645  "Jailed %s",
646  "Jailed %s",
647  pl->ob->name);
648  LOG(llevInfo, "Player %s arrested by %s\n", pl->ob->name, op->name);
649  return 1;
650 }
651 
661 int command_summon(object *op, char *params) {
662  int i;
663  object *dummy;
664  player *pl;
665 
666  if (!op)
667  return 0;
668 
669  if (params == NULL) {
671  "Usage: summon <player>.", NULL);
672  return 1;
673  }
674 
675  pl = get_other_player_from_name(op, params);
676  if (!pl)
677  return 1;
678 
679  i = find_free_spot(op, op->map, op->x, op->y, 1, 9);
680  if (i == -1) {
682  "Can not find a free spot to place summoned player.", NULL);
683  return 1;
684  }
685 
686  dummy = get_object();
687  EXIT_PATH(dummy) = add_string(op->map->path);
688  EXIT_X(dummy) = op->x+freearr_x[i];
689  EXIT_Y(dummy) = op->y+freearr_y[i];
690  enter_exit(pl->ob, dummy);
691  free_object(dummy);
693  "You are summoned.", NULL);
695  "You summon %s",
696  "You summon %s",
697  pl->ob->name);
698  return 1;
699 }
700 
711 /* mids 01/16/2002 */
712 int command_teleport(object *op, char *params) {
713  int i;
714  object *dummy;
715  player *pl;
716 
717  if (!op)
718  return 0;
719 
720  if (params == NULL) {
722  "Usage: teleport <player>.", NULL);
723  return 0;
724  }
725 
726  pl = find_player_partial_name(params);
727  if (!pl) {
729  "No such player or ambiguous name.", NULL);
730  return 0;
731  }
732 
733  i = find_free_spot(pl->ob, pl->ob->map, pl->ob->x, pl->ob->y, 1, 9);
734  if (i == -1) {
736  "Can not find a free spot to teleport to.", NULL);
737  return 0;
738  }
739 
740  dummy = get_object();
741  EXIT_PATH(dummy) = add_string(pl->ob->map->path);
742  EXIT_X(dummy) = pl->ob->x+freearr_x[i];
743  EXIT_Y(dummy) = pl->ob->y+freearr_y[i];
744  enter_exit(op, dummy);
745  free_object(dummy);
746  if (!op->contr->hidden)
748  "You see a portal open.", NULL);
750  "You teleport to %s",
751  "You teleport to %s",
752  pl->ob->name);
753 
754  return 1;
755 }
756 
783 int command_create(object *op, char *params) {
784  object *tmp = NULL;
785  int i, magic, set_magic = 0, set_nrof = 0, gotquote, gotspace;
786  uint32 nrof;
787  char buf[MAX_BUF], *cp, *bp = buf, *bp2, *bp3, *bp4, *endline;
788  archetype *at, *at_spell = NULL;
789  artifact *art = NULL;
790 
791  if (!op)
792  return 0;
793 
794  if (params == NULL) {
796  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]",
797  NULL);
798  return 1;
799  }
800  bp = params;
801 
802  /* We need to know where the line ends */
803  endline = bp+strlen(bp);
804 
805  if (sscanf(bp, "%u ", &nrof)) {
806  if ((bp = strchr(params, ' ')) == NULL) {
808  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]",
809  NULL);
810  return 1;
811  }
812  bp++;
813  set_nrof = 1;
814  LOG(llevDebug, "%s creates: (%u) %s\n", op->name, nrof, bp);
815  }
816  if (sscanf(bp, "%d ", &magic)) {
817  if ((bp = strchr(bp, ' ')) == NULL) {
819  "Usage: create [nr] [magic] <archetype> [ of <artifact>] [variable_to_patch setting]",
820  NULL);
821  return 1;
822  }
823  bp++;
824  set_magic = 1;
825  LOG(llevDebug, "%s creates: (%d) (%d) %s\n", op->name, nrof, magic, bp);
826  }
827  if ((cp = strstr(bp, " of ")) != NULL) {
828  *cp = '\0';
829  cp += 4;
830  }
831  for (bp2 = bp; *bp2; bp2++) {
832  if (*bp2 == ' ') {
833  *bp2 = '\0';
834  bp2++;
835  break;
836  }
837  }
838 
839  if ((at = find_archetype(bp)) == NULL) {
841  "No such archetype.", NULL);
842  return 1;
843  }
844 
845  if (cp) {
846  char spell_name[MAX_BUF], *fsp = NULL;
847 
848  /*
849  * Try to find a spell object for this. Note that
850  * we also set up spell_name which is only
851  * the first word.
852  */
853 
854  at_spell = find_archetype(cp);
855  if (!at_spell || at_spell->clone.type != SPELL)
856  at_spell = find_archetype_by_object_name(cp);
857  if (!at_spell || at_spell->clone.type != SPELL) {
858  strcpy(spell_name, cp);
859  fsp = strchr(spell_name, ' ');
860  if (fsp) {
861  *fsp = 0;
862  fsp++;
863  at_spell = find_archetype(spell_name);
864 
865  /* Got a spell, update the first string pointer */
866  if (at_spell && at_spell->clone.type == SPELL)
867  bp2 = cp+strlen(spell_name)+1;
868  else
869  at_spell = NULL;
870  } else
871  at_spell = NULL;
872  }
873 
874  /* OK - we didn't find a spell - presume the 'of'
875  * in this case means its an artifact.
876  */
877  if (!at_spell) {
878  if (find_artifactlist(at->clone.type) == NULL) {
880  "No artifact list for type %d\n",
881  "No artifact list for type %d\n",
882  at->clone.type);
883  } else {
884  art = find_artifactlist(at->clone.type)->items;
885 
886  do {
887  if (!strcmp(art->item->name, cp))
888  break;
889  art = art->next;
890  } while (art != NULL);
891  if (!art) {
893  "No such artifact ([%d] of %s)",
894  "No such artifact ([%d] of %s)",
895  at->clone.type, cp);
896  }
897  }
898  LOG(llevDebug, "%s creates: (%d) (%d) (%s) of (%s)\n", op->name, set_nrof ? nrof : 0, set_magic ? magic : 0, bp, cp);
899  }
900  } /* if cp */
901 
902  if ((at->clone.type == ROD || at->clone.type == WAND || at->clone.type == SCROLL || at->clone.type == HORN || at->clone.type == SPELLBOOK)
903  && !at_spell) {
905  "Unable to find spell %s for object that needs it, or it is of wrong type",
906  "Unable to find spell %s for object that needs it, or it is of wrong type",
907  cp);
908  return 1;
909  }
910 
911  /*
912  * Rather than have two different blocks with a lot of similar code,
913  * just create one object, do all the processing, and then determine
914  * if that one object should be inserted or if we need to make copies.
915  */
916  tmp = object_create_arch(at);
917  if (settings.real_wiz == FALSE)
918  SET_FLAG(tmp, FLAG_WAS_WIZ);
919  if (set_magic)
920  set_abs_magic(tmp, magic);
921  if (art)
922  give_artifact_abilities(tmp, art->item);
923  if (need_identify(tmp)) {
926  }
927 
928  /*
929  * This entire block here tries to find variable pairings,
930  * eg, 'hp 4' or the like. The mess here is that values
931  * can be quoted (eg "my cool sword"); So the basic logic
932  * is we want to find two spaces, but if we got a quote,
933  * any spaces there don't count.
934  */
935  while (*bp2 && bp2 <= endline) {
936  bp4 = NULL;
937  gotspace = 0;
938  gotquote = 0;
939  /* find the first quote */
940  for (bp3 = bp2; *bp3 && gotspace < 2 && gotquote < 2; bp3++) {
941 
942  /* Found a quote - now lets find the second one */
943  if (*bp3 == '"') {
944  *bp3 = ' ';
945  bp2 = bp3+1; /* Update start of string */
946  bp3++;
947  gotquote++;
948  while (*bp3) {
949  if (*bp3 == '"') {
950  *bp3 = '\0';
951  gotquote++;
952  } else
953  bp3++;
954  }
955  } else if (*bp3 == ' ') {
956  gotspace++;
957  }
958  }
959 
960  /*
961  * If we got two spaces, send the second one to null.
962  * if we've reached the end of the line, increase gotspace -
963  * this is perfectly valid for the list entry listed.
964  */
965  if (gotspace == 2 || gotquote == 2) {
966  bp3--; /* Undo the extra increment */
967  *bp3 = '\0';
968  } else if (*bp3 == '\0')
969  gotspace++;
970 
971  if ((gotquote && gotquote != 2)
972  || (gotspace != 2 && gotquote != 2)) {
973  /*
974  * Unfortunately, we've clobbered lots of values, so printing
975  * out what we have probably isn't useful. Break out, because
976  * trying to recover is probably won't get anything useful
977  * anyways, and we'd be confused about end of line pointers
978  * anyways.
979  */
981  "Malformed create line: %s",
982  "Malformed create line: %s",
983  bp2);
984  break;
985  }
986  /* bp2 should still point to the start of this line,
987  * with bp3 pointing to the end
988  */
989  if (set_variable(tmp, bp2) == -1)
991  "Unknown variable %s",
992  "Unknown variable %s",
993  bp2);
994  else
996  "(%s#%d)->%s",
997  "(%s#%d)->%s",
998  tmp->name, tmp->count, bp2);
999  bp2 = bp3+1;
1000  }
1001 
1002  if (at->clone.nrof) {
1003  if (at_spell)
1004  insert_ob_in_ob(arch_to_object(at_spell), tmp);
1005 
1006  tmp->x = op->x;
1007  tmp->y = op->y;
1008  if (set_nrof)
1009  tmp->nrof = nrof;
1010  tmp->map = op->map;
1011 
1012  if (at->clone.randomitems != NULL && !at_spell)
1014  op->map->difficulty, 0);
1015 
1016  /* Multipart objects can't be in inventory, put'em on floor. */
1017  if (!tmp->more) {
1018  tmp = insert_ob_in_ob(tmp, op);
1019  } else {
1020  insert_ob_in_map_at(tmp, op->map, op, 0, op->x, op->y);
1021  }
1022 
1023  /* Let's put this created item on stack so dm can access it easily. */
1024  dm_stack_push(op->contr, tmp->count);
1025 
1026  return 1;
1027  } else {
1028  for (i = 0; i < (set_nrof ? nrof : 1); i++) {
1029  archetype *atmp;
1030  object *prev = NULL, *head = NULL, *dup;
1031 
1032  for (atmp = at; atmp != NULL; atmp = atmp->more) {
1033  dup = arch_to_object(atmp);
1034 
1035  if (at_spell)
1036  insert_ob_in_ob(arch_to_object(at_spell), dup);
1037 
1038  /*
1039  * The head is what contains all the important bits,
1040  * so just copying it over should be fine.
1041  */
1042  if (head == NULL) {
1043  head = dup;
1044  copy_object(tmp, dup);
1045  }
1046  if (settings.real_wiz == FALSE)
1047  SET_FLAG(dup, FLAG_WAS_WIZ);
1048  dup->x = op->x+dup->arch->clone.x;
1049  dup->y = op->y+dup->arch->clone.y;
1050  dup->map = op->map;
1051 
1052  if (head != dup) {
1053  dup->head = head;
1054  prev->more = dup;
1055  }
1056  prev = dup;
1057  }
1058 
1059  if (QUERY_FLAG(head, FLAG_ALIVE)) {
1060  object *check = head;
1061  int size_x = 0;
1062  int size_y = 0;
1063 
1064  while (check) {
1065  size_x = MAX(size_x, check->arch->clone.x);
1066  size_y = MAX(size_y, check->arch->clone.y);
1067  check = check->more;
1068  }
1069 
1070  if (out_of_map(op->map, head->x+size_x, head->y+size_y)) {
1071  if (head->x < size_x || head->y < size_y) {
1072  dm_stack_pop(op->contr);
1073  free_object(head);
1075  "Object too big to insert in map, or wrong position.", NULL);
1076  free_object(tmp);
1077  return 1;
1078  }
1079 
1080  check = head;
1081  while (check) {
1082  check->x -= size_x;
1083  check->y -= size_y;
1084  check = check->more;
1085  }
1086  }
1087 
1088  insert_ob_in_map(head, op->map, op, 0);
1089  } else
1090  head = insert_ob_in_ob(head, op);
1091 
1092  /* Let's put this created item on stack so dm can access it easily. */
1093  /* Wonder if we really want to push all of these, but since
1094  * things like rods have nrof 0, we want to cover those.
1095  */
1096  dm_stack_push(op->contr, head->count);
1097 
1098  if (at->clone.randomitems != NULL && !at_spell)
1099  create_treasure(at->clone.randomitems, head, GT_APPLY, op->map->difficulty, 0);
1100  }
1101 
1102  /* free the one we used to copy */
1103  free_object(tmp);
1104  }
1105 
1106  return 1;
1107 }
1108 
1109 /*
1110  * Now follows dm-commands which are also acceptable from sockets
1111  */
1112 
1123 int command_inventory(object *op, char *params) {
1124  object *tmp;
1125  int i;
1126 
1127  if (!params) {
1128  inventory(op, NULL);
1129  return 0;
1130  }
1131 
1132  if (!sscanf(params, "%d", &i) || (tmp = find_object(i)) == NULL) {
1134  "Inventory of what object (nr)?", NULL);
1135  return 1;
1136  }
1137 
1138  inventory(op, tmp);
1139  return 1;
1140 }
1141 
1156 int command_skills(object *op, char *params) {
1157  show_skills(op, params);
1158  return 0;
1159 }
1160 
1171 int command_dump(object *op, char *params) {
1172  object *tmp;
1173  StringBuffer *sb;
1174  char *diff;
1175 
1176  tmp = get_dm_object(op->contr, &params, NULL);
1177  if (!tmp)
1178  return 1;
1179 
1180  sb = stringbuffer_new();
1181  dump_object(tmp, sb);
1182  diff = stringbuffer_finish(sb);
1184  free(diff);
1185  if (QUERY_FLAG(tmp, FLAG_OBJ_ORIGINAL))
1187  "Object is marked original", NULL);
1188  return 1;
1189 }
1190 
1202 int command_mon_aggr(object *op, char *params) {
1203  if (op->enemy || !QUERY_FLAG(op, FLAG_UNAGGRESSIVE)) {
1204  op->enemy = NULL;
1207  "Aggression turned OFF", NULL);
1208  } else {
1212  "Aggression turned ON", NULL);
1213  }
1214 
1215  return 1;
1216 }
1217 
1232 int command_possess(object *op, char *params) {
1233  object *victim;
1234  player *pl;
1235  int i;
1236  char buf[MAX_BUF];
1237 
1238  victim = NULL;
1239  if (params != NULL) {
1240  if (sscanf(params, "%d", &i))
1241  victim = find_object(i);
1242  else if (sscanf(params, "%s", buf))
1243  victim = find_object_name(buf);
1244  }
1245  if (victim == NULL) {
1247  "Patch what object (nr)?", NULL);
1248  return 1;
1249  }
1250 
1251  if (victim == op) {
1253  "As insane as you are, I cannot allow you to possess yourself.", NULL);
1254  return 1;
1255  }
1256 
1257  /* make the switch */
1258  pl = op->contr;
1259  victim->contr = pl;
1260  pl->ob = victim;
1261  victim->type = PLAYER;
1262  SET_FLAG(victim, FLAG_WIZ);
1263 
1264  /* basic patchup */
1265  /* The use of hard coded values is terrible. Note
1266  * that really, to be fair, this shouldn't get changed at
1267  * all - if you are possessing a kobold, you should have the
1268  * same limitations. As it is, as more body locations are added,
1269  * this will give this player more locations than perhaps
1270  * they should be allowed.
1271  */
1272  for (i = 0; i < NUM_BODY_LOCATIONS; i++)
1273  if (i == 1 || i == 6 || i == 8 || i == 9)
1274  victim->body_info[i] = 2;
1275  else
1276  victim->body_info[i] = 1;
1277 
1278  esrv_new_player(pl, 80); /* just pick a weight, we don't care */
1279  esrv_send_inventory(victim, victim);
1280 
1281  fix_object(victim);
1282 
1283  do_some_living(victim);
1284  return 1;
1285 }
1286 
1296 int command_patch(object *op, char *params) {
1297  char *arg, *arg2;
1298  object *tmp;
1299 
1300  tmp = get_dm_object(op->contr, &params, NULL);
1301  if (!tmp)
1302  /* Player already informed of failure */
1303  return 1;
1304 
1305  /* params set to first value by get_dm_default */
1306  arg = params;
1307  if (arg == NULL) {
1309  "Patch what values?", NULL);
1310  return 1;
1311  }
1312 
1313  if ((arg2 = strchr(arg, ' ')))
1314  arg2++;
1315  if (settings.real_wiz == FALSE)
1316  SET_FLAG(tmp, FLAG_WAS_WIZ); /* To avoid cheating */
1317  if (set_variable(tmp, arg) == -1)
1319  "Unknown variable %s",
1320  "Unknown variable %s",
1321  arg);
1322  else {
1324  "(%s#%d)->%s=%s",
1325  "(%s#%d)->%s=%s",
1326  tmp->name, tmp->count, arg, arg2);
1327  }
1328 
1329  return 1;
1330 }
1331 
1342 int command_remove(object *op, char *params) {
1343  object *tmp;
1344  int from;
1345 
1346  tmp = get_dm_object(op->contr, &params, &from);
1347  if (!tmp) {
1349  "Remove what object (nr)?", NULL);
1350  return 1;
1351  }
1352 
1353  if (tmp->type == PLAYER) {
1355  "Unable to remove a player!", NULL);
1356  return 1;
1357  }
1358 
1359  if (QUERY_FLAG(tmp, FLAG_REMOVED)) {
1360  char name[MAX_BUF];
1361 
1362  query_name(tmp, name, MAX_BUF);
1364  "%s is already removed!",
1365  "%s is already removed!",
1366  name);
1367  return 1;
1368  }
1369 
1370  if (from != STACK_FROM_STACK)
1371  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1372  dm_stack_pop(op->contr);
1373 
1374  /* Always work on the head - otherwise object will get in odd state */
1375  if (tmp->head)
1376  tmp = tmp->head;
1377  if (tmp->speed != 0) {
1378  tmp->speed = 0;
1379  update_ob_speed(tmp);
1380  }
1381  remove_ob(tmp);
1382  return 1;
1383 }
1384 
1394 int command_free(object *op, char *params) {
1395  object *tmp;
1396  int from;
1397 
1398  tmp = get_dm_object(op->contr, &params, &from);
1399 
1400  if (!tmp) {
1402  "Free what object (nr)?", NULL);
1403  return 1;
1404  }
1405 
1406  if (from != STACK_FROM_STACK)
1407  /* Item is either stack top, or is a number thus is now stack top, let's remove it */
1408  dm_stack_pop(op->contr);
1409 
1410  if (tmp->head)
1411  tmp = tmp->head;
1412 
1413  if (!QUERY_FLAG(tmp, FLAG_REMOVED)) {
1415  "Warning: item was not removed, will do so now.", NULL);
1416  remove_ob(tmp);
1417  }
1418 
1419  free_object(tmp);
1420  return 1;
1421 }
1422 
1433 int command_addexp(object *op, char *params) {
1434  char buf[MAX_BUF], skill[MAX_BUF];
1435  int i, q;
1436  object *skillob = NULL;
1437  player *pl;
1438 
1439  skill[0] = '\0';
1440  if ((params == NULL)
1441  || (strlen(params) > MAX_BUF)
1442  || ((q = sscanf(params, "%s %d %s", buf, &i, skill)) < 2)) {
1444  "Usage: addexp player quantity [skill].", NULL);
1445  return 1;
1446  }
1447 
1448  for (pl = first_player; pl != NULL; pl = pl->next)
1449  if (!strncmp(pl->ob->name, buf, MAX_NAME))
1450  break;
1451 
1452  if (pl == NULL) {
1454  "No such player.", NULL);
1455  return 1;
1456  }
1457 
1458  if (q >= 3) {
1459  skillob = find_skill_by_name(pl->ob, skill);
1460  if (!skillob) {
1462  "Unable to find skill %s in %s",
1463  "Unable to find skill %s in %s",
1464  skill, buf);
1465  return 1;
1466  }
1467 
1468  i = check_exp_adjust(skillob, i);
1469  skillob->stats.exp += i;
1470  calc_perm_exp(skillob);
1471  player_lvl_adj(pl->ob, skillob);
1472  }
1473 
1474  pl->ob->stats.exp += i;
1475  calc_perm_exp(pl->ob);
1476  player_lvl_adj(pl->ob, NULL);
1477 
1478  if (settings.real_wiz == FALSE)
1479  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1480  return 1;
1481 }
1482 
1493 int command_speed(object *op, char *params) {
1494  int i;
1495 
1496  if (params == NULL || !sscanf(params, "%d", &i)) {
1498  "Current speed is %d",
1499  "Current speed is %d",
1500  max_time);
1501  return 1;
1502  }
1503 
1504  set_max_time(i);
1505  reset_sleep();
1507  "The speed is changed to %d.",
1508  "The speed is changed to %d.",
1509  i);
1510  return 1;
1511 }
1512 
1513 /**************************************************************************/
1514 /* Mods made by Tyler Van Gorder, May 10-13, 1992. */
1515 /* CSUChico : tvangod@cscihp.ecst.csuchico.edu */
1516 /**************************************************************************/
1517 
1528 int command_stats(object *op, char *params) {
1529  player *pl;
1530 
1531  if (params == NULL) {
1533  "Who?", NULL);
1534  return 1;
1535  }
1536 
1537  pl = find_player_partial_name(params);
1538  if (pl == NULL) {
1540  "No such player.", NULL);
1541  return 1;
1542  }
1543 
1545  "[Fixed]Statistics for %s:", "Statistics for %s:", pl->ob->name);
1546 
1548  "[fixed]Str : %-2d H.P. : %-4d MAX : %d",
1549  "Str : %-2d H.P. : %-4d MAX : %d",
1550  pl->ob->stats.Str, pl->ob->stats.hp, pl->ob->stats.maxhp);
1551 
1553  "[fixed]Dex : %-2d S.P. : %-4d MAX : %d",
1554  "Dex : %-2d S.P. : %-4d MAX : %d",
1555  pl->ob->stats.Dex, pl->ob->stats.sp, pl->ob->stats.maxsp);
1556 
1558  "[fixed]Con : %-2d AC : %-4d WC : %d",
1559  "Con : %-2d AC : %-4d WC : %d",
1560  pl->ob->stats.Con, pl->ob->stats.ac, pl->ob->stats.wc);
1561 
1563  "[fixed]Int : %-2d Damage : %d",
1564  "Int : %-2d Damage : %d",
1565  pl->ob->stats.Int, pl->ob->stats.dam);
1566 
1568  "[fixed]Wis : %-2d EXP : %"FMT64,
1569  "Wis : %-2d EXP : %"FMT64,
1570  pl->ob->stats.Wis, pl->ob->stats.exp);
1571 
1573  "[fixed]Pow : %-2d Grace : %d",
1574  "Pow : %-2d Grace : %d",
1575  pl->ob->stats.Pow, pl->ob->stats.grace);
1576 
1578  "[fixed]Cha : %-2d Food : %d",
1579  "Cha : %-2d Food : %d",
1580  pl->ob->stats.Cha, pl->ob->stats.food);
1581  return 1;
1582 }
1583 
1595 int command_abil(object *op, char *params) {
1596  char thing[20], thing2[20];
1597  int iii;
1598  player *pl;
1599 
1600  iii = 0;
1601  thing[0] = '\0';
1602  thing2[0] = '\0';
1603  if (params == NULL
1604  || !sscanf(params, "%s %s %d", thing, thing2, &iii)
1605  || thing == NULL) {
1607  "Who?", NULL);
1608  return 1;
1609  }
1610 
1611  if (thing2 == NULL) {
1613  "You can't change that.", NULL);
1614  return 1;
1615  }
1616 
1617  if (iii < MIN_STAT || iii > MAX_STAT) {
1619  "Illegal range of stat.\n", NULL);
1620  return 1;
1621  }
1622 
1623  for (pl = first_player; pl != NULL; pl = pl->next) {
1624  if (!strcmp(pl->ob->name, thing)) {
1625  if (settings.real_wiz == FALSE)
1626  SET_FLAG(pl->ob, FLAG_WAS_WIZ);
1627  if (!strcmp("str", thing2))
1628  pl->ob->stats.Str = iii, pl->orig_stats.Str = iii;
1629  if (!strcmp("dex", thing2))
1630  pl->ob->stats.Dex = iii, pl->orig_stats.Dex = iii;
1631  if (!strcmp("con", thing2))
1632  pl->ob->stats.Con = iii, pl->orig_stats.Con = iii;
1633  if (!strcmp("wis", thing2))
1634  pl->ob->stats.Wis = iii, pl->orig_stats.Wis = iii;
1635  if (!strcmp("cha", thing2))
1636  pl->ob->stats.Cha = iii, pl->orig_stats.Cha = iii;
1637  if (!strcmp("int", thing2))
1638  pl->ob->stats.Int = iii, pl->orig_stats.Int = iii;
1639  if (!strcmp("pow", thing2))
1640  pl->ob->stats.Pow = iii, pl->orig_stats.Pow = iii;
1642  "%s has been altered.",
1643  "%s has been altered.",
1644  pl->ob->name);
1645  fix_object(pl->ob);
1646  return 1;
1647  }
1648  }
1649 
1651  "No such player.", NULL);
1652  return 1;
1653 }
1654 
1665 int command_reset(object *op, char *params) {
1666  mapstruct *m;
1667  object *dummy = NULL, *tmp = NULL;
1668  char path[HUGE_BUF];
1669  char *space, *confirmation = NULL;
1670  int res = 0;
1671 
1672  if (params == NULL) {
1674  "Reset what map [name]?", NULL);
1675  return 1;
1676  }
1677 
1678  space = strchr(params, ' ');
1679  if (space != NULL) {
1680  confirmation = params;
1681  params = space + 1;
1682  }
1683 
1684  if (strcmp(params, ".") == 0)
1685  snprintf(path, sizeof(path), "%s", op->map->path);
1686  else
1687  path_combine_and_normalize(op->map->path, params, path, sizeof(path));
1688  m = has_been_loaded(path);
1689  if (m == NULL) {
1691  "No such map.", NULL);
1692  return 1;
1693  }
1694 
1695  if (confirmation) {
1696  if (strcmp(params, ".") == 0 && m->unique) {
1698  "Can't reset a player unique map while on it, use 'reset full-reset %s' while not on it.",
1699  "Can't reset a player unique map while on it, use 'reset full-reset %s' while not on it.",
1700  m->path);
1701  return;
1702  }
1703 
1704  if (strncmp("full-reset", confirmation, strlen("full-reset"))) {
1706  "Invalid confirmation, must be 'full-reset'.", "Invalid confirmation, must be 'full-reset'.");
1707  return;
1708  }
1709  }
1710 
1711  /* Forbid using reset on our own map when we're in a transport, as
1712  * it has the displeasant effect of crashing the server.
1713  * - gros, July 25th 2006 */
1714  if ((op->contr && op->contr->transport) && (op->map == m)) {
1716  "You need to disembark first.", NULL);
1717  return 1;
1718  }
1719 
1720  snprintf(path, sizeof(path), "%s", m->path);
1721 
1722  if (m->in_memory != MAP_SWAPPED) {
1723  if (m->in_memory != MAP_IN_MEMORY) {
1724  LOG(llevError, "Tried to swap out map which was not in memory.\n");
1725  return 0;
1726  }
1727 
1728  /*
1729  * Only attempt to remove the player that is doing the reset, and not other
1730  * players or wiz's.
1731  */
1732  if (op->map == m) {
1733  if (strncmp(m->path, "/random/", 8) == 0) {
1734  /* This is not a very satisfying solution - it would be much better
1735  * to recreate a random map with the same seed value as the old one.
1736  * Unfortunately, I think recreating the map would require some
1737  * knowledge about its 'parent', which appears very non-trivial to
1738  * me.
1739  * On the other hand, this should prevent the freeze that this
1740  * situation caused. - gros, 26th July 2006.
1741  */
1743  "You cannot reset a random map when inside it.", NULL);
1744  return 1;
1745  }
1746 
1747  dummy = get_object();
1748  dummy->map = NULL;
1749  EXIT_X(dummy) = op->x;
1750  EXIT_Y(dummy) = op->y;
1751  EXIT_PATH(dummy) = add_string(op->map->path);
1752  remove_ob(op);
1753  op->map = NULL;
1754  tmp = op;
1755  }
1756  res = swap_map(m);
1757  }
1758 
1759  if (res < 0 || m->in_memory != MAP_SWAPPED) {
1760  player *pl;
1761  int playercount = 0;
1762 
1763  /* Need to re-insert player if swap failed for some reason */
1764  if (tmp) {
1765  insert_ob_in_map(op, m, NULL, 0);
1766  free_object(dummy);
1767  }
1768 
1769  if (res < 0 && res != SAVE_ERROR_PLAYER)
1770  /* no need to warn if player on map, code below checks that. */
1772  "Reset failed, error code: %d.", NULL, res);
1773  else {
1775  "Reset failed, couldn't swap map, the following players are on it:",
1776  NULL);
1777  for (pl = first_player; pl != NULL; pl = pl->next) {
1778  if (pl->ob->map == m && pl->ob != op) {
1780  pl->ob->name, NULL);
1781  playercount++;
1782  }
1783  }
1784  if (!playercount)
1786  "hmm, I don't see any other players on this map, something else is the problem.",
1787  NULL);
1788  return 1;
1789  }
1790  }
1791 
1792  /* Here, map reset succeeded. */
1793 
1794  if (m && m->in_memory == MAP_SWAPPED) {
1795 
1796  if (confirmation) {
1798  LOG(llevDebug, "DM %s fully resetting map %s.\n", op->name, m->path);
1799  } else
1800  LOG(llevDebug, "DM %s resetting map %s.\n", op->name, m->path);
1801 
1802  /* setting this effectively causes an immediate reload */
1803  m->reset_time = 1;
1804  flush_old_maps();
1805  }
1806 
1807  if (confirmation)
1809  "Fully resetting map %s.", "Fully resetting map %s.",
1810  path);
1811  else
1813  "Resetting map %s.", "Resetting map %s.",
1814  path);
1815 
1816  if (tmp) {
1817  enter_exit(tmp, dummy);
1818  free_object(dummy);
1819  }
1820 
1821  if (confirmation == NULL) {
1823  "Use 'reset full-reset %s' to fully reset the map.", params);
1824  }
1825 
1826  return 1;
1827 }
1828 
1839 int command_nowiz(object *op, char *params) { /* 'noadm' is alias */
1840  CLEAR_FLAG(op, FLAG_WIZ);
1841  CLEAR_FLAG(op, FLAG_WIZPASS);
1842  CLEAR_FLAG(op, FLAG_WIZCAST);
1843  if (op->contr->followed_player)
1845 
1846  if (settings.real_wiz == TRUE)
1847  CLEAR_FLAG(op, FLAG_WAS_WIZ);
1848  if (op->contr->hidden) {
1850  "You are no longer hidden from other players", NULL);
1851  op->map->players++;
1853  "%s has entered the game.",
1854  "%s has entered the game.",
1855  op->name);
1856  op->contr->hidden = 0;
1857  op->invisible = 1;
1858  } else
1860  "The Dungeon Master is gone..", NULL);
1861 
1862  update_los(op);
1863 
1864  return 1;
1865 }
1866 
1887 static int checkdm(object *op, const char *pl_name, const char *pl_passwd, const char *pl_host) {
1888  FILE *dmfile;
1889  char buf[MAX_BUF];
1890  char line_buf[160], name[160], passwd[160], host[160];
1891 
1892 #ifdef RESTRICTIVE_DM
1893  *pl_name = op->name ? op->name : "*";
1894 #endif
1895 
1896  snprintf(buf, sizeof(buf), "%s/%s", settings.confdir, DMFILE);
1897  if ((dmfile = fopen(buf, "r")) == NULL) {
1898  LOG(llevDebug, "Could not find DM file.\n");
1899  return 0;
1900  }
1901 
1902  while (fgets(line_buf, 160, dmfile) != NULL) {
1903  if (line_buf[0] == '#')
1904  continue;
1905  if (sscanf(line_buf, "%[^:]:%[^:]:%s\n", name, passwd, host) != 3) {
1906  LOG(llevError, "Warning - malformed dm file entry: %s\n", line_buf);
1907  } else if ((!strcmp(name, "*") || (pl_name && !strcmp(pl_name, name)))
1908  && (!strcmp(passwd, "*") || !strcmp(passwd, pl_passwd))
1909  && (!strcmp(host, "*") || !strcmp(host, pl_host))) {
1910  fclose(dmfile);
1911  return (1);
1912  }
1913  }
1914  fclose(dmfile);
1915  return (0);
1916 }
1917 
1932 int do_wizard_dm(object *op, char *params, int silent) {
1933  if (!op->contr)
1934  return 0;
1935 
1936  if (QUERY_FLAG(op, FLAG_WIZ)) {
1938  "You are already the Dungeon Master!", NULL);
1939  return 0;
1940  }
1941 
1942  if (checkdm(op, op->name, (params ? params : "*"), op->contr->socket.host)) {
1943  SET_FLAG(op, FLAG_WIZ);
1944  SET_FLAG(op, FLAG_WAS_WIZ);
1945  SET_FLAG(op, FLAG_WIZPASS);
1946  SET_FLAG(op, FLAG_WIZCAST);
1948  "Ok, you are the Dungeon Master!", NULL);
1949  /*
1950  * Remove setting flying here - that won't work, because next
1951  * fix_object() is called that will get cleared - proper solution
1952  * is probably something like a wiz_force which gives that and any
1953  * other desired abilities.
1954  */
1955  clear_los(op);
1956  op->contr->write_buf[0] = '\0';
1957 
1958  if (!silent)
1961  "The Dungeon Master has arrived!", NULL);
1962 
1963  return 1;
1964  } else {
1966  "Sorry Pal, I don't think so.", NULL);
1967  op->contr->write_buf[0] = '\0';
1968  return 0;
1969  }
1970 }
1971 
1983 int command_dm(object *op, char *params) {
1984  do_wizard_dm(op, params, 0);
1985  return 1;
1986 }
1987 
1998 int command_invisible(object *op, char *params) {
1999  if (op) {
2000  op->invisible += 100;
2003  "You turn invisible.", NULL);
2004  }
2005 
2006  return 0;
2007 }
2008 
2026 static object *get_spell_by_name(object *op, const char *spell_name) {
2027  archetype *ar;
2028  archetype *found;
2029  int conflict_found;
2030  size_t spell_name_length;
2031 
2032  /* First check for full name matches. */
2033  conflict_found = 0;
2034  found = NULL;
2035  for (ar = first_archetype; ar != NULL; ar = ar->next) {
2036  if (ar->clone.type != SPELL)
2037  continue;
2038 
2039  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2040  continue;
2041 
2042  if (strcmp(ar->clone.name, spell_name) != 0)
2043  continue;
2044 
2045  if (found != NULL) {
2046  if (!conflict_found) {
2047  conflict_found = 1;
2049  "More than one archetype matches the spell name %s:",
2050  "More than one archetype matches the spell name %s:",
2051  spell_name);
2053  "- %s",
2054  "- %s",
2055  found->name);
2056  }
2058  "- %s",
2059  "- %s",
2060  ar->name);
2061  continue;
2062  }
2063 
2064  found = ar;
2065  }
2066 
2067  /* No match if more more than one archetype matches. */
2068  if (conflict_found)
2069  return NULL;
2070 
2071  /* Return if exactly one archetype matches. */
2072  if (found != NULL)
2073  return arch_to_object(found);
2074 
2075  /* No full match found: now check for partial matches. */
2076  spell_name_length = strlen(spell_name);
2077  conflict_found = 0;
2078  found = NULL;
2079  for (ar = first_archetype; ar != NULL; ar = ar->next) {
2080  if (ar->clone.type != SPELL)
2081  continue;
2082 
2083  if (strncmp(ar->name, "spelldirect_", 12) == 0)
2084  continue;
2085 
2086  if (strncmp(ar->clone.name, spell_name, spell_name_length) != 0)
2087  continue;
2088 
2089  if (found != NULL) {
2090  if (!conflict_found) {
2091  conflict_found = 1;
2093  "More than one spell matches %s:",
2094  "More than one spell matches %s:",
2095  spell_name);
2097  "- %s",
2098  "- %s",
2099  found->clone.name);
2100  }
2102  "- %s",
2103  "- %s",
2104  ar->clone.name);
2105  continue;
2106  }
2107 
2108  found = ar;
2109  }
2110 
2111  /* No match if more more than one archetype matches. */
2112  if (conflict_found)
2113  return NULL;
2114 
2115  /* Return if exactly one archetype matches. */
2116  if (found != NULL)
2117  return arch_to_object(found);
2118 
2119  /* No spell found: just print an error message. */
2121  "The spell %s does not exist.",
2122  "The spell %s does not exist.",
2123  spell_name);
2124  return NULL;
2125 }
2126 
2141 static int command_learn_spell_or_prayer(object *op, char *params, int special_prayer) {
2142  object *tmp;
2143 
2144  if (op->contr == NULL || params == NULL) {
2146  "Which spell do you want to learn?", NULL);
2147  return 0;
2148  }
2149 
2150  tmp = get_spell_by_name(op, params);
2151  if (tmp == NULL) {
2152  return 0;
2153  }
2154 
2155  if (check_spell_known(op, tmp->name)) {
2157  "You already know the spell %s.",
2158  "You already know the spell %s.",
2159  tmp->name);
2160  return 0;
2161  }
2162 
2163  do_learn_spell(op, tmp, special_prayer);
2164  free_object(tmp);
2165  return 1;
2166 }
2167 
2180 int command_learn_spell(object *op, char *params) {
2181  return command_learn_spell_or_prayer(op, params, 0);
2182 }
2183 
2196 int command_learn_special_prayer(object *op, char *params) {
2197  return command_learn_spell_or_prayer(op, params, 1);
2198 }
2199 
2210 int command_forget_spell(object *op, char *params) {
2211  object *spell;
2212 
2213  if (op->contr == NULL || params == NULL) {
2215  "Which spell do you want to forget?", NULL);
2216  return 0;
2217  }
2218 
2219  spell = lookup_spell_by_name(op, params);
2220  if (spell == NULL) {
2222  "You do not know the spell %s.",
2223  "You do not know the spell %s.",
2224  params);
2225  return 0;
2226  }
2227 
2228  do_forget_spell(op, spell->name);
2229  return 1;
2230 }
2231 
2242 int command_listplugins(object *op, char *params) {
2244  return 1;
2245 }
2246 
2259 int command_loadplugin(object *op, char *params) {
2260  char buf[MAX_BUF];
2261 
2262  if (params == NULL) {
2264  "Load which plugin?", NULL);
2265  return 1;
2266  }
2267 
2268  strcpy(buf, LIBDIR);
2269  strcat(buf, "/plugins/");
2270  strcat(buf, params);
2271  LOG(llevDebug, "Requested plugin file is %s\n", buf);
2272  if (plugins_init_plugin(buf) == 0) {
2273  LOG(llevInfo, "DM %s loaded plugin %s\n", op->name, params);
2275  "Plugin %s successfully loaded.",
2276  "Plugin %s successfully loaded.",
2277  params);
2278  } else
2280  "Could not load plugin %s.",
2281  "Could not load plugin %s.",
2282  params);
2283  return 1;
2284 }
2285 
2298 int command_unloadplugin(object *op, char *params) {
2299  if (params == NULL) {
2301  "Remove which plugin?", NULL);
2302  return 1;
2303  }
2304 
2305  if (plugins_remove_plugin(params) == 0) {
2306  LOG(llevInfo, "DM %s unloaded plugin %s\n", op->name, params);
2308  "Plugin %s successfully removed.",
2309  "Plugin %s successfully removed.",
2310  params);
2311  } else
2313  "Could not remove plugin %s.",
2314  "Could not remove plugin %s.",
2315  params);
2316  return 1;
2317 }
2318 
2333 int command_dmhide(object *op, char *params) {
2334  if (!do_wizard_dm(op, params, 1))
2335  return 0;
2336 
2337  do_wizard_hide(op, 1);
2338  return 1;
2339 }
2340 
2348  if (!pl->stack_items || !pl->stack_position) {
2350  "Empty stack!", NULL);
2351  return;
2352  }
2353 
2354  pl->stack_position--;
2356  "Popped item from stack, %d left.",
2357  "Popped item from stack, %d left.",
2358  pl->stack_position);
2359 }
2360 
2374  object *ob;
2375 
2376  if (!pl->stack_position) {
2378  "Empty stack!", NULL);
2379  return NULL;
2380  }
2381 
2382  ob = find_object(pl->stack_items[pl->stack_position-1]);
2383  if (!ob) {
2385  "Stacked item was removed!", NULL);
2386  dm_stack_pop(pl);
2387  return NULL;
2388  }
2389 
2390  return ob;
2391 }
2392 
2404  if (!pl->stack_items) {
2405  pl->stack_items = (tag_t *)malloc(sizeof(tag_t)*STACK_SIZE);
2406  memset(pl->stack_items, 0, sizeof(tag_t)*STACK_SIZE);
2407  }
2408 
2409  if (pl->stack_position == STACK_SIZE) {
2411  "Item stack full!", NULL);
2412  return;
2413  }
2414 
2415  pl->stack_items[pl->stack_position] = item;
2417  "Item stacked as %d.",
2418  "Item stacked as %d.",
2419  pl->stack_position);
2420  pl->stack_position++;
2421 }
2422 
2450 object *get_dm_object(player *pl, char **params, int *from) {
2451  int item_tag, item_position;
2452  object *ob;
2453 
2454  if (!pl)
2455  return NULL;
2456 
2457  if (!params || !*params || **params == '\0') {
2458  if (from)
2459  *from = STACK_FROM_TOP;
2460  /* No parameter => get stack item */
2461  return dm_stack_peek(pl);
2462  }
2463 
2464  /* Let's clean white spaces */
2465  while (**params == ' ')
2466  (*params)++;
2467 
2468  /* Next case: number => item tag */
2469  if (sscanf(*params, "%d", &item_tag)) {
2470  /* Move parameter to next item */
2471  while (isdigit(**params))
2472  (*params)++;
2473 
2474  /* And skip blanks, too */
2475  while (**params == ' ')
2476  (*params)++;
2477 
2478  /* Get item */
2479  ob = find_object(item_tag);
2480  if (!ob) {
2481  if (from)
2482  *from = STACK_FROM_NONE;
2484  "No such item %d!",
2485  "No such item %d!",
2486  item_tag);
2487  return NULL;
2488  }
2489 
2490  /* Got one, let's push it on stack */
2491  dm_stack_push(pl, item_tag);
2492  if (from)
2493  *from = STACK_FROM_NUMBER;
2494  return ob;
2495  }
2496 
2497  /* Next case: $number => stack item */
2498  if (sscanf(*params, "$%d", &item_position)) {
2499  /* Move parameter to next item */
2500  (*params)++;
2501 
2502  while (isdigit(**params))
2503  (*params)++;
2504  while (**params == ' ')
2505  (*params)++;
2506 
2507  if (item_position >= pl->stack_position) {
2508  if (from)
2509  *from = STACK_FROM_NONE;
2511  "No such stack item %d!",
2512  "No such stack item %d!",
2513  item_position);
2514  return NULL;
2515  }
2516 
2517  ob = find_object(pl->stack_items[item_position]);
2518  if (!ob) {
2519  if (from)
2520  *from = STACK_FROM_NONE;
2522  "Stack item %d was removed.",
2523  "Stack item %d was removed.",
2524  item_position);
2525  return NULL;
2526  }
2527 
2528  if (from)
2529  *from = item_position < pl->stack_position-1 ? STACK_FROM_STACK : STACK_FROM_TOP;
2530  return ob;
2531  }
2532 
2533  /* Next case: 'me' => return pl->ob */
2534  if (!strncmp(*params, "me", 2)) {
2535  if (from)
2536  *from = STACK_FROM_NUMBER;
2537  dm_stack_push(pl, pl->ob->count);
2538 
2539  /* Skip to next token */
2540  (*params) += 2;
2541  while (**params == ' ')
2542  (*params)++;
2543 
2544  return pl->ob;
2545  }
2546 
2547  /* Last case: get stack top */
2548  if (from)
2549  *from = STACK_FROM_TOP;
2550  return dm_stack_peek(pl);
2551 }
2552 
2563 int command_stack_pop(object *op, char *params) {
2564  dm_stack_pop(op->contr);
2565  return 0;
2566 }
2567 
2578 int command_stack_push(object *op, char *params) {
2579  object *ob;
2580  int from;
2581  ob = get_dm_object(op->contr, &params, &from);
2582 
2583  if (ob && from != STACK_FROM_NUMBER)
2584  /* Object was from stack, need to push it again */
2585  dm_stack_push(op->contr, ob->count);
2586 
2587  return 0;
2588 }
2589 
2600 int command_stack_list(object *op, char *params) {
2601  int item;
2602  object *display;
2603  player *pl = op->contr;
2604 
2606  "Item stack contents:", NULL);
2607 
2608  for (item = 0; item < pl->stack_position; item++) {
2609  display = find_object(pl->stack_items[item]);
2610  if (display)
2612  " %d : %s [%d]",
2613  " %d : %s [%d]",
2614  item, display->name, display->count);
2615  else
2616  /* Item was freed */
2618  " %d : (lost item: %d)",
2619  " %d : (lost item: %d)",
2620  item, pl->stack_items[item]);
2621  }
2622 
2623  return 0;
2624 }
2625 
2636 int command_stack_clear(object *op, char *params) {
2637  op->contr->stack_position = 0;
2639  "Item stack cleared.", NULL);
2640  return 0;
2641 }
2642 
2664 int command_diff(object *op, char *params) {
2665  object *left, *right, *top;
2666  char *diff;
2667  StringBuffer *sb;
2668  int left_from, right_from;
2669 
2670  top = NULL;
2671 
2672  left = get_dm_object(op->contr, &params, &left_from);
2673  if (!left) {
2675  "Compare to what item?", NULL);
2676  return 0;
2677  }
2678 
2679  if (left_from == STACK_FROM_NUMBER)
2680  /* Item was stacked, remove it else right will be the same... */
2681  dm_stack_pop(op->contr);
2682 
2683  right = get_dm_object(op->contr, &params, &right_from);
2684 
2685  if (!right) {
2687  "Compare what item?", NULL);
2688  return 0;
2689  }
2690 
2692  "Item difference:", NULL);
2693 
2694  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2695  /*
2696  * Special case: both items were taken from stack top.
2697  * Override the behaviour, taking left as item just below top, if exists.
2698  * See function description for why.
2699  * Besides, if we don't do anything, compare an item to itself, not really useful.
2700  */
2701  if (op->contr->stack_position > 1) {
2702  left = find_object(op->contr->stack_items[op->contr->stack_position-2]);
2703  if (left)
2705  "(Note: first item taken from undertop)", NULL);
2706  else
2707  /* Stupid case: item under top was freed, fallback to stack top */
2708  left = right;
2709  }
2710  }
2711 
2712  sb = stringbuffer_new();
2713  get_ob_diff(sb, left, right);
2714  diff = stringbuffer_finish(sb);
2715  if (*diff == '\0') {
2716  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DM, "Objects are the same.", NULL);
2717  } else {
2719  }
2720  free(diff);
2721  return 0;
2722 }
2723 
2733 int command_insert_into(object *op, char *params) {
2734  object *left, *right, *inserted;
2735  int left_from, right_from;
2736  char what[MAX_BUF], where[MAX_BUF];
2737 
2738  left = get_dm_object(op->contr, &params, &left_from);
2739  if (!left) {
2741  "Insert into what object?", NULL);
2742  return 0;
2743  }
2744 
2745  if (left_from == STACK_FROM_NUMBER)
2746  /* Item was stacked, remove it else right will be the same... */
2747  dm_stack_pop(op->contr);
2748 
2749  right = get_dm_object(op->contr, &params, &right_from);
2750 
2751  if (!right) {
2753  "Insert what item?", NULL);
2754  return 0;
2755  }
2756 
2757  if (left_from == STACK_FROM_TOP && right_from == STACK_FROM_TOP) {
2758  /*
2759  * Special case: both items were taken from stack top.
2760  * Override the behaviour, taking left as item just below top, if exists.
2761  * See function description for why.
2762  * Besides, can't insert an item into itself.
2763  */
2764  if (op->contr->stack_position > 1) {
2765  left = find_object(op->contr->stack_items[op->contr->stack_position-2]);
2766  if (left)
2768  "(Note: item to insert into taken from undertop)", NULL);
2769  else
2770  /* Stupid case: item under top was freed, fallback to stack top */
2771  left = right;
2772  }
2773  }
2774 
2775  if (left == right) {
2777  "Can't insert an object into itself!", NULL);
2778  return 0;
2779  }
2780 
2781  if (right->type == PLAYER) {
2783  "Can't insert a player into something!", NULL);
2784  return 0;
2785  }
2786 
2787  if (!QUERY_FLAG(right, FLAG_REMOVED))
2788  remove_ob(right);
2789  inserted = insert_ob_in_ob(right, left);
2790  if (left->type == PLAYER) {
2791  if (inserted != right)
2792  /* item was merged, so updating name and such. */
2793  esrv_update_item(UPD_WEIGHT|UPD_NAME|UPD_NROF, left, inserted);
2794  }
2795  query_name(inserted, what, MAX_BUF);
2796  query_name(left, where, MAX_BUF);
2798  "Inserted %s in %s",
2799  "Inserted %s in %s",
2800  what, where);
2801  return 0;
2802 
2803 }
2804 
2815 int command_style_map_info(object *op, char *params) {
2816  extern mapstruct *styles;
2817  mapstruct *mp;
2818  int maps_used = 0, mapmem = 0, objects_used = 0, x, y;
2819  object *tmp;
2820 
2821  for (mp = styles; mp != NULL; mp = mp->next) {
2822  maps_used++;
2823  mapmem += MAP_WIDTH(mp)*MAP_HEIGHT(mp)*(sizeof(object *)+sizeof(MapSpace))+sizeof(mapstruct);
2824  for (x = 0; x < MAP_WIDTH(mp); x++) {
2825  for (y = 0; y < MAP_HEIGHT(mp); y++) {
2826  for (tmp = GET_MAP_OB(mp, x, y); tmp != NULL; tmp = tmp->above)
2827  objects_used++;
2828  }
2829  }
2830  }
2832  "[fixed]Style maps loaded: %d",
2833  "Style maps loaded: %d",
2834  maps_used);
2836  "[fixed]Memory used, not",
2837  "Memory used, not");
2839  "[fixed]including objects: %d",
2840  "including objects: %d",
2841  mapmem);
2843  "Style objects: %d",
2844  "Style objects: %d",
2845  objects_used);
2847  "Mem for objects: %d",
2848  "Mem for objects: %d",
2849  objects_used*sizeof(object));
2850  return 0;
2851 }
2852 
2863 int command_follow(object *op, char *params) {
2864  player *other;
2865 
2866  if (!params) {
2867  if (op->contr->followed_player != NULL) {
2868  draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "You stop following %s.", NULL, op->contr->followed_player);
2870  }
2871  return 0;
2872  }
2873 
2874  other = find_player_partial_name(params);
2875  if (!other) {
2876  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "No such player or ambiguous name.", NULL);
2877  return 0;
2878  }
2879  if (other == op->contr) {
2880  draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_DM, "You can't follow yourself.", NULL);
2881  return 0;
2882  }
2883 
2884  if (op->contr->followed_player)
2886 
2887  op->contr->followed_player = add_string(other->ob->name);
2889  return 0;
2890 }
void do_wizard_hide(object *op, int silent_dm)
Definition: c_wiz.c:147
char path[HUGE_BUF]
Definition: map.h:384
object * lookup_spell_by_name(object *op, const char *spname)
Definition: spell_util.c:430
sint8 Int
Definition: living.h:78
#define NUM_BODY_LOCATIONS
Definition: object.h:41
int command_inventory(object *op, char *params)
Definition: c_wiz.c:1123
Definition: player.h:146
archetype * find_archetype(const char *name)
Definition: arch.c:700
sint8 ac
Definition: living.h:79
#define BANISHFILE
Definition: config.h:588
void show_skills(object *op, const char *search)
Definition: skill_util.c:773
#define UP_OBJ_FACE
Definition: object.h:356
uint32 worldmapstarty
Definition: global.h:381
uint32 worldmapstartx
Definition: global.h:380
#define FALSE
Definition: exp.c:42
void enter_exit(object *op, object *exit_ob)
Definition: server.c:740
void esrv_new_player(player *pl, uint32 weight)
Definition: request.c:868
int command_nowiz(object *op, char *params)
Definition: c_wiz.c:1839
object * check_spell_known(object *op, const char *name)
Definition: spell_util.c:408
int command_skills(object *op, char *params)
Definition: c_wiz.c:1156
int command_overlay_reset(object *op, char *params)
Definition: c_wiz.c:430
int command_create(object *op, char *params)
Definition: c_wiz.c:783
#define SET_FLAG(xyz, p)
Definition: define.h:510
uint32 worldmaptilesx
Definition: global.h:382
#define EVENT_KICK
Definition: plugin.h:93
void do_forget_spell(object *op, const char *spell)
Definition: apply.c:440
#define NDI_ALL
Definition: newclient.h:220
#define WAND
Definition: define.h:291
void do_some_living(object *op)
Definition: player.c:3017
#define UPD_NAME
Definition: newclient.h:258
#define NDI_ORANGE
Definition: newclient.h:199
#define FLAG_FRIENDLY
Definition: define.h:542
int command_forget_spell(object *op, char *params)
Definition: c_wiz.c:2210
struct artifactstruct * items
Definition: artifact.h:52
object * insert_ob_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:1761
#define DMFILE
Definition: config.h:374
int save_player(object *op, int flag)
Definition: login.c:223
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:64
int command_listplugins(object *op, char *params)
Definition: c_wiz.c:2242
object * find_object_name(const char *str)
Definition: object.c:459
#define HUGE_BUF
Definition: define.h:83
void esrv_update_item(int flags, object *pl, object *op)
Definition: standalone.c:200
struct treasureliststruct * randomitems
Definition: object.h:236
sint16 players
Definition: map.h:365
int command_arrest(object *op, char *params)
Definition: c_wiz.c:619
#define MSG_TYPE_COMMAND_SUCCESS
Definition: newclient.h:448
#define MAP_HEIGHT(m)
Definition: map.h:99
object clone
Definition: object.h:326
socket_struct socket
Definition: player.h:148
sint16 invisible
Definition: object.h:211
short freearr_x[SIZEOFFREE]
Definition: object.c:75
int command_dmhide(object *op, char *params)
Definition: c_wiz.c:2333
#define MSG_TYPE_ADMIN_PLAYER
Definition: newclient.h:414
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
void esrv_send_inventory(object *pl, object *op)
Definition: item.c:307
#define SCROLL
Definition: define.h:293
int command_insert_into(object *op, char *params)
Definition: c_wiz.c:2733
void update_object(object *op, int action)
Definition: object.c:1112
void play_again(object *op)
Definition: player.c:810
void dm_stack_pop(player *pl)
Definition: c_wiz.c:2347
sint64 exp
Definition: living.h:88
uint32 in_memory
Definition: map.h:366
struct obj * above
Definition: object.h:146
int command_stack_clear(object *op, char *params)
Definition: c_wiz.c:2636
uint32 worldmaptilesy
Definition: global.h:383
enum Sock_Status status
Definition: newserver.h:116
int command_setgod(object *op, char *params)
Definition: c_wiz.c:232
int command_style_map_info(object *op, char *params)
Definition: c_wiz.c:2815
sint16 x
Definition: object.h:179
int command_possess(object *op, char *params)
Definition: c_wiz.c:1232
sint16 sp
Definition: living.h:83
const object * find_god(const char *name)
Definition: gods.c:92
object * find_object(tag_t i)
Definition: object.c:439
int command_diff(object *op, char *params)
Definition: c_wiz.c:2664
int command_addexp(object *op, char *params)
Definition: c_wiz.c:1433
int command_toggle_shout(object *op, char *params)
Definition: c_wiz.c:459
void draw_ext_info_format(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *new_format, const char *old_format,...)
Definition: standalone.c:175
struct obj * enemy
Definition: object.h:232
#define STACK_SIZE
Definition: c_wiz.c:44
int swap_map(mapstruct *map)
Definition: swap.c:146
Definition: object.h:321
#define ST_PLAYING
Definition: define.h:886
#define NDI_DK_ORANGE
Definition: newclient.h:201
char * host
Definition: newserver.h:125
object * get_jail_exit(object *op)
Definition: region.c:272
#define PLAYER
Definition: define.h:113
sint16 maxsp
Definition: living.h:84
sint8 Con
Definition: living.h:78
#define FLAG_REMOVED
Definition: define.h:528
sint16 hp
Definition: living.h:81
void cleanup(void)
Definition: server.c:1196
sint32 timeout
Definition: map.h:362
int stack_position
Definition: player.h:254
short freearr_y[SIZEOFFREE]
Definition: object.c:81
int command_reset(object *op, char *params)
Definition: c_wiz.c:1665
#define FLAG_KNOWN_MAGICAL
Definition: define.h:616
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:499
int command_invisible(object *op, char *params)
Definition: c_wiz.c:1998
uint32 tag_t
Definition: object.h:40
#define MAP_IN_MEMORY
Definition: map.h:151
void remove_ob(object *op)
Definition: object.c:1515
sint16 maxhp
Definition: living.h:82
#define NDI_RED
Definition: newclient.h:198
void flush_old_maps(void)
Definition: swap.c:305
int command_patch(object *op, char *params)
Definition: c_wiz.c:1296
void player_lvl_adj(object *who, object *op)
Definition: living.c:1731
int command_remove(object *op, char *params)
Definition: c_wiz.c:1342
#define FLAG_ALIVE
Definition: define.h:526
mapstruct * styles
Definition: style.c:122
#define FLAG_OBJ_ORIGINAL
Definition: define.h:661
artifactlist * find_artifactlist(int type)
Definition: treasure.c:1431
#define MAP_SWAPPED
Definition: map.h:152
#define LIBDIR
Definition: win32.h:110
int command_freeze(object *op, char *params)
Definition: c_wiz.c:571
float speed_left
Definition: object.h:182
uint32 hidden
Definition: player.h:186
sint8 Wis
Definition: living.h:78
#define FLAG_UNAGGRESSIVE
Definition: define.h:568
struct mapdef * map
Definition: object.h:155
int plugins_init_plugin(const char *libfile)
Definition: plugins.c:455
tag_t * stack_items
Definition: player.h:252
static int checkdm(object *op, const char *pl_name, const char *pl_passwd, const char *pl_host)
Definition: c_wiz.c:1887
void dump_object(object *op, StringBuffer *sb)
Definition: object.c:372
#define HORN
Definition: define.h:147
object * transport
Definition: player.h:249
#define MAP_TIMEOUT(m)
Definition: map.h:85
#define FLAG_IDENTIFIED
Definition: define.h:557
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Definition: path.c:184
void set_max_time(long t)
Definition: time.c:256
sint16 dam
Definition: living.h:87
int command_speed(object *op, char *params)
Definition: c_wiz.c:1493
static object * find_object_both(char *params)
Definition: c_wiz.c:211
const char * name
Definition: object.h:167
living orig_stats
Definition: player.h:203
int command_hide(object *op, char *params)
Definition: c_wiz.c:197
#define SPELL
Definition: define.h:283
uint8 state
Definition: player.h:172
struct archt * more
Definition: object.h:325
int execute_global_event(int eventcode,...)
Definition: standalone.c:229
uint16 difficulty
Definition: map.h:364
#define EXIT_PATH(xyz)
Definition: define.h:748
archetype * find_archetype_by_object_name(const char *name)
Definition: arch.c:70
#define TRUE
Definition: exp.c:41
uint32 max_time
Definition: time.c:46
uint32 nrof
Definition: object.h:184
sint8 Cha
Definition: living.h:78
void check_score(object *op, int quiet)
Definition: hiscore.c:289
#define EXIT_X(xyz)
Definition: define.h:750
void do_learn_spell(object *op, object *spell, int special_prayer)
Definition: apply.c:398
sint16 y
Definition: object.h:179
struct pl * contr
Definition: object.h:134
int plugins_remove_plugin(const char *id)
Definition: plugins.c:566
int command_goto(object *op, char *params)
Definition: c_wiz.c:532
#define NDI_LT_GREEN
Definition: newclient.h:203
#define UPD_NROF
Definition: newclient.h:261
#define FREE_AND_CLEAR_STR(xyz)
Definition: global.h:283
static object * get_spell_by_name(object *op, const char *spell_name)
Definition: c_wiz.c:2026
int command_stack_list(object *op, char *params)
Definition: c_wiz.c:2600
#define MAX(x, y)
Definition: define.h:70
uint32 count
Definition: player.h:163
float speed
Definition: object.h:181
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
void clear_los(object *op)
Definition: los.c:258
#define FLAG_WIZ
Definition: define.h:527
object * insert_ob_in_ob(object *op, object *where)
Definition: object.c:2510
#define EXIT_Y(xyz)
Definition: define.h:751
void plugins_display_list(object *op)
Definition: plugins.c:622
#define MAX_BUF
Definition: define.h:81
#define MSG_TYPE_ADMIN
Definition: newclient.h:324
object * object_create_arch(archetype *at)
Definition: arch.c:741
object * get_object(void)
Definition: object.c:921
#define MSG_TYPE_COMMAND_DEBUG
Definition: newclient.h:446
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
void reset_sleep(void)
Definition: time.c:141
sint8 wc
Definition: living.h:79
#define MSG_TYPE_ADMIN_DM
Definition: newclient.h:415
const char * confdir
Definition: global.h:333
int command_free(object *op, char *params)
Definition: c_wiz.c:1394
static void set_magic(int difficulty, object *op, int max_magic, int flags)
Definition: treasure.c:880
int do_wizard_dm(object *op, char *params, int silent)
Definition: c_wiz.c:1932
void inventory(object *op, object *inv)
Definition: c_object.c:1653
sint8 Str
Definition: living.h:78
void calc_perm_exp(object *op)
Definition: living.c:1804
int save_map(mapstruct *m, int flag)
Definition: map.c:1453
object * ob
Definition: player.h:207
uint32 unique
Definition: map.h:358
int need_identify(const object *op)
Definition: item.c:1401
sint8 body_info[NUM_BODY_LOCATIONS]
Definition: object.h:223
void become_follower(object *op, const object *new_god)
Definition: gods.c:502
int snprintf(char *dest, int max, const char *format,...)
Definition: porting.c:498
void get_ob_diff(StringBuffer *sb, object *op, object *op2)
char killer[BIG_NAME]
Definition: player.h:222
int command_loadtest(object *op, char *params)
Definition: c_wiz.c:108
int command_summon(object *op, char *params)
Definition: c_wiz.c:661
int command_overlay_save(object *op, char *params)
Definition: c_wiz.c:406
sint8 direction
Definition: object.h:185
Definition: map.h:279
int command_follow(object *op, char *params)
Definition: c_wiz.c:2863
sint16 grace
Definition: living.h:85
int command_mon_aggr(object *op, char *params)
Definition: c_wiz.c:1202
const char * localdir
Definition: global.h:335
tag_t count
Definition: object.h:157
living stats
Definition: object.h:219
#define FLAG_WIZCAST
Definition: define.h:586
mapstruct * has_been_loaded(const char *name)
Definition: map.c:87
sint8 Dex
Definition: living.h:78
struct archt * arch
Definition: object.h:263
uint32 reset_time
Definition: map.h:353
int command_learn_spell(object *op, char *params)
Definition: c_wiz.c:2180
#define MAP_WIDTH(m)
Definition: map.h:97
int set_variable(object *op, char *buf)
#define unlink(__a)
Definition: win32.h:67
struct Settings settings
Definition: init.c:48
object * dm_stack_peek(player *pl)
Definition: c_wiz.c:2373
sint64 check_exp_adjust(const object *op, sint64 exp)
Definition: living.c:1937
struct archt * next
Definition: object.h:323
int out_of_map(mapstruct *m, int x, int y)
Definition: map.c:2300
int command_teleport(object *op, char *params)
Definition: c_wiz.c:712
#define MSG_TYPE_COMMAND
Definition: newclient.h:326
void update_los(object *op)
Definition: los.c:467
int command_stack_pop(object *op, char *params)
Definition: c_wiz.c:2563
void update_ob_speed(object *op)
Definition: object.c:1008
int command_unloadplugin(object *op, char *params)
Definition: c_wiz.c:2298
sstring add_string(const char *str)
Definition: shstr.c:116
EXTERN player * first_player
Definition: global.h:190
int command_abil(object *op, char *params)
Definition: c_wiz.c:1595
struct pl * next
Definition: player.h:147
#define UPD_WEIGHT
Definition: newclient.h:256
#define GET_MAP_OB(M, X, Y)
Definition: map.h:193
int find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3200
sint8 Pow
Definition: living.h:78
#define NDI_UNIQUE
Definition: newclient.h:219
struct obj * head
Definition: object.h:154
uint32 no_shout
Definition: player.h:188
#define SPELLBOOK
Definition: define.h:266
void give_artifact_abilities(object *op, object *artifact)
Definition: treasure.c:1884
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
unsigned int uint32
Definition: global.h:58
#define ROD
Definition: define.h:115
#define FLAG_WAS_WIZ
Definition: define.h:530
int command_learn_special_prayer(object *op, char *params)
Definition: c_wiz.c:2196
#define MAX_NAME
Definition: define.h:87
static player * get_other_player_from_name(object *op, const char *name)
Definition: c_wiz.c:67
object * get_dm_object(player *pl, char **params, int *from)
Definition: c_wiz.c:2450
void set_abs_magic(object *op, int magic)
Definition: treasure.c:844
int command_kick(object *op, const char *params)
Definition: c_wiz.c:352
struct mapdef * next
Definition: map.h:347
void copy_object(object *op2, object *op)
Definition: object.c:758
int command_banish(object *op, char *params)
Definition: c_wiz.c:293
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:628
object * item
Definition: artifact.h:38
void free_object(object *ob)
Definition: object.c:1238
void create_overlay_pathname(const char *name, char *buf, size_t size)
Definition: map.c:135
Definition: map.h:346
int command_shutdown(object *op, char *params)
Definition: c_wiz.c:508
char write_buf[MAX_BUF]
Definition: player.h:225
static int command_learn_spell_or_prayer(object *op, char *params, int special_prayer)
Definition: c_wiz.c:2141
#define MSG_TYPE_COMMAND_MAPS
Definition: newclient.h:438
#define MSG_TYPE_COMMAND_DM
Definition: newclient.h:453
#define FLAG_WIZPASS
Definition: define.h:611
void map_remove_unique_files(const mapstruct *map)
Definition: map.c:2619
int command_stats(object *op, char *params)
Definition: c_wiz.c:1528
#define SAVE_ERROR_PLAYER
Definition: map.h:173
void fix_object(object *op)
Definition: living.c:900
player * find_player_partial_name(const char *plname)
Definition: player.c:84
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:447
uint8 real_wiz
Definition: global.h:359
EXTERN archetype * first_archetype
Definition: global.h:195
object * find_skill_by_name(object *who, const char *name)
Definition: skill_util.c:207
struct obj * more
Definition: object.h:153
object * arch_to_object(archetype *at)
Definition: arch.c:576
sstring followed_player
Definition: player.h:253
const char * name
Definition: object.h:322
#define SAVE_MODE_OVERLAY
Definition: map.h:143
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:78
uint8 type
Definition: object.h:189
struct artifactstruct * next
Definition: artifact.h:41
int command_stack_push(object *op, char *params)
Definition: c_wiz.c:2578
#define MAX_STAT
Definition: define.h:78
int command_dm(object *op, char *params)
Definition: c_wiz.c:1983
int command_dump(object *op, char *params)
Definition: c_wiz.c:1171
int command_loadplugin(object *op, char *params)
Definition: c_wiz.c:2259
void dm_stack_push(player *pl, tag_t item)
Definition: c_wiz.c:2403
sint32 food
Definition: living.h:89
#define FLAG_FREED
Definition: define.h:529
#define EVENT_MUZZLE
Definition: plugin.h:92