ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_misc.C
Revision: 1.31
Committed: Wed Dec 27 09:28:02 2006 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.30: +5 -3 lines
Log Message:
introduce for_all_maps

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