OSDN Git Service

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