Changeset 312

Show
Ignore:
Timestamp:
07/08/07 20:49:04 (1 year ago)
Author:
takkaria
Message:

Recolour the monster recall, make it use more compact code (using functions adapted from obj-info.c). (part of #152)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/changes.txt

    r309 r312  
    99Changes up to now: 
    1010 
    11  * Add Ey-style quickstart.  (Eytan Zweig) 
     11Bigger 
     12------ 
    1213 
    13  * Add DTrap indicator. (pelpel
     14* Add Ey-style quickstart.  (Eytan Zweig
    1415 
    15  * Adopted various parts of the OAngband dungeon generation code. 
    16    (Leon Marrick) For more information, please see: 
    17    http://dev.rephial.org/trac/attachment/ticket/156/notes.txt 
     16* Add trap detection indicator. (pelpel)  Also, make detection spells 
     17  circular, of radius 22, and magic mapping circular of radius 30. 
    1818 
    19  * Transient indicators now appear on the bottom line, starting at the 
    20    left of the dungeon display; things like depth and speed appear on 
    21    the main sidebar.  As a result of this, every timed effect is now 
    22    displayed on the status bar. 
     19* Adopted various parts of the OAngband dungeon generation code. 
     20  (Leon Marrick) For more information, please see: 
     21  http://dev.rephial.org/trac/attachment/ticket/156/notes.txt 
     22 
     23* Transient indicators now appear on the bottom line, starting at the 
     24  left of the dungeon display; things like depth and speed appear on 
     25  the main sidebar.  As a result of this, every timed effect is now 
     26  displayed on the status bar. 
     27 
     28Smaller 
     29------- 
     30 
     31* Monster recall colours changed somewhat, they're now closer to Ey, 
     32  which I find much more readable. 
     33 
     34Invisible (or almost so) 
     35--------- 
     36 
  • trunk/src/externs.h

    r305 r312  
    658658extern void text_out_to_file(byte attr, cptr str); 
    659659extern void text_out_to_screen(byte a, cptr str); 
    660 extern void text_out(cptr str); 
    661 extern void text_out_c(byte a, cptr str); 
     660extern void text_out(const char *fmt, ...); 
     661extern void text_out_c(byte a, const char *fmt, ...); 
    662662extern void clear_from(int row); 
    663663extern bool askfor_aux_keypress(char *buf, size_t buflen, size_t *curs, size_t *len, char keypress, bool firsttime); 
  • trunk/src/monster1.c

    r48 r312  
    1 /* File: monster1.c */ 
    2  
    3 /* 
    4  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke 
     1/* 
     2 * File: obj-info.c 
     3 * Purpose: Monster description code. 
    54 * 
    6  * This software may be copied and distributed for educational, research, 
    7  * and not for profit purposes provided that this copyright and statement 
    8  * are included in all such copies.  Other copyrights may also apply. 
    9  */ 
    10  
     5 * Copyright (c) 1997-2007 Ben Harrison, James E. Wilson, Robert A. Koeneke 
     6 * 
     7 * This work is free software; you can redistribute it and/or modify it 
     8 * under the terms of either: 
     9 * 
     10 * a) the GNU General Public License as published by the Free Software 
     11 *    Foundation, version 2, or 
     12 * 
     13 * b) the "Angband licence": 
     14 *    This software may be copied and distributed for educational, research, 
     15 *    and not for profit purposes provided that this copyright and statement 
     16 *    are included in all such copies.  Other copyrights may also apply. 
     17 */ 
    1118#include "angband.h" 
    1219 
     
    1522 * Pronoun arrays, by gender. 
    1623 */ 
    17 static cptr wd_he[3] = 
    18 { "it", "he", "she" }; 
    19 static cptr wd_his[3] = 
    20 { "its", "his", "her" }; 
     24static cptr wd_he[3] = { "it", "he", "she" }; 
     25static cptr wd_his[3] = { "its", "his", "her" }; 
    2126 
    2227 
     
    2429 * Pluralizer.  Args(count, singular, plural) 
    2530 */ 
    26 #define plural(c,s,p) \ 
    27         (((c) == 1) ? (s) : (p)) 
     31#define plural(c, s, p)    (((c) == 1) ? (s) : (p)) 
     32 
     33 
     34 
     35static void output_list(const char *list[], int num, byte attr) 
     36
     37        int i; 
     38        const char *conjunction = "and "; 
     39 
     40        if (num < 0) 
     41        { 
     42                num = -num; 
     43                conjunction = "or "; 
     44        } 
     45 
     46        for (i = 0; i < num; i++) 
     47        { 
     48        if (i) 
     49                { 
     50                        if (num > 2) 
     51                                text_out(", "); 
     52                        else 
     53                                text_out(" "); 
     54 
     55                        if (i == num - 1) 
     56                                text_out(conjunction); 
     57                } 
     58 
     59                text_out_c(attr, list[i]); 
     60        } 
     61
     62 
     63 
     64static void output_desc_list(int msex, cptr intro, cptr list[], int n, byte attr) 
     65
     66        if (n != 0) 
     67        { 
     68                /* Output intro */ 
     69                text_out(format("%^s %s ", wd_he[msex], intro)); 
     70 
     71                /* Output list */ 
     72                output_list(list, n, attr); 
     73 
     74                /* Output end */ 
     75                text_out(".  "); 
     76        } 
     77
    2878 
    2979 
     
    95145        char buf[2048]; 
    96146 
    97         /* Simple method */ 
    98         my_strcpy(buf, r_text + r_ptr->text, sizeof(buf)); 
    99  
    100147        /* Dump it */ 
    101         text_out(buf); 
     148        text_out(r_text + r_ptr->text); 
    102149        text_out("\n"); 
    103150} 
     
    132179 
    133180        /* Describe innate attacks */ 
    134         if (vn) 
    135         { 
    136                 /* Intro */ 
    137                 text_out(format("%^s", wd_he[msex])); 
    138  
    139                 /* Scan */ 
    140                 for (n = 0; n < vn; n++) 
    141                 { 
    142                         /* Intro */ 
    143                         if (n == 0) text_out(" may "); 
    144                         else if (n < vn-1) text_out(", "); 
    145                         else text_out(" or "); 
    146  
    147                         /* Dump */ 
    148                         text_out_c(TERM_L_RED, vp[n]); 
    149                 } 
    150  
    151                 /* End */ 
    152                 text_out(".  "); 
    153         } 
     181        output_desc_list(msex, "may", vp, -vn, TERM_WHITE); 
    154182 
    155183 
    156184        /* Collect breaths */ 
    157185        vn = 0; 
    158         if (l_ptr->flags4 & RF4_BR_ACID)               vp[vn++] = "acid"; 
    159         if (l_ptr->flags4 & RF4_BR_ELEC)               vp[vn++] = "lightning"; 
    160         if (l_ptr->flags4 & RF4_BR_FIRE)               vp[vn++] = "fire"; 
    161         if (l_ptr->flags4 & RF4_BR_COLD)               vp[vn++] = "frost"; 
    162         if (l_ptr->flags4 & RF4_BR_POIS)               vp[vn++] = "poison"; 
    163         if (l_ptr->flags4 & RF4_BR_NETH)               vp[vn++] = "nether"; 
    164         if (l_ptr->flags4 & RF4_BR_LITE)               vp[vn++] = "light"; 
    165         if (l_ptr->flags4 & RF4_BR_DARK)               vp[vn++] = "darkness"; 
    166         if (l_ptr->flags4 & RF4_BR_CONF)               vp[vn++] = "confusion"; 
    167         if (l_ptr->flags4 & RF4_BR_SOUN)               vp[vn++] = "sound"; 
    168         if (l_ptr->flags4 & RF4_BR_CHAO)               vp[vn++] = "chaos"; 
    169         if (l_ptr->flags4 & RF4_BR_DISE)               vp[vn++] = "disenchantment"; 
    170         if (l_ptr->flags4 & RF4_BR_NEXU)               vp[vn++] = "nexus"; 
    171         if (l_ptr->flags4 & RF4_BR_TIME)               vp[vn++] = "time"; 
    172         if (l_ptr->flags4 & RF4_BR_INER)               vp[vn++] = "inertia"; 
    173         if (l_ptr->flags4 & RF4_BR_GRAV)               vp[vn++] = "gravity"; 
    174         if (l_ptr->flags4 & RF4_BR_SHAR)               vp[vn++] = "shards"; 
    175         if (l_ptr->flags4 & RF4_BR_PLAS)               vp[vn++] = "plasma"; 
    176         if (l_ptr->flags4 & RF4_BR_WALL)               vp[vn++] = "force"; 
    177         if (l_ptr->flags4 & RF4_BR_MANA)               vp[vn++] = "mana"; 
    178         if (l_ptr->flags4 & RF4_XXX5)          vp[vn++] = "something"; 
    179         if (l_ptr->flags4 & RF4_XXX6)          vp[vn++] = "something"; 
    180         if (l_ptr->flags4 & RF4_XXX7)          vp[vn++] = "something"; 
     186        if (l_ptr->flags4 & RF4_BR_ACID) vp[vn++] = "acid"; 
     187        if (l_ptr->flags4 & RF4_BR_ELEC) vp[vn++] = "lightning"; 
     188        if (l_ptr->flags4 & RF4_BR_FIRE) vp[vn++] = "fire"; 
     189        if (l_ptr->flags4 & RF4_BR_COLD) vp[vn++] = "frost"; 
     190        if (l_ptr->flags4 & RF4_BR_POIS) vp[vn++] = "poison"; 
     191        if (l_ptr->flags4 & RF4_BR_NETH) vp[vn++] = "nether"; 
     192        if (l_ptr->flags4 & RF4_BR_LITE) vp[vn++] = "light"; 
     193        if (l_ptr->flags4 & RF4_BR_DARK) vp[vn++] = "darkness"; 
     194        if (l_ptr->flags4 & RF4_BR_CONF) vp[vn++] = "confusion"; 
     195        if (l_ptr->flags4 & RF4_BR_SOUN) vp[vn++] = "sound"; 
     196        if (l_ptr->flags4 & RF4_BR_CHAO) vp[vn++] = "chaos"; 
     197        if (l_ptr->flags4 & RF4_BR_DISE) vp[vn++] = "disenchantment"; 
     198        if (l_ptr->flags4 & RF4_BR_NEXU) vp[vn++] = "nexus"; 
     199        if (l_ptr->flags4 & RF4_BR_TIME) vp[vn++] = "time"; 
     200        if (l_ptr->flags4 & RF4_BR_INER) vp[vn++] = "inertia"; 
     201        if (l_ptr->flags4 & RF4_BR_GRAV) vp[vn++] = "gravity"; 
     202        if (l_ptr->flags4 & RF4_BR_SHAR) vp[vn++] = "shards"; 
     203        if (l_ptr->flags4 & RF4_BR_PLAS) vp[vn++] = "plasma"; 
     204        if (l_ptr->flags4 & RF4_BR_WALL) vp[vn++] = "force"; 
     205        if (l_ptr->flags4 & RF4_BR_MANA) vp[vn++] = "mana"; 
     206        if (l_ptr->flags4 & RF4_XXX5)    vp[vn++] = "something"; 
     207        if (l_ptr->flags4 & RF4_XXX6)    vp[vn++] = "something"; 
     208        if (l_ptr->flags4 & RF4_XXX7)    vp[vn++] = "something"; 
    181209 
    182210        /* Describe breaths */ 
     
    186214                breath = TRUE; 
    187215 
    188                 /* Intro */ 
    189                 text_out(format("%^s", wd_he[msex])); 
    190  
    191                 /* Scan */ 
    192                 for (n = 0; n < vn; n++) 
    193                 { 
    194                         /* Intro */ 
    195                         if (n == 0) text_out(" may breathe "); 
    196                         else if (n < vn-1) text_out(", "); 
    197                         else text_out(" or "); 
    198  
    199                         /* Dump */ 
    200                         text_out_c(TERM_L_RED, vp[n]); 
    201                 } 
     216                /* Display */ 
     217                text_out("%^s may ", wd_he[msex]); 
     218                text_out_c(TERM_L_RED, "breathe "); 
     219                output_list(vp, -vn, TERM_WHITE); 
    202220        } 
    203221 
     
    264282        if (l_ptr->flags6 & RF6_S_UNDEAD)    vp[vn++] = "summon an undead"; 
    265283        if (l_ptr->flags6 & RF6_S_DRAGON)    vp[vn++] = "summon a dragon"; 
    266         if (l_ptr->flags6 & RF6_S_HI_UNDEAD) vp[vn++] = "summon Greater Undead"; 
    267         if (l_ptr->flags6 & RF6_S_HI_DRAGON) vp[vn++] = "summon Ancient Dragons"; 
    268         if (l_ptr->flags6 & RF6_S_HI_DEMON)  vp[vn++] = "summon Greater Demons"; 
    269         if (l_ptr->flags6 & RF6_S_WRAITH)    vp[vn++] = "summon Ring Wraiths"; 
    270         if (l_ptr->flags6 & RF6_S_UNIQUE)    vp[vn++] = "summon Unique Monsters"; 
     284        if (l_ptr->flags6 & RF6_S_HI_UNDEAD) vp[vn++] = "summon greater undead"; 
     285        if (l_ptr->flags6 & RF6_S_HI_DRAGON) vp[vn++] = "summon ancient dragons"; 
     286        if (l_ptr->flags6 & RF6_S_HI_DEMON)  vp[vn++] = "summon greater demons"; 
     287        if (l_ptr->flags6 & RF6_S_WRAITH)    vp[vn++] = "summon ringwraiths"; 
     288        if (l_ptr->flags6 & RF6_S_UNIQUE)    vp[vn++] = "summon uniques"; 
    271289 
    272290        /* Describe spells */ 
     
    278296                /* Intro */ 
    279297                if (breath) 
    280                 { 
    281                         text_out(", and is also"); 
    282                 } 
     298                        text_out(", and is also "); 
    283299                else 
    284                 { 
    285                         text_out(format("%^s is", wd_he[msex])); 
    286                 } 
     300                        text_out("%^s is ", wd_he[msex]); 
    287301 
    288302                /* Verb Phrase */ 
    289                 text_out(" magical, casting spells"); 
     303                text_out_c(TERM_L_RED, "magical"); 
     304                text_out(", casting spells"); 
    290305 
    291306                /* Adverb */ 
    292                 if (l_ptr->flags2 & RF2_SMART) text_out_c(TERM_ORANGE, " intelligently"); 
    293  
    294                 /* Scan */ 
    295                 for (n = 0; n < vn; n++) 
    296                 { 
    297                         /* Intro */ 
    298                         if (n == 0) text_out(" which "); 
    299                         else if (n < vn-1) text_out(", "); 
    300                         else text_out(" or "); 
    301  
    302                         /* Dump */ 
    303                         text_out_c(TERM_L_RED, vp[n]); 
    304                 } 
     307                if (l_ptr->flags2 & RF2_SMART) text_out(" intelligently"); 
     308 
     309                /* List */ 
     310                text_out(" which "); 
     311                output_list(vp, -vn, TERM_WHITE); 
    305312        } 
    306313 
     
    318325                if (m > 100) 
    319326                { 
    320                         text_out(format("; 1 time in %d", 100 / n)); 
     327                        text_out("; "); 
     328                        text_out_c(TERM_L_GREEN, "1"); 
     329                        text_out(" time in "); 
     330                        text_out_c(TERM_L_GREEN, "%d", 100 / n); 
    321331                } 
    322332 
     
    325335                { 
    326336                        n = ((n + 9) / 10) * 10; 
    327                         text_out(format("; about 1 time in %d", 100 / n)); 
     337                        text_out("; about "); 
     338                        text_out_c(TERM_L_GREEN, "1"); 
     339                        text_out(" time in "); 
     340                        text_out_c(TERM_L_GREEN, "%d", 100 / n); 
    328341                } 
    329342 
     
    333346} 
    334347 
    335  
     348/* 
     349 * Describe a monster's drop. 
     350 */ 
    336351static void describe_monster_drop(int r_idx, const monster_lore *l_ptr) 
    337352{ 
     
    342357        int n; 
    343358 
    344         cptr p
     359        const char *p = NULL
    345360 
    346361        int msex = 0; 
     
    355370        { 
    356371                /* Intro */ 
    357                 text_out(format("%^s may carry", wd_he[msex])); 
     372                text_out("%^s may carry", wd_he[msex]); 
    358373 
    359374                /* Count maximum drop */ 
    360375                n = MAX(l_ptr->drop_gold, l_ptr->drop_item); 
    361376 
    362                 /* One drop (may need an "n") */ 
    363                 if (n == 1) 
    364                 { 
    365                         text_out(" a"); 
    366                         sin = TRUE; 
    367                 } 
    368  
    369                 /* Two drops */ 
    370                 else if (n == 2) 
    371                 { 
    372                         text_out(" one or two"); 
    373                 } 
    374  
    375                 /* Many drops */ 
    376                 else 
    377                 { 
    378                         text_out(format(" up to %d", n)); 
    379                 } 
    380  
    381  
    382                 /* Great */ 
    383                 if (l_ptr->flags1 & RF1_DROP_GREAT) 
    384                 { 
    385                         p = " exceptional"; 
    386                 } 
    387  
    388                 /* Good (no "n" needed) */ 
    389                 else if (l_ptr->flags1 & RF1_DROP_GOOD) 
    390                 { 
    391                         p = " good"; 
    392                         sin = FALSE; 
    393                 } 
    394  
    395                 /* Okay */ 
    396                 else 
    397                 { 
    398                         p = NULL; 
    399                 } 
     377                /* Count drops */ 
     378                if (n == 1) text_out(" a single "); 
     379                else if (n == 2) text_out(" one or two "); 
     380                else text_out(format(" up to %d ", n)); 
     381 
     382 
     383                /* Quality */ 
     384                if (l_ptr->flags1 & RF1_DROP_GREAT) text_out("exceptional "); 
     385                else if (l_ptr->flags1 & RF1_DROP_GOOD) text_out("good "); 
    400386 
    401387 
     
    403389                if (l_ptr->drop_item) 
    404390                { 
    405                         /* Handle singular "an" */ 
    406                         if (sin) text_out("n"); 
    407                         sin = FALSE; 
    408  
    409391                        /* Dump "object(s)" */ 
    410                         if (p) text_out(p); 
    411                         text_out(" object"); 
    412                         if (n != 1) text_out("s"); 
    413  
    414                         /* Conjunction replaces variety, if needed for "gold" below */ 
    415                         p = " or"; 
     392                        text_out("object%s", PLURAL(n)); 
     393 
     394                        /* Add conjunction if also dropping gold */ 
     395                        if (l_ptr->drop_gold) text_out(" or "); 
    416396                } 
    417397 
     
    419399                if (l_ptr->drop_gold) 
    420400                { 
    421                         /* Cancel prefix */ 
    422                         if (!p) sin = FALSE; 
    423  
    424                         /* Handle singular "an" */ 
    425                         if (sin) text_out("n"); 
    426  
    427401                        /* Dump "treasure(s)" */ 
    428                         if (p) text_out(p); 
    429                         text_out(" treasure"); 
    430                         if (n != 1) text_out("s"); 
     402                        text_out("treasure%s", PLURAL(n)); 
    431403                } 
    432404 
     
    436408} 
    437409 
    438  
     410/* 
     411 * Describe all of a monster's attacks. 
     412 */ 
    439413static void describe_monster_attack(int r_idx, const monster_lore *l_ptr) 
    440414{ 
    441415        const monster_race *r_ptr = &r_info[r_idx]; 
    442416        int m, n, r; 
    443         cptr p, q; 
    444417 
    445418        int msex = 0; 
     
    449422        else if (r_ptr->flags1 & RF1_MALE) msex = 1; 
    450423 
    451          
     424 
    452425        /* Count the number of "known" attacks */ 
    453426        for (n = 0, m = 0; m < MONSTER_BLOW_MAX; m++) 
     
    464437        { 
    465438                int method, effect, d1, d2; 
    466  
    467                 /* Skip non-attacks */ 
    468                 if (!r_ptr->blow[m].method) continue; 
    469  
    470                 /* Skip unknown attacks */ 
    471                 if (!l_ptr->blows[m]) continue; 
     439                const char *p = NULL; 
     440                const char *q = NULL; 
     441 
     442                /* Skip unknown and undefined attacks */ 
     443                if (!r_ptr->blow[m].method || !l_ptr->blows[m]) continue; 
    472444 
    473445 
     
    479451 
    480452 
    481                 /* No method yet */ 
    482                 p = NULL; 
    483  
    484453                /* Get the method */ 
    485454                switch (method) 
    486455                { 
    487                         case RBM_HIT:   p = "hit"; break; 
    488                         case RBM_TOUCH: p = "touch"; break; 
    489                         case RBM_PUNCH: p = "punch"; break; 
    490                         case RBM_KICK:  p = "kick"; break; 
    491                         case RBM_CLAW:  p = "claw"; break; 
    492                         case RBM_BITE:  p = "bite"; break; 
    493                         case RBM_STING: p = "sting"; break; 
    494                         case RBM_XXX1:  break; 
    495                         case RBM_BUTT:  p = "butt"; break; 
    496                         case RBM_CRUSH: p = "crush"; break; 
    497                         case RBM_ENGULF:        p = "engulf"; break; 
    498                         case RBM_XXX2:  break; 
    499                         case RBM_CRAWL: p = "crawl on you"; break; 
    500                         case RBM_DROOL: p = "drool on you"; break; 
    501                         case RBM_SPIT:  p = "spit"; break; 
    502                         case RBM_XXX3:  break; 
    503                         case RBM_GAZE:  p = "gaze"; break; 
    504                         case RBM_WAIL:  p = "wail"; break; 
    505                         case RBM_SPORE: p = "release spores"; break; 
    506                         case RBM_XXX4:  break; 
    507                         case RBM_BEG:   p = "beg"; break; 
    508                         case RBM_INSULT:        p = "insult"; break; 
    509                         case RBM_MOAN:  p = "moan"; break; 
    510                         case RBM_XXX5:  break; 
    511                 } 
    512  
    513  
    514                 /* Default effect */ 
    515                 q = NULL; 
     456                        case RBM_HIT:    p = "hit"; break; 
     457                        case RBM_TOUCH:  p = "touch"; break; 
     458                        case RBM_PUNCH:  p = "punch"; break; 
     459                        case RBM_KICK:   p = "kick"; break; 
     460                        case RBM_CLAW:   p = "claw"; break; 
     461                        case RBM_BITE:   p = "bite"; break; 
     462                        case RBM_STING:  p = "sting"; break; 
     463                        case RBM_BUTT:   p = "butt"; break; 
     464                        case RBM_CRUSH:  p = "crush"; break; 
     465                        case RBM_ENGULF: p = "engulf"; break; 
     466                        case RBM_CRAWL:  p = "crawl on you"; break; 
     467                        case RBM_DROOL:  p = "drool on you"; break; 
     468                        case RBM_SPIT:   p = "spit"; break; 
     469                        case RBM_GAZE:   p = "gaze"; break; 
     470                        case RBM_WAIL:   p = "wail"; break; 
     471                        case RBM_SPORE:  p = "release spores"; break; 
     472                        case RBM_BEG:    p = "beg"; break; 
     473                        case RBM_INSULT: p = "insult"; break; 
     474                        case RBM_MOAN:   p = "moan"; break; 
     475                        case RBM_XXX1: 
     476                        case RBM_XXX2: 
     477                        case RBM_XXX3: 
     478                        case RBM_XXX4: 
     479                        case RBM_XXX5: 
     480                        default:                p = "do something weird"; 
     481                } 
     482 
    516483 
    517484                /* Get the effect */ 
     
    552519                /* Introduce the attack description */ 
    553520                if (!r) 
    554                 { 
    555                         text_out(format("%^s can ", wd_he[msex])); 
    556                 } 
    557                 else if (r < n-1) 
    558                 { 
     521                        text_out("%^s can ", wd_he[msex]); 
     522                else if (r < n - 1) 
    559523                        text_out(", "); 
    560                 } 
    561524                else 
    562                 { 
    563525                        text_out(", and "); 
    564                 } 
    565  
    566  
    567                 /* Hack -- force a method */ 
    568                 if (!p) p = "do something weird"; 
    569526 
    570527                /* Describe the method */ 
    571528                text_out(p); 
    572529 
    573  
    574530                /* Describe the effect (if any) */ 
    575531                if (q) 
    576532                { 
    577533                        /* Describe the attack type */ 
    578                         text_out(" to "); 
    579                         text_out_c(TERM_L_RED, q); 
     534                        text_out(" to %s", q); 
    580535 
    581536                        /* Describe damage (if known) */ 
    582537                        if (d1 && d2 && know_damage(r_idx, l_ptr, m)) 
    583538                        { 
    584                                 /* Display the damage */ 
    585                                 text_out(" with damage"); 
    586                                 text_out(format(" %dd%d", d1, d2)); 
     539                                text_out(" with damage "); 
     540                                text_out_c(TERM_L_GREEN, "%dd%d", d1, d2); 
    587541                        } 
    588542                } 
    589  
    590543 
    591544                /* Count the attacks as printed */ 
     
    595548        /* Finish sentence above */ 
    596549        if (r) 
    597         { 
    598550                text_out(".  "); 
    599         } 
    600551 
    601552        /* Notice lack of attacks */ 
    602553        else if (l_ptr->flags1 & RF1_NEVER_BLOW) 
    603         { 
    604                 text_out(format("%^s has no physical attacks.  ", wd_he[msex])); 
    605         } 
     554                text_out("%^s has no physical attacks.  ", wd_he[msex]); 
    606555 
    607556        /* Or describe the lack of knowledge */ 
    608557        else 
    609         { 
    610                 text_out(format("Nothing is known about %s attack.  ", wd_his[msex])); 
    611         } 
    612 
    613  
    614  
     558                text_out("Nothing is known about %s attack.  ", wd_his[msex]); 
     559
     560 
     561 
     562/* 
     563 * Describe special abilities of monsters. 
     564 */ 
    615565static void describe_monster_abilities(int r_idx, const monster_lore *l_ptr) 
    616566{ 
     
    618568 
    619569        int n; 
     570        bool prev = FALSE; 
    620571 
    621572        int vn; 
     
    628579        if (r_ptr->flags1 & RF1_FEMALE) msex = 2; 
    629580        else if (r_ptr->flags1 & RF1_MALE) msex = 1; 
     581 
    630582 
    631583        /* Collect special abilities. */ 
     
    641593 
    642594        /* Describe special abilities. */ 
    643         if (vn) 
    644         { 
    645                 /* Intro */ 
    646                 text_out(format("%^s", wd_he[msex])); 
    647  
    648                 /* Scan */ 
    649                 for (n = 0; n < vn; n++) 
    650                 { 
    651                         /* Intro */ 
    652                         if (n == 0) text_out(" can "); 
    653                         else if (n < vn-1) text_out(", "); 
    654                         else text_out(" and "); 
    655  
    656                         /* Dump */ 
    657                         text_out(vp[n]); 
    658                 } 
    659  
    660                 /* End */ 
    661                 text_out(".  "); 
    662         } 
    663  
    664  
    665         /* Describe special abilities. */ 
    666         if (l_ptr->flags2 & RF2_INVISIBLE) 
    667         { 
    668                 text_out(format("%^s is invisible.  ", wd_he[msex])); 
    669         } 
    670         if (l_ptr->flags2 & RF2_COLD_BLOOD) 
    671         { 
    672                 text_out(format("%^s is cold blooded.  ", wd_he[msex])); 
    673         } 
    674         if (l_ptr->flags2 & RF2_EMPTY_MIND) 
    675         { 
    676                 text_out(format("%^s is not detected by telepathy.  ", wd_he[msex])); 
    677         } 
    678         if (l_ptr->flags2 & RF2_WEIRD_MIND) 
    679         { 
    680                 text_out(format("%^s is rarely detected by telepathy.  ", wd_he[msex])); 
    681         } 
     595        output_desc_list(msex, "can", vp, vn, TERM_WHITE); 
     596 
     597 
     598        /* Describe detection traits */ 
     599        vn = 0; 
     600        if (l_ptr->flags2 & RF2_INVISIBLE)  vp[vn++] = "invisible"; 
     601        if (l_ptr->flags2 & RF2_COLD_BLOOD) vp[vn++] = "cold blooded"; 
     602        if (l_ptr->flags2 & RF2_EMPTY_MIND) vp[vn++] = "not detected by telepathy"; 
     603        if (l_ptr->flags2 & RF2_WEIRD_MIND) vp[vn++] = "rarely detected by telepathy"; 
     604 
     605        output_desc_list(msex, "is", vp, vn, TERM_WHITE); 
     606 
     607 
     608        /* Describe special things */ 
    682609        if (l_ptr->flags2 & RF2_MULTIPLY) 
    683         { 
    684                 text_out(format("%^s breeds explosively.  ", wd_he[msex])); 
    685         } 
     610                text_out("%^s breeds explosively.  ", wd_he[msex]); 
    686611        if (l_ptr->flags2 & RF2_REGENERATE) 
    687         { 
    688                 text_out(format("%^s regenerates quickly.  ", wd_he[msex])); 
    689         } 
     612                text_out("%^s regenerates quickly.  ", wd_he[msex]); 
     613 
    690614 
    691615 
     
    697621        if (l_ptr->flags3 & RF3_HURT_COLD) vp[vn++] = "cold"; 
    698622 
    699         /* Describe susceptibilities */ 
    700623        if (vn) 
    701624        { 
    702                 /* Intro */ 
    703                 text_out(format("%^s", wd_he[msex])); 
    704  
    705                 /* Scan */ 
    706                 for (n = 0; n < vn; n++) 
    707                 { 
    708                         /* Intro */ 
    709                         if (n == 0) text_out(" is hurt by "); 
    710                         else if (n < vn-1) text_out(", "); 
    711                         else text_out(" and "); 
    712  
    713                         /* Dump */ 
    714                         text_out_c(TERM_YELLOW, vp[n]); 
    715                 } 
    716  
    717                 /* End */ 
    718                 text_out(".  "); 
    719         } 
    720  
     625                /* Output connecting text */ 
     626                text_out("%^s is hurt by ", wd_he[msex]); 
     627                output_list(vp, vn, TERM_YELLOW); 
     628                prev = TRUE; 
     629        } 
    721630 
    722631        /* Collect immunities and resistances */ 
    723632        vn = 0; 
    724         if (l_ptr->flags3 & RF3_IM_ACID) vp[vn++] = "acid"; 
    725         if (l_ptr->flags3 & RF3_IM_ELEC) vp[vn++] = "lightning"; 
    726         if (l_ptr->flags3 & RF3_IM_FIRE) vp[vn++] = "fire"; 
    727         if (l_ptr->flags3 & RF3_IM_COLD) vp[vn++] = "cold"; 
    728         if (l_ptr->flags3 & RF3_IM_POIS) vp[vn++] = "poison"; 
    729         if (l_ptr->flags3 & RF3_IM_WATER) vp[vn++] = "water"; 
     633        if (l_ptr->flags3 & RF3_IM_ACID)   vp[vn++] = "acid"; 
     634        if (l_ptr->flags3 & RF3_IM_ELEC)   vp[vn++] = "lightning"; 
     635        if (l_ptr->flags3 & RF3_IM_FIRE)   vp[vn++] = "fire"; 
     636        if (l_ptr->flags3 & RF3_IM_COLD)   vp[vn++] = "cold"; 
     637        if (l_ptr->flags3 & RF3_IM_POIS)   vp[vn++] = "poison"; 
     638        if (l_ptr->flags3 & RF3_IM_WATER) vp[vn++] = "water"; 
    730639        if (l_ptr->flags3 & RF3_RES_NETH)  vp[vn++] = "nether"; 
    731640        if (l_ptr->flags3 & RF3_RES_PLAS)  vp[vn++] = "plasma"; 
     
    733642        if (l_ptr->flags3 & RF3_RES_DISE)  vp[vn++] = "disenchantment"; 
    734643 
    735         /* Describe immunities and resistances */ 
    736644        if (vn) 
    737645        { 
    738                 /* Intro */ 
    739                 text_out(format("%^s", wd_he[msex])); 
    740  
    741                 /* Scan */ 
    742                 for (n = 0; n < vn; n++) 
    743                 { 
    744                         /* Intro */ 
    745                         if (n == 0) text_out(" resists "); 
    746                         else if (n < vn-1) text_out(", "); 
    747                         else text_out(" and "); 
    748  
    749                         /* Dump */ 
    750                         text_out_c(TERM_ORANGE, vp[n]); 
    751                 } 
    752  
    753                 /* End */ 
    754                 text_out(".  "); 
    755         } 
    756  
     646                /* Output connecting text */ 
     647                if (prev) 
     648                        text_out(", but resists "); 
     649                else 
     650                        text_out("%^s resists ", wd_he[msex]); 
     651 
     652                /* Write the text */ 
     653                output_list(vp, vn, TERM_ORANGE); 
     654                prev = TRUE; 
     655        } 
    757656 
    758657        /* Collect non-effects */ 
     
    763662        if (l_ptr->flags3 & RF3_NO_SLEEP) vp[vn++] = "slept"; 
    764663 
    765         /* Describe non-effects */ 
    766664        if (vn) 
    767665        { 
    768                 /* Intro */ 
    769                 text_out(format("%^s", wd_he[msex])); 
    770  
    771                 /* Scan */ 
    772                 for (n = 0; n < vn; n++) 
    773                 { 
    774                         /* Intro */ 
    775                         if (n == 0) text_out(" cannot be "); 
    776                         else if (n < vn-1) text_out(", "); 
    777                         else text_out(" or "); 
    778  
    779                         /* Dump */ 
    780                         text_out_c(TERM_YELLOW, vp[n]); 
    781                 } 
    782  
    783                 /* End */ 
    784                 text_out(".  "); 
    785         } 
     666                /* Output connecting text */ 
     667                if (prev) 
     668                        text_out(", and cannot be "); 
     669                else 
     670                        text_out("%^s cannot be ", wd_he[msex]); 
     671 
     672                output_list(vp, -vn, TERM_ORANGE); 
     673                prev = TRUE; 
     674        } 
     675 
     676 
     677        /* Full stop. */ 
     678        if (prev) text_out(".  "); 
     679 
    786680 
    787681 
     
    793687                cptr act; 
    794688 
    795                 if (r_ptr->sleep > 200) 
    796                 { 
    797                         act = "prefers to ignore"; 
    798                 } 
    799                 else if (r_ptr->sleep > 95) 
    800                 { 
    801                         act = "pays very little attention to"; 
    802                 } 
    803                 else if (r_ptr->sleep > 75) 
    804                 { 
    805                         act = "pays little attention to"; 
    806                 } 
    807                 else if (r_ptr->sleep > 45) 
    808                 { 
    809                         act = "tends to overlook"; 
    810                 } 
    811                 else if (r_ptr->sleep > 25) 
    812                 { 
    813                         act = "takes quite a while to see"; 
    814                 } 
    815                 else if (r_ptr->sleep > 10) 
    816                 { 
    817                         act = "takes a while to see"; 
    818                 } 
    819                 else if (r_ptr->sleep > 5) 
    820                 { 
    821                         act = "is fairly observant of"; 
    822                 } 
    823                 else if (r_ptr->sleep > 3) 
    824                 { 
    825                         act = "is observant of"; 
    826                 } 
    827                 else if (r_ptr->sleep > 1) 
    828                 { 
    829                         act = "is very observant of"; 
    830                 } 
    831                 else if (r_ptr->sleep > 0) 
    832                 { 
    833                         act = "is vigilant for"; 
    834                 } 
    835                 else 
    836                 { 
    837                         act = "is ever vigilant for"; 
    838                 } 
    839  
    840                 text_out(format("%^s %s intruders, which %s may notice from %d feet.  ", 
    841                             wd_he[msex], act, wd_he[msex], 10 * r_ptr->aaf)); 
     689                if (r_ptr->sleep > 200)     act = "prefers to ignore"; 
     690                else if (r_ptr->sleep > 95) act = "pays very little attention to"; 
     691                else if (r_ptr->sleep > 75) act = "pays little attention to"; 
     692                else if (r_ptr->sleep > 45) act = "tends to overlook"; 
     693                else if (r_ptr->sleep > 25) act = "takes quite a while to see"; 
     694                else if (r_ptr->sleep > 10) act = "takes a while to see"; 
     695                else if (r_ptr->sleep > 5)  act = "is fairly observant of"; 
     696                else if (r_ptr->sleep > 3)  act = "is observant of"; 
     697                else if (r_ptr->sleep > 1)  act = "is very observant of"; 
     698                else if (r_ptr->sleep > 0)  act = "is vigilant for"; 
     699                else                        act = "is ever vigilant for"; 
     700 
     701                text_out("%^s %s intruders, which %s may notice from ", wd_he[msex], act, wd_he[msex]); 
     702                text_out_c(TERM_L_GREEN, "%d", 10 * r_ptr->aaf); 
     703                text_out(" feet.  "); 
    842704        } 
    843705 
     
    845707        if ((l_ptr->flags1 & RF1_ESCORT) || (l_ptr->flags1 & RF1_ESCORTS)) 
    846708        { 
    847                 text_out(format("%^s usually appears with escorts.  ", 
    848                             wd_he[msex])); 
     709                text_out("%^s usually appears with escorts.  ", wd_he[msex]); 
    849710        } 
    850711 
     
    852713        else if ((l_ptr->flags1 & RF1_FRIEND) || (l_ptr->flags1 & RF1_FRIENDS)) 
    853714        { 
    854                 text_out(format("%^s usually appears in groups.  ", 
    855                             wd_he[msex])); 
    856         } 
    857 
    858  
    859  
     715                text_out("%^s usually appears in groups.  ", wd_he[msex]); 
     716        } 
     717
     718 
     719 
     720/* 
     721 * Describe how often the monster has killed/been killed. 
     722 */ 
    860723static void describe_monster_kills(int r_idx, const monster_lore *l_ptr) 
    86172