Add 'readable' Hawaiian shirt designs
authorMichael Meyer <me@entrez.cc>
Thu, 29 Oct 2020 21:19:31 +0000 (17:19 -0400)
committerPatric Mueller <bhaak@gmx.net>
Fri, 16 Jul 2021 16:05:21 +0000 (18:05 +0200)
Functionally similar to reading a T-shirt or apron, but rather than
actual text printed on the shirt being displayed, the design of the
Hawaiian shirt is described: for example, "hula dancers on an orange
background" or "tropical fish on an abstract background".  Much like
T-shirts have their text included in the game-end inventory list ('a
blessed +2 T-shirt with text "foo"'), Hawaiian shirts now have a brief
description of their design appended to their item name under the same
circumstances.

Because 'reading' a Hawaiian shirt doesn't actually involve reading
text, using the 'r' command in this way doesn't break illiterate
conduct.

include/extern.h
include/obj.h
src/objnam.c
src/read.c

index 0a54e94dc7c5c3626cc78fb4fabfea03dfdcd7a0..0f59d7043200446c7e7b56a304dbf9e5440669d0 100644 (file)
@@ -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 *);
index 1e540e4c0a3d10f125c5a8498bb909d60f552171..3adbce284f864b9515cb70cf08a6e88dbfcc3d48 100644 (file)
@@ -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)                                 \
index 47bcb29645a0b4e06b65331524359e3a76992170..e7e00187c477ae111368cdb8b087273adf8ef1e7 100644 (file)
@@ -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;
         }
index a9cf9036a0971c02508b268032592fc3972eec0c..6e3e78edc733170328a13c40307e4a9ff31ffe77 100644 (file)
@@ -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)