ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_misc.C
Revision: 1.62
Committed: Sun Jul 1 05:00:19 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.61: +10 -11 lines
Log Message:
- upgrade crossfire trt to the GPL version 3 (hopefully correctly).
- add a single file covered by the GNU Affero General Public License
  (which is not yet released, so I used the current draft, which is
  legally a bit wavy, but its likely better than nothing as it expresses
  direct intent by the authors, and we can upgrade as soon as it has been
  released).
  * this should ensure availability of source code for the server at least
    and hopefully also archetypes and maps even when modified versions
    are not being distributed, in accordance of section 13 of the agplv3.

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.59 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 pippijn 1.36 *
4 root 1.59 * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5     * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7 pippijn 1.36 *
8 root 1.62 * Crossfire TRT is free software: you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation, either version 3 of the License, or
11     * (at your option) any later version.
12 pippijn 1.36 *
13 root 1.62 * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17 pippijn 1.36 *
18 root 1.62 * You should have received a copy of the GNU General Public License
19     * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 root 1.59 *
21     * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 pippijn 1.36 */
23 elmex 1.1
24     #include <global.h>
25     #include <loader.h>
26 root 1.21 #include <sproto.h>
27    
28 pippijn 1.55 /* Handles misc. input request - things like hash table, malloc, maps, etc */
29 elmex 1.1
30 root 1.7 int
31     command_motd (object *op, char *params)
32 elmex 1.1 {
33 root 1.7 display_motd (op);
34     return 1;
35 elmex 1.1 }
36    
37     #ifdef DEBUG_MALLOC_LEVEL
38 root 1.7 int
39     command_malloc_verify (object *op, char *parms)
40 elmex 1.1 {
41 root 1.7 extern int malloc_verify (void);
42 pippijn 1.54
43 root 1.7 if (!malloc_verify ())
44     new_draw_info (NDI_UNIQUE, 0, op, "Heap is corrupted.");
45     else
46     new_draw_info (NDI_UNIQUE, 0, op, "Heap checks out OK.");
47     return 1;
48     }
49 elmex 1.1 #endif
50    
51 root 1.7 int
52     command_whereabouts (object *op, char *params)
53     {
54 root 1.38 //TODO: should obviously not waste space in struct region for this.
55 root 1.7 /*
56     * reset the counter on the region, then use it to store the number of
57     * players there.
58     * I don't know how thread-safe this would be, I suspect not very....
59     */
60 root 1.41 for_all_regions (rgn)
61     rgn->counter = 0;
62 root 1.38
63 root 1.28 for_all_players (pl)
64 root 1.38 if (pl->ob->map)
65     ++pl->ob->region ()->counter;
66 root 1.7
67     /* we only want to print out by places with a 'longname' field... */
68 root 1.41 for_all_regions (rgn)
69 root 1.7 {
70 root 1.41 if (!rgn->longname && rgn->counter > 0)
71 root 1.7 {
72 root 1.41 if (rgn->parent)
73 root 1.7 {
74 root 1.41 rgn->parent->counter += rgn->counter;
75     rgn->counter = 0;
76 root 1.3 }
77 root 1.7 else /*uh oh, we shouldn't be here. */
78 root 1.41 LOG (llevError, "command_whereabouts() Region %s with no longname has no parent", &rgn->name);
79 root 1.3 }
80     }
81 root 1.38
82 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "In the world currently there are:");
83 root 1.38
84 root 1.41 for_all_regions (rgn)
85     if (rgn->counter)
86 root 1.44 new_draw_info_format (NDI_UNIQUE, 0, op, "%u players %s", rgn->counter, &rgn->longname);
87 root 1.38
88 root 1.7 return 1;
89 elmex 1.1 }
90    
91     typedef struct
92 root 1.7 {
93     char namebuf[MAX_BUF];
94     int login_order;
95     } chars_names;
96 elmex 1.1
97 root 1.7 int
98     command_time (object *op, char *params)
99 elmex 1.1 {
100 root 1.2 print_tod (op);
101     return 1;
102     }
103 elmex 1.1
104 root 1.7 int
105     command_weather (object *op, char *params)
106 elmex 1.1 {
107 root 1.33 #if 0
108 root 1.7 int wx, wy, temp, sky;
109     char buf[MAX_BUF];
110    
111     if (settings.dynamiclevel < 1)
112     return 1;
113    
114     if (op->map == NULL)
115     return 1;
116    
117     if (worldmap_to_weathermap (op->x, op->y, &wx, &wy, op->map) != 0)
118     return 1;
119    
120     if (QUERY_FLAG (op, FLAG_WIZ))
121     {
122     /* dump the weather, Dm style! Yo! */
123     new_draw_info_format (NDI_UNIQUE, 0, op, "Real temp: %d", real_world_temperature (op->x, op->y, op->map));
124     new_draw_info_format (NDI_UNIQUE, 0, op, "Base temp: %d", weathermap[wx][wy].temp);
125     new_draw_info_format (NDI_UNIQUE, 0, op, "Humid: %d", weathermap[wx][wy].humid);
126     new_draw_info_format (NDI_UNIQUE, 0, op, "Wind: dir=%d speed=%d", weathermap[wx][wy].winddir, weathermap[wx][wy].windspeed);
127     new_draw_info_format (NDI_UNIQUE, 0, op, "Pressure: %d", weathermap[wx][wy].pressure);
128     new_draw_info_format (NDI_UNIQUE, 0, op, "Avg Elevation: %d", weathermap[wx][wy].avgelev);
129     new_draw_info_format (NDI_UNIQUE, 0, op, "Rainfall: %d Water: %d", weathermap[wx][wy].rainfall, weathermap[wx][wy].water);
130     }
131    
132     temp = real_world_temperature (op->x, op->y, op->map);
133     new_draw_info_format (NDI_UNIQUE, 0, op, "It's currently %d degrees " "Centigrade out.", temp);
134    
135     /* humid */
136     if (weathermap[wx][wy].humid < 20)
137     new_draw_info (NDI_UNIQUE, 0, op, "It is very dry.");
138     else if (weathermap[wx][wy].humid < 40)
139     new_draw_info (NDI_UNIQUE, 0, op, "It is very comfortable today.");
140     else if (weathermap[wx][wy].humid < 60)
141     new_draw_info (NDI_UNIQUE, 0, op, "It is a bit muggy.");
142     else if (weathermap[wx][wy].humid < 80)
143     new_draw_info (NDI_UNIQUE, 0, op, "It is muggy.");
144     else
145     new_draw_info (NDI_UNIQUE, 0, op, "It is uncomfortably muggy.");
146 elmex 1.1
147 root 1.7 /* wind */
148     switch (weathermap[wx][wy].winddir)
149     {
150     case 1:
151     sprintf (buf, "north");
152     break;
153     case 2:
154     sprintf (buf, "northeast");
155     break;
156     case 3:
157     sprintf (buf, "east");
158     break;
159     case 4:
160     sprintf (buf, "southeast");
161     break;
162     case 5:
163     sprintf (buf, "south");
164     break;
165     case 6:
166     sprintf (buf, "southwest");
167     break;
168     case 7:
169     sprintf (buf, "west");
170     break;
171     case 8:
172     sprintf (buf, "northwest");
173     break;
174     }
175     if (weathermap[wx][wy].windspeed < 5)
176     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a mild breeze " "coming from the %s.", buf);
177     else if (weathermap[wx][wy].windspeed < 10)
178     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a strong breeze " "coming from the %s.", buf);
179     else if (weathermap[wx][wy].windspeed < 15)
180     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a light wind " "coming from the %s.", buf);
181     else if (weathermap[wx][wy].windspeed < 25)
182     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a strong wind " "coming from the %s.", buf);
183     else if (weathermap[wx][wy].windspeed < 35)
184     new_draw_info_format (NDI_UNIQUE, 0, op, "There is a heavy wind " "coming from the %s.", buf);
185     else
186     new_draw_info_format (NDI_UNIQUE, 0, op, "The wind from the %s is " "incredibly strong!", buf);
187 elmex 1.1
188 root 1.7 sky = weathermap[wx][wy].sky;
189     if (temp <= 0 && sky > SKY_OVERCAST && sky < SKY_FOG)
190     sky += 10; /*let it snow */
191     switch (sky)
192     {
193     case SKY_CLEAR:
194     new_draw_info (NDI_UNIQUE, 0, op, "There isn''t a cloud in the sky.");
195     break;
196     case SKY_LIGHTCLOUD:
197     new_draw_info (NDI_UNIQUE, 0, op, "There are a few light clouds in the sky.");
198     break;
199     case SKY_OVERCAST:
200     new_draw_info (NDI_UNIQUE, 0, op, "The sky is cloudy and dreary.");
201     break;
202     case SKY_LIGHT_RAIN:
203     new_draw_info (NDI_UNIQUE, 0, op, "It is raining softly.");
204     break;
205     case SKY_RAIN:
206     new_draw_info (NDI_UNIQUE, 0, op, "It is raining.");
207     break;
208     case SKY_HEAVY_RAIN:
209     new_draw_info (NDI_UNIQUE, 0, op, "It is raining heavily.");
210     break;
211     case SKY_HURRICANE:
212     new_draw_info (NDI_UNIQUE, 0, op, "There is a heavy storm! You should go inside!");
213     break;
214     case SKY_FOG:
215     new_draw_info (NDI_UNIQUE, 0, op, "It''s foggy and miserable.");
216     break;
217     case SKY_HAIL:
218     new_draw_info (NDI_UNIQUE, 0, op, "It''s hailing out! Take cover!");
219     break;
220     case SKY_LIGHT_SNOW:
221     new_draw_info (NDI_UNIQUE, 0, op, "Snow is gently falling from the sky.");
222     break;
223     case SKY_SNOW:
224     new_draw_info (NDI_UNIQUE, 0, op, "It''s snowing out.");
225     break;
226     case SKY_HEAVY_SNOW:
227     new_draw_info (NDI_UNIQUE, 0, op, "The snow is falling very heavily now.");
228     break;
229     case SKY_BLIZZARD:
230     new_draw_info (NDI_UNIQUE, 0, op, "A full blown blizzard is in effect. You might want to take cover!");
231     break;
232 elmex 1.1 }
233 root 1.33 #endif
234 root 1.7 return 1;
235 elmex 1.1 }
236    
237 root 1.7 int
238     command_hiscore (object *op, char *params)
239 elmex 1.1 {
240 root 1.7 display_high_score (op, op == NULL ? 9999 : 50, params);
241     return 1;
242     }
243 elmex 1.1
244 root 1.7 int
245     command_debug (object *op, char *params)
246 elmex 1.1 {
247 root 1.7 int i;
248     char buf[MAX_BUF];
249    
250     if (params == NULL || !sscanf (params, "%d", &i))
251     {
252     sprintf (buf, "Global debug level is %d.", settings.debug);
253     new_draw_info (NDI_UNIQUE, 0, op, buf);
254 elmex 1.1 return 1;
255     }
256 root 1.58
257     settings.debug = i;
258    
259 root 1.7 sprintf (buf, "Set debug level to %d.", i);
260     new_draw_info (NDI_UNIQUE, 0, op, buf);
261     return 1;
262     }
263 elmex 1.1
264    
265     /*
266     * Those dumps should be just one dump with good parser
267     */
268    
269 root 1.7 int
270     command_dumpbelow (object *op, char *params)
271 elmex 1.1 {
272 root 1.7 if (op && op->below)
273     {
274 root 1.14 char *dump = dump_object (op->below);
275     new_draw_info (NDI_UNIQUE, 0, op, dump);
276     free (dump);
277 elmex 1.1 /* Let's push that item on the dm's stack */
278 root 1.7 dm_stack_push (op->contr, op->below->count);
279     }
280 elmex 1.1 return 0;
281     }
282    
283 root 1.7 int
284     command_dumpfriendlyobjects (object *op, char *params)
285 elmex 1.1 {
286 root 1.7 dump_friendly_objects ();
287 elmex 1.1 return 0;
288     }
289    
290 root 1.7 int
291     command_printlos (object *op, char *params)
292 elmex 1.1 {
293     if (op)
294 root 1.7 print_los (op);
295 elmex 1.1 return 0;
296     }
297    
298    
299 root 1.7 int
300     command_version (object *op, char *params)
301 elmex 1.1 {
302 root 1.7 version (op);
303     return 0;
304 elmex 1.1 }
305    
306     #ifndef BUG_LOG
307 root 1.7 # define BUG_LOG "bug_log"
308 elmex 1.1 #endif
309 root 1.7 void
310     bug_report (const char *reportstring)
311     {
312     FILE *fp;
313    
314     if ((fp = fopen (BUG_LOG, "a")) != NULL)
315     {
316     fprintf (fp, "%s\n", reportstring);
317     fclose (fp);
318     }
319     else
320     {
321     LOG (llevError, "Cannot write bugs file %s: %s\n", BUG_LOG, strerror (errno));
322 elmex 1.1 }
323 root 1.7 }
324    
325 elmex 1.1 /* Prints out some useful information for the character. Everything we print
326     * out can be determined by the docs, so we aren't revealing anything extra -
327     * rather, we are making it convenient to find the values. params have
328     * no meaning here.
329     */
330 root 1.7 int
331     command_statistics (object *pl, char *params)
332 elmex 1.1 {
333 root 1.7 if (!pl->contr)
334     return 1;
335 root 1.18 new_draw_info_format (NDI_UNIQUE, 0, pl, " Experience: %" PRId64, pl->stats.exp);
336     new_draw_info_format (NDI_UNIQUE, 0, pl, " Next Level: %" PRId64, level_exp (pl->level + 1, pl->expmul));
337 root 1.7 new_draw_info (NDI_UNIQUE, 0, pl, "\nStat Nat/Real/Max");
338 elmex 1.1
339 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Str %2d/ %3d/%3d",
340 root 1.61 pl->contr->orig_stats.Str, pl->stats.Str, 20 + pl->arch->stats.Str);
341 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Dex %2d/ %3d/%3d",
342 root 1.61 pl->contr->orig_stats.Dex, pl->stats.Dex, 20 + pl->arch->stats.Dex);
343 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Con %2d/ %3d/%3d",
344 root 1.61 pl->contr->orig_stats.Con, pl->stats.Con, 20 + pl->arch->stats.Con);
345 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Int %2d/ %3d/%3d",
346 root 1.61 pl->contr->orig_stats.Int, pl->stats.Int, 20 + pl->arch->stats.Int);
347 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Wis %2d/ %3d/%3d",
348 root 1.61 pl->contr->orig_stats.Wis, pl->stats.Wis, 20 + pl->arch->stats.Wis);
349 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Pow %2d/ %3d/%3d",
350 root 1.61 pl->contr->orig_stats.Pow, pl->stats.Pow, 20 + pl->arch->stats.Pow);
351 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "Cha %2d/ %3d/%3d",
352 root 1.61 pl->contr->orig_stats.Cha, pl->stats.Cha, 20 + pl->arch->stats.Cha);
353 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, pl, "\nAttack Mode: %s", pl->contr->peaceful ? "Peaceful" : "Hostile");
354 elmex 1.1
355 root 1.7 /* Can't think of anything else to print right now */
356     return 0;
357 elmex 1.1 }
358    
359 root 1.7 int
360     command_fix_me (object *op, char *params)
361 elmex 1.1 {
362 root 1.7 sum_weight (op);
363 root 1.27 op->update_stats ();
364 pippijn 1.51 new_draw_info (NDI_UNIQUE, 0, op, "Your character was fixed.");
365    
366 root 1.7 return 1;
367 elmex 1.1 }
368    
369 root 1.7 int
370     command_logs (object *op, char *params)
371 elmex 1.1 {
372 root 1.10 new_draw_info (NDI_UNIQUE, 0, op, "Nobody is currently logging kills.");
373 elmex 1.1
374 root 1.7 return 1;
375 elmex 1.1 }
376    
377 root 1.7 int
378     command_bowmode (object *op, char *params)
379 elmex 1.1 {
380 root 1.7 bowtype_t oldtype = op->contr->bowtype;
381     static const char *const types[] = { "normal", "threewide", "spreadshot", "firenorth",
382     "firene", "fireeast", "firese", "firesouth",
383     "firesw", "firewest", "firenw", "bestarrow"
384     };
385     char buf[MAX_BUF];
386     int i, found;
387    
388     if (!params)
389     {
390     new_draw_info_format (NDI_UNIQUE, 0, op, "bowmode is set to %s", types[op->contr->bowtype]);
391     return 1;
392     }
393    
394     for (i = 0, found = 0; i <= bow_bestarrow; i++)
395     {
396     if (!strcmp (params, types[i]))
397     {
398     found++;
399     op->contr->bowtype = (bowtype_t) i;
400     break;
401 root 1.3 }
402 elmex 1.1 }
403 root 1.38
404 root 1.7 if (!found)
405     {
406     sprintf (buf, "bowmode: Unknown options %s, valid options are:", params);
407     for (i = 0; i <= bow_bestarrow; i++)
408     {
409     strcat (buf, " ");
410     strcat (buf, types[i]);
411     if (i < bow_nw)
412     strcat (buf, ",");
413     else
414     strcat (buf, ".");
415 root 1.3 }
416 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, buf);
417     return 0;
418 elmex 1.1 }
419 root 1.38
420 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]);
421     return 1;
422 elmex 1.1 }
423    
424 root 1.7 int
425     command_showpets (object *op, char *params)
426 elmex 1.1 {
427 root 1.7 objectlink *obl, *next;
428     int counter = 0, target = 0;
429     int have_shown_pet = 0;
430    
431     if (params != NULL)
432     target = atoi (params);
433     for (obl = first_friendly_object; obl != NULL; obl = next)
434     {
435     object *ob = obl->ob;
436    
437     next = obl->next;
438 root 1.22 if (ob->owner == op)
439 root 1.7 {
440     if (target == 0)
441     {
442     if (counter == 0)
443     new_draw_info (NDI_UNIQUE, 0, op, "Pets:");
444     new_draw_info_format (NDI_UNIQUE, 0, op, "%d %s - level %d", ++counter, &ob->name, ob->level);
445     }
446     else if (!have_shown_pet && ++counter == target)
447     {
448     new_draw_info_format (NDI_UNIQUE, 0, op, "level %d %s", ob->level, &ob->name);
449     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);
450     /* this is not a nice way to do this, it should be made to be more like the statistics command */
451     new_draw_info_format (NDI_UNIQUE, 0, op, "Str %d", ob->stats.Str);
452     new_draw_info_format (NDI_UNIQUE, 0, op, "Dex %d", ob->stats.Dex);
453     new_draw_info_format (NDI_UNIQUE, 0, op, "Con %d", ob->stats.Con);
454     new_draw_info_format (NDI_UNIQUE, 0, op, "Int %d", ob->stats.Int);
455     new_draw_info_format (NDI_UNIQUE, 0, op, "Wis %d", ob->stats.Wis);
456     new_draw_info_format (NDI_UNIQUE, 0, op, "Cha %d", ob->stats.Cha);
457     new_draw_info_format (NDI_UNIQUE, 0, op, "Pow %d", ob->stats.Pow);
458     new_draw_info_format (NDI_UNIQUE, 0, op, "wc %d damage %d ac %d ", ob->stats.wc, ob->stats.dam, ob->stats.ac);
459     have_shown_pet = 1;
460 root 1.3 }
461     }
462 elmex 1.1 }
463 root 1.7 if (counter == 0)
464     new_draw_info (NDI_UNIQUE, 0, op, "you have no pets.");
465     else if (target != 0 && have_shown_pet == 0)
466     new_draw_info (NDI_UNIQUE, 0, op, "no such pet.");
467     return 0;
468 elmex 1.1 }
469    
470 root 1.7 int
471     command_resistances (object *op, char *params)
472 elmex 1.1 {
473 root 1.7 int i;
474 elmex 1.1
475 root 1.7 if (!op)
476     return 0;
477    
478     for (i = 0; i < NROFATTACKS; i++)
479     {
480     if (i == ATNR_INTERNAL)
481     continue;
482 elmex 1.1
483 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "%-20s %+5d", attacktype_desc[i], op->resist[i]);
484 elmex 1.1 }
485    
486 root 1.7 /* If dragon player, let's display natural resistances */
487     if (is_dragon_pl (op))
488     {
489     int attack;
490     object *tmp;
491    
492     for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
493 elmex 1.1 {
494 root 1.60 if ((tmp->type == FORCE) && (strcmp (tmp->arch->archname, "dragon_skin_force") == 0))
495 elmex 1.1 {
496 root 1.7 new_draw_info (NDI_UNIQUE, 0, op, "\nNatural skin resistances:");
497     for (attack = 0; attack < NROFATTACKS; attack++)
498 elmex 1.1 {
499 root 1.7 if (atnr_is_dragon_enabled (attack))
500 elmex 1.1 {
501 root 1.7 new_draw_info_format (NDI_UNIQUE, 0, op, "%s: %d", change_resist_msg[attack], tmp->resist[attack]);
502 elmex 1.1 }
503     }
504 root 1.7 break;
505 elmex 1.1 }
506     }
507 root 1.7 }
508 elmex 1.1
509 root 1.7 return 0;
510 elmex 1.1 }
511 root 1.7
512 elmex 1.1 /*
513     * Actual commands.
514     * Those should be in small separate files (c_object.c, c_wiz.c, cmove.c,...)
515     */
516    
517 root 1.7 int
518     onoff_value (const char *line)
519 elmex 1.1 {
520     int i;
521    
522 root 1.7 if (sscanf (line, "%d", &i))
523 elmex 1.1 return (i != 0);
524 root 1.7 switch (line[0])
525     {
526     case 'o':
527     switch (line[1])
528     {
529     case 'n':
530     return 1; /* on */
531     default:
532     return 0; /* o[ff] */
533     }
534     case 'y': /* y[es] */
535     case 'k': /* k[ylla] */
536     case 's':
537     case 'd':
538     return 1;
539     case 'n': /* n[o] */
540     case 'e': /* e[i] */
541     case 'u':
542     default:
543     return 0;
544     }
545 elmex 1.1 }
546    
547 root 1.7 int
548     command_title (object *op, char *params)
549 elmex 1.1 {
550 root 1.7 char buf[MAX_BUF];
551    
552     if (settings.set_title == FALSE)
553     {
554     new_draw_info (NDI_UNIQUE, 0, op, "You cannot change your title.");
555     return 1;
556 elmex 1.1 }
557 root 1.7
558     /* dragon players cannot change titles */
559     if (is_dragon_pl (op))
560     {
561     new_draw_info (NDI_UNIQUE, 0, op, "Dragons cannot change titles.");
562     return 1;
563     }
564    
565     if (params == NULL)
566     {
567     if (op->contr->own_title[0] == '\0')
568     sprintf (buf, "Your title is '%s'.", op->contr->title);
569     else
570     sprintf (buf, "Your title is '%s'.", op->contr->own_title);
571     new_draw_info (NDI_UNIQUE, 0, op, buf);
572     return 1;
573     }
574     if (strcmp (params, "clear") == 0 || strcmp (params, "default") == 0)
575     {
576     if (op->contr->own_title[0] == '\0')
577     new_draw_info (NDI_UNIQUE, 0, op, "Your title is the default title.");
578     else
579     new_draw_info (NDI_UNIQUE, 0, op, "Title set to default.");
580     op->contr->own_title[0] = '\0';
581     return 1;
582     }
583    
584     if ((int) strlen (params) >= MAX_NAME)
585     {
586     new_draw_info (NDI_UNIQUE, 0, op, "Title too long.");
587     return 1;
588     }
589     strcpy (op->contr->own_title, params);
590     return 1;
591 elmex 1.1 }
592    
593 root 1.7 int
594     command_kill_pets (object *op, char *params)
595 elmex 1.1 {
596 root 1.7 objectlink *obl, *next;
597     int counter = 0, removecount = 0;
598    
599 root 1.57 if (!params)
600 root 1.7 {
601     terminate_all_pets (op);
602     new_draw_info (NDI_UNIQUE, 0, op, "Your pets have been killed.");
603     }
604     else
605     {
606     int target = atoi (params);
607    
608 root 1.57 for (obl = first_friendly_object; obl; obl = next)
609 root 1.7 {
610     object *ob = obl->ob;
611    
612     next = obl->next;
613 root 1.56
614 root 1.22 if (ob->owner == op)
615 root 1.7 if (++counter == target || (target == 0 && !strcasecmp (ob->name, params)))
616     {
617 root 1.20 ob->destroy ();
618 root 1.3 removecount++;
619 root 1.7 }
620 root 1.3 }
621 root 1.56
622 root 1.7 if (removecount != 0)
623     new_draw_info_format (NDI_UNIQUE, 0, op, "killed %d pets.\n", removecount);
624     else
625     new_draw_info (NDI_UNIQUE, 0, op, "Couldn't find any suitable pets to kill.\n");
626 elmex 1.1 }
627 root 1.56
628 root 1.7 return 0;
629 elmex 1.1 }