ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_misc.C
Revision: 1.32
Committed: Wed Dec 27 13:13:47 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.31: +5 -8 lines
Log Message:
misc stuff

File Contents

# User Rev Content
1 elmex 1.1 /*
2     CrossFire, A Multiplayer game for X-windows
3    
4     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5     Copyright (C) 1992 Frank Tore Johansen
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21 root 1.8 The authors can be reached via e-mail at <crossfire@schmorp.de>
22 elmex 1.1 */
23    
24     #include <global.h>
25     #include <loader.h>
26 root 1.21 #include <sproto.h>
27    
28     #include <dirent.h>
29 elmex 1.1
30     extern weathermap_t **weathermap;
31    
32     /* Handles misc. input request - things like hash table, malloc, maps,
33     * who, etc.
34     */
35    
36 root 1.7 void
37     map_info (object *op, char *search)
38     {
39 root 1.9 maptile *m;
40 root 1.32 char buf[MAX_BUF], map_path[31];
41 root 1.21 long sec = time (0);
42 root 1.7
43     new_draw_info_format (NDI_UNIQUE, 0, op, "Current time is: %02ld:%02ld:%02ld.", (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60);
44 root 1.32 new_draw_info (NDI_UNIQUE, 0, op, "Path Pl PlM IM TO Dif Reset");
45 root 1.31
46     for_all_maps (m)
47 root 1.7 {
48 root 1.31 if (search && !strstr (m->path, search))
49     continue; /* Skip unwanted maps */
50 root 1.7
51 root 1.32 /* Print out the last 30 characters of the map name... */
52     strcpy (map_path, m->path + max (0, (int)strlen (m->path) - 30));
53 root 1.31
54 root 1.32 sprintf (buf, "%-30.30s %2d %2d %1d %4d %2d %02d:%02d:%02d",
55 root 1.7 map_path, m->players, players_on_map (m, FALSE),
56     m->in_memory, m->timeout, m->difficulty,
57 root 1.30 (m->reset_time % 86400) / 3600, (m->reset_time % 3600) / 60, m->reset_time % 60);
58 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, buf);
59     }
60 elmex 1.1 }
61    
62     /* This command dumps the body information for object *op.
63     * it doesn't care what the params are.
64     * This is mostly meant as a debug command.
65     */
66 root 1.7 int
67     command_body (object *op, char *params)
68 elmex 1.1 {
69 root 1.7 int i;
70 elmex 1.1
71 root 1.7 /* Too hard to try and make a header that lines everything up, so just
72     * give a description.
73     */
74     new_draw_info (NDI_UNIQUE, 0, op, "The first column is the name of the body location.");
75     new_draw_info (NDI_UNIQUE, 0, op, "The second column is how many of those locations your body has.");
76     new_draw_info (NDI_UNIQUE, 0, op, "The third column is how many slots in that location are available.");
77     for (i = 0; i < NUM_BODY_LOCATIONS; i++)
78     {
79     /* really debugging - normally body_used should not be set to anything
80     * if body_info isn't also set.
81     */
82     if (op->body_info[i] || op->body_used[i])
83     {
84     new_draw_info_format (NDI_UNIQUE, 0, op, "%-30s %5d %5d", body_locations[i].use_name, op->body_info[i], op->body_used[i]);
85 root 1.3 }
86 elmex 1.1 }
87 root 1.7 if (!QUERY_FLAG (op, FLAG_USE_ARMOUR))
88     new_draw_info (NDI_UNIQUE, 0, op, "You are not allowed to wear armor");
89     if (!QUERY_FLAG (op, FLAG_USE_WEAPON))
90     new_draw_info (NDI_UNIQUE, 0, op, "You are not allowed to use weapons");
91 elmex 1.1
92 root 1.7 return 1;
93 elmex 1.1 }
94    
95    
96 root 1.7 int
97     command_motd (object *op, char *params)
98 elmex 1.1 {
99 root 1.7 display_motd (op);
100     return 1;
101 elmex 1.1 }
102    
103 root 1.7 int
104     command_bug (object *op, char *params)
105 elmex 1.1 {
106 root 1.7 char buf[MAX_BUF];
107 elmex 1.1
108 root 1.7 if (params == NULL)
109     {
110     new_draw_info (NDI_UNIQUE, 0, op, "what bugs?");
111 elmex 1.1 return 1;
112     }
113 root 1.7 strcpy (buf, op->name);
114     strcat (buf, " bug-reports: ");
115     strncat (buf, ++params, MAX_BUF - strlen (buf));
116     buf[MAX_BUF - 1] = '\0';
117     bug_report (buf);
118     LOG (llevError, "%s\n", buf);
119     new_draw_info (NDI_ALL | NDI_UNIQUE, 1, NULL, buf);
120     new_draw_info (NDI_UNIQUE, 0, op, "OK, thanks!");
121     return 1;
122 elmex 1.1 }
123    
124     /*
125     * Pretty much identical to current map_info, but on a bigger scale
126     * This function returns the name of the players current region, and
127     * a description of it. It is there merely for flavour text.
128     */
129 root 1.7 void
130     current_region_info (object *op)
131     {
132     /*
133     * Ok I /suppose/ I should write a seperate function for this, but it isn't
134     * going to be /that/ slow, and won't get called much
135     */
136     region *r = get_region_by_name (get_name_of_region_for_map (op->map));
137 elmex 1.1
138 root 1.7 if (!r)
139     return;
140     /* This should only be possible if regions are not operating on this server. */
141 elmex 1.1
142 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "You are in %s. \n %s", get_region_longname (r), get_region_msg (r));
143 elmex 1.1 }
144    
145 root 1.7 void
146     current_map_info (object *op)
147     {
148 root 1.9 maptile *m = op->map;
149 elmex 1.1
150 root 1.7 if (!m)
151     return;
152 elmex 1.1
153 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "%s (%s) in %s", m->name, m->path, get_name_of_region_for_map (m));
154 elmex 1.1
155 root 1.7 if (QUERY_FLAG (op, FLAG_WIZ))
156     {
157     new_draw_info_format (NDI_UNIQUE, 0, op,
158     "players:%d difficulty:%d size:%dx%d start:%dx%d timeout %ld",
159 root 1.30 m->players, m->difficulty, m->width, m->height, m->enter_x, m->enter_y, m->timeout);
160 elmex 1.1
161     }
162 root 1.7 if (m->msg)
163     new_draw_info (NDI_UNIQUE, NDI_NAVY, op, m->msg);
164 elmex 1.1 }
165    
166     #ifdef DEBUG_MALLOC_LEVEL
167 root 1.7 int
168     command_malloc_verify (object *op, char *parms)
169 elmex 1.1 {
170 root 1.7 extern int malloc_verify (void);
171 elmex 1.1
172 root 1.7 if (!malloc_verify ())
173     new_draw_info (NDI_UNIQUE, 0, op, "Heap is corrupted.");
174     else
175     new_draw_info (NDI_UNIQUE, 0, op, "Heap checks out OK.");
176     return 1;
177     }
178 elmex 1.1 #endif
179    
180 root 1.7 int
181     command_whereabouts (object *op, char *params)
182     {
183    
184     region *reg;
185     player *pl;
186 elmex 1.1
187 root 1.7 /*
188     * reset the counter on the region, then use it to store the number of
189     * players there.
190     * I don't know how thread-safe this would be, I suspect not very....
191     */
192     for (reg = first_region; reg != NULL; reg = reg->next)
193     {
194     reg->counter = 0;
195     }
196 root 1.28 for_all_players (pl)
197 root 1.7 if (pl->ob->map != NULL)
198     get_region_by_map (pl->ob->map)->counter++;
199    
200     /* we only want to print out by places with a 'longname' field... */
201     for (reg = first_region; reg != NULL; reg = reg->next)
202     {
203     if (reg->longname == NULL && reg->counter > 0)
204     {
205     if (reg->parent != NULL)
206     {
207     reg->parent->counter += reg->counter;
208     reg->counter = 0;
209 root 1.3 }
210 root 1.7 else /*uh oh, we shouldn't be here. */
211     LOG (llevError, "command_whereabouts() Region %s with no longname has no parent", reg->name);
212 root 1.3 }
213     }
214 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "In the world currently there are:");
215     for (reg = first_region; reg != NULL; reg = reg->next)
216     if (reg->counter > 0)
217     new_draw_info_format (NDI_UNIQUE, 0, op, "%u players in %s", reg->counter, get_region_longname (reg));
218     return 1;
219 elmex 1.1 }
220    
221     typedef struct
222 root 1.7 {
223     char namebuf[MAX_BUF];
224     int login_order;
225     } chars_names;
226 elmex 1.1
227 root 1.7 int
228     command_afk (object *op, char *params)
229     {
230 root 1.28 if ((op->contr->ns->afk = !op->contr->ns->afk))
231     new_draw_info (NDI_UNIQUE, 0, op, "You are no longer AFK");
232 root 1.7 else
233 root 1.28 new_draw_info (NDI_UNIQUE, 0, op, "You are now AFK");
234 root 1.24
235 root 1.7 return 1;
236 elmex 1.1 }
237    
238 root 1.7 int
239     command_mapinfo (object *op, char *params)
240 elmex 1.1 {
241 root 1.7 current_map_info (op);
242     return 1;
243     }
244 elmex 1.1
245 root 1.7 int
246     command_whereami (object *op, char *params)
247 elmex 1.1 {
248 root 1.7 current_region_info (op);
249     return 1;
250 elmex 1.1 }
251    
252 root 1.7 int
253     command_maps (object *op, char *params)
254 elmex 1.1 {
255 root 1.7 map_info (op, params);
256     return 1;
257     }
258 elmex 1.1
259 root 1.7 int
260     command_time (object *op, char *params)
261 elmex 1.1 {
262 root 1.2 print_tod (op);
263     return 1;
264     }
265 elmex 1.1
266 root 1.7 int
267     command_weather (object *op, char *params)
268 elmex 1.1 {
269 root 1.7 int wx, wy, temp, sky;
270     char buf[MAX_BUF];
271    
272     if (settings.dynamiclevel < 1)
273     return 1;
274    
275     if (op->map == NULL)
276     return 1;
277    
278     if (worldmap_to_weathermap (op->x, op->y, &wx, &wy, op->map) != 0)
279     return 1;
280    
281     if (QUERY_FLAG (op, FLAG_WIZ))
282     {
283     /* dump the weather, Dm style! Yo! */
284     new_draw_info_format (NDI_UNIQUE, 0, op, "Real temp: %d", real_world_temperature (op->x, op->y, op->map));
285     new_draw_info_format (NDI_UNIQUE, 0, op, "Base temp: %d", weathermap[wx][wy].temp);
286     new_draw_info_format (NDI_UNIQUE, 0, op, "Humid: %d", weathermap[wx][wy].humid);
287     new_draw_info_format (NDI_UNIQUE, 0, op, "Wind: dir=%d speed=%d", weathermap[wx][wy].winddir, weathermap[wx][wy].windspeed);
288     new_draw_info_format (NDI_UNIQUE, 0, op, "Pressure: %d", weathermap[wx][wy].pressure);
289     new_draw_info_format (NDI_UNIQUE, 0, op, "Avg Elevation: %d", weathermap[wx][wy].avgelev);
290     new_draw_info_format (NDI_UNIQUE, 0, op, "Rainfall: %d Water: %d", weathermap[wx][wy].rainfall, weathermap[wx][wy].water);
291     }
292    
293     temp = real_world_temperature (op->x, op->y, op->map);
294     new_draw_info_format (NDI_UNIQUE, 0, op, "It's currently %d degrees " "Centigrade out.", temp);
295    
296     /* humid */
297     if (weathermap[wx][wy].humid < 20)
298     new_draw_info (NDI_UNIQUE, 0, op, "It is very dry.");
299     else if (weathermap[wx][wy].humid < 40)
300     new_draw_info (NDI_UNIQUE, 0, op, "It is very comfortable today.");
301     else if (weathermap[wx][wy].humid < 60)
302     new_draw_info (NDI_UNIQUE, 0, op, "It is a bit muggy.");
303     else if (weathermap[wx][wy].humid < 80)
304     new_draw_info (NDI_UNIQUE, 0, op, "It is muggy.");
305     else
306     new_draw_info (NDI_UNIQUE, 0, op, "It is uncomfortably muggy.");
307 elmex 1.1
308 root 1.7 /* wind */
309     switch (weathermap[wx][wy].winddir)
310     {
311     case 1:
312     sprintf (buf, "north");
313     break;
314     case 2:
315     sprintf (buf, "northeast");
316     break;
317     case 3:
318     sprintf (buf, "east");
319     break;
320     case 4:
321     sprintf (buf, "southeast");
322     break;
323     case 5:
324     sprintf (buf, "south");
325     break;
326     case 6:
327     sprintf (buf, "southwest");
328     break;
329     case 7:
330     sprintf (buf, "west");
331     break;
332     case 8:
333     sprintf (buf, "northwest");
334     break;
335     }
336     if (weathermap[wx][wy].windspeed < 5)
337     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a mild breeze " "coming from the %s.", buf);
338     else if (weathermap[wx][wy].windspeed < 10)
339     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a strong breeze " "coming from the %s.", buf);
340     else if (weathermap[wx][wy].windspeed < 15)
341     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a light wind " "coming from the %s.", buf);
342     else if (weathermap[wx][wy].windspeed < 25)
343     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a strong wind " "coming from the %s.", buf);
344     else if (weathermap[wx][wy].windspeed < 35)
345     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a heavy wind " "coming from the %s.", buf);
346     else
347     new_draw_info_format (NDI_UNIQUE, 0, op, "The wind from the %s is " "incredibly strong!", buf);
348 elmex 1.1
349 root 1.7 sky = weathermap[wx][wy].sky;
350     if (temp <= 0 && sky > SKY_OVERCAST && sky < SKY_FOG)
351     sky += 10; /*let it snow */
352     switch (sky)
353     {
354     case SKY_CLEAR:
355     new_draw_info (NDI_UNIQUE, 0, op, "There isn''t a cloud in the sky.");
356     break;
357     case SKY_LIGHTCLOUD:
358     new_draw_info (NDI_UNIQUE, 0, op, "There are a few light clouds in the sky.");
359     break;
360     case SKY_OVERCAST:
361     new_draw_info (NDI_UNIQUE, 0, op, "The sky is cloudy and dreary.");
362     break;
363     case SKY_LIGHT_RAIN:
364     new_draw_info (NDI_UNIQUE, 0, op, "It is raining softly.");
365     break;
366     case SKY_RAIN:
367     new_draw_info (NDI_UNIQUE, 0, op, "It is raining.");
368     break;
369     case SKY_HEAVY_RAIN:
370     new_draw_info (NDI_UNIQUE, 0, op, "It is raining heavily.");
371     break;
372     case SKY_HURRICANE:
373     new_draw_info (NDI_UNIQUE, 0, op, "There is a heavy storm! You should go inside!");
374     break;
375     case SKY_FOG:
376     new_draw_info (NDI_UNIQUE, 0, op, "It''s foggy and miserable.");
377     break;
378     case SKY_HAIL:
379     new_draw_info (NDI_UNIQUE, 0, op, "It''s hailing out! Take cover!");
380     break;
381     case SKY_LIGHT_SNOW:
382     new_draw_info (NDI_UNIQUE, 0, op, "Snow is gently falling from the sky.");
383     break;
384     case SKY_SNOW:
385     new_draw_info (NDI_UNIQUE, 0, op, "It''s snowing out.");
386     break;
387     case SKY_HEAVY_SNOW:
388     new_draw_info (NDI_UNIQUE, 0, op, "The snow is falling very heavily now.");
389     break;
390     case SKY_BLIZZARD:
391     new_draw_info (NDI_UNIQUE, 0, op, "A full blown blizzard is in effect. You might want to take cover!");
392     break;
393 elmex 1.1 }
394 root 1.7 return 1;
395 elmex 1.1 }
396    
397 root 1.7 int
398     command_archs (object *op, char *params)
399 elmex 1.1 {
400 root 1.7 arch_info (op);
401     return 1;
402     }
403 elmex 1.1
404 root 1.7 int
405     command_hiscore (object *op, char *params)
406 elmex 1.1 {
407 root 1.7 display_high_score (op, op == NULL ? 9999 : 50, params);
408     return 1;
409     }
410 elmex 1.1
411 root 1.7 int
412     command_debug (object *op, char *params)
413 elmex 1.1 {
414 root 1.7 int i;
415     char buf[MAX_BUF];
416    
417     if (params == NULL || !sscanf (params, "%d", &i))
418     {
419     sprintf (buf, "Global debug level is %d.", settings.debug);
420     new_draw_info (NDI_UNIQUE, 0, op, buf);
421 elmex 1.1 return 1;
422     }
423 root 1.7 if (op != NULL && !QUERY_FLAG (op, FLAG_WIZ))
424     {
425     new_draw_info (NDI_UNIQUE, 0, op, "Privileged command.");
426 elmex 1.1 return 1;
427     }
428 root 1.7 settings.debug = (enum LogLevel) FABS (i);
429     sprintf (buf, "Set debug level to %d.", i);
430     new_draw_info (NDI_UNIQUE, 0, op, buf);
431     return 1;
432     }
433 elmex 1.1
434    
435     /*
436     * Those dumps should be just one dump with good parser
437     */
438    
439 root 1.7 int
440     command_dumpbelow (object *op, char *params)
441 elmex 1.1 {
442 root 1.7 if (op && op->below)
443     {
444 root 1.14 char *dump = dump_object (op->below);
445     new_draw_info (NDI_UNIQUE, 0, op, dump);
446     free (dump);
447 elmex 1.1 /* Let's push that item on the dm's stack */
448 root 1.7 dm_stack_push (op->contr, op->below->count);
449     }
450 elmex 1.1 return 0;
451     }
452    
453 root 1.7 int
454     command_dumpfriendlyobjects (object *op, char *params)
455 elmex 1.1 {
456 root 1.7 dump_friendly_objects ();
457 elmex 1.1 return 0;
458     }
459    
460 root 1.7 int
461     command_dumpmap (object *op, char *params)
462 elmex 1.1 {
463 root 1.7 if (op)
464     dump_map (op->map);
465 elmex 1.1 return 0;
466     }
467    
468 root 1.7 int
469     command_dumpallmaps (object *op, char *params)
470 elmex 1.1 {
471 root 1.7 dump_all_maps ();
472 elmex 1.1 return 0;
473     }
474    
475 root 1.7 int
476     command_printlos (object *op, char *params)
477 elmex 1.1 {
478     if (op)
479 root 1.7 print_los (op);
480 elmex 1.1 return 0;
481     }
482    
483    
484 root 1.7 int
485     command_version (object *op, char *params)
486 elmex 1.1 {
487 root 1.7 version (op);
488     return 0;
489 elmex 1.1 }
490    
491    
492     #ifndef BUG_LOG
493 root 1.7 # define BUG_LOG "bug_log"
494 elmex 1.1 #endif
495 root 1.7 void
496     bug_report (const char *reportstring)
497     {
498     FILE *fp;
499    
500     if ((fp = fopen (BUG_LOG, "a")) != NULL)
501     {
502     fprintf (fp, "%s\n", reportstring);
503     fclose (fp);
504     }
505     else
506     {
507     LOG (llevError, "Cannot write bugs file %s: %s\n", BUG_LOG, strerror (errno));
508 elmex 1.1 }
509 root 1.7 }
510    
511     int
512     command_output_sync (object *op, char *params)
513     {
514     int val;
515    
516     if (!params)
517     {
518     new_draw_info_format (NDI_UNIQUE, 0, op, "Output sync time is presently %d", op->contr->outputs_sync);
519     return 1;
520     }
521     val = atoi (params);
522     if (val > 0)
523     {
524     op->contr->outputs_sync = val;
525     new_draw_info_format (NDI_UNIQUE, 0, op, "Output sync time now set to %d", op->contr->outputs_sync);
526     }
527     else
528     new_draw_info (NDI_UNIQUE, 0, op, "Invalid value for output_sync.");
529 elmex 1.1
530 root 1.7 return 1;
531 elmex 1.1 }
532    
533 root 1.7 int
534     command_output_count (object *op, char *params)
535 elmex 1.1 {
536 root 1.7 int val;
537 elmex 1.1
538 root 1.7 if (!params)
539     {
540     new_draw_info_format (NDI_UNIQUE, 0, op, "Output count is presently %d", op->contr->outputs_count);
541     return 1;
542 elmex 1.1 }
543 root 1.7 val = atoi (params);
544     if (val > 0)
545     {
546     op->contr->outputs_count = val;
547     new_draw_info_format (NDI_UNIQUE, 0, op, "Output count now set to %d", op->contr->outputs_count);
548     }
549     else
550     new_draw_info (NDI_UNIQUE, 0, op, "Invalid value for output_count.");
551 elmex 1.1
552 root 1.7 return 1;
553 elmex 1.1 }
554    
555 root 1.7 int
556     command_listen (object *op, char *params)
557 elmex 1.1 {
558     int i;
559    
560 root 1.7 if (params == NULL || !sscanf (params, "%d", &i))
561     {
562     new_draw_info_format (NDI_UNIQUE, 0, op, "Set listen to what (presently %d)?", op->contr->listening);
563 elmex 1.1 return 1;
564     }
565 root 1.7 op->contr->listening = (char) i;
566     new_draw_info_format (NDI_UNIQUE, 0, op, "Your verbose level is now %d.", i);
567     return 1;
568 elmex 1.1 }
569    
570     /* Prints out some useful information for the character. Everything we print
571     * out can be determined by the docs, so we aren't revealing anything extra -
572     * rather, we are making it convenient to find the values. params have
573     * no meaning here.
574     */
575 root 1.7 int
576     command_statistics (object *pl, char *params)
577 elmex 1.1 {
578 root 1.7 if (!pl->contr)
579     return 1;
580 root 1.18 new_draw_info_format (NDI_UNIQUE, 0, pl, " Experience: %" PRId64, pl->stats.exp);
581     new_draw_info_format (NDI_UNIQUE, 0, pl, " Next Level: %" PRId64, level_exp (pl->level + 1, pl->expmul));
582 root 1.7 new_draw_info (NDI_UNIQUE, 0, pl, "\nStat Nat/Real/Max");
583 elmex 1.1
584 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Str %2d/ %3d/%3d",
585     pl->contr->orig_stats.Str, pl->stats.Str, 20 + pl->arch->clone.stats.Str);
586     new_draw_info_format (NDI_UNIQUE, 0, pl, "Dex %2d/ %3d/%3d",
587     pl->contr->orig_stats.Dex, pl->stats.Dex, 20 + pl->arch->clone.stats.Dex);
588     new_draw_info_format (NDI_UNIQUE, 0, pl, "Con %2d/ %3d/%3d",
589     pl->contr->orig_stats.Con, pl->stats.Con, 20 + pl->arch->clone.stats.Con);
590     new_draw_info_format (NDI_UNIQUE, 0, pl, "Int %2d/ %3d/%3d",
591     pl->contr->orig_stats.Int, pl->stats.Int, 20 + pl->arch->clone.stats.Int);
592     new_draw_info_format (NDI_UNIQUE, 0, pl, "Wis %2d/ %3d/%3d",
593     pl->contr->orig_stats.Wis, pl->stats.Wis, 20 + pl->arch->clone.stats.Wis);
594     new_draw_info_format (NDI_UNIQUE, 0, pl, "Pow %2d/ %3d/%3d",
595     pl->contr->orig_stats.Pow, pl->stats.Pow, 20 + pl->arch->clone.stats.Pow);
596     new_draw_info_format (NDI_UNIQUE, 0, pl, "Cha %2d/ %3d/%3d",
597     pl->contr->orig_stats.Cha, pl->stats.Cha, 20 + pl->arch->clone.stats.Cha);
598     new_draw_info_format (NDI_UNIQUE, 0, pl, "\nAttack Mode: %s", pl->contr->peaceful ? "Peaceful" : "Hostile");
599 elmex 1.1
600 root 1.7 /* Can't think of anything else to print right now */
601     return 0;
602 elmex 1.1 }
603    
604 root 1.7 int
605     command_fix_me (object *op, char *params)
606 elmex 1.1 {
607 root 1.7 sum_weight (op);
608 root 1.27 op->update_stats ();
609 root 1.7 return 1;
610 elmex 1.1 }
611    
612 root 1.7 int
613     command_players (object *op, char *paramss)
614 elmex 1.1 {
615 root 1.7 char buf[MAX_BUF];
616     char *t;
617     DIR *Dir;
618    
619     sprintf (buf, "%s/%s/", settings.localdir, settings.playerdir);
620     t = buf + strlen (buf);
621     if ((Dir = opendir (buf)) != NULL)
622     {
623     const struct dirent *Entry;
624    
625 root 1.21 while ((Entry = readdir (Dir)))
626 root 1.7 {
627     /* skip '.' , '..' */
628     if (!((Entry->d_name[0] == '.' && Entry->d_name[1] == '\0') ||
629     (Entry->d_name[0] == '.' && Entry->d_name[1] == '.' && Entry->d_name[2] == '\0')))
630 root 1.3 {
631 root 1.7 struct stat Stat;
632 elmex 1.1
633 root 1.7 strcpy (t, Entry->d_name);
634     if (stat (buf, &Stat) == 0)
635     {
636     /* This was not posix compatible
637     * if ((Stat.st_mode & S_IFMT)==S_IFDIR) {
638     */
639     if (S_ISDIR (Stat.st_mode))
640     {
641     char buf2[MAX_BUF];
642     struct tm *tm = localtime (&Stat.st_mtime);
643    
644     sprintf (buf2, "%s\t%04d %02d %02d %02d %02d %02d",
645     Entry->d_name, 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
646     new_draw_info (NDI_UNIQUE, 0, op, buf2);
647 root 1.3 }
648     }
649     }
650     }
651 elmex 1.1 }
652 root 1.7 closedir (Dir);
653     return 0;
654 elmex 1.1 }
655    
656    
657    
658 root 1.7 int
659     command_logs (object *op, char *params)
660 elmex 1.1 {
661 root 1.10 new_draw_info (NDI_UNIQUE, 0, op, "Nobody is currently logging kills.");
662 elmex 1.1
663 root 1.7 return 1;
664 elmex 1.1 }
665    
666 root 1.7 int
667     command_applymode (object *op, char *params)
668 elmex 1.1 {
669 root 1.7 unapplymode unapply = op->contr->unapply;
670     static const char *const types[] = { "nochoice", "never", "always" };
671 elmex 1.1
672 root 1.7 if (!params)
673     {
674     new_draw_info_format (NDI_UNIQUE, 0, op, "applymode is set to %s", types[op->contr->unapply]);
675     return 1;
676     }
677    
678     if (!strcmp (params, "nochoice"))
679     op->contr->unapply = unapply_nochoice;
680     else if (!strcmp (params, "never"))
681     op->contr->unapply = unapply_never;
682     else if (!strcmp (params, "always"))
683     op->contr->unapply = unapply_always;
684     else
685     {
686     new_draw_info_format (NDI_UNIQUE, 0, op, "applymode: Unknown options %s, valid options are nochoice, never, always", params);
687     return 0;
688     }
689     new_draw_info_format (NDI_UNIQUE, 0, op, "Applymode %s set to %s",
690     (unapply == op->contr->unapply ? "" : " now"), types[op->contr->unapply]);
691     return 1;
692 elmex 1.1 }
693    
694 root 1.7 int
695     command_bowmode (object *op, char *params)
696 elmex 1.1 {
697 root 1.7 bowtype_t oldtype = op->contr->bowtype;
698     static const char *const types[] = { "normal", "threewide", "spreadshot", "firenorth",
699     "firene", "fireeast", "firese", "firesouth",
700     "firesw", "firewest", "firenw", "bestarrow"
701     };
702     char buf[MAX_BUF];
703     int i, found;
704    
705     if (!params)
706     {
707     new_draw_info_format (NDI_UNIQUE, 0, op, "bowmode is set to %s", types[op->contr->bowtype]);
708     return 1;
709     }
710    
711     for (i = 0, found = 0; i <= bow_bestarrow; i++)
712     {
713     if (!strcmp (params, types[i]))
714     {
715     found++;
716     op->contr->bowtype = (bowtype_t) i;
717     break;
718 root 1.3 }
719 elmex 1.1 }
720 root 1.7 if (!found)
721     {
722     sprintf (buf, "bowmode: Unknown options %s, valid options are:", params);
723     for (i = 0; i <= bow_bestarrow; i++)
724     {
725     strcat (buf, " ");
726     strcat (buf, types[i]);
727     if (i < bow_nw)
728     strcat (buf, ",");
729     else
730     strcat (buf, ".");
731 root 1.3 }
732 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, buf);
733     return 0;
734 elmex 1.1 }
735 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "bowmode %s set to %s", (oldtype == op->contr->bowtype ? "" : "now"), types[op->contr->bowtype]);
736     return 1;
737 elmex 1.1 }
738    
739 root 1.7 int
740     command_petmode (object *op, char *params)
741 elmex 1.1 {
742 root 1.7 petmode_t oldtype = op->contr->petmode;
743     static const char *const types[] = { "normal", "sad", "defend", "arena" };
744 elmex 1.1
745 root 1.7 if (!params)
746     {
747     new_draw_info_format (NDI_UNIQUE, 0, op, "petmode is set to %s", types[op->contr->petmode]);
748     return 1;
749     }
750    
751     if (!strcmp (params, "normal"))
752     op->contr->petmode = pet_normal;
753     else if (!strcmp (params, "sad"))
754     op->contr->petmode = pet_sad;
755     else if (!strcmp (params, "defend"))
756     op->contr->petmode = pet_defend;
757     else if (!strcmp (params, "arena"))
758     op->contr->petmode = pet_arena;
759     else
760     {
761     new_draw_info_format (NDI_UNIQUE, 0, op,
762     "petmode: Unknown options %s, valid options are normal," "sad (seek and destroy), defend, arena", params);
763     return 0;
764     }
765     new_draw_info_format (NDI_UNIQUE, 0, op, "petmode %s set to %s", (oldtype == op->contr->petmode ? "" : "now"), types[op->contr->petmode]);
766     return 1;
767 elmex 1.1 }
768    
769 root 1.7 int
770     command_showpets (object *op, char *params)
771 elmex 1.1 {
772 root 1.7 objectlink *obl, *next;
773     int counter = 0, target = 0;
774     int have_shown_pet = 0;
775    
776     if (params != NULL)
777     target = atoi (params);
778     for (obl = first_friendly_object; obl != NULL; obl = next)
779     {
780     object *ob = obl->ob;
781    
782     next = obl->next;
783 root 1.22 if (ob->owner == op)
784 root 1.7 {
785     if (target == 0)
786     {
787     if (counter == 0)
788     new_draw_info (NDI_UNIQUE, 0, op, "Pets:");
789     new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s - level %d", ++counter, &ob->name, ob->level);
790     }
791     else if (!have_shown_pet && ++counter == target)
792     {
793     new_draw_info_format (NDI_UNIQUE, 0, op, "level %d %s", ob->level, &ob->name);
794     new_draw_info_format (NDI_UNIQUE, 0, op, "%d/%d HP, %d/%d SP", ob->stats.hp, ob->stats.maxhp, ob->stats.sp, ob->stats.maxsp);
795     /* this is not a nice way to do this, it should be made to be more like the statistics command */
796     new_draw_info_format (NDI_UNIQUE, 0, op, "Str %d", ob->stats.Str);
797     new_draw_info_format (NDI_UNIQUE, 0, op, "Dex %d", ob->stats.Dex);
798     new_draw_info_format (NDI_UNIQUE, 0, op, "Con %d", ob->stats.Con);
799     new_draw_info_format (NDI_UNIQUE, 0, op, "Int %d", ob->stats.Int);
800     new_draw_info_format (NDI_UNIQUE, 0, op, "Wis %d", ob->stats.Wis);
801     new_draw_info_format (NDI_UNIQUE, 0, op, "Cha %d", ob->stats.Cha);
802     new_draw_info_format (NDI_UNIQUE, 0, op, "Pow %d", ob->stats.Pow);
803     new_draw_info_format (NDI_UNIQUE, 0, op, "wc %d damage %d ac %d ", ob->stats.wc, ob->stats.dam, ob->stats.ac);
804     have_shown_pet = 1;
805 root 1.3 }
806     }
807 elmex 1.1 }
808 root 1.7 if (counter == 0)
809     new_draw_info (NDI_UNIQUE, 0, op, "you have no pets.");
810     else if (target != 0 && have_shown_pet == 0)
811     new_draw_info (NDI_UNIQUE, 0, op, "no such pet.");
812     return 0;
813 elmex 1.1 }
814    
815 root 1.7 int
816     command_usekeys (object *op, char *params)
817 elmex 1.1 {
818 root 1.7 usekeytype oldtype = op->contr->usekeys;
819     static const char *const types[] = { "inventory", "keyrings", "containers" };
820 elmex 1.1
821 root 1.7 if (!params)
822     {
823     new_draw_info_format (NDI_UNIQUE, 0, op, "usekeys is set to %s", types[op->contr->usekeys]);
824     return 1;
825     }
826    
827     if (!strcmp (params, "inventory"))
828     op->contr->usekeys = key_inventory;
829     else if (!strcmp (params, "keyrings"))
830     op->contr->usekeys = keyrings;
831     else if (!strcmp (params, "containers"))
832     op->contr->usekeys = containers;
833     else
834     {
835     new_draw_info_format (NDI_UNIQUE, 0, op, "usekeys: Unknown options %s, valid options are inventory, keyrings, containers", params);
836     return 0;
837     }
838     new_draw_info_format (NDI_UNIQUE, 0, op, "usekeys %s set to %s", (oldtype == op->contr->usekeys ? "" : "now"), types[op->contr->usekeys]);
839     return 1;
840 elmex 1.1 }
841    
842 root 1.7 int
843     command_resistances (object *op, char *params)
844 elmex 1.1 {
845 root 1.7 int i;
846 elmex 1.1
847 root 1.7 if (!op)
848     return 0;
849    
850     for (i = 0; i < NROFATTACKS; i++)
851     {
852     if (i == ATNR_INTERNAL)
853     continue;
854 elmex 1.1
855 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "%-20s %+5d", attacktype_desc[i], op->resist[i]);
856 elmex 1.1 }
857    
858 root 1.7 /* If dragon player, let's display natural resistances */
859     if (is_dragon_pl (op))
860     {
861     int attack;
862     object *tmp;
863    
864     for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
865 elmex 1.1 {
866 root 1.7 if ((tmp->type == FORCE) && (strcmp (tmp->arch->name, "dragon_skin_force") == 0))
867 elmex 1.1 {
868 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, "\nNatural skin resistances:");
869     for (attack = 0; attack < NROFATTACKS; attack++)
870 elmex 1.1 {
871 root 1.7 if (atnr_is_dragon_enabled (attack))
872 elmex 1.1 {
873 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "%s: %d", change_resist_msg[attack], tmp->resist[attack]);
874 elmex 1.1 }
875     }
876 root 1.7 break;
877 elmex 1.1 }
878     }
879 root 1.7 }
880 elmex 1.1
881 root 1.7 return 0;
882 elmex 1.1 }
883 root 1.7
884 elmex 1.1 /*
885     * Actual commands.
886     * Those should be in small separate files (c_object.c, c_wiz.c, cmove.c,...)
887     */
888    
889    
890 root 1.7 static void
891     help_topics (object *op, int what)
892 elmex 1.1 {
893 root 1.7 DIR *dirp;
894     struct dirent *de;
895     char filename[MAX_BUF], line[80];
896     int namelen, linelen = 0;
897    
898     switch (what)
899     {
900 root 1.21 case 1:
901     sprintf (filename, "%s/wizhelp", settings.datadir);
902     new_draw_info (NDI_UNIQUE, 0, op, " Wiz commands:");
903     break;
904     case 3:
905     sprintf (filename, "%s/mischelp", settings.datadir);
906     new_draw_info (NDI_UNIQUE, 0, op, " Misc help:");
907     break;
908     default:
909     sprintf (filename, "%s/help", settings.datadir);
910     new_draw_info (NDI_UNIQUE, 0, op, " Commands:");
911     break;
912 root 1.7 }
913 root 1.21
914 root 1.7 if (!(dirp = opendir (filename)))
915     return;
916    
917     line[0] = '\0';
918 root 1.21 while (de = readdir (dirp))
919 root 1.7 {
920 root 1.21 namelen = strlen (de->d_name);
921 root 1.7 if (namelen <= 2 && *de->d_name == '.' && (namelen == 1 || de->d_name[1] == '.'))
922     continue;
923     linelen += namelen + 1;
924     if (linelen > 42)
925     {
926     new_draw_info (NDI_UNIQUE, 0, op, line);
927     sprintf (line, " %s", de->d_name);
928     linelen = namelen + 1;
929     continue;
930 root 1.3 }
931 root 1.7 strcat (line, " ");
932     strcat (line, de->d_name);
933 elmex 1.1 }
934 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, line);
935     closedir (dirp);
936 elmex 1.1 }
937    
938 root 1.7 static void
939     show_commands (object *op, int what)
940 elmex 1.1 {
941     char line[80];
942 root 1.7 int i, size, namelen, linelen = 0;
943 elmex 1.1 CommArray_s *ap;
944     extern CommArray_s Commands[], WizCommands[];
945     extern const int CommandsSize, WizCommandsSize;
946 root 1.7
947     switch (what)
948     {
949     case 1:
950     ap = WizCommands;
951     size = WizCommandsSize;
952     new_draw_info (NDI_UNIQUE, 0, op, " Wiz commands:");
953     break;
954     case 2:
955     ap = CommunicationCommands;
956     size = CommunicationCommandSize;
957     new_draw_info (NDI_UNIQUE, 0, op, " Communication commands:");
958     break;
959     default:
960     ap = Commands;
961     size = CommandsSize;
962     new_draw_info (NDI_UNIQUE, 0, op, " Commands:");
963     break;
964     }
965    
966     line[0] = '\0';
967     for (i = 0; i < size; i++)
968     {
969     namelen = strlen (ap[i].name);
970     linelen += namelen + 1;
971     if (linelen > 42)
972     {
973     new_draw_info (NDI_UNIQUE, 0, op, line);
974     sprintf (line, " %s", ap[i].name);
975     linelen = namelen + 1;
976     continue;
977     }
978     strcat (line, " ");
979     strcat (line, ap[i].name);
980     }
981     new_draw_info (NDI_UNIQUE, 0, op, line);
982 elmex 1.1 }
983    
984    
985 root 1.7 int
986     command_help (object *op, char *params)
987 elmex 1.1 {
988     struct stat st;
989     FILE *fp;
990     char filename[MAX_BUF], line[MAX_BUF];
991     int len;
992    
993 root 1.7 if (op != NULL)
994     clear_win_info (op);
995 elmex 1.1
996     /*
997     * Main help page?
998     */
999 root 1.7 if (!params)
1000     {
1001     sprintf (filename, "%s/def_help", settings.datadir);
1002     if ((fp = fopen (filename, "r")) == NULL)
1003     {
1004     LOG (llevError, "Cannot open help file %s: %s\n", filename, strerror (errno));
1005     return 0;
1006     }
1007     while (fgets (line, MAX_BUF, fp))
1008     {
1009     line[MAX_BUF - 1] = '\0';
1010     len = strlen (line) - 1;
1011     if (line[len] == '\n')
1012     line[len] = '\0';
1013     new_draw_info (NDI_UNIQUE, 0, op, line);
1014     }
1015     fclose (fp);
1016 elmex 1.1 return 0;
1017     }
1018    
1019     /*
1020     * Topics list
1021     */
1022 root 1.7 if (!strcmp (params, "topics"))
1023     {
1024     help_topics (op, 3);
1025     help_topics (op, 0);
1026     if (QUERY_FLAG (op, FLAG_WIZ))
1027     help_topics (op, 1);
1028     return 0;
1029 elmex 1.1 }
1030 root 1.7
1031 elmex 1.1 /*
1032     * Commands list
1033     */
1034 root 1.7 if (!strcmp (params, "commands"))
1035     {
1036     show_commands (op, 0);
1037     show_commands (op, 2); /* show comm commands */
1038     if (QUERY_FLAG (op, FLAG_WIZ))
1039     show_commands (op, 1);
1040     return 0;
1041     }
1042 elmex 1.1
1043     /*
1044     * User wants info about command
1045     */
1046 root 1.7 if (strchr (params, '.') || strchr (params, ' ') || strchr (params, '/'))
1047     {
1048     sprintf (line, "Illegal characters in '%s'", params);
1049     new_draw_info (NDI_UNIQUE, 0, op, line);
1050     return 0;
1051     }
1052 elmex 1.1
1053 root 1.7 sprintf (filename, "%s/mischelp/%s", settings.datadir, params);
1054     if (stat (filename, &st) || !S_ISREG (st.st_mode))
1055     {
1056     if (op)
1057     {
1058     sprintf (filename, "%s/help/%s", settings.datadir, params);
1059     if (stat (filename, &st) || !S_ISREG (st.st_mode))
1060     {
1061     if (QUERY_FLAG (op, FLAG_WIZ))
1062     {
1063     sprintf (filename, "%s/wizhelp/%s", settings.datadir, params);
1064     if (stat (filename, &st) || !S_ISREG (st.st_mode))
1065     goto nohelp;
1066     }
1067     else
1068     goto nohelp;
1069     }
1070     }
1071     }
1072 elmex 1.1
1073     /*
1074     * Found that. Just cat it to screen.
1075     */
1076 root 1.7 if ((fp = fopen (filename, "r")) == NULL)
1077     {
1078     LOG (llevError, "Cannot open help file %s: %s\n", filename, strerror (errno));
1079     return 0;
1080     }
1081     sprintf (line, "Help about '%s'", params);
1082     new_draw_info (NDI_UNIQUE, 0, op, line);
1083     while (fgets (line, MAX_BUF, fp))
1084     {
1085     line[MAX_BUF - 1] = '\0';
1086     len = strlen (line) - 1;
1087     if (line[len] == '\n')
1088     line[len] = '\0';
1089     new_draw_info (NDI_UNIQUE, 0, op, line);
1090 elmex 1.1 }
1091 root 1.7 fclose (fp);
1092 elmex 1.1 return 0;
1093    
1094     /*
1095     * No_help -escape
1096     */
1097 root 1.7 nohelp:
1098     sprintf (line, "No help available on '%s'", params);
1099     new_draw_info (NDI_UNIQUE, 0, op, line);
1100 elmex 1.1 return 0;
1101     }
1102    
1103    
1104 root 1.7 int
1105     onoff_value (const char *line)
1106 elmex 1.1 {
1107     int i;
1108    
1109 root 1.7 if (sscanf (line, "%d", &i))
1110 elmex 1.1 return (i != 0);
1111 root 1.7 switch (line[0])
1112     {
1113     case 'o':
1114     switch (line[1])
1115     {
1116     case 'n':
1117     return 1; /* on */
1118     default:
1119     return 0; /* o[ff] */
1120     }
1121     case 'y': /* y[es] */
1122     case 'k': /* k[ylla] */
1123     case 's':
1124     case 'd':
1125     return 1;
1126     case 'n': /* n[o] */
1127     case 'e': /* e[i] */
1128     case 'u':
1129     default:
1130     return 0;
1131     }
1132 elmex 1.1 }
1133    
1134 root 1.7 int
1135     command_quit (object *op, char *params)
1136 elmex 1.1 {
1137 root 1.7 new_draw_info (NDI_UNIQUE, 0, op,
1138     "Quitting will delete your character PERMANENTLY. If you are sure you want to do this, then use the quit_character command instead of quit.");
1139     return 1;
1140 elmex 1.1 }
1141    
1142 root 1.7 int
1143     command_real_quit (object *op, char *params)
1144 elmex 1.1 {
1145 root 1.26 send_query (op->contr->ns, CS_QUERY_SINGLECHAR, "Quitting will delete your character.\nAre you sure you want to quit (y/n):");
1146 elmex 1.1
1147 root 1.26 op->contr->ns->state = ST_CONFIRM_QUIT;
1148 root 1.7 return 1;
1149     }
1150 elmex 1.1
1151     /*
1152     * don't allow people to exit explore mode. It otherwise becomes
1153     * really easy to abuse this.
1154     */
1155 root 1.7 int
1156     command_explore (object *op, char *params)
1157 elmex 1.1 {
1158 root 1.7 if (settings.explore_mode == FALSE)
1159     return 1;
1160 elmex 1.1 /*
1161     * I guess this is the best way to see if we are solo or not. Actually,
1162     * are there any cases when first_player->next==NULL and we are not solo?
1163     */
1164 root 1.7 if ((first_player != op->contr) || (first_player->next != NULL))
1165     {
1166     new_draw_info (NDI_UNIQUE, 0, op, "You can not enter explore mode if you are in a party");
1167     }
1168     else if (op->contr->explore)
1169     new_draw_info (NDI_UNIQUE, 0, op, "There is no return from explore mode");
1170     else
1171     {
1172     op->contr->explore = 1;
1173     new_draw_info (NDI_UNIQUE, 0, op, "You are now in explore mode");
1174 elmex 1.1 }
1175 root 1.7 return 1;
1176 elmex 1.1 }
1177    
1178 root 1.7 int
1179     command_sound (object *op, char *params)
1180 elmex 1.1 {
1181 root 1.26 if (op->contr->ns->sound)
1182 root 1.7 {
1183 root 1.26 op->contr->ns->sound = 0;
1184 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, "Silence is golden...");
1185     }
1186     else
1187     {
1188 root 1.26 op->contr->ns->sound = 1;
1189 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, "The sounds are enabled.");
1190 elmex 1.1 }
1191 root 1.23
1192 root 1.7 return 1;
1193 elmex 1.1 }
1194    
1195 root 1.7 int
1196     explore_mode (void)
1197     {
1198     player *pl;
1199 elmex 1.1
1200 root 1.7 if (settings.explore_mode == TRUE)
1201     {
1202     for (pl = first_player; pl != (player *) NULL; pl = pl->next)
1203     if (pl->explore)
1204     return 1;
1205 elmex 1.1 }
1206 root 1.7 return 0;
1207 elmex 1.1 }
1208    
1209 root 1.7 int
1210     command_title (object *op, char *params)
1211 elmex 1.1 {
1212 root 1.7 char buf[MAX_BUF];
1213    
1214     if (settings.set_title == FALSE)
1215     {
1216     new_draw_info (NDI_UNIQUE, 0, op, "You cannot change your title.");
1217     return 1;
1218 elmex 1.1 }
1219 root 1.7
1220     /* dragon players cannot change titles */
1221     if (is_dragon_pl (op))
1222     {
1223     new_draw_info (NDI_UNIQUE, 0, op, "Dragons cannot change titles.");
1224     return 1;
1225     }
1226    
1227     if (params == NULL)
1228     {
1229     if (op->contr->own_title[0] == '\0')
1230     sprintf (buf, "Your title is '%s'.", op->contr->title);
1231     else
1232     sprintf (buf, "Your title is '%s'.", op->contr->own_title);
1233     new_draw_info (NDI_UNIQUE, 0, op, buf);
1234     return 1;
1235     }
1236     if (strcmp (params, "clear") == 0 || strcmp (params, "default") == 0)
1237     {
1238     if (op->contr->own_title[0] == '\0')
1239     new_draw_info (NDI_UNIQUE, 0, op, "Your title is the default title.");
1240     else
1241     new_draw_info (NDI_UNIQUE, 0, op, "Title set to default.");
1242     op->contr->own_title[0] = '\0';
1243     return 1;
1244     }
1245    
1246     if ((int) strlen (params) >= MAX_NAME)
1247     {
1248     new_draw_info (NDI_UNIQUE, 0, op, "Title too long.");
1249     return 1;
1250     }
1251     strcpy (op->contr->own_title, params);
1252     return 1;
1253 elmex 1.1 }
1254    
1255 root 1.7 int
1256     command_save (object *op, char *params)
1257 elmex 1.1 {
1258 root 1.7 if (!op->stats.exp)
1259 root 1.27 new_draw_info (NDI_UNIQUE, 0, op, "You don't deserve to save yet.");
1260 root 1.7 else
1261     {
1262 root 1.27 op->contr->save ();
1263     new_draw_info (NDI_UNIQUE, 0, op, "You have been saved.");
1264 elmex 1.1 }
1265 root 1.27
1266 root 1.7 return 1;
1267 elmex 1.1 }
1268    
1269 root 1.7 int
1270     command_peaceful (object *op, char *params)
1271 elmex 1.1 {
1272 root 1.7 new_draw_info (NDI_UNIQUE, 0, op,
1273     "You cannot change your peaceful setting with this command."
1274     " Please speak to the priest in the temple of Gorokh"
1275     " if you want to become hostile or in temple of Valriel" " if you want to become peaceful again.");
1276 elmex 1.1
1277     /*
1278     if((op->contr->peaceful=!op->contr->peaceful))
1279     new_draw_info(NDI_UNIQUE, 0,op,"You will not attack other players.");
1280     else
1281     new_draw_info(NDI_UNIQUE, 0,op,"You will attack other players.");
1282     */
1283 root 1.7 return 1;
1284 elmex 1.1 }
1285    
1286 root 1.7 int
1287     command_wimpy (object *op, char *params)
1288 elmex 1.1 {
1289 root 1.7 int i;
1290     char buf[MAX_BUF];
1291 elmex 1.1
1292 root 1.7 if (params == NULL || !sscanf (params, "%d", &i))
1293     {
1294     sprintf (buf, "Your current wimpy level is %d.", op->run_away);
1295     new_draw_info (NDI_UNIQUE, 0, op, buf);
1296     return 1;
1297     }
1298     sprintf (buf, "Your new wimpy level is %d.", i);
1299     new_draw_info (NDI_UNIQUE, 0, op, buf);
1300     op->run_away = i;
1301     return 1;
1302 elmex 1.1 }
1303    
1304 root 1.7 int
1305     command_brace (object *op, char *params)
1306 elmex 1.1 {
1307     if (!params)
1308 root 1.7 op->contr->braced = !op->contr->braced;
1309 elmex 1.1 else
1310 root 1.7 op->contr->braced = onoff_value (params);
1311 elmex 1.1
1312 root 1.7 if (op->contr->braced)
1313     new_draw_info (NDI_UNIQUE, 0, op, "You are braced.");
1314 elmex 1.1 else
1315 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, "Not braced.");
1316 elmex 1.1
1317 root 1.27 op->update_stats ();
1318 elmex 1.1 return 0;
1319     }
1320    
1321 root 1.7 int
1322     command_style_map_info (object *op, char *params)
1323 elmex 1.1 {
1324 root 1.9 extern maptile *styles;
1325     maptile *mp;
1326 root 1.7 int maps_used = 0, mapmem = 0, objects_used = 0, x, y;
1327     object *tmp;
1328    
1329     for (mp = styles; mp != NULL; mp = mp->next)
1330     {
1331     maps_used++;
1332 root 1.29 mapmem += mp->width * mp->height * (sizeof (object *) + sizeof (mapspace)) + sizeof (maptile);
1333     for (x = 0; x < mp->width; x++)
1334 root 1.7 {
1335 root 1.29 for (y = 0; y < mp->height; y++)
1336 root 1.7 {
1337 root 1.25 for (tmp = GET_MAP_OB (mp, x, y); tmp != NULL; tmp = tmp->above)
1338 root 1.7 objects_used++;
1339 root 1.3 }
1340     }
1341 elmex 1.1 }
1342 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "Style maps loaded: %d", maps_used);
1343     new_draw_info (NDI_UNIQUE, 0, op, "Memory used, not");
1344     new_draw_info_format (NDI_UNIQUE, 0, op, "including objects: %d", mapmem);
1345     new_draw_info_format (NDI_UNIQUE, 0, op, "Style objects: %d", objects_used);
1346     new_draw_info_format (NDI_UNIQUE, 0, op, "Mem for objects: %d", objects_used * sizeof (object));
1347     return 0;
1348 elmex 1.1 }
1349    
1350 root 1.7 int
1351     command_kill_pets (object *op, char *params)
1352 elmex 1.1 {
1353 root 1.7 objectlink *obl, *next;
1354     int counter = 0, removecount = 0;
1355    
1356     if (params == NULL)
1357     {
1358     terminate_all_pets (op);
1359     new_draw_info (NDI_UNIQUE, 0, op, "Your pets have been killed.");
1360     }
1361     else
1362     {
1363     int target = atoi (params);
1364    
1365     for (obl = first_friendly_object; obl != NULL; obl = next)
1366     {
1367     object *ob = obl->ob;
1368    
1369     next = obl->next;
1370 root 1.22 if (ob->owner == op)
1371 root 1.7 if (++counter == target || (target == 0 && !strcasecmp (ob->name, params)))
1372     {
1373 root 1.20 ob->destroy ();
1374 root 1.3 removecount++;
1375 root 1.7 }
1376 root 1.3 }
1377 root 1.7 if (removecount != 0)
1378     new_draw_info_format (NDI_UNIQUE, 0, op, "killed %d pets.\n", removecount);
1379     else
1380     new_draw_info (NDI_UNIQUE, 0, op, "Couldn't find any suitable pets to kill.\n");
1381 elmex 1.1 }
1382 root 1.7 return 0;
1383 elmex 1.1 }