ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_misc.C
Revision: 1.30
Committed: Mon Dec 25 14:54:44 2006 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.29: +2 -2 lines
Log Message:
the big rename

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