Ejemplo n.º 1
0
/* Recursively search obj for an object made of specified material and return 1st found */
static struct obj *o_material(struct obj *obj, unsigned material)
{
    struct obj* otmp;
    struct obj *temp;

    if (objects[obj->otyp].oc_material == material) return obj;

    if (Has_contents(obj)) {
	for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
	    if (objects[otmp->otyp].oc_material == material) return otmp;
	    else if (Has_contents(otmp) && (temp = o_material(otmp, material)))
		return temp;
    }
    return NULL;
}
Ejemplo n.º 2
0
/* Recursively search obj for an object in class oclass and return 1st found */
static struct obj *o_in(struct obj *obj, char oclass)
{
    struct obj *otmp;
    struct obj *temp;

    if (obj->oclass == oclass) return obj;

    if (Has_contents(obj)) {
	for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
	    if (otmp->oclass == oclass) return otmp;
	    else if (Has_contents(otmp) && (temp = o_in(otmp, oclass)))
		return temp;
    }
    return NULL;
}
Ejemplo n.º 3
0
static dbref 
parse_linkable_room(dbref player, char *room_name)
{
    dbref room;

    init_match(player, room_name, NOTYPE);
    match_everything(MAT_NO_EXITS | MAT_NUMERIC | MAT_HOME);
    room = match_result();

    /* HOME is always linkable */

    if (room == HOME)
	return HOME;

    /* Make sure we can link to it */

    if (!Good_obj(room)) {
	notify_quiet(player, "That's not a valid object.");
	return NOTHING;
    } else if (!Has_contents(room) || !Linkable(player, room)) {
	notify_quiet(player, "You can't link to that.");
	return NOTHING;
    } else {
	return room;
    }
}
Ejemplo n.º 4
0
static void do_dknown_of(struct obj *obj)
{
    struct obj *otmp;

    obj->dknown = 1;
    if (Has_contents(obj)) {
	for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
	    do_dknown_of(otmp);
    }
}
Ejemplo n.º 5
0
long hidden_gold(void) {
    long value = 0L;
    struct obj *obj;

    for (obj = invent; obj; obj = obj->nobj)
        if (Has_contents(obj))
            value += contained_gold(obj);
    /* unknown gold stuck inside statues may cause some consternation... */

    return (value);
}
Ejemplo n.º 6
0
void migrate_to_level(
	struct monst *mtmp,
	xchar tolev,	/* destination level */
	xchar xyloc,	/* MIGR_xxx destination xy location: */
	coord *cc)	/* optional destination coordinates */
{
	struct obj *obj;
	d_level new_lev;
	xchar xyflags;
	int num_segs = 0;	/* count of worm segments */

	if (mtmp->isshk)
	    set_residency(mtmp, TRUE);

	if (mtmp->wormno) {
	    int cnt;
	  /* **** NOTE: worm is truncated to # segs = max wormno size **** */
	    cnt = count_wsegs(mtmp);
	    num_segs = min(cnt, MAX_NUM_WORMS - 1);
	    wormgone(mtmp);
	}

	/* set minvent's obj->no_charge to 0 */
	for (obj = mtmp->minvent; obj; obj = obj->nobj) {
	    if (Has_contents(obj))
		picked_container(obj);	/* does the right thing */
	    obj->no_charge = 0;
	}

	if (mtmp->mleashed) {
		mtmp->mtame--;
		m_unleash(mtmp, TRUE);
	}
	relmon(mtmp);
	mtmp->nmon = migrating_mons;
	migrating_mons = mtmp;
	newsym(mtmp->mx,mtmp->my);

	new_lev.dnum = ledger_to_dnum((xchar)tolev);
	new_lev.dlevel = ledger_to_dlev((xchar)tolev);
	/* overload mtmp->[mx,my], mtmp->[mux,muy], and mtmp->mtrack[] as */
	/* destination codes (setup flag bits before altering mx or my) */
	xyflags = (depth(&new_lev) < depth(&u.uz));	/* 1 => up */
	if (In_W_tower(mtmp->mx, mtmp->my, &u.uz)) xyflags |= 2;
	mtmp->wormno = num_segs;
	mtmp->mlstmv = moves;
	mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx;
	mtmp->mtrack[1].y = cc ? cc->y : mtmp->my;
	mtmp->mtrack[0].x = xyloc;
	mtmp->mtrack[0].y = xyflags;
	mtmp->mux = new_lev.dnum;
	mtmp->muy = new_lev.dlevel;
	mtmp->mx = mtmp->my = 0;	/* this implies migration */
}
Ejemplo n.º 7
0
void match_possession(void)
{
    if (md.confidence >= CON_DBREF)
    {
        return;
    }
    if (Good_obj(md.player) && Has_contents(md.player))
    {
        match_list(Contents(md.player), CON_LOCAL);
    }
}
Ejemplo n.º 8
0
Archivo: save.c Proyecto: mbi/NitroHack
static void free_objchn(struct obj *otmp)
{
	struct obj *otmp2;
	while (otmp) {
	    otmp2 = otmp->nobj;
	    if (Has_contents(otmp))
		free_objchn(otmp->cobj);
	    
	    otmp->where = OBJ_FREE;	/* set to free so dealloc will work */
	    otmp->timed = 0;	/* not timed any more */
	    otmp->lamplit = 0;	/* caller handled lights */
	    dealloc_obj(otmp);
	    otmp = otmp2;
	}
}
Ejemplo n.º 9
0
Archivo: save.c Proyecto: mbi/NitroHack
static void saveobjchn(struct memfile *mf, struct obj *otmp)
{
	int count = 0;
	struct obj *otmp2;
	
	mfmagic_set(mf, OBJCHAIN_MAGIC);
	for (otmp2 = otmp; otmp2; otmp2 = otmp2->nobj)
	    count++;
	mwrite32(mf, count);
	
	while (otmp) {
	    save_obj(mf, otmp);
	    if (Has_contents(otmp))
		saveobjchn(mf, otmp->cobj);
	    
	    otmp = otmp->nobj;
	}
}
Ejemplo n.º 10
0
Archivo: glue.c Proyecto: chazu/btmux
/* Main entry point */
int HandledCommand(dbref player, dbref loc, char *command)
{
	dbref curr, temp;

	if(Slave(player))
		return 0;
	if(strlen(command) > (LBUF_SIZE - MBUF_SIZE))
		return 0;
	if(OkayHcode(player) && HandledCommand_sub(player, player, command))
		return 1;
	if(OkayHcode(loc) && HandledCommand_sub(player, loc, command))
		return 1;
	SAFE_DOLIST(curr, temp, Contents(player)) {
		if(OkayHcode(curr))
			if(HandledCommand_sub(player, curr, command))
				return 1;
#if 0							/* Recursion is evil ; let's not do that, this time */
		if(Has_contents(curr))
			if(HandledCommand_contents(player, curr, command))
				return 1;
#endif
	}
	return 0;
}
Ejemplo n.º 11
0
void 
do_link(dbref player, dbref cause, int key, char *what, char *where)
{
    dbref thing, room;
    char *buff;
    int nomtest;

    if ( (key & SIDEEFFECT) && !SideFX(player) ) {
       notify(player, "#-1 FUNCTION DISABLED");
       return;
    }

    /* Find the thing to link */

    init_match(player, what, TYPE_EXIT);
    match_everything(0);
    thing = noisy_match_result();
    if (thing == NOTHING)
	return;

    nomtest = ((NoMod(thing) && !WizMod(player)) || (DePriv(player,Owner(thing),DP_MODIFY,POWER7,NOTHING) && (Owner(thing) != Owner(player))) || (Backstage(player) && NoBackstage(thing) && !Immortal(player)));
    /* Allow unlink if where is not specified */

    if (!where || !*where) {
      if (!nomtest)
	do_unlink(player, cause, key, what);
      else
	notify(player,"Permission denied.");
      return;
    }
    switch (Typeof(thing)) {
    case TYPE_EXIT:

	/* Set destination */

	room = parse_linkable_room(player, where);
	if (room != NOTHING) {
	  if (!nomtest)
	    link_exit(player, thing, room, key);
	  else
	    notify(player,"Permission denied.");
	}
	break;
    case TYPE_PLAYER:
    case TYPE_THING:

	/* Set home */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	init_match(player, where, NOTYPE);
	match_everything(MAT_NO_EXITS);
	room = noisy_match_result();
	if (!Good_obj(room))
	    break;
	if (!Has_contents(room)) {
	    notify_quiet(player, "Can't link to an exit.");
	    break;
	}
	if (!can_set_home(player, thing, room) ||
	    !could_doit(player, room, A_LLINK, 1, 0)) {
	    notify_quiet(player, "Permission denied.");
	} else if (room == HOME) {
	    notify_quiet(player, "Can't set home to home.");
	} else {
	    s_Home(thing, room);
	    if (!(Quiet(player) || (key & SIDEEFFECT)) )
		notify_quiet(player, "Home set.");
	}
	break;
    case TYPE_ROOM:

	/* Set dropto */

	if (!Controls(player, thing) || nomtest) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}
	room = parse_linkable_room(player, where);
	if (!Good_obj(room) && (room != HOME)) {
	    notify_quiet(player, "Permission denied.");
	    break;
	}

	if ((room != HOME) && !isRoom(room)) {
	    notify_quiet(player, "That is not a room!");
	} else if ((room != HOME) &&
		   ((!controls(player, room) && !Link_ok(room)) ||
		    !could_doit(player, room, A_LLINK, 1, 0))) {
	    notify_quiet(player, "Permission denied.");
	} else {
	    s_Dropto(thing, room);
	    if (!Quiet(player))
		notify_quiet(player, "Dropto set.");
	}
	break;
    default:
	STARTLOG(LOG_BUGS, "BUG", "OTYPE")
	    buff = alloc_mbuf("do_link.LOG.badtype");
	sprintf(buff, "Strange object type: object #%d = %d",
		thing, Typeof(thing));
	log_text(buff);
	free_mbuf(buff);
	ENDLOG
    }
}
Ejemplo n.º 12
0
/*
 * Allocate a new and possibly larger storage space for an obj.
 */
struct obj *
realloc_obj(struct obj *obj, int oextra_size, void *oextra_src, int oname_size,
            const char *name)
{
    struct obj *otmp;

    otmp = newobj(oextra_size + oname_size, obj);

    if (oextra_size) {
        if (oextra_src)
            memcpy(otmp->oextra, oextra_src, oextra_size);
    } else {
        otmp->oattached = OATTACHED_NOTHING;
    }
    otmp->oxlth = oextra_size;
    otmp->onamelth = oname_size;

    if (oname_size) {
        if (name)
            strcpy(ONAME_MUTABLE(otmp), name);
    }

    /* !obj->olev means the obj is currently being restored and no pointer from 
       or to it is valid. Re-equipping, timer linking, etc. will happen
       elsewhere in that case. */
    if (obj->olev) {
        int i;
        if (obj->owornmask) {
            boolean save_twoweap = u.twoweap;

            /* unwearing the old instance will clear dual-wield mode if this
               object is either of the two weapons */
            setworn(NULL, obj->owornmask);
            setworn(otmp, otmp->owornmask);
            u.twoweap = save_twoweap;
        }

        /* replace obj with otmp */
        replace_object(obj, otmp);

        /* fix ocontainer pointers */
        if (Has_contents(obj)) {
            struct obj *inside;

            for (inside = obj->cobj; inside; inside = inside->nobj)
                inside->ocontainer = otmp;
        }

        /* move timers and light sources from obj to otmp */
        otmp->timed = 0;        /* not timed, yet */
        if (obj->timed)
            obj_move_timers(obj, otmp);
        otmp->lamplit = 0;      /* ditto */
        if (obj->lamplit)
            obj_move_light_source(obj, otmp);

        /* objects possibly being manipulated by multi-turn occupations which
           have been interrupted but might be subsequently resumed */
        for (i = 0; i <= tos_last_slot; i++) {
            if (obj == u.utracked[i])
                u.utracked[i] = otmp;
        }
        /* This is probably paranoia; it would only come up if an item can
           end up being specific-named as a result of trying to use it. */
        for (i = 0; i <= ttos_last_slot; i++) {
            if (obj == turnstate.tracked[i])
                turnstate.tracked[i] = otmp;
        }
    } else {
        /* During restore, floating objects are on the floating objects
           chain, /but/ may not have OBJ_FREE set. */
        otmp->where = obj->where;
        obj->where = OBJ_FREE;
        obj->timed = FALSE;
        obj->lamplit = FALSE;
    }
    /* obfree(obj, otmp); now unnecessary: no pointers on bill */

    dealloc_obj(obj);   /* let us hope nobody else saved a pointer */
    return otmp;
}
Ejemplo n.º 13
0
void
migrate_to_level(struct monst *mtmp, xchar tolev,       /* destination level */
                 xchar xyloc,   /* MIGR_xxx destination xy location: */
                 coord * cc)
{       /* optional destination coordinates */
    struct obj *obj;
    d_level new_lev;
    xchar xyflags;
    int num_segs = 0;   /* count of worm segments */

    if (mtmp->isshk)
        set_residency(mtmp, TRUE);

    if (mtmp->wormno) {
        int cnt;

        /* **** NOTE: worm is truncated to # segs = max wormno size **** */
        cnt = count_wsegs(mtmp);
        num_segs = min(cnt, MAX_NUM_WORMS - 1);
        wormgone(mtmp);
    }

    /* set minvent's obj->no_charge to 0 */
    for (obj = mtmp->minvent; obj; obj = obj->nobj) {
        if (Has_contents(obj))
            picked_container(obj);      /* does the right thing */
        obj->no_charge = 0;
    }

    if (mtmp->mleashed) {
        mtmp->mtame--;
        m_unleash(mtmp, TRUE);
    }
    relmon(mtmp);
    mtmp->nmon = migrating_mons;
    migrating_mons = mtmp;
    if (mtmp->dlevel == level)
        newsym(mtmp->mx, mtmp->my);

    /* The dlevel pointer is meaningless for a migrating monster. Set it to NULL
       so that any uses of it are detected quickly via the resulting
       segfault. */
    mtmp->dlevel = NULL;

    new_lev.dnum = ledger_to_dnum((xchar) tolev);
    new_lev.dlevel = ledger_to_dlev((xchar) tolev);

    /* set migration data */
    xyflags = (depth(&new_lev) < depth(&u.uz)); /* 1 => up */
    if (In_W_tower(mtmp->mx, mtmp->my, &u.uz))
        xyflags |= 2;
    mtmp->wormno = num_segs;
    mtmp->mlstmv = moves;
    mtmp->xlocale = cc ? cc->x : mtmp->mx;
    mtmp->ylocale = cc ? cc->y : mtmp->my;
    mtmp->xyloc = xyloc;
    mtmp->xyflags = xyflags;
    mtmp->mux = new_lev.dnum;
    mtmp->muy = new_lev.dlevel;
    mtmp->mx = COLNO;
    mtmp->my = ROWNO;    /* this implies migration */
}
Ejemplo n.º 14
0
/* called when you move to another level
 * pets_only: true for ascension or final escape */
void
keepdogs(boolean pets_only)
{
    struct monst *mtmp, *mtmp2;
    struct obj *obj;
    int num_segs;
    boolean stay_behind;

    for (mtmp = level->monlist; mtmp; mtmp = mtmp2) {
        mtmp2 = mtmp->nmon;
        if (DEADMONSTER(mtmp))
            continue;
        if (pets_only && !mtmp->mtame)
            continue;
        if (((monnear(mtmp, u.ux, u.uy) && levl_follower(mtmp)) ||
             (mtmp == u.usteed) ||
             /* the wiz will level t-port from anywhere to chase the amulet; if
                you don't have it, will chase you only if in range. -3. */
             (Uhave_amulet && mtmp->iswiz))
            && ((!mtmp->msleeping && mtmp->mcanmove)
                /* eg if level teleport or new trap, steed has no control to
                   avoid following */
                || (mtmp == u.usteed))
            /* monster won't follow if it hasn't noticed you yet */
            && !(mtmp->mstrategy & STRAT_WAITFORU)) {
            stay_behind = FALSE;
            if (!pets_only && mtmp->mtame && mtmp->meating) {
                if (canseemon(mtmp))
                    pline("%s is still eating.", Monnam(mtmp));
                stay_behind = TRUE;
            } else if (mon_has_amulet(mtmp)) {
                if (canseemon(mtmp))
                    pline("%s seems very disoriented for a moment.",
                          Monnam(mtmp));
                stay_behind = TRUE;
            } else if (!pets_only && mtmp->mtame && mtmp->mtrapped) {
                if (canseemon(mtmp))
                    pline("%s is still trapped.", Monnam(mtmp));
                stay_behind = TRUE;
            }
            if (mtmp == u.usteed)
                stay_behind = FALSE;

            if (stay_behind) {
                if (mtmp->mleashed) {
                    pline("%s leash suddenly comes loose.", humanoid(mtmp->data)
                          ? (mtmp->female ? "Her" : "His")
                          : "Its");
                    m_unleash(mtmp, FALSE);
                }
                continue;
            }
            if (mtmp->isshk)
                set_residency(mtmp, TRUE);

            if (mtmp->wormno) {
                int cnt;

                /* NOTE: worm is truncated to # segs = max wormno size */
                cnt = count_wsegs(mtmp);
                num_segs = min(cnt, MAX_NUM_WORMS - 1);
                wormgone(mtmp);
            } else
                num_segs = 0;

            /* set minvent's obj->no_charge to 0 */
            for (obj = mtmp->minvent; obj; obj = obj->nobj) {
                if (Has_contents(obj))
                    picked_container(obj);      /* does the right thing */
                obj->no_charge = 0;
            }

            relmon(mtmp);
            newsym(mtmp->mx, mtmp->my);
            mtmp->mx = COLNO;    /* avoid mnexto()/MON_AT() problem */
            mtmp->my = ROWNO;
            mtmp->wormno = num_segs;
            mtmp->mlstmv = moves;
            mtmp->nmon = turnstate.migrating_pets;
            turnstate.migrating_pets = mtmp;
        } else if (mtmp->iswiz) {
            /* we want to be able to find him when his next resurrection chance
               comes up, but have him resume his present location if player
               returns to this level before that time */
            migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_EXACT_XY, NULL);
        } else if (mtmp->mleashed) {
            /* this can happen if your quest leader ejects you from the "home"
               level while a leashed pet isn't next to you */
            pline("%s leash goes slack.", s_suffix(Monnam(mtmp)));
            m_unleash(mtmp, FALSE);
        }
    }
}
Ejemplo n.º 15
0
/*
 * Allocate a new and possibly larger storage space for an obj.
 */
struct obj *realloc_obj(struct obj *obj, int oextra_size, void *oextra_src,
			int oname_size, const char *name)
{
	struct obj *otmp;

	otmp = newobj(oextra_size + oname_size);
	*otmp = *obj;	/* the cobj pointer is copied to otmp */
	if (oextra_size) {
	    if (oextra_src)
		memcpy(otmp->oextra, oextra_src, oextra_size);
	} else {
	    otmp->oattached = OATTACHED_NOTHING;
	}
	otmp->oxlth = oextra_size;
	otmp->onamelth = oname_size;
	
	if (oname_size) {
	    if (name)
		strcpy(ONAME(otmp), name);
	}

	/* !obj->olev means the obj is currently being restored and no pointer
	 * from or to it is valid. Re-equipping, timer linking, etc. will happen
	 * elsewhere in that case. */
	if (obj->olev) { 
	    if (obj->owornmask) {
		    boolean save_twoweap = u.twoweap;
		    /* unwearing the old instance will clear dual-wield mode
		    if this object is either of the two weapons */
		    setworn(NULL, obj->owornmask);
		    setworn(otmp, otmp->owornmask);
		    u.twoweap = save_twoweap;
	    }

	    /* replace obj with otmp */
	    replace_object(obj, otmp);

	    /* fix ocontainer pointers */
	    if (Has_contents(obj)) {
		    struct obj *inside;

		    for (inside = obj->cobj; inside; inside = inside->nobj)
			    inside->ocontainer = otmp;
	    }

	    /* move timers and light sources from obj to otmp */
	    otmp->timed = 0;	/* not timed, yet */
	    if (obj->timed) obj_move_timers(obj, otmp);
	    otmp->lamplit = 0;	/* ditto */
	    if (obj->lamplit) obj_move_light_source(obj, otmp);

	    /* objects possibly being manipulated by multi-turn occupations
	    which have been interrupted but might be subsequently resumed */
	    if (obj->oclass == FOOD_CLASS)
		food_substitution(obj, otmp);	/* eat food or open tin */
	    else if (obj->oclass == SPBOOK_CLASS)
		book_substitution(obj, otmp);	/* read spellbook */
	} else {
	    /* make sure dealloc_obj doesn't explode */
	    obj->where = OBJ_FREE;
	    obj->timed = FALSE;
	    obj->lamplit = FALSE;
	}
	/* obfree(obj, otmp);	now unnecessary: no pointers on bill */
	dealloc_obj(obj);	/* let us hope nobody else saved a pointer */
	return otmp;
}