示例#1
0
// Helper function which adds an new enemy while checking
// for bad places
bool new_enemy(int &ex, int &ey) {
	// Add a new enemy
	ENEMY e;
	e.clear();

	// Check for bad places
	int x = RAND(0, MAP_W-1);
	int y = RAND(0, MAP_H-1);
	int counter = 0;
	while((!can_teleport(x, y) || is_player_close(x,y)) && counter < 10000) {
		x = RAND(0, MAP_W-1);
		y = RAND(0, MAP_H-1);
		counter++;
	}

	if(counter >= 10000)
		return false;

	e.x = x;
	e.y = y;
	ex = x;
	ey = y;
	e.tx = e.x;
	e.ty = e.y;
	e.type = RAND(0,2);
	e.alive = true;
	enemylist.push_back(e);
	return true;
}
示例#2
0
void
stealamulet(struct monst *mtmp)
{
    struct obj *otmp = NULL;
    int real = 0, fake = 0;

    /* select the artifact to steal */
    if (u.uhave.amulet) {
        real = AMULET_OF_YENDOR;
        fake = FAKE_AMULET_OF_YENDOR;
    } else if (u.uhave.questart) {
        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (is_quest_artifact(otmp))
                break;
        if (!otmp)
            return;     /* should we panic instead? */
    } else if (u.uhave.bell) {
        real = BELL_OF_OPENING;
        fake = BELL;
    } else if (u.uhave.book) {
        real = SPE_BOOK_OF_THE_DEAD;
    } else if (u.uhave.menorah) {
        real = CANDELABRUM_OF_INVOCATION;
    } else
        return; /* you have nothing of special interest */

    if (!otmp) {
        /* If we get here, real and fake have been set up. */
        for (otmp = invent; otmp; otmp = otmp->nobj)
            if (otmp->otyp == real || (otmp->otyp == fake && !mtmp->iswiz))
                break;
    }

    if (otmp) { /* we have something to snatch */
        if (otmp->owornmask)
            remove_worn_item(otmp, TRUE);
        freeinv(otmp);
        /* mpickobj wont merge otmp because none of the above things to steal
           are mergable */
        mpickobj(mtmp, otmp);   /* may merge and free otmp */
        pline("%s stole %s!", Monnam(mtmp), doname(otmp));
        if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
            rloc(mtmp, FALSE);
    }
}
示例#3
0
文件: spell.c 项目: FredrIQ/nhfourk
boolean
supernatural_ability_available(int spid)
{
    switch (spid) {
    case SPID_PRAY:
        return TRUE;
    case SPID_TURN: /* 3.4.3 doturn: "Knights & Priest(esse)s only please" */
        return Role_if(PM_PRIEST) || Role_if(PM_KNIGHT);
    case SPID_RLOC:
        return Teleportation &&
            (u.ulevel >= (Role_if(PM_WIZARD) ? 8 : 12) ||
             can_teleport(youmonst.data));
    case SPID_JUMP:
        return Jumping;
    case SPID_MONS:
        return has_polyform_ability(youmonst.data, NULL);
    default:
        impossible("Unknown supernatural ability %d", spid);
        return FALSE;
    }
}
示例#4
0
int
dotele(void)
{
    struct trap *trap;

    trap = t_at(level, u.ux, u.uy);
    if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
        trap = 0;

    if (trap) {
        if (trap->once) {
            pline("This is a vault teleport, usable once only.");
            if (yn("Jump in?") == 'n')
                trap = 0;
            else {
                deltrap(level, trap);
                newsym(u.ux, u.uy);
            }
        }
        if (trap)
            pline("You %s onto the teleportation trap.",
                  locomotion(youmonst.data, "jump"));
    }
    if (!trap) {
        boolean castit = FALSE;
        int sp_no = 0, energy = 0;

        if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
                               && !can_teleport(youmonst.data))) {
            /* Try to use teleport away spell. */
            if (objects[SPE_TELEPORT_AWAY].oc_name_known && !Confusion)
                for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
                    if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) {
                        castit = TRUE;
                        break;
                    }
            if (!wizard) {
                if (!castit) {
                    if (!Teleportation)
                        pline("You don't know that spell.");
                    else
                        pline("You are not able to teleport at will.");
                    return 0;
                }
            }
        }

        if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
            if (!wizard) {
                pline("You lack the strength %s.",
                      castit ? "for a teleport spell" : "to teleport");
                return 1;
            }
        }

        energy = objects[SPE_TELEPORT_AWAY].oc_level * 7 / 2 - 2;
        if (u.uen <= energy) {
            if (wizard)
                energy = u.uen;
            else {
                pline("You lack the energy %s.",
                      castit ? "for a teleport spell" : "to teleport");
                return 1;
            }
        }

        if (check_capacity("Your concentration falters from carrying so much."))
            return 1;

        if (castit) {
            exercise(A_WIS, TRUE);
            if (spelleffects(sp_no, TRUE))
                return 1;
            else if (!wizard)
                return 0;
        } else {
            u.uen -= energy;
            iflags.botl = 1;
        }
    }

    if (next_to_u()) {
        if (trap && trap->once)
            vault_tele();
        else
            tele();
        next_to_u();
    } else {
        pline("You shudder for a moment.");
        return 0;
    }
    if (!trap)
        morehungry(100);
    return 1;
}
示例#5
0
文件: prop.c 项目: FredrIQ/nethack4
/* Returns an object slot mask giving all the reasons why the given
   player/monster might have the given property, limited by "reasons", an object
   slot mask (W_EQUIP, INTRINSIC, and ANY_PROPERTY are the most likely values
   here, but you can specify slots individually if you like). */
unsigned
m_has_property(const struct monst *mon, enum youprop property,
               unsigned reasons, boolean even_if_blocked)
{
    unsigned rv = 0;
    struct obj *otmp;

    /* The general case for equipment */
    rv |= mworn_extrinsic(mon, property);

    if (mon == &youmonst) {
        /* Intrinsics */
        if (u.uintrinsic[property] & TIMEOUT)
            rv |= W_MASK(os_timeout);
        rv |= u.uintrinsic[property] & (INTRINSIC | I_SPECIAL);

        /* Birth options */
        if (property == BLINDED && flags.permablind)
            rv |= W_MASK(os_birthopt);
        if (property == HALLUC && flags.permahallu)
            rv |= W_MASK(os_birthopt);
        if (property == UNCHANGING && flags.polyinit_mnum != -1)
            rv |= W_MASK(os_birthopt);

    } else {
        /* Monster tempraries are boolean flags.

           TODO: Monsters with no eyes are not considered blind. This doesn't
           make much sense. However, changing it would be a major balance
           change (due to Elbereth), and so it has been left alone for now. */
        if (property == BLINDED && (!mon->mcansee || mon->mblinded))
            rv |= W_MASK(os_timeout);
        if (property == FAST && mon->mspeed == MFAST)
            rv |= (mon->permspeed == FAST ?
                   W_MASK(os_polyform) : W_MASK(os_outside));
        if (property == INVIS && mon->perminvis && !pm_invisible(mon->data))
            rv |= W_MASK(os_outside);
        if (property == STUNNED && mon->mstun)
            rv |= W_MASK(os_timeout);
        if (property == CONFUSION && mon->mconf)
            rv |= W_MASK(os_timeout);
    }


    /* Polyform / monster intrinsic */
    /* TODO: Change the monster data code into something that doesn't require a
       giant switch statement or ternary chain to get useful information from
       it. We use a ternary chain here because it cuts down on repetitive code
       and so is easier to read. */
    if (property == FIRE_RES     ? resists_fire(mon)                     :
        property == COLD_RES     ? resists_cold(mon)                     :
        property == SLEEP_RES    ? resists_sleep(mon)                    :
        property == DISINT_RES   ? resists_disint(mon)                   :
        property == SHOCK_RES    ? resists_elec(mon)                     :
        property == POISON_RES   ? resists_poison(mon)                   :
        property == DRAIN_RES    ? resists_drli(mon)                     :
        property == SICK_RES     ? mon->data->mlet == S_FUNGUS ||
                                   mon->data == &mons[PM_GHOUL]          :
        property == ANTIMAGIC    ? resists_magm(mon)                     :
        property == ACID_RES     ? resists_acid(mon)                     :
        property == STONE_RES    ? resists_ston(mon)                     :
        property == STUNNED      ? u.umonnum == PM_STALKER ||
                                   mon->data->mlet == S_BAT              :
        property == BLINDED      ? !haseyes(mon->data)                   :
        property == HALLUC       ? Upolyd && dmgtype(mon->data, AD_HALU) :
        property == SEE_INVIS    ? perceives(mon->data)                  :
        property == TELEPAT      ? telepathic(mon->data)                 :
        property == INFRAVISION  ? infravision(mon->data)                :
        /* Note: This one assumes that there's no way to permanently turn
           visible when you're in stalker form (i.e. mummy wrappings only). */
        property == INVIS        ? pm_invisible(mon->data)               :
        property == TELEPORT     ? can_teleport(mon->data)               :
        property == LEVITATION   ? is_floater(mon->data)                 :
        property == FLYING       ? is_flyer(mon->data)                   :
        property == SWIMMING     ? is_swimmer(mon->data)                 :
        property == PASSES_WALLS ? passes_walls(mon->data)               :
        property == REGENERATION ? regenerates(mon->data)                :
        property == REFLECTING   ? mon->data == &mons[PM_SILVER_DRAGON]  :
        property == TELEPORT_CONTROL  ? control_teleport(mon->data)      :
        property == MAGICAL_BREATHING ? amphibious(mon->data)            :
        0)
        rv |= W_MASK(os_polyform);

    if (mon == &youmonst) {
        /* External circumstances */
        if (property == BLINDED && u_helpless(hm_unconscious))
            rv |= W_MASK(os_circumstance);

        /* Riding */
        if (property == FLYING && u.usteed && is_flyer(u.usteed->data))
            rv |= W_MASK(os_saddle);
        if (property == SWIMMING && u.usteed && is_swimmer(u.usteed->data))
            rv |= W_MASK(os_saddle);
    }

    /* Overrides */
    if (!even_if_blocked) {
        if (property == BLINDED) {
            for (otmp = m_minvent(mon); otmp; otmp = otmp->nobj)
                if (otmp->oartifact == ART_EYES_OF_THE_OVERWORLD &&
                    otmp->owornmask & W_MASK(os_tool))
                    rv &= (unsigned)(W_MASK(os_circumstance) |
                                     W_MASK(os_birthopt));
        }

        if (property == WWALKING && Is_waterlevel(m_mz(mon)))
            rv &= (unsigned)(W_MASK(os_birthopt));
        if (mworn_blocked(mon, property))
            rv &= (unsigned)(W_MASK(os_birthopt));
    }

    return rv & reasons;
}