OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / src / mplayer.c
1 /* NetHack 3.6  mplayer.c       $NHDT-Date: 1432512774 2015/05/25 00:12:54 $  $NHDT-Branch: master $:$NHDT-Revision: 1.19 $ */
2 /*      Copyright (c) Izchak Miller, 1992.                        */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #include "hack.h"
6
7 STATIC_DCL const char *NDECL(dev_name);
8 STATIC_DCL void FDECL(get_mplname, (struct monst *, char *));
9 STATIC_DCL void FDECL(mk_mplayer_armor, (struct monst *, SHORT_P));
10
11 /* These are the names of those who
12  * contributed to the development of NetHack 3.2/3.3/3.4/3.6.
13  *
14  * Keep in alphabetical order within teams.
15  * Same first name is entered once within each team.
16  */
17 static const char *developers[] = {
18     /* devteam */
19     "Dave",    "Dean",   "Eric",    "Izchak", "Janet",    "Jessie",
20     "Ken",     "Kevin",  "Michael", "Mike",   "Pat",      "Paul",
21     "Steve",   "Timo",   "Warwick",
22     /* PC team */
23     "Bill",    "Eric",   "Keizo",   "Ken",    "Kevin",    "Michael",
24     "Mike",    "Paul",   "Stephen", "Steve",  "Timo",     "Yitzhak",
25     /* Amiga team */
26     "Andy",    "Gregg",  "Janne",   "Keni",   "Mike",     "Olaf",
27     "Richard",
28     /* Mac team */
29     "Andy",    "Chris",  "Dean",    "Jon",    "Jonathan", "Kevin",
30     "Wang",
31     /* Atari team */
32     "Eric",    "Marvin", "Warwick",
33     /* NT team */
34     "Alex",    "Dion",   "Michael",
35     /* OS/2 team */
36     "Helge",   "Ron",    "Timo",
37     /* VMS team */
38     "Joshua",  "Pat",    ""
39 };
40
41 /* return a randomly chosen developer name */
42 STATIC_OVL const char *
43 dev_name()
44 {
45     register int i, m = 0, n = SIZE(developers);
46     register struct monst *mtmp;
47     register boolean match;
48
49     do {
50         match = FALSE;
51         i = rn2(n);
52         for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
53             if (!is_mplayer(mtmp->data))
54                 continue;
55             if (!strncmp(developers[i], (has_mname(mtmp)) ? MNAME(mtmp) : "",
56                          strlen(developers[i]))) {
57                 match = TRUE;
58                 break;
59             }
60         }
61         m++;
62     } while (match && m < 100); /* m for insurance */
63
64     if (match)
65         return (const char *) 0;
66     return (developers[i]);
67 }
68
69 STATIC_OVL void
70 get_mplname(mtmp, nam)
71 register struct monst *mtmp;
72 char *nam;
73 {
74     boolean fmlkind = is_female(mtmp->data);
75     const char *devnam;
76
77     devnam = dev_name();
78     if (!devnam)
79         Strcpy(nam, fmlkind ? "Eve" : "Adam");
80     else if (fmlkind && !!strcmp(devnam, "Janet"))
81         Strcpy(nam, rn2(2) ? "Maud" : "Eve");
82     else
83         Strcpy(nam, devnam);
84
85     if (fmlkind || !strcmp(nam, "Janet"))
86         mtmp->female = 1;
87     else
88         mtmp->female = 0;
89     Strcat(nam, " the ");
90     Strcat(nam, rank_of((int) mtmp->m_lev, monsndx(mtmp->data),
91                         (boolean) mtmp->female));
92 }
93
94 STATIC_OVL void
95 mk_mplayer_armor(mon, typ)
96 struct monst *mon;
97 short typ;
98 {
99     struct obj *obj;
100
101     if (typ == STRANGE_OBJECT)
102         return;
103     obj = mksobj(typ, FALSE, FALSE);
104     if (!rn2(3))
105         obj->oerodeproof = 1;
106     if (!rn2(3))
107         curse(obj);
108     if (!rn2(3))
109         bless(obj);
110     /* Most players who get to the endgame who have cursed equipment
111      * have it because the wizard or other monsters cursed it, so its
112      * chances of having plusses is the same as usual....
113      */
114     obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4, 4)) : -rnd(3);
115     (void) mpickobj(mon, obj);
116 }
117
118 struct monst *
119 mk_mplayer(ptr, x, y, special)
120 register struct permonst *ptr;
121 xchar x, y;
122 register boolean special;
123 {
124     register struct monst *mtmp;
125     char nam[PL_NSIZ];
126
127     if (!is_mplayer(ptr))
128         return ((struct monst *) 0);
129
130     if (MON_AT(x, y))
131         (void) rloc(m_at(x, y), FALSE); /* insurance */
132
133     if (!In_endgame(&u.uz))
134         special = FALSE;
135
136     if ((mtmp = makemon(ptr, x, y, NO_MM_FLAGS)) != 0) {
137         short weapon = rn2(2) ? LONG_SWORD : rnd_class(SPEAR, BULLWHIP);
138         short armor =
139             rnd_class(GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL);
140         short cloak = !rn2(8)
141                           ? STRANGE_OBJECT
142                           : rnd_class(OILSKIN_CLOAK, CLOAK_OF_DISPLACEMENT);
143         short helm = !rn2(8) ? STRANGE_OBJECT : rnd_class(ELVEN_LEATHER_HELM,
144                                                           HELM_OF_TELEPATHY);
145         short shield = !rn2(8)
146                            ? STRANGE_OBJECT
147                            : rnd_class(ELVEN_SHIELD, SHIELD_OF_REFLECTION);
148         int quan;
149         struct obj *otmp;
150
151         mtmp->m_lev = (special ? rn1(16, 15) : rnd(16));
152         mtmp->mhp = mtmp->mhpmax =
153             d((int) mtmp->m_lev, 10) + (special ? (30 + rnd(30)) : 30);
154         if (special) {
155             get_mplname(mtmp, nam);
156             mtmp = christen_monst(mtmp, nam);
157             /* that's why they are "stuck" in the endgame :-) */
158             (void) mongets(mtmp, FAKE_AMULET_OF_YENDOR);
159         }
160         mtmp->mpeaceful = 0;
161         set_malign(mtmp); /* peaceful may have changed again */
162
163         switch (monsndx(ptr)) {
164         case PM_ARCHEOLOGIST:
165             if (rn2(2))
166                 weapon = BULLWHIP;
167             break;
168         case PM_BARBARIAN:
169             if (rn2(2)) {
170                 weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
171                 shield = STRANGE_OBJECT;
172             }
173             if (rn2(2))
174                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
175             if (helm == HELM_OF_BRILLIANCE)
176                 helm = STRANGE_OBJECT;
177             break;
178         case PM_CAVEMAN:
179         case PM_CAVEWOMAN:
180             if (rn2(4))
181                 weapon = MACE;
182             else if (rn2(2))
183                 weapon = CLUB;
184             if (helm == HELM_OF_BRILLIANCE)
185                 helm = STRANGE_OBJECT;
186             break;
187         case PM_HEALER:
188             if (rn2(4))
189                 weapon = QUARTERSTAFF;
190             else if (rn2(2))
191                 weapon = rn2(2) ? UNICORN_HORN : SCALPEL;
192             if (rn2(4))
193                 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
194             if (rn2(2))
195                 shield = STRANGE_OBJECT;
196             break;
197         case PM_KNIGHT:
198             if (rn2(4))
199                 weapon = LONG_SWORD;
200             if (rn2(2))
201                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
202             break;
203         case PM_MONK:
204             weapon = !rn2(3) ? SHURIKEN : STRANGE_OBJECT;
205             armor = STRANGE_OBJECT;
206             cloak = ROBE;
207             if (rn2(2))
208                 shield = STRANGE_OBJECT;
209             break;
210         case PM_PRIEST:
211         case PM_PRIESTESS:
212             if (rn2(2))
213                 weapon = MACE;
214             if (rn2(2))
215                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
216             if (rn2(4))
217                 cloak = ROBE;
218             if (rn2(4))
219                 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
220             if (rn2(2))
221                 shield = STRANGE_OBJECT;
222             break;
223         case PM_RANGER:
224             if (rn2(2))
225                 weapon = ELVEN_DAGGER;
226             break;
227         case PM_ROGUE:
228             if (rn2(2))
229                 weapon = rn2(2) ? SHORT_SWORD : ORCISH_DAGGER;
230             break;
231         case PM_SAMURAI:
232             if (rn2(2))
233                 weapon = KATANA;
234             break;
235         case PM_TOURIST:
236             /* Defaults are just fine */
237             break;
238         case PM_VALKYRIE:
239             if (rn2(2))
240                 weapon = WAR_HAMMER;
241             if (rn2(2))
242                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
243             break;
244         case PM_WIZARD:
245             if (rn2(4))
246                 weapon = rn2(2) ? QUARTERSTAFF : ATHAME;
247             if (rn2(2)) {
248                 armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL
249                                : SILVER_DRAGON_SCALE_MAIL;
250                 cloak = CLOAK_OF_MAGIC_RESISTANCE;
251             }
252             if (rn2(4))
253                 helm = HELM_OF_BRILLIANCE;
254             shield = STRANGE_OBJECT;
255             break;
256         default:
257             impossible("bad mplayer monster");
258             weapon = 0;
259             break;
260         }
261
262         if (weapon != STRANGE_OBJECT) {
263             otmp = mksobj(weapon, TRUE, FALSE);
264             otmp->spe = (special ? rn1(5, 4) : rn2(4));
265             if (!rn2(3))
266                 otmp->oerodeproof = 1;
267             else if (!rn2(2))
268                 otmp->greased = 1;
269             if (special && rn2(2))
270                 otmp = mk_artifact(otmp, A_NONE);
271             /* usually increase stack size if stackable weapon */
272             if (objects[otmp->otyp].oc_merge && !otmp->oartifact)
273                 otmp->quan += (long) rn2(is_spear(otmp) ? 4 : 8);
274             /* mplayers knew better than to overenchant Magicbane */
275             if (otmp->oartifact == ART_MAGICBANE)
276                 otmp->spe = rnd(4);
277             (void) mpickobj(mtmp, otmp);
278         }
279
280         if (special) {
281             if (!rn2(10))
282                 (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
283             mk_mplayer_armor(mtmp, armor);
284             mk_mplayer_armor(mtmp, cloak);
285             mk_mplayer_armor(mtmp, helm);
286             mk_mplayer_armor(mtmp, shield);
287             if (rn2(8))
288                 mk_mplayer_armor(
289                     mtmp, rnd_class(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY));
290             if (rn2(8))
291                 mk_mplayer_armor(mtmp,
292                                  rnd_class(LOW_BOOTS, LEVITATION_BOOTS));
293             m_dowear(mtmp, TRUE);
294
295             quan = rn2(3) ? rn2(3) : rn2(16);
296             while (quan--)
297                 (void) mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
298             /* To get the gold "right" would mean a player can double his */
299             /* gold supply by killing one mplayer.  Not good. */
300             mkmonmoney(mtmp, rn2(1000));
301             quan = rn2(10);
302             while (quan--)
303                 (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
304         }
305         quan = rnd(3);
306         while (quan--)
307             (void) mongets(mtmp, rnd_offensive_item(mtmp));
308         quan = rnd(3);
309         while (quan--)
310             (void) mongets(mtmp, rnd_defensive_item(mtmp));
311         quan = rnd(3);
312         while (quan--)
313             (void) mongets(mtmp, rnd_misc_item(mtmp));
314     }
315
316     return (mtmp);
317 }
318
319 /* create the indicated number (num) of monster-players,
320  * randomly chosen, and in randomly chosen (free) locations
321  * on the level.  If "special", the size of num should not
322  * be bigger than the number of _non-repeated_ names in the
323  * developers array, otherwise a bunch of Adams and Eves will
324  * fill up the overflow.
325  */
326 void
327 create_mplayers(num, special)
328 register int num;
329 boolean special;
330 {
331     int pm, x, y;
332     struct monst fakemon;
333
334     while (num) {
335         int tryct = 0;
336
337         /* roll for character class */
338         pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
339         fakemon.data = &mons[pm];
340
341         /* roll for an available location */
342         do {
343             x = rn1(COLNO - 4, 2);
344             y = rnd(ROWNO - 2);
345         } while (!goodpos(x, y, &fakemon, 0) && tryct++ <= 50);
346
347         /* if pos not found in 50 tries, don't bother to continue */
348         if (tryct > 50)
349             return;
350
351         (void) mk_mplayer(&mons[pm], (xchar) x, (xchar) y, special);
352         num--;
353     }
354 }
355
356 void
357 mplayer_talk(mtmp)
358 register struct monst *mtmp;
359 {
360     static const char *same_class_msg[3] =
361         {
362           "I can't win, and neither will you!", "You don't deserve to win!",
363           "Mine should be the honor, not yours!",
364         },
365                       *other_class_msg[3] = {
366                           "The low-life wants to talk, eh?", "Fight, scum!",
367                           "Here is what I have to say!",
368                       };
369
370     if (mtmp->mpeaceful)
371         return; /* will drop to humanoid talk */
372
373     pline("Talk? -- %s", (mtmp->data == &mons[urole.malenum]
374                           || mtmp->data == &mons[urole.femalenum])
375                              ? same_class_msg[rn2(3)]
376                              : other_class_msg[rn2(3)]);
377 }
378
379 /*mplayer.c*/