예제 #1
0
int
rndmonnum(void)	/* select a random, common monster type */
{
    register struct permonst *ptr;
    register int	i;

    /* Plan A: get a level-appropriate common monster */
    ptr = rndmonst();
    if (ptr) return(monsndx(ptr));

    /* Plan B: get any common proper monster */
    int count = 0;
    do {
        i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
        ptr = &mons[i];
        count++;
    } while (((ptr->geno & G_NOGEN) || prohibited_by_generation_flags(ptr)) && count < 10000);

    /* Plan C: get any common monster */
    do {
        i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
        ptr = &mons[i];
        count++;
    } while(ptr->geno & G_NOGEN);

    return(i);
}
예제 #2
0
파일: quest.c 프로젝트: FredrIQ/nhfourk
static void
chat_with_guardian(void)
{
/* These guys/gals really don't have much to say... */
    if (Uhave_questart && Qstat(killed_nemesis))
        qt_pager(rn1(5, QT_GUARDTALK2));
    else
        qt_pager(rn1(5, QT_GUARDTALK));
}
예제 #3
0
void
losexp(const char *drainer)		/* e.g., hit by drain life attack */
                    	/* cause of death, if drain should be fatal */
{
    register int num;

#ifdef WIZARD
    /* override life-drain resistance when handling an explicit
       wizard mode request to reduce level; never fatal though */
    if (drainer && !strcmp(drainer, "#levelchange"))
        drainer = 0;
    else
#endif
        if (resists_drli(&youmonst)) return;

    if (u.ulevel > 1) {
        pline("%s level %d.", Goodbye(), u.ulevel--);
        /* remove intrinsic abilities */
        adjabil(u.ulevel + 1, u.ulevel);
        reset_rndmonst(NON_PM);	/* new monster selection */
    } else {
        if (drainer) {
            killer_format = KILLED_BY;
            killer = drainer;
            done(DIED);
        }
        /* no drainer or lifesaved */
        u.uexp = 0;
    }
    num = newhp();
    u.uhpmax -= num;
    check_uhpmax();
    if (u.uhpmax < 1) u.uhpmax = 1;
    u.uhp -= num;
    if (u.uhp < 1) u.uhp = 1;
    else if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;

    if (u.ulevel < urole.xlev)
        num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,
                  urole.enadv.lofix + urace.enadv.lofix);
    else
        num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,
                  urole.enadv.hifix + urace.enadv.hifix);
    num = enermod(num);		/* M. Stephenson */
    u.uenmax -= num;
    if (u.uenmax < 0) u.uenmax = 0;
    u.uen -= num;
    if (u.uen < 0) u.uen = 0;
    else if (u.uen > u.uenmax) u.uen = u.uenmax;

    if (u.uexp > 0)
        u.uexp = newuexp(u.ulevel) - 1;
    flags.botl = 1;
}
예제 #4
0
void
rloc(struct monst *mtmp)
{
	int tx, ty;
	char ch = mtmp->data->mlet;

#ifndef NOWORM
	if (ch == 'w' && mtmp->mx)	/* do not relocate worms */
		return;
#endif /* NOWORM */
	do {
		tx = rn1(COLNO - 3, 2);
		ty = rn2(ROWNO);
	} while (!goodpos(tx, ty));
	mtmp->mx = tx;
	mtmp->my = ty;
	if (u.ustuck == mtmp) {
		if (u.uswallow) {
			u.ux = tx;
			u.uy = ty;
			docrt();
		} else
			u.ustuck = 0;
	}
	pmon(mtmp);
}
예제 #5
0
void
rloco_pos(struct level *lev, struct obj *obj, int *nx, int *ny)
{
    xchar tx, ty, otx;
    boolean restricted_fall;
    int try_limit = 4000;

    otx = obj->ox;
    restricted_fall = (otx == 0 && lev->dndest.lx);
    do {
        tx = rn1(COLNO - 3, 2);
        ty = rn2(ROWNO);
        if (!--try_limit)
            break;
    } while (!goodpos(lev, tx, ty, NULL, 0) ||
             /* bug: this lacks provision for handling the Wizard's tower */
             (restricted_fall &&
              (!within_bounded_area
               (tx, ty, lev->dndest.lx, lev->dndest.ly, lev->dndest.hx,
                lev->dndest.hy) ||
               (level->dndest.nlx &&
                within_bounded_area(tx, ty,
                                    lev->dndest.nlx, lev->dndest.nly,
                                    lev->dndest.nhx, lev->dndest.nhy)))));

    *nx = tx;
    *ny = ty;
}
예제 #6
0
struct region *
create_gas_cloud(struct level *lev, xchar x, xchar y, int radius, int damage)
{
    struct region *cloud;
    int i, nrect;
    struct nhrect tmprect;

    cloud = create_region(NULL, 0);
    nrect = radius;
    tmprect.lx = x;
    tmprect.hx = x;
    tmprect.ly = y - (radius - 1);
    tmprect.hy = y + (radius - 1);
    for (i = 0; i < nrect; i++) {
        add_rect_to_reg(cloud, &tmprect);
        tmprect.lx--;
        tmprect.hx++;
        tmprect.ly++;
        tmprect.hy--;
    }
    cloud->ttl = rn1(3, 4);
    if (!in_mklev && !flags.mon_moving)
        set_heros_fault(cloud); /* assume player has created it */
    cloud->inside_f = INSIDE_GAS_CLOUD;
    cloud->expire_f = EXPIRE_GAS_CLOUD;
    cloud->arg = damage;
    cloud->visible = TRUE;
    cloud->effect_id = dbuf_effect(E_MISC, E_gascloud);
    add_region(lev, cloud);
    return cloud;
}
예제 #7
0
void
ballfall(void)
{
    boolean gets_hit;

    gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) &&
                ((uwep == uball) ? FALSE : (boolean) rn2(5)));
    if (carried(uball)) {
        pline("Startled, you drop the iron ball.");
        unwield_silently(uball);
        if (uwep != uball)
            freeinv(uball);
    }
    if (gets_hit) {
        int dmg = rn1(7, 25);

        pline("The iron ball falls on your %s.", body_part(HEAD));
        if (uarmh) {
            if (is_metallic(uarmh)) {
                pline("Fortunately, you are wearing a hard helmet.");
                dmg = 3;
            } else if (flags.verbose)
                pline("Your %s does not protect you.", xname(uarmh));
        }
        losehp(dmg, "crunched in the head by an iron ball");
    }
}
예제 #8
0
파일: ball.c 프로젝트: Arc0re/acehack
void
ballfall()
{
	boolean gets_hit;

	gets_hit = (((uball->ox != u.ux) || (uball->oy != u.uy)) &&
		    ((uwep == uball)? FALSE : (boolean)rn2(5)));
	if (carried(uball)) {
		pline("Startled, you drop the iron ball.");
		if (uwep == uball)
			setuwep((struct obj *)0);
		if (uswapwep == uball)
			setuswapwep((struct obj *)0);
		if (uquiver == uball)
			setuqwep((struct obj *)0);;
		if (uwep != uball)
			freeinv(uball);
	}
	if(gets_hit){
		int dmg = rn1(7,25);
		pline_The("iron ball falls on your %s.",
			body_part(HEAD));
		if (uarmh) {
		    if(is_metallic(uarmh)) {
			pline("Fortunately, you are wearing a hard helmet.");
			dmg = 3;
		    } else if (flags.verbose)
			Your("%s does not protect you.", xname(uarmh));
		}
		losehp(dmg, "crunched in the head by an iron ball",
			NO_KILLER_PREFIX);
	}
}
예제 #9
0
파일: quest.c 프로젝트: FredrIQ/nhfourk
static void
chat_with_nemesis(void)
{
/* The nemesis will do most of the talking, but... */
    qt_pager(rn1(10, QT_DISCOURAGE));
    if (!Qstat(met_nemesis))
        Qstat(met_nemesis++);
}
예제 #10
0
파일: extralev.c 프로젝트: mbi/NitroHack
void makerogueghost(struct level *lev)
{
	struct monst *ghost;
	struct obj *ghostobj;
	struct mkroom *croom;
	int x,y;

	if (!lev->nroom)
	    return; /* Should never happen */
	croom = &lev->rooms[rn2(lev->nroom)];
	x = somex(croom);
	y = somey(croom);
	
	if (!(ghost = makemon(&mons[PM_GHOST], lev, x, y, NO_MM_FLAGS)))
		return;
	ghost->msleeping = 1;
	christen_monst(ghost, roguename());

	if (rn2(4)) {
		ghostobj = mksobj_at(FOOD_RATION, lev, x, y, FALSE, FALSE);
		ghostobj->quan = (long) rnd(7);
		ghostobj->owt = weight(ghostobj);
	}
	if (rn2(2)) {
		ghostobj = mksobj_at(MACE, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(3);
		if (rn2(4)) curse(ghostobj);
	} else {
		ghostobj = mksobj_at(TWO_HANDED_SWORD, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(5) - 2;
		if (rn2(4)) curse(ghostobj);
	}
	ghostobj = mksobj_at(BOW, lev, x, y, FALSE, FALSE);
	ghostobj->spe = 1;
	if (rn2(4)) curse(ghostobj);

	ghostobj = mksobj_at(ARROW, lev, x, y, FALSE, FALSE);
	ghostobj->spe = 0;
	ghostobj->quan = (long) rn1(10,25);
	ghostobj->owt = weight(ghostobj);
	if (rn2(4)) curse(ghostobj);

	if (rn2(2)) {
		ghostobj = mksobj_at(RING_MAIL, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rn2(3);
		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
		if (rn2(4)) curse(ghostobj);
	} else {
		ghostobj = mksobj_at(PLATE_MAIL, lev, x, y, FALSE, FALSE);
		ghostobj->spe = rnd(5) - 2;
		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
		if (rn2(4)) curse(ghostobj);
	}
	if (rn2(2)) {
		ghostobj = mksobj_at(FAKE_AMULET_OF_YENDOR, lev, x, y, TRUE, FALSE);
		ghostobj->known = TRUE;
	}
}
예제 #11
0
void exerchk (void) {
    int     i, mod_val;

    /*      Check out the periodic accumulations */
    exerper();

    /*      Are we ready for a test?        */
    if(moves >= next_check && !multi) {
        /*
         *  Law of diminishing returns (Part II):
         *
         *  The effects of "exercise" and "abuse" wear
         *  off over time.  Even if you *don't* get an
         *  increase/decrease, you lose some of the
         *  accumulated effects.
         */
        for(i = 0; i < A_MAX; AEXE(i++) /= 2) {

            if(ABASE(i) >= 18 || !AEXE(i)) continue;
            if(i == A_INT || i == A_CHA) continue;/* can't exercise these */

            /*
             *      Law of diminishing returns (Part III):
             *
             *      You don't *always* gain by exercising.
             *      [MRS 92/10/28 - Treat Wisdom specially for balance.]
             */
            if(rn2(AVAL) > ((i != A_WIS) ? abs(AEXE(i)*2/3) : abs(AEXE(i))))
                continue;
            mod_val = sgn(AEXE(i));

            if(adjattrib(i, mod_val, -1)) {
                /* if you actually changed an attrib - zero accumulation */
                AEXE(i) = 0;
                /* then print an explanation */
                switch(i) {
                    case A_STR: You((mod_val >0) ?
                                        "must have been exercising." :
                                        "must have been abusing your body.");
                                break;
                    case A_WIS: You((mod_val >0) ?
                                        "must have been very observant." :
                                        "haven't been paying attention.");
                                break;
                    case A_DEX: You((mod_val >0) ?
                                        "must have been working on your reflexes." :
                                        "haven't been working on reflexes lately.");
                                break;
                    case A_CON: You((mod_val >0) ?
                                        "must be leading a healthy life-style." :
                                        "haven't been watching your health.");
                                break;
                }
            }
        }
        next_check += rn1(200,800);
    }
}
예제 #12
0
/* returns 1 if it won't attack. */
int
demon_talk(struct monst *mtmp)
{
    long cash, demand, offer;

    if (uwep && uwep->oartifact == ART_EXCALIBUR) {
        pline("%s looks very angry.", Amonnam(mtmp));
        msethostility(mtmp, TRUE, TRUE);
        return 0;
    }

    /* Slight advantage given. */
    if (is_dprince(mtmp->data) && mtmp->minvis) {
        mtmp->minvis = mtmp->perminvis = 0;
        if (!Blind)
            pline("%s appears before you.", Amonnam(mtmp));
        newsym(mtmp->mx, mtmp->my);
    }
    if (youmonst.data->mlet == S_DEMON) {       /* Won't blackmail their own. */
        pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
              u.ufemale ? "Sister" : "Brother");
        if (!tele_restrict(mtmp))
            rloc(mtmp, TRUE);
        return 1;
    }
    cash = money_cnt(invent);
    /* don't bother with a custom RNG here, too much unpredictability is
       involved */
    demand = (cash * (rnd(80) + 20 * Athome)) /
        (100 * (1 + (sgn(u.ualign.type) == sgn(mtmp->data->maligntyp))));

    if (!demand) {      /* you have no gold */
        msethostility(mtmp, TRUE, TRUE);
        return 0;
    } else {
        /* make sure that the demand is unmeetable if the monster has the
           Amulet, preventing monster from being satisified and removed from
           the game (along with said Amulet...) */
        if (mon_has_amulet(mtmp))
            demand = cash + (long)rn1(1000, 40);

        pline("%s demands %ld %s for safe passage.", Amonnam(mtmp), demand,
              currency(demand));

        if ((offer = bribe(mtmp)) >= demand) {
            pline("%s vanishes, laughing about cowardly %s.", Amonnam(mtmp),
                  makeplural(mortal_or_creature(youmonst.data, FALSE)));
        } else if (offer > 0L && (long)rnd(40) > (demand - offer)) {
            pline("%s scowls at you menacingly, then vanishes.", Amonnam(mtmp));
        } else {
            pline("%s gets angry...", Amonnam(mtmp));
            msethostility(mtmp, TRUE, TRUE);
            return 0;
        }
    }
    mongone(mtmp);
    return 1;
}
예제 #13
0
void
pluslvl(boolean incr)
             	/* true iff via incremental experience growth */
{
    /*	(false for potion of gain level)      */
    register int num;

    if (!incr) You_feel("more experienced.");
    num = newhp();
    u.uhpmax += num;
    u.uhp += num;
    if (Upolyd) {
        num = rnd(8);
        u.mhmax += num;
        u.mh += num;
    }
    if (u.ulevel < urole.xlev)
        num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.lornd + urace.enadv.lornd,
                  urole.enadv.lofix + urace.enadv.lofix);
    else
        num = rn1((int)ACURR(A_WIS)/2 + urole.enadv.hirnd + urace.enadv.hirnd,
                  urole.enadv.hifix + urace.enadv.hifix);
    num = enermod(num);	/* M. Stephenson */
    if (!Role_if(PM_TOURIST)) { /* Tourists have no innate magic abilities */
        u.uenmax += num;
        u.uen += num;
    }
    if (u.ulevel < MAXULEV) {
        if (incr) {
            long tmp = newuexp(u.ulevel + 1);
            if (u.uexp >= tmp) u.uexp = tmp - 1;
        } else {
            u.uexp = newuexp(u.ulevel);
        }
        ++u.ulevel;
        if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel;
        pline("Welcome to experience level %d.", u.ulevel);
        adjabil(u.ulevel - 1, u.ulevel);	/* give new intrinsics */
        reset_rndmonst(NON_PM);		/* new monster selection */
    }
    flags.botl = 1;
}
예제 #14
0
파일: quest.c 프로젝트: FredrIQ/nhfourk
void
nemesis_speaks(void)
{
    if (!Qstat(in_battle)) {
        if (Uhave_questart)
            qt_pager(QT_NEMWANTSIT);
        else if (Qstat(made_goal) == 1 || !Qstat(met_nemesis))
            qt_pager(QT_FIRSTNEMESIS);
        else if (Qstat(made_goal) < 4)
            qt_pager(QT_NEXTNEMESIS);
        else if (Qstat(made_goal) < 7)
            qt_pager(QT_OTHERNEMESIS);
        else if (!rn2(5))
            qt_pager(rn1(10, QT_DISCOURAGE));
        if (Qstat(made_goal) < 7)
            Qstat(made_goal)++;
        Qstat(met_nemesis) = TRUE;
    } else /* he will spit out random maledictions */ if (!rn2(5))
        qt_pager(rn1(10, QT_DISCOURAGE));
}
예제 #15
0
파일: makemon.c 프로젝트: msharov/bsd-games
void rloc(struct monst *mtmp)
{
    int tx, ty;
    do {
	tx = rn1(COLNO - 3, 2);
	ty = rn2(ROWNO);
    } while (!goodpos(tx, ty));
    mtmp->mx = tx;
    mtmp->my = ty;
    pmon(mtmp);
}
예제 #16
0
파일: priest.c 프로젝트: FredrIQ/nhfourk
/*
 * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
 */
int
pri_move(struct monst *priest)
{
    xchar gx, gy, omx, omy;
    schar temple;
    boolean avoid = TRUE;

    omx = priest->mx;
    omy = priest->my;

    if (!histemple_at(priest, omx, omy))
        return -1;

    temple = CONST_EPRI(priest)->shroom;

    gx = CONST_EPRI(priest)->shrpos.x;
    gy = CONST_EPRI(priest)->shrpos.y;

    gx += rn1(3, -1);   /* mill around the altar */
    gy += rn1(3, -1);

    if (!priest->mpeaceful || (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
        if (monnear(priest, u.ux, u.uy)) {
            if (Displaced)
                pline("Your displaced image doesn't fool %s!", mon_nam(priest));
            mattacku(priest);
            return 0;
        } else if (strchr(u.urooms, temple)) {
            /* chase player if inside temple & can sense him */
            if (m_cansenseu(priest)) {
                gx = u.ux;
                gy = u.uy;
            }
            avoid = FALSE;
        }
    } else if (Invis)
        avoid = FALSE;

    return move_special(priest, FALSE, TRUE, FALSE, avoid, omx, omy, gx, gy);
}
예제 #17
0
int
dlord(aligntyp atyp)
{
    int tryct, pm;

    for (tryct = 0; tryct < 20; tryct++) {
        pm = rn1(PM_YEENOGHU + 1 - PM_JUIBLEX, PM_JUIBLEX);
        if (!(mvitals[pm].mvflags & G_GONE) &&
            (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
            return pm;
    }
    return ndemon(&u.uz, atyp); /* approximate */
}
예제 #18
0
int
dprince(aligntyp atyp)
{
    int tryct, pm;

    for (tryct = 0; tryct < 20; tryct++) {
        pm = rn1(PM_DEMOGORGON + 1 - PM_ORCUS, PM_ORCUS);
        if (!(mvitals[pm].mvflags & G_GONE) &&
            (atyp == A_NONE || sgn(mons[pm].maligntyp) == sgn(atyp)))
            return pm;
    }
    return dlord(atyp); /* approximate */
}
예제 #19
0
void rloc(struct monst *mtmp)
{
    int tx;
    int ty;
    char ch = mtmp->data->mlet;

#ifndef NOWORM
    if((ch == 'w') && (mtmp->mx)) {
        /* Do not relocate worms */
        return;
    }
#endif

    tx = rn1(COLNO - 3, 2);
    ty = rn2(ROWNO);

    while(goodpos(tx, ty) == 0) {
        tx = rn1(COLNO - 3, 2);
        ty = rn2(ROWNO);
    }

    mtmp->mx = tx;
    mtmp->my = ty;

    if(u.ustuck == mtmp) {
        if(u.uswallow != 0) {
            u.ux = tx;
            u.uy = ty;
            docrt();
        }
        else {
            u.ustuck = 0;
        }
    }

    pmon(mtmp);
}
예제 #20
0
void poisoned(char *string, char *pname)
{
    if(Blind != 0) {
        pline("It was poisoned.");
    }
    else {
        pline("The %s was poisoned!", string);
    }

    if(Poison_resistance != 0) {
        pline("The poison doesn't seem to affect you.");

        return;
    }

    switch(rnd(6)) {
    case 1:
        u.uhp = -1;
        
        break;
    case 2:
    case 3:
    case 4:
        losestr(rn1(3, 3));

        break;
    case 5:
    case 6:
        losehp(rn1(10, 6), pname);

        return;
    }

    if(u.uhp < 1) {
        killer = pname;
    }
}
예제 #21
0
/* return TRUE if successful, FALSE if not */
boolean
rloc(struct monst *mtmp,        /* mx==0 implies migrating monster arrival */
     boolean suppress_impossible)
{
    int x, y, trycount;

    if (mtmp == u.usteed) {
        tele();
        return TRUE;
    }

    if (mtmp->iswiz && mtmp->mx) {      /* Wizard, not just arriving */
        if (!In_W_tower(u.ux, u.uy, &u.uz))
            x = level->upstair.sx, y = level->upstair.sy;
        else if (!level->dnladder.sx)   /* bottom level of tower */
            x = level->upladder.sx, y = level->upladder.sy;
        else
            x = level->dnladder.sx, y = level->dnladder.sy;
        /* if the wiz teleports away to heal, try the up staircase, to block
           the player's escaping before he's healed (deliberately use `goodpos' 
           rather than `rloc_pos_ok' here) */
        if (goodpos(level, x, y, mtmp, 0))
            goto found_xy;
    }

    trycount = 0;
    do {
        x = rn1(COLNO - 3, 2);
        y = rn2(ROWNO);
        if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
            : goodpos(level, x, y, mtmp, 0))
            goto found_xy;
    } while (++trycount < 1000);

    /* last ditch attempt to find a good place */
    for (x = 2; x < COLNO - 1; x++)
        for (y = 0; y < ROWNO; y++)
            if (goodpos(level, x, y, mtmp, 0))
                goto found_xy;

    /* level either full of monsters or somehow faulty */
    if (!suppress_impossible)
        impossible("rloc(): couldn't relocate monster");
    return FALSE;

found_xy:
    rloc_to(mtmp, x, y);
    return TRUE;
}
예제 #22
0
파일: steed.c 프로젝트: FredrIQ/nhfourk
/* The player kicks or whips the steed */
void
kick_steed(void)
{
    char He[4];

    if (!u.usteed)
        return;

    /* [ALI] Various effects of kicking sleeping/paralyzed steeds */
    if (u.usteed->msleeping || !u.usteed->mcanmove) {
        /* We assume a message has just been output of the form "You kick
           <steed>." */
        strcpy(He, mhe(u.usteed));
        *He = highc(*He);
        if ((u.usteed->mcanmove || u.usteed->mfrozen) && !rn2(2)) {
            if (u.usteed->mcanmove)
                u.usteed->msleeping = 0;
            else if (u.usteed->mfrozen > 2)
                u.usteed->mfrozen -= 2;
            else {
                u.usteed->mfrozen = 0;
                u.usteed->mcanmove = 1;
            }
            if (u.usteed->msleeping || !u.usteed->mcanmove)
                pline("%s stirs.", He);
            else
                pline("%s rouses %sself!", He, mhim(u.usteed));
        } else
            pline("%s does not respond.", He);
        return;
    }

    /* Make the steed less tame and check if it resists */
    if (u.usteed->mtame)
        u.usteed->mtame--;
    if (!u.usteed->mtame && u.usteed->mleashed)
        m_unleash(u.usteed, TRUE);
    if (!u.usteed->mtame ||
            (u.ulevel + u.usteed->mtame < rnd(MAXULEV / 2 + 5))) {
        newsym(u.usteed->mx, u.usteed->my);
        dismount_steed(DISMOUNT_THROWN);
        return;
    }

    pline("%s gallops!", Monnam(u.usteed));
    u.ugallop += rn1(20, 30);
    return;
}
예제 #23
0
파일: hack.zap.c 프로젝트: blakeney/slack
static void
rloco(struct obj *obj)
{
	int tx,ty,otx,oty;

	otx = obj->ox;
	oty = obj->oy;
	do {
		tx = rn1(COLNO-3,2);
		ty = rn2(ROWNO);
	} while(!goodpos(tx,ty));
	obj->ox = tx;
	obj->oy = ty;
	if(cansee(otx,oty))
		newsym(otx,oty);
}
예제 #24
0
파일: mkobj.c 프로젝트: DanielT/NitroHack
/* select a random, common monster type */
int rndmonnum(const d_level *dlev)
{
	const struct permonst *ptr;
	int i;

	/* Plan A: get a level-appropriate common monster */
	ptr = rndmonst(dlev);
	if (ptr) return monsndx(ptr);

	/* Plan B: get any common monster */
	do {
	    i = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
	    ptr = &mons[i];
	} while ((ptr->geno & G_NOGEN) || (!In_hell(dlev) && (ptr->geno & G_HELL)));

	return i;
}
예제 #25
0
static void
init_fill(struct level *lev, schar bg_typ, schar fg_typ)
{
    int i, j;
    long limit, count;

    limit = (WIDTH * HEIGHT * 2) / 5;
    count = 0;
    while (count < limit) {
        i = rn1(WIDTH - 1, 2);
        j = rnd(HEIGHT - 1);
        if (lev->locations[i][j].typ == bg_typ) {
            lev->locations[i][j].typ = fg_typ;
            count++;
        }
    }
}
예제 #26
0
void rloco(struct obj *obj)
{
	xchar tx, ty, otx, oty;
	boolean restricted_fall;
	int try_limit = 4000;

	if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
	    if (revive_corpse(obj)) return;
	}

	obj_extract_self(obj);
	otx = obj->ox;
	oty = obj->oy;
	restricted_fall = (otx == 0 && level->dndest.lx);
	do {
	    tx = rn1(COLNO-3,2);
	    ty = rn2(ROWNO);
	    if (!--try_limit) break;
	} while (!goodpos(level, tx, ty, NULL, 0) ||
		/* bug: this lacks provision for handling the Wizard's tower */
		 (restricted_fall &&
		  (!within_bounded_area(tx, ty, level->dndest.lx, level->dndest.ly,
						level->dndest.hx, level->dndest.hy) ||
		   (level->dndest.nlx &&
		    within_bounded_area(tx, ty, level->dndest.nlx, level->dndest.nly,
						level->dndest.nhx, level->dndest.nhy)))));

	if (flooreffects(obj, tx, ty, "fall")) {
	    return;
	} else if (otx == 0 && oty == 0) {
	    ;	/* fell through a trap door; no update of old loc needed */
	} else {
	    if (costly_spot(otx, oty)
	      && (!costly_spot(tx, ty) ||
		  !strchr(in_rooms(level, tx, ty, 0), *in_rooms(level, otx, oty, 0)))) {
		if (costly_spot(u.ux, u.uy) &&
			    strchr(u.urooms, *in_rooms(level, otx, oty, 0)))
		    addtobill(obj, FALSE, FALSE, FALSE);
		else stolen_value(obj, otx, oty, FALSE, FALSE);
	    }
	    newsym(otx, oty);	/* update old location */
	}
	place_object(obj, level, tx, ty);
	newsym(tx, ty);
}
예제 #27
0
STATIC_OVL void
init_fill(schar bg_typ, schar fg_typ)
{
    register int i,j;
    long limit, count;

    if (fg_typ >= MAX_TYPE) return;

    limit = (WIDTH * HEIGHT * 2) / 5;
    count = 0;
    while(count < limit) {
        i = rn1(WIDTH-1, 2);
        j = rnd(HEIGHT-1);
        if (levl[i][j].typ == bg_typ) {
            levl[i][j].typ = fg_typ;
            count++;
        }
    }
}
예제 #28
0
파일: fountain.c 프로젝트: saihack/NetHack
static void
dowatersnakes() /* Fountain of snakes! */
{
    register int num = rn1(5,2);
    struct monst *mtmp;

    if (!(mons[PM_WATER_MOCCASIN].geno & (G_GENOD | G_EXTINCT))) {
	if (!Blind)
	    pline("An endless stream of %s pours forth!",
		  Hallucination ? makeplural(rndmonnam()) : "snakes");
	else
	    You("hear something hissing!");
	while(num-- > 0)
	    if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy)) &&
	       t_at(mtmp->mx, mtmp->my))
		(void) mintrap(mtmp);
    } else
	pline("The fountain bubbles furiously for a moment, then calms.");
}
예제 #29
0
파일: worm.c 프로젝트: FredrIQ/fiqhack
/*
 *  worm_move()
 *
 *  Check for mon->wormno before calling this function!
 *
 *  Move the worm.  Maybe grow.
 */
void
worm_move(struct monst *worm)
{
    struct wseg *seg, *new_seg; /* new segment */
    int wnum = worm->wormno;    /* worm number */


/*  if (!wnum) return;  bullet proofing */

    /* 
     *  Place a segment at the old worm head.  The head has already moved.
     */
    seg = level->wheads[wnum];
    place_worm_seg(worm, seg->wx, seg->wy);
    newsym(seg->wx, seg->wy);   /* display the new segment */

    /* 
     *  Create a new dummy segment head and place it at the end of the list.
     */
    new_seg = malloc(sizeof (struct wseg));
    new_seg->wx = worm->mx;
    new_seg->wy = worm->my;
    new_seg->nseg = NULL;
    seg->nseg = new_seg;        /* attach it to the end of the list */
    level->wheads[wnum] = new_seg;      /* move the end pointer */


    if (level->wgrowtime[wnum] <= moves) {
        if (!level->wgrowtime[wnum])
            level->wgrowtime[wnum] = moves + rnd(5);
        else
            level->wgrowtime[wnum] += rn1(15, 3);
        worm->mhp += 3;
        if (worm->mhp > MHPMAX)
            worm->mhp = MHPMAX;
        if (worm->mhp > worm->mhpmax)
            worm->mhpmax = worm->mhp;
    } else
        /* The worm doesn't grow, so the last segment goes away. */
        shrink_worm(wnum);
}
예제 #30
0
/*
 * called with [x,y] = coordinates;
 *	[0,0] means anyplace
 *	[u.ux,u.uy] means: call mnexto (if !in_mklev)
 *
 *	In case we make an Orc or killer bee, we make an entire horde (swarm);
 *	note that in this case we return only one of them (the one at [x,y]).
 */
struct monst *
makemon(struct permonst *ptr, int x, int y)
{
	struct monst *mtmp;
	int tmp, ct;
	boolean anything = (!ptr);
	extern boolean in_mklev;

	if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
	if(ptr){
		if(strchr(fut_geno, ptr->mlet)) return((struct monst *) 0);
	} else {
		ct = CMNUM - strlen(fut_geno);
		if(strchr(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
		if(strchr(fut_geno, '@')) ct++;
		if(ct <= 0) return(0); 		  /* no more monsters! */
		tmp = rn2(ct*dlevel/24 + 7);
		if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
		if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
		for(ct = 0; ct < CMNUM; ct++){
			ptr = &mons[ct];
			if(strchr(fut_geno, ptr->mlet))
				continue;
			if(!tmp--) goto gotmon;
		}
		panic("makemon?");
	}
gotmon:
	mtmp = newmonst(ptr->pxlth);
	*mtmp = zeromonst;	/* clear all entries in structure */
	for(ct = 0; ct < ptr->pxlth; ct++)
		((char *) &(mtmp->mextra[0]))[ct] = 0;
	mtmp->nmon = fmon;
	fmon = mtmp;
	mtmp->m_id = flags.ident++;
	mtmp->data = ptr;
	mtmp->mxlth = ptr->pxlth;
	if(ptr->mlet == 'D') mtmp->mhpmax = mtmp->mhp = 80;
	else if(!ptr->mlevel) mtmp->mhpmax = mtmp->mhp = rnd(4);
	else mtmp->mhpmax = mtmp->mhp = d(ptr->mlevel, 8);
	mtmp->mx = x;
	mtmp->my = y;
	mtmp->mcansee = 1;
	if(ptr->mlet == 'M'){
		mtmp->mimic = 1;
		mtmp->mappearance = ']';
	}
	if(!in_mklev) {
		if(x == u.ux && y == u.uy && ptr->mlet != ' ')
			mnexto(mtmp);
		if(x == 0 && y == 0)
			rloc(mtmp);
	}
	if(ptr->mlet == 's' || ptr->mlet == 'S') {
		mtmp->mhide = mtmp->mundetected = 1;
		if(in_mklev)
		if(mtmp->mx && mtmp->my)
			(void) mkobj_at(0, mtmp->mx, mtmp->my);
	}
	if(ptr->mlet == ':') {
		mtmp->cham = 1;
		(void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
	}
	if(ptr->mlet == 'I' || ptr->mlet == ';')
		mtmp->minvis = 1;
	if(ptr->mlet == 'L' || ptr->mlet == 'N'
	    || (in_mklev && strchr("&w;", ptr->mlet) && rn2(5))
	) mtmp->msleep = 1;

#ifndef NOWORM
	if(ptr->mlet == 'w' && getwn(mtmp))
		initworm(mtmp);
#endif /* NOWORM */

	if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
		coord mm;
		int cnt = rnd(10);
		mm.x = x;
		mm.y = y;
		while(cnt--) {
			mm = enexto(mm.x, mm.y);
			(void) makemon(ptr, mm.x, mm.y);
		}
	}

	return(mtmp);
}