char *Adjmonnam(const struct monst *mtmp, const char *adj) { char *bp = x_monnam(mtmp, ARTICLE_THE, adj, mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE); *bp = highc(*bp); return bp; }
char *coyotename(const struct monst *mtmp, char *buf) { if (mtmp && buf) { sprintf(buf, "%s - %s", x_monnam(mtmp, ARTICLE_NONE, NULL, 0, TRUE), mtmp->mcan ? coynames[SIZE(coynames)-1] : coynames[display_rng(SIZE(coynames)-1)]); } return buf; }
/* pet name: "your little dog" */ char *y_monnam(const struct monst *mtmp) { int prefix, suppression_flag; prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE; /* "saddled" is redundant when mounted */ suppression_flag = (mtmp->mnamelth || mtmp == u.usteed) ? SUPPRESS_SADDLE : 0; return x_monnam(mtmp, prefix, NULL, suppression_flag, FALSE); }
/* article: only ARTICLE_NONE and ARTICLE_THE are handled here */ char *distant_monnam(const struct monst *mon, int article, char *outbuf) { /* high priest(ess)'s identity is concealed on the Astral Plane, unless you're adjacent (overridden for hallucination which does its own obfuscation) */ if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) { strcpy(outbuf, article == ARTICLE_THE ? "the " : ""); strcat(outbuf, mon->female ? "high priestess" : "high priest"); } else { strcpy(outbuf, x_monnam(mon, article, NULL, 0, TRUE)); } return outbuf; }
static size_t g_monnam(char *out_buf, int buf_size, struct monst * mtmp) { return x_monnam(out_buf, buf_size, mtmp, ARTICLE_NONE, (char *)0, SUPPRESS_IT, false); }
/* Generate earthquake :-) of desired force. That is: create random chasms (pits). Currently assumes that the player created it (you'll need to change at least messages, angering, and kill credit if you generalize it). */ static void do_earthquake(int force) { int x, y; struct monst *mtmp; struct obj *otmp; struct trap *chasm, *oldtrap; int start_x, start_y, end_x, end_y; start_x = youmonst.mx - (force * 2); start_y = youmonst.my - (force * 2); end_x = youmonst.mx + (force * 2); end_y = youmonst.my + (force * 2); if (start_x < 0) start_x = 0; if (start_y < 0) start_y = 0; if (end_x >= COLNO) end_x = COLNO - 1; if (end_y >= ROWNO) end_y = ROWNO - 1; for (x = start_x; x <= end_x; x++) for (y = start_y; y <= end_y; y++) { if ((mtmp = m_at(level, x, y)) != 0) { wakeup(mtmp, FALSE); /* peaceful monster will become hostile */ if (mtmp->mundetected && is_hider(mtmp->data)) { mtmp->mundetected = 0; if (cansee(x, y)) pline(msgc_youdiscover, "%s is shaken loose from %s!", Amonnam(mtmp), mtmp->data == &mons[PM_TRAPPER] ? "its hiding place" : the(ceiling(youmonst.mx, youmonst.my))); else You_hear(msgc_levelsound, "a thumping sound."); if (x == youmonst.mx && y == youmonst.my && mtmp->data != &mons[PM_TRAPPER]) pline(msgc_moncombatgood, "You easily dodge the falling %s.", mon_nam(mtmp)); newsym(x, y); } } if (!rn2(14 - force)) switch (level->locations[x][y].typ) { case FOUNTAIN: /* Make the fountain disappear */ if (cansee(x, y)) pline(msgc_consequence, "The fountain falls into a chasm."); goto do_pit; case SINK: if (cansee(x, y)) pline(msgc_consequence, "The kitchen sink falls into a chasm."); goto do_pit; case ALTAR: if (level->locations[x][y].altarmask & AM_SANCTUM) break; if (cansee(x, y)) pline(msgc_consequence, "The altar falls into a chasm."); goto do_pit; case GRAVE: if (cansee(x, y)) pline(msgc_consequence, "The headstone topples into a chasm."); goto do_pit; case THRONE: if (cansee(x, y)) pline(msgc_consequence, "The throne falls into a chasm."); /* Falls into next case */ case ROOM: case CORR: /* Try to make a pit */ /* Pits, spiked pits, holes, trapdoors, vibrating squares, magic portals are immune. A bear trap will leave the trap in the pit. It would be kind of cool to make landmines detonate, but that's more trouble than it's worth. */ if ((oldtrap = t_at(level, x, y))) { if (oldtrap->ttyp == PIT || oldtrap->ttyp == SPIKED_PIT || oldtrap->ttyp == HOLE || oldtrap->ttyp == TRAPDOOR || oldtrap->ttyp == VIBRATING_SQUARE || oldtrap->ttyp == MAGIC_PORTAL) break; if (oldtrap->ttyp == BEAR_TRAP) { if (mtmp) mtmp->mtrapped = 0; cnv_trap_obj(level, BEARTRAP, 1, oldtrap); } } do_pit: chasm = maketrap(level, x, y, PIT, rng_main); if (!chasm) break; /* no pit if portal at that location */ chasm->tseen = 1; level->locations[x][y].doormask = 0; mtmp = m_at(level, x, y); if ((otmp = sobj_at(BOULDER, level, x, y)) != 0) { if (cansee(x, y)) pline(msgc_consequence, "KADOOM! The boulder falls into a chasm%s!", ((x == youmonst.mx) && (y == youmonst.my)) ? " below you" : ""); if (mtmp) mtmp->mtrapped = 0; obj_extract_self(otmp); flooreffects(otmp, x, y, ""); break; } /* We have to check whether monsters or player falls in a chasm... */ if (mtmp) { if (!flying(mtmp) && !levitates(mtmp) && !is_clinger(mtmp->data)) { mtmp->mtrapped = 1; if (cansee(x, y)) pline(combat_msgc(&youmonst, mtmp, cr_hit), "%s falls into a chasm!", Monnam(mtmp)); else if (humanoid(mtmp->data)) You_hear(msgc_levelsound, "a scream!"); mselftouch(mtmp, "Falling, ", &youmonst); if (!DEADMONSTER(mtmp)) if ((mtmp->mhp -= rnd(6)) <= 0) { if (!cansee(x, y)) pline(msgc_kill, "It is destroyed!"); else { pline(msgc_petfatal, "You destroy %s!", mtmp->mtame ? x_monnam(mtmp, ARTICLE_THE, "poor", mx_name(mtmp) ? SUPPRESS_SADDLE : 0, FALSE) : mon_nam(mtmp)); } xkilled(mtmp, 0); } } } else if (!u.utrap && x == youmonst.mx && y == youmonst.my) { if (Levitation || Flying || is_clinger(youmonst.data)) { pline(msgc_noconsequence, "A chasm opens up under you!"); pline(msgc_noconsequence, "You don't fall in!"); } else { pline(msgc_badidea, "You fall into a chasm!"); u.utrap = rn1(6, 2); u.utraptype = TT_PIT; turnstate.vision_full_recalc = TRUE; losehp(rnd(6), "fell into a chasm"); selftouch("Falling, you", "falling into a chasm while wielding"); } } else newsym(x, y); break; case DOOR: /* Make the door collapse */ if (level->locations[x][y].doormask == D_NODOOR) goto do_pit; if (cansee(x, y)) pline(msgc_consequence, "The door collapses."); if (*in_rooms(level, x, y, SHOPBASE)) add_damage(x, y, 0L); level->locations[x][y].doormask = D_NODOOR; unblock_point(x, y); newsym(x, y); break; } } }
void mstatusline(struct monst *mtmp) { aligntyp alignment; const char *info, *monnambuf; if (mtmp->ispriest || (mtmp->isminion && roamer_type(mtmp->data))) alignment = CONST_EPRI(mtmp)->shralign; else if (mtmp->isminion) alignment = EMIN(mtmp)->min_align; else { alignment = mtmp->data->maligntyp; alignment = (alignment > 0) ? A_LAWFUL : (alignment == A_NONE) ? A_NONE : (alignment < 0) ? A_CHAOTIC : A_NEUTRAL; } info = ""; if (mtmp->mtame) { info = msgcat(info, ", tame"); if (wizard) { info = msgprintf("%s (%d", info, mtmp->mtame); if (!mtmp->isminion) info = msgprintf("%s; hungry %u; apport %d", info, EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport); info = msgcat(info, ")"); } } else if (mtmp->mpeaceful) info = msgcat(info, ", peaceful"); if (mtmp->meating) info = msgcat(info, ", eating"); if (mtmp->mcan) info = msgcat(info, ", cancelled"); if (mtmp->mconf) info = msgcat(info, ", confused"); if (mtmp->mblinded || !mtmp->mcansee) info = msgcat(info, ", blind"); if (mtmp->mstun) info = msgcat(info, ", stunned"); if (mtmp->msleeping) info = msgcat(info, ", asleep"); else if (mtmp->mfrozen || !mtmp->mcanmove) info = msgcat(info, ", can't move"); /* [arbitrary reason why it isn't moving] */ else if (mtmp->mstrategy & STRAT_WAITMASK) info = msgcat(info, ", meditating"); else if (mtmp->mflee) info = msgcat(info, ", scared"); if (mtmp->mtrapped) info = msgcat(info, ", trapped"); if (mtmp->mspeed) info = msgcat(info, mtmp->mspeed == MFAST ? ", fast" : mtmp->mspeed == MSLOW ? ", slow" : ", ???? speed"); if (mtmp->mundetected) info = msgcat(info, ", concealed"); if (mtmp->minvis) info = msgcat(info, ", invisible"); if (mtmp == u.ustuck) info = msgcat(info, (sticks(youmonst.data)) ? ", held by you" : Engulfed ? (is_animal(u.ustuck->data) ? ", swallowed you" : ", engulfed you") : ", holding you"); if (mtmp == u.usteed) info = msgcat(info, ", carrying you"); /* avoid "Status of the invisible newt ..., invisible" */ /* and unlike a normal mon_nam, use "saddled" even if it has a name */ monnambuf = x_monnam(mtmp, ARTICLE_THE, NULL, (SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE); pline("Status of %s (%s): Level %d HP %d(%d) Def %d%s.", monnambuf, align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax, 10 - find_mac(mtmp), info); }
/* Start riding, with the given monster */ boolean mount_steed(struct monst * mtmp, /* The animal */ boolean force) { /* Quietly force this animal */ struct obj *otmp; const struct permonst *ptr; /* Sanity checks */ if (u.usteed) { pline("You are already riding %s.", mon_nam(u.usteed)); return FALSE; } /* Is the player in the right form? */ if (Hallucination && !force) { pline("Maybe you should find a designated driver."); return FALSE; } /* While riding Wounded_legs refers to the steed's, not the hero's legs. That opens up a potential abuse where the player can mount a steed, then dismount immediately to heal leg damage, because leg damage is always healed upon dismount (Wounded_legs context switch). By preventing a hero with Wounded_legs from mounting a steed, the potential for abuse is minimized, if not eliminated altogether. */ if (Wounded_legs) { pline("Your %s are in no shape for riding.", makeplural(body_part(LEG))); if (force && wizard && yn("Heal your legs?") == 'y') LWounded_legs = RWounded_legs = 0; else return FALSE; } if (Upolyd && (!humanoid(youmonst.data) || verysmall(youmonst.data) || bigmonst(youmonst.data) || slithy(youmonst.data))) { pline("You won't fit on a saddle."); return FALSE; } if (!force && (near_capacity() > SLT_ENCUMBER)) { pline("You can't do that while carrying so much stuff."); return FALSE; } /* Can the player reach and see the monster? */ if (!mtmp || (!force && ((Blind && !Blind_telepat) || mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE || mtmp->m_ap_type == M_AP_OBJECT))) { pline("I see nobody there."); return FALSE; } struct test_move_cache cache; init_test_move_cache(&cache); if (Engulfed || u.ustuck || u.utrap || Punished || !test_move(u.ux, u.uy, mtmp->mx - u.ux, mtmp->my - u.uy, 0, TEST_MOVE, &cache)) { if (Punished || !(Engulfed || u.ustuck || u.utrap)) pline("You are unable to swing your %s over.", body_part(LEG)); else pline("You are stuck here for now."); return FALSE; } /* Is this a valid monster? */ otmp = which_armor(mtmp, os_saddle); if (!otmp) { pline("%s is not saddled.", Monnam(mtmp)); return FALSE; } ptr = mtmp->data; if (touch_petrifies(ptr) && !Stone_resistance) { pline("You touch %s.", mon_nam(mtmp)); instapetrify(killer_msg(STONING, msgcat("attempting to ride ", an(mtmp->data->mname)))); } if (!mtmp->mtame || mtmp->isminion) { pline("I think %s would mind.", mon_nam(mtmp)); return FALSE; } if (mtmp->mtrapped) { struct trap *t = t_at(level, mtmp->mx, mtmp->my); pline("You can't mount %s while %s's trapped in %s.", mon_nam(mtmp), mhe(mtmp), t ? an(trapexplain[t->ttyp - 1]) : "ice"); return FALSE; } if (!force && !Role_if(PM_KNIGHT) && !(--mtmp->mtame)) { /* no longer tame */ newsym(mtmp->mx, mtmp->my); pline("%s resists%s!", Monnam(mtmp), mtmp->mleashed ? " and its leash comes off" : ""); if (mtmp->mleashed) m_unleash(mtmp, FALSE); return FALSE; } if (!force && Underwater && !is_swimmer(ptr)) { pline("You can't ride that creature while under water."); return FALSE; } if (!can_saddle(mtmp) || !can_ride(mtmp)) { pline("You can't ride such a creature."); return 0; } /* Is the player impaired? */ if (!force && !is_floater(ptr) && !is_flyer(ptr) && Levitation && !Lev_at_will) { pline("You cannot reach %s.", mon_nam(mtmp)); return FALSE; } if (!force && uarm && is_metallic(uarm) && greatest_erosion(uarm)) { pline("Your %s armor is too stiff to be able to mount %s.", uarm->oeroded ? "rusty" : "corroded", mon_nam(mtmp)); return FALSE; } if (!force && (Confusion || Fumbling || Glib || Wounded_legs || otmp->cursed || ((u.ulevel + mtmp->mtame < rnd(MAXULEV / 2 + 5)) && (!Role_if(PM_KNIGHT))))) { if (Levitation) { pline("%s slips away from you.", Monnam(mtmp)); return FALSE; } pline("You slip while trying to get on %s.", mon_nam(mtmp)); const char *buf = msgcat( "slipped while mounting ", /* "a saddled mumak" or "a saddled pony called Dobbin" */ x_monnam(mtmp, ARTICLE_A, NULL, SUPPRESS_IT | SUPPRESS_INVISIBLE | SUPPRESS_HALLUCINATION, TRUE)); losehp(rn1(5, 10), buf); return FALSE; } /* Success */ maybewakesteed(mtmp); if (!force) { if (Levitation && !is_floater(ptr) && !is_flyer(ptr)) /* Must have Lev_at_will at this point */ pline("%s magically floats up!", Monnam(mtmp)); pline("You mount %s.", mon_nam(mtmp)); } /* setuwep handles polearms differently when you're mounted */ if (uwep && is_pole(uwep)) u.bashmsg = TRUE; u.usteed = mtmp; remove_monster(level, mtmp->mx, mtmp->my); teleds(mtmp->mx, mtmp->my, TRUE); return TRUE; }
char *a_monnam(const struct monst *mtmp) { return x_monnam(mtmp, ARTICLE_A, NULL, mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE); }
/* monster's own name */ char *m_monnam(const struct monst *mtmp) { return x_monnam(mtmp, ARTICLE_NONE, NULL, EXACT_NAME, FALSE); }
/* print the name as if mon_nam() was called, but assume that the player * can always see the monster--used for probing and for monsters aggravating * the player with a cursed potion of invisibility */ char *noit_mon_nam(const struct monst *mtmp) { return(x_monnam(mtmp, ARTICLE_THE, NULL, mtmp->mnamelth ? (SUPPRESS_SADDLE|SUPPRESS_IT) : SUPPRESS_IT, FALSE)); }
char *mon_nam(const struct monst *mtmp) { return(x_monnam(mtmp, ARTICLE_THE, NULL, mtmp->mnamelth ? SUPPRESS_SADDLE : 0, FALSE)); }
char *l_monnam(const struct monst *mtmp) { return(x_monnam(mtmp, ARTICLE_NONE, NULL, mtmp->mnamelth ? SUPPRESS_SADDLE : 0, TRUE)); }