OSDN Git Service

change potion un-id desc
[jnethack/source.git] / src / minion.c
1 /* NetHack 3.6  minion.c        $NHDT-Date: 1432512773 2015/05/25 00:12:53 $  $NHDT-Branch: master $:$NHDT-Revision: 1.33 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 void
13 newemin(mtmp)
14 struct monst *mtmp;
15 {
16     if (!mtmp->mextra)
17         mtmp->mextra = newmextra();
18     if (!EMIN(mtmp)) {
19         EMIN(mtmp) = (struct emin *) alloc(sizeof(struct emin));
20         (void) memset((genericptr_t) EMIN(mtmp), 0, sizeof(struct emin));
21     }
22 }
23
24 void
25 free_emin(mtmp)
26 struct monst *mtmp;
27 {
28     if (mtmp->mextra && EMIN(mtmp)) {
29         free((genericptr_t) EMIN(mtmp));
30         EMIN(mtmp) = (struct emin *) 0;
31     }
32     mtmp->isminion = 0;
33 }
34
35 /* count the number of monsters on the level */
36 int
37 monster_census(spotted)
38 boolean spotted; /* seen|sensed vs all */
39 {
40     struct monst *mtmp;
41     int count = 0;
42
43     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
44         if (DEADMONSTER(mtmp))
45             continue;
46         if (spotted && !canspotmon(mtmp))
47             continue;
48         ++count;
49     }
50     return count;
51 }
52
53 /* mon summons a monster */
54 int
55 msummon(mon)
56 struct monst *mon;
57 {
58     struct permonst *ptr;
59     int dtype = NON_PM, cnt = 0, result = 0, census;
60     aligntyp atyp;
61     struct monst *mtmp;
62
63     if (mon) {
64         ptr = mon->data;
65         atyp = mon->ispriest ? EPRI(mon)->shralign
66                              : mon->isminion ? EMIN(mon)->min_align
67                                              : (ptr->maligntyp == A_NONE)
68                                                    ? A_NONE
69                                                    : sgn(ptr->maligntyp);
70     } else {
71         ptr = &mons[PM_WIZARD_OF_YENDOR];
72         atyp = (ptr->maligntyp == A_NONE) ? A_NONE : sgn(ptr->maligntyp);
73     }
74
75     if (is_dprince(ptr) || (ptr == &mons[PM_WIZARD_OF_YENDOR])) {
76         dtype = (!rn2(20)) ? dprince(atyp) : (!rn2(4)) ? dlord(atyp)
77                                                        : ndemon(atyp);
78         cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
79     } else if (is_dlord(ptr)) {
80         dtype = (!rn2(50)) ? dprince(atyp) : (!rn2(20)) ? dlord(atyp)
81                                                         : ndemon(atyp);
82         cnt = (!rn2(4) && is_ndemon(&mons[dtype])) ? 2 : 1;
83     } else if (is_ndemon(ptr)) {
84         dtype = (!rn2(20)) ? dlord(atyp) : (!rn2(6)) ? ndemon(atyp)
85                                                      : monsndx(ptr);
86         cnt = 1;
87     } else if (is_lminion(mon)) {
88         dtype = (is_lord(ptr) && !rn2(20))
89                     ? llord()
90                     : (is_lord(ptr) || !rn2(6)) ? lminion() : monsndx(ptr);
91         cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
92     } else if (ptr == &mons[PM_ANGEL]) {
93         /* non-lawful angels can also summon */
94         if (!rn2(6)) {
95             switch (atyp) { /* see summon_minion */
96             case A_NEUTRAL:
97                 dtype = PM_AIR_ELEMENTAL + rn2(4);
98                 break;
99             case A_CHAOTIC:
100             case A_NONE:
101                 dtype = ndemon(atyp);
102                 break;
103             }
104         } else {
105             dtype = PM_ANGEL;
106         }
107         cnt = (!rn2(4) && !is_lord(&mons[dtype])) ? 2 : 1;
108     }
109
110     if (dtype == NON_PM)
111         return 0;
112
113     /* sanity checks */
114     if (cnt > 1 && (mons[dtype].geno & G_UNIQ))
115         cnt = 1;
116     /*
117      * If this daemon is unique and being re-summoned (the only way we
118      * could get this far with an extinct dtype), try another.
119      */
120     if (mvitals[dtype].mvflags & G_GONE) {
121         dtype = ndemon(atyp);
122         if (dtype == NON_PM)
123             return 0;
124     }
125
126     /* some candidates can generate a group of monsters, so simple
127        count of non-null makemon() result is not sufficient */
128     census = monster_census(FALSE);
129
130     while (cnt > 0) {
131         mtmp = makemon(&mons[dtype], u.ux, u.uy, MM_EMIN);
132         if (mtmp) {
133             result++;
134             /* an angel's alignment should match the summoner */
135             if (dtype == PM_ANGEL) {
136                 mtmp->isminion = 1;
137                 EMIN(mtmp)->min_align = atyp;
138                 /* renegade if same alignment but not peaceful
139                    or peaceful but different alignment */
140                 EMIN(mtmp)->renegade =
141                     (atyp != u.ualign.type) ^ !mtmp->mpeaceful;
142             }
143         }
144         cnt--;
145     }
146
147     /* how many monsters exist now compared to before? */
148     if (result)
149         result = monster_census(FALSE) - census;
150
151     return result;
152 }
153
154 void
155 summon_minion(alignment, talk)
156 aligntyp alignment;
157 boolean talk;
158 {
159     register struct monst *mon;
160     int mnum;
161
162     switch ((int) alignment) {
163     case A_LAWFUL:
164         mnum = lminion();
165         break;
166     case A_NEUTRAL:
167         mnum = PM_AIR_ELEMENTAL + rn2(4);
168         break;
169     case A_CHAOTIC:
170     case A_NONE:
171         mnum = ndemon(alignment);
172         break;
173     default:
174         impossible("unaligned player?");
175         mnum = ndemon(A_NONE);
176         break;
177     }
178     if (mnum == NON_PM) {
179         mon = 0;
180     } else if (mnum == PM_ANGEL) {
181         mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
182         if (mon) {
183             mon->isminion = 1;
184             EMIN(mon)->min_align = alignment;
185             EMIN(mon)->renegade = FALSE;
186         }
187     } else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD
188                && mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) {
189         /* This was mons[mnum].pxlth == 0 but is this restriction
190            appropriate or necessary now that the structures are separate? */
191         mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN);
192         if (mon) {
193             mon->isminion = 1;
194             EMIN(mon)->min_align = alignment;
195             EMIN(mon)->renegade = FALSE;
196         }
197     } else {
198         mon = makemon(&mons[mnum], u.ux, u.uy, NO_MM_FLAGS);
199     }
200     if (mon) {
201         if (talk) {
202 /*JP
203             pline_The("voice of %s booms:", align_gname(alignment));
204 */
205             pline("%s\82Ì\90º\82ª\8b¿\82¢\82½:", align_gname(alignment));
206 /*JP
207             verbalize("Thou shalt pay for thine indiscretion!");
208 */
209             verbalize("\93ð\81C\96³\95ª\95Ê\82È\82é\8ds\82¢\82Ì\94±\82ð\8eó\82¯\82é\82×\82µ\81I");
210             if (!Blind)
211 /*JP
212                 pline("%s appears before you.", Amonnam(mon));
213 */
214                 pline("%s\82ª\82 \82È\82½\82Ì\91O\82É\8c»\82í\82ê\82½\81D", Amonnam(mon));
215             mon->mstrategy &= ~STRAT_APPEARMSG;
216         }
217         mon->mpeaceful = FALSE;
218         /* don't call set_malign(); player was naughty */
219     }
220 }
221
222 #define Athome (Inhell && (mtmp->cham == NON_PM))
223
224 /* returns 1 if it won't attack. */
225 int
226 demon_talk(mtmp)
227 register struct monst *mtmp;
228 {
229     long cash, demand, offer;
230
231     if (uwep && uwep->oartifact == ART_EXCALIBUR) {
232 /*JP
233         pline("%s looks very angry.", Amonnam(mtmp));
234 */
235         pline("%s\82Í\82Æ\82Ä\82à\93{\82Á\82Ä\82¢\82é\82æ\82¤\82É\8c©\82¦\82é\81D", Amonnam(mtmp));
236         mtmp->mpeaceful = mtmp->mtame = 0;
237         set_malign(mtmp);
238         newsym(mtmp->mx, mtmp->my);
239         return 0;
240     }
241
242     if (is_fainted()) {
243         reset_faint(); /* if fainted - wake up */
244     } else {
245         stop_occupation();
246         if (multi > 0) {
247             nomul(0);
248             unmul((char *) 0);
249         }
250     }
251
252     /* Slight advantage given. */
253     if (is_dprince(mtmp->data) && mtmp->minvis) {
254         boolean wasunseen = !canspotmon(mtmp);
255
256         mtmp->minvis = mtmp->perminvis = 0;
257         if (wasunseen && canspotmon(mtmp)) {
258 /*JP
259             pline("%s appears before you.", Amonnam(mtmp));
260 */
261             pline("%s\82ª\96Ú\82Ì\91O\82É\8c»\82í\82ê\82½\81D", Amonnam(mtmp));
262             mtmp->mstrategy &= ~STRAT_APPEARMSG;
263         }
264         newsym(mtmp->mx, mtmp->my);
265     }
266     if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
267 #if 0 /*JP*/
268         pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
269               flags.female ? "Sister" : "Brother");
270 #else
271         pline("%s\82Í\8c¾\82Á\82½\81u\82æ\82¤\8cZ%s\81I\81v\81D\82»\82µ\82Ä\8fÁ\82¦\82½\81D", Amonnam(mtmp),
272               flags.female ? "\96\85" : "\92í");
273 #endif
274         if (!tele_restrict(mtmp))
275             (void) rloc(mtmp, TRUE);
276         return (1);
277     }
278     cash = money_cnt(invent);
279     demand =
280         (cash * (rnd(80) + 20 * Athome))
281         / (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));
282
283     if (!demand || multi < 0) { /* you have no gold or can't move */
284         mtmp->mpeaceful = 0;
285         set_malign(mtmp);
286         return 0;
287     } else {
288         /* make sure that the demand is unmeetable if the monster
289            has the Amulet, preventing monster from being satisfied
290            and removed from the game (along with said Amulet...) */
291         if (mon_has_amulet(mtmp))
292             demand = cash + (long) rn1(1000, 40);
293
294 #if 0 /*JP*/
295         pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
296               currency(demand));
297 #else
298         pline("%s\82Í\92Ê\8ds\97¿\82Æ\82µ\82Ä%ld%s\97v\8b\81\82µ\82½\81D", Amonnam(mtmp), demand,
299               currency(demand));
300 #endif
301
302         if ((offer = bribe(mtmp)) >= demand) {
303 /*JP
304             pline("%s vanishes, laughing about cowardly mortals.",
305 */
306             pline("\89°\95a\82È\92è\96½\82Ì\82à\82Ì\82ð\8fÎ\82¢\82È\82ª\82ç\81C%s\82Í\8fÁ\82¦\82½\81D",
307                   Amonnam(mtmp));
308         } else if (offer > 0L && (long) rnd(40) > (demand - offer)) {
309 /*JP
310             pline("%s scowls at you menacingly, then vanishes.",
311 */
312             pline("%s\82Í\82 \82È\82½\82ð\88Ð\8ad\82µ\81C\8fÁ\82¦\82½\81D",
313                   Amonnam(mtmp));
314         } else {
315 /*JP
316             pline("%s gets angry...", Amonnam(mtmp));
317 */
318             pline("%s\82Í\93{\82Á\82½\81D\81D\81D", Amonnam(mtmp));
319             mtmp->mpeaceful = 0;
320             set_malign(mtmp);
321             return 0;
322         }
323     }
324     mongone(mtmp);
325     return (1);
326 }
327
328 long
329 bribe(mtmp)
330 struct monst *mtmp;
331 {
332     char buf[BUFSZ];
333     long offer;
334     long umoney = money_cnt(invent);
335
336 /*JP
337     getlin("How much will you offer?", buf);
338 */
339     getlin("\82¨\8bà\82ð\82¢\82­\82ç\97^\82¦\82é\81H", buf);
340     if (sscanf(buf, "%ld", &offer) != 1)
341         offer = 0L;
342
343     /*Michael Paddon -- fix for negative offer to monster*/
344     /*JAR880815 - */
345     if (offer < 0L) {
346 /*JP
347         You("try to shortchange %s, but fumble.", mon_nam(mtmp));
348 */
349         You("%s\82ð\82¾\82Ü\82»\82¤\82Æ\82µ\82½\82ª\81C\8e¸\94s\82µ\82½\81D", mon_nam(mtmp));
350         return 0L;
351     } else if (offer == 0L) {
352 /*JP
353         You("refuse.");
354 */
355         You("\8b\91\82ñ\82¾\81D");
356         return 0L;
357     } else if (offer >= umoney) {
358 /*JP
359         You("give %s all your gold.", mon_nam(mtmp));
360 */
361         You("%s\82É\82¨\8bà\82ð\91S\82Ä\97^\82¦\82½\81D", mon_nam(mtmp));
362         offer = umoney;
363     } else {
364 /*JP
365         You("give %s %ld %s.", mon_nam(mtmp), offer, currency(offer));
366 */
367         You("%s\82É%ld%s\97^\82¦\82½\81D", mon_nam(mtmp), offer, currency(offer));
368     }
369     (void) money2mon(mtmp, offer);
370     context.botl = 1;
371     return (offer);
372 }
373
374 int
375 dprince(atyp)
376 aligntyp atyp;
377 {
378     int tryct, pm;
379
380     for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
381         pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
382         if (!(mvitals[pm].mvflags & G_GONE)
383             && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
384             return (pm);
385     }
386     return (dlord(atyp)); /* approximate */
387 }
388
389 int
390 dlord(atyp)
391 aligntyp atyp;
392 {
393     int tryct, pm;
394
395     for (tryct = !In_endgame(&u.uz) ? 20 : 0; tryct > 0; --tryct) {
396         pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
397         if (!(mvitals[pm].mvflags & G_GONE)
398             && (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
399             return (pm);
400     }
401     return (ndemon(atyp)); /* approximate */
402 }
403
404 /* create lawful (good) lord */
405 int
406 llord()
407 {
408     if (!(mvitals[PM_ARCHON].mvflags & G_GONE))
409         return (PM_ARCHON);
410
411     return (lminion()); /* approximate */
412 }
413
414 int
415 lminion()
416 {
417     int tryct;
418     struct permonst *ptr;
419
420     for (tryct = 0; tryct < 20; tryct++) {
421         ptr = mkclass(S_ANGEL, 0);
422         if (ptr && !is_lord(ptr))
423             return (monsndx(ptr));
424     }
425
426     return NON_PM;
427 }
428
429 int
430 ndemon(atyp)
431 aligntyp atyp;
432 {
433     int tryct;
434     struct permonst *ptr;
435
436     for (tryct = 0; tryct < 20; tryct++) {
437         ptr = mkclass(S_DEMON, 0);
438         if (ptr && is_ndemon(ptr)
439             && (atyp == A_NONE || sgn(ptr->maligntyp) == sgn(atyp)))
440             return (monsndx(ptr));
441     }
442
443     return NON_PM;
444 }
445
446 /* guardian angel has been affected by conflict so is abandoning hero */
447 void
448 lose_guardian_angel(mon)
449 struct monst *mon; /* if null, angel hasn't been created yet */
450 {
451     coord mm;
452     int i;
453
454     if (mon) {
455         if (canspotmon(mon)) {
456             if (!Deaf) {
457 /*JP
458                 pline("%s rebukes you, saying:", Monnam(mon));
459 */
460                 pline("%s\82Í\82 \82È\82½\82ð\94ñ\93ï\82µ\82½\81F", Monnam(mon));
461 /*JP
462                 verbalize("Since you desire conflict, have some more!");
463 */
464                 verbalize("\93¬\91\88\82ð\96]\82ñ\82Å\82¢\82é\82æ\82¤\82¾\82©\82ç\81C\82à\82Á\82Æ\97^\82¦\82Ä\82â\82ë\82¤\81I");
465             } else {
466 /*JP
467                 pline("%s vanishes!", Monnam(mon));
468 */
469                 pline("%s\82Í\8fÁ\82¦\82½\81I", Monnam(mon));
470             }
471         }
472         mongone(mon);
473     }
474     /* create 2 to 4 hostile angels to replace the lost guardian */
475     for (i = rn1(3, 2); i > 0; --i) {
476         mm.x = u.ux;
477         mm.y = u.uy;
478         if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL]))
479             (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
480                              FALSE);
481     }
482 }
483
484 /* just entered the Astral Plane; receive tame guardian angel if worthy */
485 void
486 gain_guardian_angel()
487 {
488     struct monst *mtmp;
489     struct obj *otmp;
490     coord mm;
491
492     Hear_again(); /* attempt to cure any deafness now (divine
493                      message will be heard even if that fails) */
494     if (Conflict) {
495 /*JP
496         pline("A voice booms:");
497 */
498         pline("\90º\82ª\8b¿\82¢\82½:");
499 /*JP
500         verbalize("Thy desire for conflict shall be fulfilled!");
501 */
502         verbalize("\81u\93ð\82Ì\93¬\91\88\82Ö\82Ì\96]\82Ý\81C\82©\82È\82¦\82ç\82ê\82é\82×\82µ\81I\81v");
503         /* send in some hostile angels instead */
504         lose_guardian_angel((struct monst *) 0);
505     } else if (u.ualign.record > 8) { /* fervent */
506 /*JP
507         pline("A voice whispers:");
508 */
509         pline("\82³\82³\82â\82«\90º\82ª\95·\82±\82¦\82½:");
510 /*JP
511         verbalize("Thou hast been worthy of me!");
512 */
513         verbalize("\81u\93ð\81C\89ä\82ª\95]\89¿\82ð\93¾\82½\82è\81I\81v");
514         mm.x = u.ux;
515         mm.y = u.uy;
516         if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])
517             && (mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, mm.x, mm.y,
518                                  TRUE)) != 0) {
519             mtmp->mstrategy &= ~STRAT_APPEARMSG;
520             if (!Blind)
521 /*JP
522                 pline("An angel appears near you.");
523 */
524                 pline("\93V\8eg\82ª\82 \82È\82½\82Ì\82»\82Î\82É\8c»\82í\82ê\82½\81D");
525             else
526 /*JP
527                 You_feel("the presence of a friendly angel near you.");
528 */
529                 You("\8bß\82­\82É\97F\8dD\93I\82È\93V\8eg\82Ì\91\8dÝ\82ð\8a´\82\82½\81D");
530             /* guardian angel -- the one case mtame doesn't
531              * imply an edog structure, so we don't want to
532              * call tamedog().
533              */
534             mtmp->mtame = 10;
535             /* make him strong enough vs. endgame foes */
536             mtmp->m_lev = rn1(8, 15);
537             mtmp->mhp = mtmp->mhpmax =
538                 d((int) mtmp->m_lev, 10) + 30 + rnd(30);
539             if ((otmp = select_hwep(mtmp)) == 0) {
540                 otmp = mksobj(SILVER_SABER, FALSE, FALSE);
541                 if (mpickobj(mtmp, otmp))
542                     panic("merged weapon?");
543             }
544             bless(otmp);
545             if (otmp->spe < 4)
546                 otmp->spe += rnd(4);
547             if ((otmp = which_armor(mtmp, W_ARMS)) == 0
548                 || otmp->otyp != SHIELD_OF_REFLECTION) {
549                 (void) mongets(mtmp, AMULET_OF_REFLECTION);
550                 m_dowear(mtmp, TRUE);
551             }
552         }
553     }
554 }
555
556 /*minion.c*/