diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6b1d49be6..26dce96e8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1166,6 +1166,7 @@ check bones data directly for deja vu messages (#374) unify code for extracting an object from a monster's inventory (#455) make engraving an occupation (#460) fpostfx index out of bounds when eating standard eggs (github pr#547) +"readable" Hawaiian shirt designs (github pr#407) Code Cleanup and Reorganization diff --git a/include/extern.h b/include/extern.h index 0a54e94dc..0f59d7043 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2113,6 +2113,7 @@ extern long random(void); extern void learnscroll(struct obj *); extern char *tshirt_text(struct obj *, char *); +extern char *hawaiian_motif(struct obj *, char *); extern char *apron_text(struct obj *, char *); extern const char *candy_wrapper_text(struct obj *); extern void assign_candy_wrapper(struct obj *); diff --git a/include/obj.h b/include/obj.h index 1e540e4c0..3adbce284 100644 --- a/include/obj.h +++ b/include/obj.h @@ -345,7 +345,7 @@ struct obj { || (otmp)->otyp == ALCHEMY_SMOCK || (otmp)->otyp == CREDIT_CARD \ || (otmp)->otyp == CAN_OF_GREASE || (otmp)->otyp == MAGIC_MARKER \ || (otmp)->oclass == COIN_CLASS || (otmp)->oartifact == ART_ORB_OF_FATE \ - || (otmp)->otyp == CANDY_BAR) + || (otmp)->otyp == CANDY_BAR || (otmp)->otyp == HAWAIIAN_SHIRT) /* special stones */ #define is_graystone(obj) \ diff --git a/src/objnam.c b/src/objnam.c index 47bcb2964..e7e00187c 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -750,6 +750,10 @@ xname_flags( if (*lbl) Sprintf(eos(buf), " labeled \"%s\"", lbl); break; + case HAWAIIAN_SHIRT: + Sprintf(eos(buf), " with %s motif", + an(hawaiian_motif(obj, tmpbuf))); + break; default: break; } diff --git a/src/read.c b/src/read.c index a9cf9036a..6e3e78edc 100644 --- a/src/read.c +++ b/src/read.c @@ -15,6 +15,7 @@ static boolean learnscrolltyp(short); static void cap_spe(struct obj *); static char *erode_obj_text(struct obj *, char *); +static char *hawaiian_design(struct obj *, char *); static int read_ok(struct obj *); static void stripspe(struct obj *); static void p_glow1(struct obj *); @@ -186,6 +187,70 @@ tshirt_text(struct obj* tshirt, char* buf) return erode_obj_text(tshirt, buf); } +char * +hawaiian_motif(struct obj *shirt, char *buf) +{ + static const char *hawaiian_motifs[] = { + /* birds */ + "flamingo", + "parrot", + "toucan", + "bird of paradise", /* could be a bird or a flower */ + /* sea creatures */ + "sea turtle", + "tropical fish", + "jellyfish", + "giant eel", + "water nymph", + /* plants */ + "plumeria", + "orchid", + "hibiscus flower", + "palm tree", + /* other */ + "hula dancer", + "sailboat", + "ukulele", + }; + + /* a tourist's starting shirt always has the same o_id; we need some + additional randomness or else its design will never differ */ + unsigned motif = shirt->o_id ^ (unsigned) ubirthday; + + Strcpy(buf, hawaiian_motifs[motif % SIZE(hawaiian_motifs)]); + return buf; +} + +static char * +hawaiian_design(struct obj *shirt, char *buf) +{ + static const char *hawaiian_bgs[] = { + /* solid colors */ + "purple", + "yellow", + "red", + "blue", + "orange", + "black", + "green", + /* adjectives */ + "abstract", + "geometric", + "patterned", + "naturalistic", + }; + + /* This hash method is slightly different than the one in hawaiian_motif; + using the same formula in both cases may lead to some shirt combos + never appearing, if the sizes of the two lists have common factors. */ + unsigned bg = shirt->o_id ^ (unsigned) ~ubirthday; + + Sprintf(buf, "%s on %s background", + makeplural(hawaiian_motif(shirt, buf)), + an(hawaiian_bgs[bg % SIZE(hawaiian_bgs)])); + return buf; +} + char * apron_text(struct obj* apron, char* buf) { @@ -303,7 +368,8 @@ doread(void) u.uconduct.literate++; useup(scroll); return 1; - } else if (otyp == T_SHIRT || otyp == ALCHEMY_SMOCK) { + } else if (otyp == T_SHIRT || otyp == ALCHEMY_SMOCK + || otyp == HAWAIIAN_SHIRT) { char buf[BUFSZ], *mesg; const char *endpunct; @@ -312,12 +378,18 @@ doread(void) return 0; } /* can't read shirt worn under suit (under cloak is ok though) */ - if (otyp == T_SHIRT && uarm && scroll == uarmu) { + if ((otyp == T_SHIRT || otyp == HAWAIIAN_SHIRT) && uarm + && scroll == uarmu) { pline("%s shirt is obscured by %s%s.", scroll->unpaid ? "That" : "Your", shk_your(buf, uarm), suit_simple_name(uarm)); return 0; } + if (otyp == HAWAIIAN_SHIRT) { + pline("%s features %s.", flags.verbose ? "The design" : "It", + hawaiian_design(scroll, buf)); + return 1; + } u.uconduct.literate++; /* populate 'buf[]' */ mesg = (otyp == T_SHIRT) ? tshirt_text(scroll, buf)