/** * Show and delete the stacked monster messages. * Some messages are delayed so that they show up after everything else. * This is to avoid things like "The snaga dies. The snaga runs in fear!" * So we only flush messages matching the delay parameter. */ static void flush_monster_messages(bool delay) { int i, r_idx, count; const monster_race *r_ptr; char buf[512]; char *action; bool action_only; /* Show every message */ for (i = 0; i < size_mon_msg; i++) { if (mon_msg[i].delay != delay) continue; /* Cache the monster count */ count = mon_msg[i].mon_count; /* Paranoia */ if (count < 1) continue; /* Start with an empty string */ buf[0] = '\0'; /* Cache the race index */ r_idx = mon_msg[i].mon_race; /* Get the proper message action */ action = get_mon_msg_action(mon_msg[i].msg_code, (count > 1), &r_info[r_idx]); /* Is it a regular race? */ if (r_idx > 0) { /* Get the race */ r_ptr = &r_info[r_idx]; } /* It's the special mark for non-visible monsters */ else { /* No race */ r_ptr = NULL; } /* Monster is marked as invisible */ if(mon_msg[i].mon_flags & 0x04) r_ptr = NULL; /* Special message? */ action_only = (*action == '~'); /* Format the proper message for visible monsters */ if (r_ptr && !action_only) { char race_name[80]; /* Get the race name */ my_strcpy(race_name, r_ptr->name, sizeof(race_name)); /* Uniques */ if (rf_has(r_ptr->flags, RF_UNIQUE)) { /* Just copy the race name */ my_strcpy(buf, (r_ptr->name), sizeof(buf)); } /* We have more than one monster */ else if (count > 1) { /* Get the plural of the race name */ plural_aux(race_name, sizeof(race_name)); /* Put the count and the race name together */ strnfmt(buf, sizeof(buf), "%d %s", count, race_name); } /* Normal lonely monsters */ else { /* Just add a slight flavor */ strnfmt(buf, sizeof(buf), "the %s", race_name); } } /* Format the message for non-viewable monsters if necessary */ else if (!r_ptr && !action_only) { if (count > 1) { /* Show the counter */ strnfmt(buf, sizeof(buf), "%d monsters", count); } else { /* Just one non-visible monster */ my_strcpy(buf, "it", sizeof(buf)); } } /* Special message. Nuke the mark */ if (action_only) ++action; /* Regular message */ else { /* Add special mark. Monster is offscreen */ if (mon_msg[i].mon_flags & 0x02) my_strcat(buf, " (offscreen)", sizeof(buf)); /* Add the separator */ my_strcat(buf, " ", sizeof(buf)); } /* Append the action to the message */ my_strcat(buf, action, sizeof(buf)); /* Capitalize the message */ *buf = toupper((unsigned char)*buf); /* Hack - play sound for fear message */ if (mon_msg[i].msg_code == MON_MSG_FLEE_IN_TERROR) sound(MSG_FLEE); /* Show the message */ msg(buf); } }
/** * Show and delete the stacked monster messages. * Some messages are delayed so that they show up after everything else. * This is to avoid things like "The snaga dies. The snaga runs in fear!" * So we only flush messages matching the delay parameter. */ static void flush_monster_messages(bool delay, byte delay_tag) { const monster_race *r_ptr; int i, count; char buf[512]; char *action; bool action_only; /* Show every message */ for (i = 0; i < size_mon_msg; i++) { int type = MSG_GENERIC; if (mon_msg[i].delay != delay) continue; /* Skip if we are delaying and the tags don't match */ if (mon_msg[i].delay && mon_msg[i].delay_tag != delay_tag) continue; /* Cache the monster count */ count = mon_msg[i].mon_count; /* Paranoia */ if (count < 1) continue; /* Start with an empty string */ buf[0] = '\0'; /* Cache the race index */ r_ptr = mon_msg[i].race; /* Get the proper message action */ action = get_mon_msg_action(mon_msg[i].msg_code, (count > 1), r_ptr); /* Monster is marked as invisible */ if (mon_msg[i].mon_flags & MON_MSG_FLAG_INVISIBLE) r_ptr = NULL; /* Special message? */ action_only = (*action == '~'); /* Format the proper message depending on type, number and visibility */ if (r_ptr && !action_only) { char race_name[80]; /* Get the race name */ my_strcpy(race_name, r_ptr->name, sizeof(race_name)); /* Uniques, multiple monsters, or just one */ if (rf_has(r_ptr->flags, RF_UNIQUE)) { /* Just copy the race name */ my_strcpy(buf, (r_ptr->name), sizeof(buf)); } else if (count > 1) { /* Get the plural of the race name */ if (r_ptr->plural != NULL) { my_strcpy(race_name, r_ptr->plural, sizeof(race_name)); } else { plural_aux(race_name, sizeof(race_name)); } /* Put the count and the race name together */ strnfmt(buf, sizeof(buf), "%d %s", count, race_name); } else { /* Just add a slight flavor */ strnfmt(buf, sizeof(buf), "the %s", race_name); } } else if (!r_ptr && !action_only) { if (count > 1) { /* Show the counter */ strnfmt(buf, sizeof(buf), "%d monsters", count); } else { /* Just one non-visible monster */ my_strcpy(buf, "it", sizeof(buf)); } } /* Special message. Nuke the mark */ if (action_only) ++action; /* Regular message */ else { /* Add special mark. Monster is offscreen */ if (mon_msg[i].mon_flags & MON_MSG_FLAG_OFFSCREEN) my_strcat(buf, " (offscreen)", sizeof(buf)); /* Add the separator */ my_strcat(buf, " ", sizeof(buf)); } /* Append the action to the message */ my_strcat(buf, action, sizeof(buf)); /* Capitalize the message */ *buf = toupper((unsigned char)*buf); switch (mon_msg[i].msg_code) { case MON_MSG_FLEE_IN_TERROR: type = MSG_FLEE; break; case MON_MSG_MORIA_DEATH: case MON_MSG_DESTROYED: case MON_MSG_DIE: case MON_MSG_SHRIVEL_LIGHT: case MON_MSG_DISENTEGRATES: case MON_MSG_FREEZE_SHATTER: case MON_MSG_DISSOLVE: { /* Assume normal death sound */ type = MSG_KILL; /* Play a special sound if the monster was unique */ if (r_ptr != NULL && rf_has(r_ptr->flags, RF_UNIQUE)) { if (r_ptr->base == lookup_monster_base("Morgoth")) type = MSG_KILL_KING; else type = MSG_KILL_UNIQUE; } break; } } /* Show the message */ msgt(type, "%s", buf); } }