/* This is the one we want to use when printing messages. */
int
pronoun_gender(struct monst *mtmp)
{
    if (is_neuter(mtmp->data) || !canclassifymon(mtmp))
        return 2;
    return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ) ||
            type_is_pname(mtmp->data)) ? (int)mtmp->female : 2;
}
static const char *
convert_arg(char c)
{
    switch (c) {
    case 'p':
        return msg_from_string(u.uplname);
    case 'c':
        return (u.ufemale && urole.name.f) ? urole.name.f : urole.name.m;
    case 'r':
        return rank_of(u.ulevel, Role_switch, u.ufemale);
    case 'R':
        return rank_of(MIN_QUEST_LEVEL, Role_switch, u.ufemale);
    case 's':
        return (u.ufemale) ? "sister" : "brother";
    case 'S':
        return (u.ufemale) ? "daughter" : "son";
    case 'l':
    case 'n': {
        int i = c == 'l' ? urole.ldrnum : urole.neminum;;
        return msgcat(type_is_pname(&mons[i]) ? "" : "the ",
                      mons[i].mname);
    }
    case 'i':
        return urole.intermed;
    case 'o':
        return the(artiname(urole.questarti));
    case 'g':
        return mons[urole.guardnum].mname;
    case 'G':
        return align_gtitle(u.ualignbase[A_ORIGINAL]);
    case 'H':
        return urole.homebase;
    case 'a':
        return align_str(u.ualignbase[A_ORIGINAL]);
    case 'A':
        return align_str(u.ualign.type);
    case 'd':
        return align_gname(u.ualignbase[A_ORIGINAL]);
    case 'D':
        return align_gname(A_LAWFUL);
    case 'C':
        return "chaotic";
    case 'N':
        return "neutral";
    case 'L':
        return "lawful";
    case 'x':
        return Blind ? "sense" : "see";
    case 'Z':
        return msg_from_string(gamestate.dungeons[0].dname);
    case '%':
        return "%";
    default:
        return "";
    }
}
Example #3
0
static const char *
neminame (void) /* return your role nemesis' name */
{
        int i = urole.neminum;

        sprintf(nambuf, "%s%s",
                type_is_pname(&mons[i]) ? "" : "the ",
                mons[i].mname);
        return nambuf;
}
Example #4
0
const char *
ldrname (void)  /* return your role leader's name */
{
        int i = urole.ldrnum;

        sprintf(nambuf, "%s%s",
                type_is_pname(&mons[i]) ? "" : "the ",
                mons[i].mname);
        return nambuf;
}
Example #5
0
/* Return a random monster name, for hallucination.
 * KNOWN BUG: May be a proper name (Godzilla, Barney), may not
 * (the Terminator, a Dalek).  There's no elegant way to deal
 * with this without radically modifying the calling functions.
 */
const char *rndmonnam(void)
{
	int name;

	do {
	    name = display_rng(SPECIAL_PM + SIZE(bogusmons) - LOW_PM) + LOW_PM;
	} while (name < SPECIAL_PM &&
	    (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN)));

	if (name >= SPECIAL_PM) return bogusmons[name - SPECIAL_PM];
	return mons[name].mname;
}
Example #6
0
void
nh_timeout()
{
	register struct prop *upp;
	int sleeptime;
	int m_idx;
	int baseluck = (flags.moonphase == FULL_MOON) ? 1 : 0;

	if (flags.friday13) baseluck -= 1;

	if (u.uluck != baseluck &&
		moves % (u.uhave.amulet || u.ugangr ? 300 : 600) == 0) {
	/* Cursed luckstones stop bad luck from timing out; blessed luckstones
	 * stop good luck from timing out; normal luckstones stop both;
	 * neither is stopped if you don't have a luckstone.
	 * Luck is based at 0 usually, +1 if a full moon and -1 on Friday 13th
	 */
	    register int time_luck = stone_luck(FALSE);
	    boolean nostone = !carrying(LUCKSTONE) && !stone_luck(TRUE);

	    if(u.uluck > baseluck && (nostone || time_luck < 0))
		u.uluck--;
	    else if(u.uluck < baseluck && (nostone || time_luck > 0))
		u.uluck++;
	}
	if(u.uinvulnerable) return; /* things past this point could kill you */
	if(Stoned) stoned_dialogue();
	if(Slimed) slime_dialogue();
	if(Vomiting) vomiting_dialogue();
	if(Strangled) choke_dialogue();
	if(u.mtimedone && !--u.mtimedone) {
		if (Unchanging)
			u.mtimedone = rnd(100*youmonst.data->mlevel + 1);
		else
			rehumanize();
	}
	if(u.ucreamed) u.ucreamed--;

	/* Dissipate spell-based protection. */
	if (u.usptime) {
	    if (--u.usptime == 0 && u.uspellprot) {
		u.usptime = u.uspmtime;
		u.uspellprot--;
		find_ac();
		if (!Blind)
		    Norep("The %s haze around you %s.", hcolor(NH_GOLDEN),
			  u.uspellprot ? "becomes less dense" : "disappears");
	    }
	}

#ifdef STEED
	if (u.ugallop) {
	    if (--u.ugallop == 0L && u.usteed)
	    	pline("%s stops galloping.", Monnam(u.usteed));
	}
#endif

	for(upp = u.uprops; upp < u.uprops+SIZE(u.uprops); upp++)
	    if((upp->intrinsic & TIMEOUT) && !(--upp->intrinsic & TIMEOUT)) {
		switch(upp - u.uprops){
		case STONED:
			if (delayed_killer && !killer) {
				killer = delayed_killer;
				delayed_killer = 0;
			}
			if (!killer) {
				/* leaving killer_format would make it
				   "petrified by petrification" */
				killer_format = NO_KILLER_PREFIX;
				killer = "killed by petrification";
			}
			done(STONING);
			break;
		case SLIMED:
			if (delayed_killer && !killer) {
				killer = delayed_killer;
				delayed_killer = 0;
			}
			if (!killer) {
				killer_format = NO_KILLER_PREFIX;
				killer = "turned into green slime";
			}
			done(TURNED_SLIME);
			break;
		case VOMITING:
			make_vomiting(0L, TRUE);
			break;
		case SICK:
			You("die from your illness.");
			killer_format = KILLED_BY_AN;
			killer = u.usick_cause;
			if ((m_idx = name_to_mon(killer)) >= LOW_PM) {
			    if (type_is_pname(&mons[m_idx])) {
				killer_format = KILLED_BY;
			    } else if (mons[m_idx].geno & G_UNIQ) {
				killer = the(killer);
				Strcpy(u.usick_cause, killer);
				killer_format = KILLED_BY;
			    }
			}
			u.usick_type = 0;
			done(POISONING);
			break;
		case FAST:
			if (!Very_fast)
				You_feel("yourself slowing down%s.",
							Fast ? " a bit" : "");
			break;
		case CONFUSION:
			HConfusion = 1; /* So make_confused works properly */
			make_confused(0L, TRUE);
			stop_occupation();
			break;
		case STUNNED:
			HStun = 1;
			make_stunned(0L, TRUE);
			stop_occupation();
			break;
		case BLINDED:
			Blinded = 1;
			make_blinded(0L, TRUE);
			stop_occupation();
			break;
		case INVIS:
			newsym(u.ux,u.uy);
			if (!Invis && !BInvis && !Blind) {
			    You(!See_invisible ?
				    "are no longer invisible." :
				    "can no longer see through yourself.");
			    stop_occupation();
			}
			break;
		case SEE_INVIS:
			set_mimic_blocking(); /* do special mimic handling */
			see_monsters();		/* make invis mons appear */
			newsym(u.ux,u.uy);	/* make self appear */
			stop_occupation();
			break;
		case WOUNDED_LEGS:
			heal_legs();
			stop_occupation();
			break;
		case HALLUC:
			HHallucination = 1;
			(void) make_hallucinated(0L, TRUE, 0L);
			stop_occupation();
			break;
		case SLEEPING:
			if (unconscious() || Sleep_resistance)
				HSleeping += rnd(100);
			else if (Sleeping) {
				You("fall asleep.");
				sleeptime = rnd(20);
				fall_asleep(-sleeptime, TRUE);
				HSleeping += sleeptime + rnd(100);
			}
			break;
		case LEVITATION:
			(void) float_down(I_SPECIAL|TIMEOUT, 0L);
			break;
		case STRANGLED:
			killer_format = KILLED_BY;
			killer = (u.uburied) ? "suffocation" : "strangulation";
			done(DIED);
			break;
		case FUMBLING:
			/* call this only when a move took place.  */
			/* otherwise handle fumbling msgs locally. */
			if (u.umoved && !Levitation) {
			    slip_or_trip();
			    nomul(-2, "fumbling");
			    nomovemsg = "";
			    /* The more you are carrying the more likely you
			     * are to make noise when you fumble.  Adjustments
			     * to this number must be thoroughly play tested.
			     */
			    if ((inv_weight() > -500)) {
				You("make a lot of noise!");
				wake_nearby();
			    }
			}
			/* from outside means slippery ice; don't reset
			   counter if that's the only fumble reason */
			HFumbling &= ~FROMOUTSIDE;
			if (Fumbling)
			    HFumbling += rnd(20);
			break;
		case DETECT_MONSTERS:
			see_monsters();
			break;
		case PREGNANT: {
			char buf[BUFSZ];
			if (!flags.female) {
			    strcpy(buf, body_part(STOMACH));
			    if (!strcmp(buf, "stomach"))
				strcpy(buf, "belly");
			    pline("Something bursts out of your %s!");
			    killer_format = KILLED_BY;
			    killer = "male childbirth";
			    done(DIED);
			}
			mksobj_at(PLACENTA, u.ux, u.uy, FALSE, FALSE);
			pline("BABIES!"); /* TODO */
			stop_occupation();
			break;
		    }
		}
	}

	run_timers();
}
Example #7
0
/* Bug: if the monster is a priest or shopkeeper, not every one of these
 * options works, since those are special cases.
 */
char *x_monnam(const struct monst *mtmp,
	       int article, /* ARTICLE_NONE, ARTICLE_THE, ARTICLE_A: obvious
	                     * ARTICLE_YOUR: "your" on pets, "the" on everything
			     * else
			     * If the monster would be referred to as "it" or if the monster has a name
			     * _and_ there is no adjective, "invisible", "saddled", etc., override this
			     * and always use no article.
			     */
	       const char *adjective,
	       int suppress, /* SUPPRESS_IT, SUPPRESS_INVISIBLE, SUPPRESS_HALLUCINATION, SUPPRESS_SADDLE.
	                      * EXACT_NAME: combination of all the above
			      */
	       boolean called)
{
	static char buf[BUFSZ];

	const struct permonst *mdat = mtmp->data;
	boolean do_hallu, do_invis, do_it, do_saddle;
	boolean name_at_start, has_adjectives;
	char *bp;

	if (program_state.gameover)
	    suppress |= SUPPRESS_HALLUCINATION;
	if (article == ARTICLE_YOUR && !mtmp->mtame)
	    article = ARTICLE_THE;

	do_hallu = Hallucination && !(suppress & SUPPRESS_HALLUCINATION);
	do_invis = mtmp->minvis && !(suppress & SUPPRESS_INVISIBLE);
	do_it = !canspotmon(mtmp) && 
	    article != ARTICLE_YOUR &&
	    !program_state.gameover &&
	    mtmp != u.usteed &&
	    !(u.uswallow && mtmp == u.ustuck) &&
	    !(suppress & SUPPRESS_IT);
	do_saddle = !(suppress & SUPPRESS_SADDLE);

	buf[0] = 0;

	/* unseen monsters, etc.  Use "it" */
	if (do_it) {
	    strcpy(buf, "it");
	    return buf;
	}

	/* priests and minions: don't even use this function */
	if (mtmp->ispriest || mtmp->isminion) {
	    struct monst *priestmon = newmonst(mtmp->mxtyp, mtmp->mnamelth);
	    char priestnambuf[BUFSZ];
	    char *name;
	    long save_prop = EHalluc_resistance;
	    memcpy(priestmon, mtmp, sizeof(struct monst) + mtmp->mxlth + mtmp->mnamelth);

	    /* when true name is wanted, explicitly block Hallucination */
	    if (!do_hallu) EHalluc_resistance = 1L;
	    if (!do_invis) priestmon->minvis = 0;
	    name = priestname(priestmon, priestnambuf);
	    EHalluc_resistance = save_prop;
	    if (article == ARTICLE_NONE && !strncmp(name, "the ", 4))
		name += 4;
	    strcpy(buf, name);
	    free(priestmon);
	    return buf;
	}

	/* Shopkeepers: use shopkeeper name.  For normal shopkeepers, just
	 * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible
	 * shopkeeper" or "Asidonhopo the blue dragon".  If hallucinating,
	 * none of this applies.
	 */
	if (mtmp->isshk && !do_hallu) {
	    if (adjective && article == ARTICLE_THE) {
		/* pathological case: "the angry Asidonhopo the blue dragon"
		   sounds silly */
		strcpy(buf, "the ");
		strcat(strcat(buf, adjective), " ");
		strcat(buf, shkname(mtmp));
		return buf;
	    }
	    strcat(buf, shkname(mtmp));
	    if (mdat == &mons[PM_SHOPKEEPER] && !do_invis)
		return buf;
	    strcat(buf, " the ");
	    if (do_invis)
		strcat(buf, "invisible ");
	    strcat(buf, mdat->mname);
	    return buf;
	}

	/* Put the adjectives in the buffer */
	if (adjective)
	    strcat(strcat(buf, adjective), " ");
	if (do_invis)
	    strcat(buf, "invisible ");

	if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) &&
	    !Blind && !Hallucination)
	    strcat(buf, "saddled ");

	if (buf[0] != 0)
	    has_adjectives = TRUE;
	else
	    has_adjectives = FALSE;

	/* Put the actual monster name or type into the buffer now */
	/* Be sure to remember whether the buffer starts with a name */
	if (do_hallu) {
	    strcat(buf, rndmonnam());
	    name_at_start = FALSE;
	} else if (mtmp->mnamelth) {
	    char *name = NAME(mtmp);

	    if (mdat == &mons[PM_GHOST]) {
		sprintf(eos(buf), "%s ghost", s_suffix(name));
		name_at_start = TRUE;
	    } else if (called) {
		sprintf(eos(buf), "%s called %s", mdat->mname, name);
		name_at_start = (boolean)type_is_pname(mdat);
	    } else if (is_mplayer(mdat) && (bp = strstri(name, " the ")) != 0) {
		/* <name> the <adjective> <invisible> <saddled> <rank> */
		char pbuf[BUFSZ];

		strcpy(pbuf, name);
		pbuf[bp - name + 5] = '\0'; /* adjectives right after " the " */
		if (has_adjectives)
		    strcat(pbuf, buf);
		strcat(pbuf, bp + 5);	/* append the rest of the name */
		strcpy(buf, pbuf);
		article = ARTICLE_NONE;
		name_at_start = TRUE;
	    } else {
		strcat(buf, name);
		name_at_start = TRUE;
	    }
	} else if (is_mplayer(mdat) && !In_endgame(&u.uz)) {
	    char pbuf[BUFSZ];
	    strcpy(pbuf, rank_of((int)mtmp->m_lev,
				 monsndx(mdat), (boolean)mtmp->female));
	    strcat(buf, lcase(pbuf));
	    name_at_start = FALSE;
	} else {
	    strcat(buf, mdat->mname);
	    name_at_start = (boolean)type_is_pname(mdat);
	}

	if (name_at_start && (article == ARTICLE_YOUR || !has_adjectives)) {
	    if (mdat == &mons[PM_WIZARD_OF_YENDOR])
		article = ARTICLE_THE;
	    else
		article = ARTICLE_NONE;
	} else if ((mdat->geno & G_UNIQ) && article == ARTICLE_A) {
	    article = ARTICLE_THE;
	}

	{
	    char buf2[BUFSZ];

	    switch(article) {
		case ARTICLE_YOUR:
		    strcpy(buf2, "your ");
		    strcat(buf2, buf);
		    strcpy(buf, buf2);
		    return buf;
		case ARTICLE_THE:
		    strcpy(buf2, "the ");
		    strcat(buf2, buf);
		    strcpy(buf, buf2);
		    return buf;
		case ARTICLE_A:
		    return an(buf);
		case ARTICLE_NONE:
		default:
		    return buf;
	    }
	}
}