OSDN Git Service

fix #36659
[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 #if 1 /*JP*/
77     char tmp_nam[PL_NSIZ];
78 #endif
79
80     devnam = dev_name();
81     if (!devnam)
82         Strcpy(nam, fmlkind ? "Eve" : "Adam");
83     else if (fmlkind && !!strcmp(devnam, "Janet"))
84         Strcpy(nam, rn2(2) ? "Maud" : "Eve");
85     else
86         Strcpy(nam, devnam);
87
88     if (fmlkind || !strcmp(nam, "Janet"))
89         mtmp->female = 1;
90     else
91         mtmp->female = 0;
92 #if 0 /*JP*/
93     Strcat(nam, " the ");
94     Strcat(nam, rank_of((int) mtmp->m_lev, monsndx(mtmp->data),
95                         (boolean) mtmp->female));
96 #else /*\8fÌ\8d\86\82ð\91O\82É\95t\82¯\82½\82¢\82Ì\82Åtmp_nam\82É\88ê\92U\8d\\92z\82µ\82Änam\82É\96ß\82·*/
97     Strcpy(tmp_nam, rank_of((int) mtmp->m_lev, monsndx(mtmp->data),
98                         (boolean)mtmp->female));
99     Strcat(tmp_nam, "\82Ì");
100     Strcat(tmp_nam, nam);
101     Strcpy(nam, tmp_nam);
102 #endif
103 }
104
105 STATIC_OVL void
106 mk_mplayer_armor(mon, typ)
107 struct monst *mon;
108 short typ;
109 {
110     struct obj *obj;
111
112     if (typ == STRANGE_OBJECT)
113         return;
114     obj = mksobj(typ, FALSE, FALSE);
115     if (!rn2(3))
116         obj->oerodeproof = 1;
117     if (!rn2(3))
118         curse(obj);
119     if (!rn2(3))
120         bless(obj);
121     /* Most players who get to the endgame who have cursed equipment
122      * have it because the wizard or other monsters cursed it, so its
123      * chances of having plusses is the same as usual....
124      */
125     obj->spe = rn2(10) ? (rn2(3) ? rn2(5) : rn1(4, 4)) : -rnd(3);
126     (void) mpickobj(mon, obj);
127 }
128
129 struct monst *
130 mk_mplayer(ptr, x, y, special)
131 register struct permonst *ptr;
132 xchar x, y;
133 register boolean special;
134 {
135     register struct monst *mtmp;
136     char nam[PL_NSIZ];
137
138     if (!is_mplayer(ptr))
139         return ((struct monst *) 0);
140
141     if (MON_AT(x, y))
142         (void) rloc(m_at(x, y), FALSE); /* insurance */
143
144     if (!In_endgame(&u.uz))
145         special = FALSE;
146
147     if ((mtmp = makemon(ptr, x, y, NO_MM_FLAGS)) != 0) {
148         short weapon = rn2(2) ? LONG_SWORD : rnd_class(SPEAR, BULLWHIP);
149         short armor =
150             rnd_class(GRAY_DRAGON_SCALE_MAIL, YELLOW_DRAGON_SCALE_MAIL);
151         short cloak = !rn2(8)
152                           ? STRANGE_OBJECT
153                           : rnd_class(OILSKIN_CLOAK, CLOAK_OF_DISPLACEMENT);
154         short helm = !rn2(8) ? STRANGE_OBJECT : rnd_class(ELVEN_LEATHER_HELM,
155                                                           HELM_OF_TELEPATHY);
156         short shield = !rn2(8)
157                            ? STRANGE_OBJECT
158                            : rnd_class(ELVEN_SHIELD, SHIELD_OF_REFLECTION);
159         int quan;
160         struct obj *otmp;
161
162         mtmp->m_lev = (special ? rn1(16, 15) : rnd(16));
163         mtmp->mhp = mtmp->mhpmax =
164             d((int) mtmp->m_lev, 10) + (special ? (30 + rnd(30)) : 30);
165         if (special) {
166             get_mplname(mtmp, nam);
167             mtmp = christen_monst(mtmp, nam);
168             /* that's why they are "stuck" in the endgame :-) */
169             (void) mongets(mtmp, FAKE_AMULET_OF_YENDOR);
170         }
171         mtmp->mpeaceful = 0;
172         set_malign(mtmp); /* peaceful may have changed again */
173
174         switch (monsndx(ptr)) {
175         case PM_ARCHEOLOGIST:
176             if (rn2(2))
177                 weapon = BULLWHIP;
178             break;
179         case PM_BARBARIAN:
180             if (rn2(2)) {
181                 weapon = rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE;
182                 shield = STRANGE_OBJECT;
183             }
184             if (rn2(2))
185                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
186             if (helm == HELM_OF_BRILLIANCE)
187                 helm = STRANGE_OBJECT;
188             break;
189         case PM_CAVEMAN:
190         case PM_CAVEWOMAN:
191             if (rn2(4))
192                 weapon = MACE;
193             else if (rn2(2))
194                 weapon = CLUB;
195             if (helm == HELM_OF_BRILLIANCE)
196                 helm = STRANGE_OBJECT;
197             break;
198         case PM_HEALER:
199             if (rn2(4))
200                 weapon = QUARTERSTAFF;
201             else if (rn2(2))
202                 weapon = rn2(2) ? UNICORN_HORN : SCALPEL;
203             if (rn2(4))
204                 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
205             if (rn2(2))
206                 shield = STRANGE_OBJECT;
207             break;
208         case PM_KNIGHT:
209             if (rn2(4))
210                 weapon = LONG_SWORD;
211             if (rn2(2))
212                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
213             break;
214         case PM_MONK:
215             weapon = !rn2(3) ? SHURIKEN : STRANGE_OBJECT;
216             armor = STRANGE_OBJECT;
217             cloak = ROBE;
218             if (rn2(2))
219                 shield = STRANGE_OBJECT;
220             break;
221         case PM_PRIEST:
222         case PM_PRIESTESS:
223             if (rn2(2))
224                 weapon = MACE;
225             if (rn2(2))
226                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
227             if (rn2(4))
228                 cloak = ROBE;
229             if (rn2(4))
230                 helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
231             if (rn2(2))
232                 shield = STRANGE_OBJECT;
233             break;
234         case PM_RANGER:
235             if (rn2(2))
236                 weapon = ELVEN_DAGGER;
237             break;
238         case PM_ROGUE:
239             if (rn2(2))
240                 weapon = rn2(2) ? SHORT_SWORD : ORCISH_DAGGER;
241             break;
242         case PM_SAMURAI:
243             if (rn2(2))
244                 weapon = KATANA;
245             break;
246         case PM_TOURIST:
247             /* Defaults are just fine */
248             break;
249         case PM_VALKYRIE:
250             if (rn2(2))
251                 weapon = WAR_HAMMER;
252             if (rn2(2))
253                 armor = rnd_class(PLATE_MAIL, CHAIN_MAIL);
254             break;
255         case PM_WIZARD:
256             if (rn2(4))
257                 weapon = rn2(2) ? QUARTERSTAFF : ATHAME;
258             if (rn2(2)) {
259                 armor = rn2(2) ? BLACK_DRAGON_SCALE_MAIL
260                                : SILVER_DRAGON_SCALE_MAIL;
261                 cloak = CLOAK_OF_MAGIC_RESISTANCE;
262             }
263             if (rn2(4))
264                 helm = HELM_OF_BRILLIANCE;
265             shield = STRANGE_OBJECT;
266             break;
267         default:
268             impossible("bad mplayer monster");
269             weapon = 0;
270             break;
271         }
272
273         if (weapon != STRANGE_OBJECT) {
274             otmp = mksobj(weapon, TRUE, FALSE);
275             otmp->spe = (special ? rn1(5, 4) : rn2(4));
276             if (!rn2(3))
277                 otmp->oerodeproof = 1;
278             else if (!rn2(2))
279                 otmp->greased = 1;
280             if (special && rn2(2))
281                 otmp = mk_artifact(otmp, A_NONE);
282             /* usually increase stack size if stackable weapon */
283             if (objects[otmp->otyp].oc_merge && !otmp->oartifact)
284                 otmp->quan += (long) rn2(is_spear(otmp) ? 4 : 8);
285             /* mplayers knew better than to overenchant Magicbane */
286             if (otmp->oartifact == ART_MAGICBANE)
287                 otmp->spe = rnd(4);
288             (void) mpickobj(mtmp, otmp);
289         }
290
291         if (special) {
292             if (!rn2(10))
293                 (void) mongets(mtmp, rn2(3) ? LUCKSTONE : LOADSTONE);
294             mk_mplayer_armor(mtmp, armor);
295             mk_mplayer_armor(mtmp, cloak);
296             mk_mplayer_armor(mtmp, helm);
297             mk_mplayer_armor(mtmp, shield);
298             if (rn2(8))
299                 mk_mplayer_armor(
300                     mtmp, rnd_class(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY));
301             if (rn2(8))
302                 mk_mplayer_armor(mtmp,
303                                  rnd_class(LOW_BOOTS, LEVITATION_BOOTS));
304             m_dowear(mtmp, TRUE);
305
306             quan = rn2(3) ? rn2(3) : rn2(16);
307             while (quan--)
308                 (void) mongets(mtmp, rnd_class(DILITHIUM_CRYSTAL, JADE));
309             /* To get the gold "right" would mean a player can double his */
310             /* gold supply by killing one mplayer.  Not good. */
311             mkmonmoney(mtmp, rn2(1000));
312             quan = rn2(10);
313             while (quan--)
314                 (void) mpickobj(mtmp, mkobj(RANDOM_CLASS, FALSE));
315         }
316         quan = rnd(3);
317         while (quan--)
318             (void) mongets(mtmp, rnd_offensive_item(mtmp));
319         quan = rnd(3);
320         while (quan--)
321             (void) mongets(mtmp, rnd_defensive_item(mtmp));
322         quan = rnd(3);
323         while (quan--)
324             (void) mongets(mtmp, rnd_misc_item(mtmp));
325     }
326
327     return (mtmp);
328 }
329
330 /* create the indicated number (num) of monster-players,
331  * randomly chosen, and in randomly chosen (free) locations
332  * on the level.  If "special", the size of num should not
333  * be bigger than the number of _non-repeated_ names in the
334  * developers array, otherwise a bunch of Adams and Eves will
335  * fill up the overflow.
336  */
337 void
338 create_mplayers(num, special)
339 register int num;
340 boolean special;
341 {
342     int pm, x, y;
343     struct monst fakemon;
344
345     while (num) {
346         int tryct = 0;
347
348         /* roll for character class */
349         pm = PM_ARCHEOLOGIST + rn2(PM_WIZARD - PM_ARCHEOLOGIST + 1);
350         fakemon.data = &mons[pm];
351
352         /* roll for an available location */
353         do {
354             x = rn1(COLNO - 4, 2);
355             y = rnd(ROWNO - 2);
356         } while (!goodpos(x, y, &fakemon, 0) && tryct++ <= 50);
357
358         /* if pos not found in 50 tries, don't bother to continue */
359         if (tryct > 50)
360             return;
361
362         (void) mk_mplayer(&mons[pm], (xchar) x, (xchar) y, special);
363         num--;
364     }
365 }
366
367 void
368 mplayer_talk(mtmp)
369 register struct monst *mtmp;
370 {
371 #if 0 /*JP*/
372     static const char *same_class_msg[3] =
373         {
374           "I can't win, and neither will you!", "You don't deserve to win!",
375           "Mine should be the honor, not yours!",
376         },
377                       *other_class_msg[3] = {
378                           "The low-life wants to talk, eh?", "Fight, scum!",
379                           "Here is what I have to say!",
380                       };
381 #else
382     static const char *same_class_msg[2][3] = {
383         {
384             "\8e\84\82Å\82·\82ç\92B\90¬\82Å\82«\82È\82¢\82Ì\82É\81C\82¨\91O\82É\92B\90¬\82Å\82«\82é\82Ì\82©\81H",
385             "\82¨\91O\82ª\90¬\8c÷\82·\82é\82È\82ñ\82Ä\82±\82Æ\82Í\82È\82¢\82È\81D",
386             "\96¼\97_\82ð\89ä\82É\81I\82¨\91O\82\82á\82È\82¢\81I",
387         },
388         {
389             "\8e\84\82Å\82·\82ç\92B\90¬\82Å\82«\82È\82¢\82Ì\82É\81C\82 \82È\82½\82É\92B\90¬\82Å\82«\82Ä\81H",
390             "\82 \82È\82½\82ª\90¬\8c÷\82·\82é\82È\82ñ\82Ä\82 \82è\82¦\82Ü\82¹\82ñ\82í\81D",
391             "\96¼\97_\82Í\8e\84\82É\81I\82 \82È\82½\82É\82È\82ñ\82Ä\82Æ\82ñ\82Å\82à\82È\82¢\81D",
392         }
393     },
394     *other_class_msg[2][3] = {
395         {
396             "\89º\8fO\82ª\98b\82µ\82©\82¯\82é\82©\81H\82Í\82Í\81[\82ñ\81H",
397             "\90í\82¦\81I\82±\82Ì\96ì\98Y\81I",
398             "\82¨\91O\82Æ\98b\82·\82±\82Æ\82È\82Ç\82È\82É\82à\82È\82¢\81I",
399         },
400         {
401             "\8e\84\82Æ\98b\82µ\82½\82¢\82Å\82·\82Á\82Ä\81H",
402             "\8c\95\82ð\8eæ\82è\82È\82³\82¢\81I",
403             "\82 \82È\82½\82Æ\98b\82·\82±\82Æ\82È\82Ç\82 \82è\82Ü\82¹\82ñ\82í\81I",
404         }
405     };
406     int female;
407 #endif
408
409     if (mtmp->mpeaceful)
410         return; /* will drop to humanoid talk */
411
412 #if 0 /*JP*/
413     pline("Talk? -- %s", (mtmp->data == &mons[urole.malenum]
414                           || mtmp->data == &mons[urole.femalenum])
415                              ? same_class_msg[rn2(3)]
416                              : other_class_msg[rn2(3)]);
417 #else
418     female = (mtmp->female ? 1 : 0);
419     pline("\98b\82·\81H -- %s", (mtmp->data == &mons[urole.malenum]
420                           || mtmp->data == &mons[urole.femalenum])
421           ? same_class_msg[female][rn2(3)]
422           : other_class_msg[female][rn2(3)]);
423 #endif
424 }
425
426 /*mplayer.c*/