]> granicus.if.org Git - nethack/commitdiff
Allow Juiblex to split
authorPasi Kallinen <paxed@alt.org>
Fri, 20 Mar 2020 09:39:55 +0000 (11:39 +0200)
committerPatric Mueller <bhaak@gmx.net>
Sat, 28 Jan 2023 22:12:49 +0000 (23:12 +0100)
Juiblex can split like a pudding. The clones cannot split.
If you kill the original Juiblex, one of the clones becomes it.

src/makemon.c
src/mhitm.c
src/mon.c
src/uhitm.c
src/wizard.c

index 5e63da39a5ea3a5265c3ca0200bf0d317f1b0df1..7312d99c725ed4551424dbbaf648bd309338f6d7 100644 (file)
@@ -941,7 +941,9 @@ propagate(int mndx, boolean tally, boolean ghostly)
     result = ((int) gm.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE;
 
     /* if it's unique, don't ever make it again */
-    if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC)
+    if ((mons[mndx].geno & G_UNIQ) != 0
+        && mndx != PM_HIGH_CLERIC
+        && mndx != PM_JUIBLEX)
         gm.mvitals[mndx].mvflags |= G_EXTINCT;
 
     if (gm.mvitals[mndx].born < 255 && tally && (!ghostly || result))
index 82058a9bbaf97c8224660f5fcddc2e8944d20fba..445a5731f27b66e783e3f99ef347115873b743f2 100644 (file)
@@ -426,7 +426,8 @@ mattackm(register struct monst *magr, register struct monst *mdef)
             if (strike) {
                 res[i] = hitmm(magr, mdef, mattk, mwep, dieroll);
                 if ((mdef->data == &mons[PM_BLACK_PUDDING]
-                     || mdef->data == &mons[PM_BROWN_PUDDING])
+                     || mdef->data == &mons[PM_BROWN_PUDDING]
+                     || (mdef->data == &mons[PM_JUIBLEX] && !mdef->mcloned))
                     && (mwep && (objects[mwep->otyp].oc_material == IRON
                                  || objects[mwep->otyp].oc_material == METAL))
                     && mdef->mhp > 1 && !mdef->mcan) {
index a7f45c4f6fc7cea0b421cc141dcc7e3d1b431de1..0a91a2a8f9ca78c9b4c8da32d0ea47d00c30d096 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -19,6 +19,7 @@ static void mon_leaving_level(struct monst *);
 static void m_detach(struct monst *, struct permonst *);
 static void set_mon_min_mhpmax(struct monst *, int);
 static void lifesaved_monster(struct monst *);
+static void juiblex_transferral(void);
 static boolean ok_to_obliterate(struct monst *);
 static void m_restartcham(struct monst *);
 static boolean restrap(struct monst *);
@@ -2544,6 +2545,20 @@ lifesaved_monster(struct monst* mtmp)
 
 DISABLE_WARNING_FORMAT_NONLITERAL
 
+/* transfer the juiblex "mind" to a clone */
+static void
+juiblex_transferral(void)
+{
+    struct monst *mtmp;
+
+    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+        if (!DEADMONSTER(mtmp)
+            && mtmp->data == &mons[PM_JUIBLEX] && mtmp->mcloned) {
+            mtmp->mcloned = 0;
+            return;
+        }
+}
+
 void
 mondead(struct monst *mtmp)
 {
@@ -2642,6 +2657,9 @@ mondead(struct monst *mtmp)
     else if (mtmp->data == &mons[PM_WERERAT])
         set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT]);
 
+    if (mtmp->data == &mons[PM_JUIBLEX] && !mtmp->mcloned)
+        juiblex_transferral();
+
     /*
      * gm.mvitals[].died does double duty as total number of dead monsters
      * and as experience factor for the player killing more monsters.
index 7f09598b58602e55805799c7e23d0147ba31b336..aaabbd0604229ff18a989fb83c8fef222d5177b8 100644 (file)
@@ -1394,7 +1394,9 @@ hmon_hitmon_pet(struct _hitmon_data *hmd, struct monst *mon, struct obj *obj UNU
 static void
 hmon_hitmon_splitmon(struct _hitmon_data *hmd, struct monst *mon, struct obj *obj)
 {
-    if ((hmd->mdat == &mons[PM_BLACK_PUDDING] || hmd->mdat == &mons[PM_BROWN_PUDDING])
+    if ((hmd->mdat == &mons[PM_BLACK_PUDDING]
+         || hmd->mdat == &mons[PM_BROWN_PUDDING]
+         || (hmd->mdat == &mons[PM_JUIBLEX] && !mon->mcloned))
         /* pudding is alive and healthy enough to split */
         && mon->mhp > 1 && !mon->mcan
         /* iron weapon using melee or polearm hit [3.6.1: metal weapon too;
@@ -1410,12 +1412,15 @@ hmon_hitmon_splitmon(struct _hitmon_data *hmd, struct monst *mon, struct obj *ob
         char withwhat[BUFSZ];
 
         if ((mclone = clone_mon(mon, 0, 0)) != 0) {
-            withwhat[0] = '\0';
-            if (u.twoweap && Verbose(4, hmon_hitmon1))
-                Sprintf(withwhat, " with %s", yname(obj));
-            pline("%s divides as you hit it%s!", Monnam(mon), withwhat);
-            hmd->hittxt = TRUE;
-            (void) mintrap(mclone, NO_TRAP_FLAGS);
+            if (canspotmon(mclone) && !u.uswallow) {
+                withwhat[0] = '\0';
+                if (u.twoweap && Verbose(4, hmon_hitmon1))
+                    Sprintf(withwhat, " with %s", yname(obj));
+                pline("%s divides as you hit it%s!", Monnam(mon),
+                        withwhat);
+                hmd->hittxt = TRUE;
+                (void) mintrap(mclone, NO_TRAP_FLAGS);
+            }
         }
     }
 }
@@ -3226,7 +3231,7 @@ mhitm_ad_slim(struct monst *magr, struct attack *mattk, struct monst *mdef,
 
                 if (gv.vis && canseemon(mdef))
                     ncflags |= NC_SHOW_MSG;
-                if (newcham(mdef, &mons[PM_GREEN_SLIME], ncflags)) 
+                if (newcham(mdef, &mons[PM_GREEN_SLIME], ncflags))
                     pd = mdef->data;
                 mdef->mstrategy &= ~STRAT_WAITFORU;
                 mhm->hitflags = MM_HIT;
index fd3af1d733b33d105353d65a2bb46377ec3b9871..d27555617098b7fa42a02cec0f3dca91ea325882 100644 (file)
@@ -255,6 +255,10 @@ strategy(struct monst *mtmp)
 {
     unsigned long strat, dstrat;
 
+    /* Only one Juiblex has a mind */
+    if (mtmp->data == &mons[PM_JUIBLEX] && mtmp->mcloned)
+        return STRAT_NONE;
+
     if (!is_covetous(mtmp->data)
         /* perhaps a shopkeeper has been polymorphed into a master
            lich; we don't want it teleporting to the stairs to heal