Ejemplo n.º 1
0
static void
chest_shatter_msg(struct obj *otmp)
{
    const char *disposition;
    const char *thing;
    long save_Blinded;

    if (otmp->oclass == POTION_CLASS) {
        pline(msgc_itemloss, "You %s %s shatter!", Blind ? "hear" : "see",
              an(bottlename()));
        if (!breathless(youmonst.data) || haseyes(youmonst.data))
            potionbreathe(&youmonst, otmp);
        return;
    }
    /* We have functions for distant and singular names, but not one
       which does _both_...
       TODO: fix this blindness kludge (it doesn't even work -- see eoto) */
    save_Blinded = property_timeout(&youmonst, BLINDED);
    set_property(&youmonst, BLINDED, 1, TRUE);
    thing = singular(otmp, xname);
    if (save_Blinded)
        set_property(&youmonst, BLINDED, save_Blinded, TRUE);

    switch (objects[otmp->otyp].oc_material) {
    case PAPER:
        disposition = "is torn to shreds";
        break;
    case WAX:
        disposition = "is crushed";
        break;
    case VEGGY:
        disposition = "is pulped";
        break;
    case FLESH:
        disposition = "is mashed";
        break;
    case GLASS:
        disposition = "shatters";
        break;
    case WOOD:
        disposition = "splinters to fragments";
        break;
    default:
        disposition = "is destroyed";
        break;
    }
    pline(msgc_itemloss, "%s %s!", An(thing), disposition);
}
Ejemplo n.º 2
0
int
dothrow()
{
	struct obj *obj;
	struct monst *mon;
	int tmp;

	obj = getobj("#)", "throw");   /* it is also possible to throw food */
				       /* (or jewels, or iron balls ... ) */
	if(!obj || !getdir(1))	       /* ask "in what direction?" */
		return(0);
	if(obj->owornmask & (W_ARMOR | W_RING)){
		pline("You can't throw something you are wearing.");
		return(0);
	}

	u_wipe_engr(2);

	if(obj == uwep){
		if(obj->cursed){
			pline("Your weapon is welded to your hand.");
			return(1);
		}
		if(obj->quan > 1)
			setuwep(splitobj(obj, 1));
		else
			setuwep((struct obj *) 0);
	}
	else if(obj->quan > 1)
		(void) splitobj(obj, 1);
	freeinv(obj);
	if(u.uswallow) {
		mon = u.ustuck;
		bhitpos.x = mon->mx;
		bhitpos.y = mon->my;
	} else if(u.dz) {
	  if(u.dz < 0) {
	    pline("%s hits the ceiling, then falls back on top of your head.",
		Doname(obj));		/* note: obj->quan == 1 */
	    if(obj->olet == POTION_SYM)
		potionhit(&youmonst, obj);
	    else {
		if(uarmh) pline("Fortunately, you are wearing a helmet!");
		losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
		dropy(obj);
	    }
	  } else {
	    pline("%s hits the floor.", Doname(obj));
	    if(obj->otyp == EXPENSIVE_CAMERA) {
		pline("It is shattered in a thousand pieces!");
		obfree(obj, Null(obj));
	    } else if(obj->otyp == EGG) {
		pline("\"Splash!\"");
		obfree(obj, Null(obj));
	    } else if(obj->olet == POTION_SYM) {
		pline("The flask breaks, and you smell a peculiar odor ...");
		potionbreathe(obj);
		obfree(obj, Null(obj));
	    } else {
		dropy(obj);
	    }
	  }
	  return(1);
	} else if(obj->otyp == BOOMERANG) {
		mon = boomhit(u.dx, u.dy);
		if(mon == &youmonst) {		/* the thing was caught */
			(void) addinv(obj);
			return(1);
		}
	} else {
		if(obj->otyp == PICK_AXE && shkcatch(obj))
		    return(1);

		mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
			(!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
			obj->olet, NULL, NULL, obj);
	}
	if(mon) {
		/* awake monster if sleeping */
		wakeup(mon);

		if(obj->olet == WEAPON_SYM) {
			tmp = -1+u.ulevel+mon->data->ac+abon();
			if(obj->otyp < ROCK) {
				if(!uwep ||
				    uwep->otyp != obj->otyp+(BOW-ARROW))
					tmp -= 4;
				else {
					tmp += uwep->spe;
				}
			} else
			if(obj->otyp == BOOMERANG) tmp += 4;
			tmp += obj->spe;
			if(u.uswallow || tmp >= rnd(20)) {
				if(hmon(mon,obj,1) == TRUE){
				  /* mon still alive */
#ifndef NOWORM
				  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
#endif /* NOWORM */
				} else mon = 0;
				/* weapons thrown disappear sometimes */
				if(obj->otyp < BOOMERANG && rn2(3)) {
					/* check bill; free */
					obfree(obj, (struct obj *) 0);
					return(1);
				}
			} else miss(objects[obj->otyp].oc_name, mon);
		} else if(obj->otyp == HEAVY_IRON_BALL) {
			tmp = -1+u.ulevel+mon->data->ac+abon();
			if(!Punished || obj != uball) tmp += 2;
			if(u.utrap) tmp -= 2;
			if(u.uswallow || tmp >= rnd(20)) {
				if(hmon(mon,obj,1) == FALSE)
					mon = 0;	/* he died */
			} else miss("iron ball", mon);
		} else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
			potionhit(mon, obj);
			return(1);
		} else {
			if(cansee(bhitpos.x,bhitpos.y))
				pline("You miss %s.",monnam(mon));
			else pline("You miss it.");
			if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
				if(tamedog(mon,obj)) return(1);
			if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
				!mon->mtame){
			 if(obj->dknown && objects[obj->otyp].oc_name_known){
			  if(objects[obj->otyp].g_val > 0){
			    u.uluck += 5;
			    goto valuable;
			  } else {
			    pline("%s is not interested in your junk.",
				Monnam(mon));
			  }
			 } else { /* value unknown to @ */
			    u.uluck++;
			valuable:
			    if(u.uluck > LUCKMAX)	/* dan@ut-ngp */
				u.uluck = LUCKMAX;
			    pline("%s graciously accepts your gift.",
				Monnam(mon));
			    mpickobj(mon, obj);
			    rloc(mon);
			    return(1);
			 }
			}
		}
	}
		/* the code following might become part of dropy() */
	if(obj->otyp == CRYSKNIFE)
		obj->otyp = WORM_TOOTH;
	obj->ox = bhitpos.x;
	obj->oy = bhitpos.y;
	obj->nobj = fobj;
	fobj = obj;
	/* prevent him from throwing articles to the exit and escaping */
	/* subfrombill(obj); */
	stackobj(obj);
	if(Punished && obj == uball &&
		(bhitpos.x != u.ux || bhitpos.y != u.uy)){
		freeobj(uchain);
		unpobj(uchain);
		if(u.utrap){
			if(u.utraptype == TT_PIT)
				pline("The ball pulls you out of the pit!");
			else {
			    long side =
				rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
			    pline("The ball pulls you out of the bear trap.");
			    pline("Your %s leg is severely damaged.",
				(side == LEFT_SIDE) ? "left" : "right");
			    set_wounded_legs(side, 500+rn2(1000));
			    losehp(2, "thrown ball");
			}
			u.utrap = 0;
		}
		unsee();
		uchain->nobj = fobj;
		fobj = uchain;
		u.ux = uchain->ox = bhitpos.x - u.dx;
		u.uy = uchain->oy = bhitpos.y - u.dy;
		setsee();
		(void) inshop();
	}
	if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
	return(1);
}
Ejemplo n.º 3
0
void
potionhit(struct monst *mon, struct obj *obj)
{
	char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
	boolean uclose, isyou = (mon == &youmonst);

	if(isyou) {
		uclose = TRUE;
		pline("The %s crashes on your head and breaks into shivers.",
			botlnam);
		losehp(rnd(2), "thrown potion");
	} else {
		uclose = (dist(mon->mx,mon->my) < 3);
		/* perhaps 'E' and 'a' have no head? */
		pline("The %s crashes on %s's head and breaks into shivers.",
			botlnam, monnam(mon));
		if(rn2(5) && mon->mhp > 1)
			mon->mhp--;
	}
	pline("The %s evaporates.", xname(obj));

	if(!isyou && !rn2(3)) switch(obj->otyp) {

	case POT_RESTORE_STRENGTH:
	case POT_GAIN_STRENGTH:
	case POT_HEALING:
	case POT_EXTRA_HEALING:
		if(mon->mhp < mon->mhpmax) {
			mon->mhp = mon->mhpmax;
			pline("%s looks sound and hale again!", Monnam(mon));
		}
		break;
	case POT_SICKNESS:
		if(mon->mhpmax > 3)
			mon->mhpmax /= 2;
		if(mon->mhp > 2)
			mon->mhp /= 2;
		break;
	case POT_CONFUSION:
	case POT_BOOZE:
		mon->mconf = 1;
		break;
	case POT_INVISIBILITY:
		unpmon(mon);
		mon->minvis = 1;
		pmon(mon);
		break;
	case POT_PARALYSIS:
		mon->mfroz = 1;
		break;
	case POT_SPEED:
		mon->mspeed = MFAST;
		break;
	case POT_BLINDNESS:
		mon->mblinded |= 64 + rn2(64);
		break;
/*	
	case POT_GAIN_LEVEL:
	case POT_LEVITATION:
	case POT_FRUIT_JUICE:
	case POT_MONSTER_DETECTION:
	case POT_OBJECT_DETECTION:
		break;
*/
	}
	if(uclose && rn2(5))
		potionbreathe(obj);
	obfree(obj, Null(obj));
}
Ejemplo n.º 4
0
// NOTE: To hit "you" with a potion p, call "potionhit(NULL, p)". no "youmonst"
void potionhit(monst_t *mon, obj_t *obj)
{
  Char *botlnam = bottlenames[rund(MAX_BOTTLES)];
  Boolean uclose; // , isyou = (mon==NULL);

  if (!mon) {
    uclose = true;
    StrPrintF(ScratchBuffer, "The %s crashes on your head and breaks into shivers.",
	      botlnam);
    message(ScratchBuffer);
    losehp(rnd(2), "thrown potion");
  } else {
    uclose = (dist(mon->mx,mon->my) < 3);
    /* perhaps 'E' and 'a' have no head? */
    StrPrintF(ScratchBuffer, "The %s crashes on %s's head and breaks into shivers.",
	  botlnam, monnam(mon));
    message(ScratchBuffer);
    if (rund(5) && mon->mhp > 1)
      mon->mhp--;
  }
  StrPrintF(ScratchBuffer, "The %s evaporates.", xname(obj));
  message(ScratchBuffer);

  if (mon && !rund(3)) {
    switch(obj->otype) {
    case POT_RESTORE_STRENGTH:
    case POT_GAIN_STRENGTH:
    case POT_HEALING:
    case POT_EXTRA_HEALING:
      if (mon->mhp < mon->mhpmax) {
	mon->mhp = mon->mhpmax;
	StrPrintF(ScratchBuffer, "%s looks sound and hale again!",
		  Monnam(mon));
	message(ScratchBuffer);
      }
      break;
    case POT_SICKNESS:
      if (mon->mhpmax > 3)
	mon->mhpmax /= 2;
      if (mon->mhp > 2)
	mon->mhp /= 2;
      break;
    case POT_CONFUSION:
    case POT_BOOZE:
      mon->bitflags |= M_IS_CONFUSED; // mon->mconf = 1;
      break;
    case POT_INVISIBILITY:
      unpmon(mon);
      mon->bitflags |= M_IS_INVISIBLE; // mon->minvis = 1;
      pmon(mon);
      break;
    case POT_PARALYSIS:
      mon->bitflags |= M_IS_FROZEN; // mon->mfroz = 1;
      break;
    case POT_SPEED:
      mon->mspeed = MFAST;
      break;
    case POT_BLINDNESS:
      mon->mcansee_and_blinded |= 64 + rund(64); // "|="?  "=" to turn off SEE?
      break;
      /*	
	case POT_GAIN_LEVEL:
	case POT_LEVITATION:
	case POT_FRUIT_JUICE:
	case POT_MONSTER_DETECTION:
	case POT_OBJECT_DETECTION:
	break;
      */
    default: break;
    }
  }
  if (uclose && rund(5))
    potionbreathe(obj);
  free_obj(obj, NULL);
}