Skip to content

Commit 0abcae9

Browse files
committed
Hide plastic babies in slices of king cake
Sometimes the hero will find a plastic baby inside a piece of king cake, just like in real life. In order to make this apply to 'real' king cake created during Mardi Gras, and not to user-defined fruit with an identical name, change holiday fruits to use a negative fruit ID as their spe. To enable this, add a new macro, fruit_id() -- which provides the absolute value of fruit->spe -- and use it in most cases the fruit ID needs to be accessed. Negative fruit IDs are already used when saving bones, to mark fruits which don't exist on the current level and therefore don't need to be included in the bones file, but those are negative fids in the g.ffruit linked list, not negative spe on individual items. These changes shouldn't interfere with that process as long as the possible negative spe is taken into consideration when saving and loading bones, which it now should be.
1 parent 01b2d68 commit 0abcae9

7 files changed

Lines changed: 47 additions & 8 deletions

File tree

include/obj.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,11 @@ struct obj {
476476
#define thiefstone_ledger_valid(stone) \
477477
((stone)->keyed_ledger > 0 && (stone)->keyed_ledger <= maxledgerno())
478478

479+
/* special holiday fruits are differentiated from user-defined fruits by
480+
* negative spe */
481+
#define is_holiday_fruit(obj) ((obj)->otyp == SLIME_MOLD && (obj)->spe < 0)
482+
#define fruit_id(obj) (abs((obj)->spe))
483+
479484
/*
480485
* Notes for adding new oextra structures:
481486
*

src/bones.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ resetobjs(struct obj *ochain, boolean restore)
137137
}
138138

139139
if (otmp->otyp == SLIME_MOLD) {
140-
goodfruit(otmp->spe);
140+
goodfruit(fruit_id(otmp));
141141
#ifdef MAIL_STRUCTURES
142142
} else if (otmp->otyp == SCR_MAIL) {
143143
/* 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
321321
otmp->owt = weight(otmp);
322322

323323
if (otmp->otyp == SLIME_MOLD)
324-
goodfruit(otmp->spe);
324+
goodfruit(fruit_id(otmp));
325325

326326
if (rn2(5))
327327
curse(otmp);

src/eat.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,34 @@ fpostfx(struct obj *otmp)
23852385
if (!u.uconduct.literate++)
23862386
livelog_printf(LL_CONDUCT, "became literate by reading the fortune inside a cookie");
23872387
break;
2388+
case SLIME_MOLD:
2389+
if (is_holiday_fruit(otmp)) {
2390+
struct fruit *f = fruit_from_indx(fruit_id(otmp));
2391+
if (!rn2(15) && f && !strcmp("slice of king cake", f->fname)) {
2392+
static const int babies[] = {
2393+
PM_BABY_CROCODILE,
2394+
PM_BABY_LONG_WORM,
2395+
PM_BABY_PURPLE_WORM,
2396+
PM_BABY_GRAY_DRAGON,
2397+
PM_BABY_GOLD_DRAGON,
2398+
PM_BABY_SILVER_DRAGON,
2399+
PM_BABY_RED_DRAGON,
2400+
PM_BABY_WHITE_DRAGON,
2401+
PM_BABY_ORANGE_DRAGON,
2402+
PM_BABY_BLACK_DRAGON,
2403+
PM_BABY_BLUE_DRAGON,
2404+
PM_BABY_GREEN_DRAGON,
2405+
PM_BABY_YELLOW_DRAGON,
2406+
};
2407+
struct obj *feve = mksobj(FIGURINE, TRUE, FALSE);
2408+
set_corpsenm(feve, babies[rn2(SIZE(babies))]);
2409+
set_material(feve, PLASTIC);
2410+
There("is a plastic baby inside the slice of king cake!");
2411+
hold_another_object(feve, "It falls to the floor.",
2412+
(const char *) 0, (const char *) 0);
2413+
}
2414+
}
2415+
break;
23882416
case LUMP_OF_ROYAL_JELLY:
23892417
/* This stuff seems to be VERY healthy! */
23902418
gainstr(otmp, 1, TRUE); /* will -1 if cursed */

src/mkobj.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,8 @@ mksobj(int otyp, boolean init, boolean artif)
990990
/* fruitadd requires a modifiable string */
991991
char foodbuf[BUFSZ];
992992
Strcpy(foodbuf, foods[rn2(idx)]);
993-
otmp->spe = fruitadd(foodbuf, NULL);
993+
/* holiday fruits have negative spe */
994+
otmp->spe = -fruitadd(foodbuf, NULL);
994995
}
995996
}
996997
flags.made_fruit = TRUE;

src/objnam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ xname_flags(
631631
case FOOD_CLASS:
632632
/* we could include partly-eaten-hack on fruit but don't need to */
633633
if (typ == SLIME_MOLD) {
634-
struct fruit *f = fruit_from_indx(obj->spe);
634+
struct fruit *f = fruit_from_indx(fruit_id(obj));
635635

636636
if (!f) {
637637
impossible("Bad fruit #%d?", obj->spe);

src/options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7172,7 +7172,7 @@ fruitadd(char *str, struct fruit *replace_fruit)
71727172
char buf[PL_FSIZ], altname[PL_FSIZ];
71737173
boolean user_specified = (str == g.pl_fruit);
71747174
/* if not user-specified, then it's a fruit name for a fruit on
7175-
* a bones level or from orctown raider's loot...
7175+
* a bones level, a holiday food, or from orctown raider's loot...
71767176
*/
71777177

71787178
/* Note: every fruit has an id (kept in obj->spe) of at least 1;

src/restore.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,18 @@ ghostfruit(register struct obj* otmp)
507507
register struct fruit *oldf;
508508

509509
for (oldf = g.oldfruit; oldf; oldf = oldf->nextf)
510-
if (oldf->fid == otmp->spe)
510+
if (oldf->fid == fruit_id(otmp))
511511
break;
512512

513-
if (!oldf)
513+
if (!oldf) {
514514
impossible("no old fruit?");
515-
else
515+
} else {
516+
boolean holiday_food = is_holiday_fruit(otmp);
516517
otmp->spe = fruitadd(oldf->fname, (struct fruit *) 0);
518+
if (holiday_food) {
519+
otmp->spe = -(otmp->spe);
520+
}
521+
}
517522
}
518523

519524
#ifdef SYSCF

0 commit comments

Comments
 (0)