diff --git a/include/obj.h b/include/obj.h index 670b3ee60d..c8f05cf50d 100644 --- a/include/obj.h +++ b/include/obj.h @@ -476,6 +476,11 @@ struct obj { #define thiefstone_ledger_valid(stone) \ ((stone)->keyed_ledger > 0 && (stone)->keyed_ledger <= maxledgerno()) +/* special holiday fruits are differentiated from user-defined fruits by + * negative spe */ +#define is_holiday_fruit(obj) ((obj)->otyp == SLIME_MOLD && (obj)->spe < 0) +#define fruit_id(obj) (abs((obj)->spe)) + /* * Notes for adding new oextra structures: * diff --git a/src/bones.c b/src/bones.c index c1b2c8154c..ab616af8a6 100644 --- a/src/bones.c +++ b/src/bones.c @@ -137,7 +137,7 @@ resetobjs(struct obj *ochain, boolean restore) } if (otmp->otyp == SLIME_MOLD) { - goodfruit(otmp->spe); + goodfruit(fruit_id(otmp)); #ifdef MAIL_STRUCTURES } else if (otmp->otyp == SCR_MAIL) { /* 0: delivered in-game via external event; @@ -321,7 +321,7 @@ drop_upon_death(struct monst *mtmp, /* monster if hero turned into one (other th otmp->owt = weight(otmp); if (otmp->otyp == SLIME_MOLD) - goodfruit(otmp->spe); + goodfruit(fruit_id(otmp)); if (rn2(5)) curse(otmp); diff --git a/src/eat.c b/src/eat.c index 8523e170cb..0311ac2590 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2385,6 +2385,34 @@ fpostfx(struct obj *otmp) if (!u.uconduct.literate++) livelog_printf(LL_CONDUCT, "became literate by reading the fortune inside a cookie"); break; + case SLIME_MOLD: + if (is_holiday_fruit(otmp)) { + struct fruit *f = fruit_from_indx(fruit_id(otmp)); + if (!rn2(8) && f && !strcmp("slice of king cake", f->fname)) { + static const int babies[] = { + PM_BABY_CROCODILE, + PM_BABY_LONG_WORM, + PM_BABY_PURPLE_WORM, + PM_BABY_GRAY_DRAGON, + PM_BABY_GOLD_DRAGON, + PM_BABY_SILVER_DRAGON, + PM_BABY_RED_DRAGON, + PM_BABY_WHITE_DRAGON, + PM_BABY_ORANGE_DRAGON, + PM_BABY_BLACK_DRAGON, + PM_BABY_BLUE_DRAGON, + PM_BABY_GREEN_DRAGON, + PM_BABY_YELLOW_DRAGON, + }; + struct obj *feve = mksobj(FIGURINE, TRUE, FALSE); + set_corpsenm(feve, babies[rn2(SIZE(babies))]); + set_material(feve, PLASTIC); + There("is a plastic baby inside the slice of king cake!"); + hold_another_object(feve, "It falls to the floor.", + (const char *) 0, (const char *) 0); + } + } + break; case LUMP_OF_ROYAL_JELLY: /* This stuff seems to be VERY healthy! */ gainstr(otmp, 1, TRUE); /* will -1 if cursed */ diff --git a/src/mkobj.c b/src/mkobj.c index 57c12f6878..cb73aac93d 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -990,7 +990,8 @@ mksobj(int otyp, boolean init, boolean artif) /* fruitadd requires a modifiable string */ char foodbuf[BUFSZ]; Strcpy(foodbuf, foods[rn2(idx)]); - otmp->spe = fruitadd(foodbuf, NULL); + /* holiday fruits have negative spe */ + otmp->spe = -fruitadd(foodbuf, NULL); } } flags.made_fruit = TRUE; diff --git a/src/objnam.c b/src/objnam.c index 3ae21629f8..93653daf15 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -631,7 +631,7 @@ xname_flags( case FOOD_CLASS: /* we could include partly-eaten-hack on fruit but don't need to */ if (typ == SLIME_MOLD) { - struct fruit *f = fruit_from_indx(obj->spe); + struct fruit *f = fruit_from_indx(fruit_id(obj)); if (!f) { impossible("Bad fruit #%d?", obj->spe); diff --git a/src/options.c b/src/options.c index 5e2f2d861c..32de4bec85 100644 --- a/src/options.c +++ b/src/options.c @@ -7172,7 +7172,7 @@ fruitadd(char *str, struct fruit *replace_fruit) char buf[PL_FSIZ], altname[PL_FSIZ]; boolean user_specified = (str == g.pl_fruit); /* if not user-specified, then it's a fruit name for a fruit on - * a bones level or from orctown raider's loot... + * a bones level, a holiday food, or from orctown raider's loot... */ /* Note: every fruit has an id (kept in obj->spe) of at least 1; diff --git a/src/restore.c b/src/restore.c index 9e25f8ed95..77b279f703 100644 --- a/src/restore.c +++ b/src/restore.c @@ -507,13 +507,18 @@ ghostfruit(register struct obj* otmp) register struct fruit *oldf; for (oldf = g.oldfruit; oldf; oldf = oldf->nextf) - if (oldf->fid == otmp->spe) + if (oldf->fid == fruit_id(otmp)) break; - if (!oldf) + if (!oldf) { impossible("no old fruit?"); - else + } else { + boolean holiday_food = is_holiday_fruit(otmp); otmp->spe = fruitadd(oldf->fname, (struct fruit *) 0); + if (holiday_food) { + otmp->spe = -(otmp->spe); + } + } } #ifdef SYSCF