fire effects should burn green slime globs, too

On floor, in inventory, whatever. This probably needs to be extended to
support a much wider group of objects, but this will do to start.
This commit is contained in:
Derek S. Ray
2015-04-05 21:56:15 -04:00
parent b3e2772f7b
commit 07e0bc592c
5 changed files with 181 additions and 162 deletions
+1 -1
View File
@@ -2656,7 +2656,7 @@ E struct monst *FDECL(bhit, (int,int,int,int,int (*)(MONST_P,OBJ_P),
int (*)(OBJ_P,OBJ_P),struct obj **)); int (*)(OBJ_P,OBJ_P),struct obj **));
E struct monst *FDECL(boomhit, (struct obj *,int,int)); E struct monst *FDECL(boomhit, (struct obj *,int,int));
E int FDECL(zhitm, (struct monst *,int,int,struct obj **)); E int FDECL(zhitm, (struct monst *,int,int,struct obj **));
E int FDECL(burn_floor_paper, (int,int,BOOLEAN_P,BOOLEAN_P)); E int FDECL(burn_floor_objects, (int,int,BOOLEAN_P,BOOLEAN_P));
E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int)); E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int));
E void FDECL(melt_ice, (XCHAR_P,XCHAR_P,const char *)); E void FDECL(melt_ice, (XCHAR_P,XCHAR_P,const char *));
E void FDECL(start_melt_ice_timeout, (XCHAR_P,XCHAR_P,long)); E void FDECL(start_melt_ice_timeout, (XCHAR_P,XCHAR_P,long));
+1 -1
View File
@@ -2670,7 +2670,7 @@ long numused;
register struct obj *otmp; register struct obj *otmp;
boolean at_u = (obj->ox == u.ux && obj->oy == u.uy); boolean at_u = (obj->ox == u.ux && obj->oy == u.uy);
/* burn_floor_paper() keeps an object pointer that it tries to /* burn_floor_objects() keeps an object pointer that it tries to
* useupf() multiple times, so obj must survive if plural */ * useupf() multiple times, so obj must survive if plural */
if (obj->quan > numused) if (obj->quan > numused)
otmp = splitobj(obj, numused); otmp = splitobj(obj, numused);
+1 -1
View File
@@ -519,7 +519,7 @@ int spellnum;
destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SCROLL_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
(void) burn_floor_paper(u.ux, u.uy, TRUE, FALSE); (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE);
break; break;
case CLC_LIGHTNING: case CLC_LIGHTNING:
{ {
+3 -3
View File
@@ -2215,7 +2215,7 @@ glovecheck: target = which_armor(mtmp, W_ARMG);
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
} }
if (burn_floor_paper(mtmp->mx, mtmp->my, see_it, FALSE) && if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE) &&
!see_it && distu(mtmp->mx, mtmp->my) <= 3*3) !see_it && distu(mtmp->mx, mtmp->my) <= 3*3)
You("smell smoke."); You("smell smoke.");
if (is_ice(mtmp->mx,mtmp->my)) if (is_ice(mtmp->mx,mtmp->my))
@@ -2853,7 +2853,7 @@ struct obj *box; /* null for floor trap */
boolean see_it = !Blind; boolean see_it = !Blind;
int num, alt; int num, alt;
/* Bug: for box case, the equivalent of burn_floor_paper() ought /* Bug: for box case, the equivalent of burn_floor_objects() ought
* to be done upon its contents. * to be done upon its contents.
*/ */
@@ -2898,7 +2898,7 @@ struct obj *box; /* null for floor trap */
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
} }
if (!box && burn_floor_paper(u.ux, u.uy, see_it, TRUE) && !see_it) if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it)
You("smell paper burning."); You("smell paper burning.");
if (is_ice(u.ux, u.uy)) if (is_ice(u.ux, u.uy))
melt_ice(u.ux, u.uy, (char *)0); melt_ice(u.ux, u.uy, (char *)0);
+175 -156
View File
@@ -2110,18 +2110,19 @@ boolean ordinary;
case FIRE_HORN: case FIRE_HORN:
learn_it = TRUE; learn_it = TRUE;
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("rather warm."); You_feel("rather warm.");
ugolemeffects(AD_FIRE, d(12,6)); ugolemeffects(AD_FIRE, d(12,6));
} else { } else {
pline("You've set yourself afire!"); pline("You've set yourself afire!");
damage = d(12,6); damage = d(12,6);
} }
burn_away_slime(); burn_away_slime();
(void) burnarmor(&youmonst); (void) burnarmor(&youmonst);
destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SCROLL_CLASS, AD_FIRE);
destroy_item(POTION_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE);
destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */
break; break;
case WAN_COLD: case WAN_COLD:
@@ -3327,6 +3328,7 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */
if (!rn2(3)) (void)destroy_mitem(mon, POTION_CLASS, AD_FIRE); if (!rn2(3)) (void)destroy_mitem(mon, POTION_CLASS, AD_FIRE);
if (!rn2(3)) (void)destroy_mitem(mon, SCROLL_CLASS, AD_FIRE); if (!rn2(3)) (void)destroy_mitem(mon, SCROLL_CLASS, AD_FIRE);
if (!rn2(5)) (void)destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE); if (!rn2(5)) (void)destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE);
destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */
} }
break; break;
case ZT_COLD: case ZT_COLD:
@@ -3471,6 +3473,7 @@ xchar sx, sy;
if (!rn2(3)) destroy_item(POTION_CLASS, AD_FIRE); if (!rn2(3)) destroy_item(POTION_CLASS, AD_FIRE);
if (!rn2(3)) destroy_item(SCROLL_CLASS, AD_FIRE); if (!rn2(3)) destroy_item(SCROLL_CLASS, AD_FIRE);
if (!rn2(5)) destroy_item(SPBOOK_CLASS, AD_FIRE); if (!rn2(5)) destroy_item(SPBOOK_CLASS, AD_FIRE);
destroy_item(FOOD_CLASS, AD_FIRE);
} }
break; break;
case ZT_COLD: case ZT_COLD:
@@ -3567,11 +3570,11 @@ xchar sx, sy;
} }
/* /*
* burn scrolls and spellbooks on floor at position x,y * burn objects (such as scrolls and spellbooks) on floor
* return the number of scrolls and spellbooks burned * at position x,y; return the number of objects burned
*/ */
int int
burn_floor_paper(x, y, give_feedback, u_caused) burn_floor_objects(x, y, give_feedback, u_caused)
int x, y; int x, y;
boolean give_feedback; /* caller needs to decide about visibility checks */ boolean give_feedback; /* caller needs to decide about visibility checks */
boolean u_caused; boolean u_caused;
@@ -3583,37 +3586,39 @@ boolean u_caused;
for (obj = level.objects[x][y]; obj; obj = obj2) { for (obj = level.objects[x][y]; obj; obj = obj2) {
obj2 = obj->nexthere; obj2 = obj->nexthere;
if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS) { if (obj->oclass == SCROLL_CLASS || obj->oclass == SPBOOK_CLASS
if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL || || (obj->oclass == FOOD_CLASS
obj_resists(obj, 2, 100)) && obj->otyp == GLOB_OF_GREEN_SLIME)) {
continue; if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL ||
scrquan = obj->quan; /* number present */ obj_resists(obj, 2, 100))
delquan = 0L; /* number to destroy */ continue;
for (i = scrquan; i > 0L; i--) scrquan = obj->quan; /* number present */
if (!rn2(3)) delquan++; delquan = 0L; /* number to destroy */
if (delquan) { for (i = scrquan; i > 0L; i--)
/* save name before potential delobj() */ if (!rn2(3)) delquan++;
if (give_feedback) { if (delquan) {
obj->quan = 1L; /* save name before potential delobj() */
Strcpy(buf1, (x == u.ux && y == u.uy) ? if (give_feedback) {
xname(obj) : distant_name(obj, xname)); obj->quan = 1L;
obj->quan = 2L; Strcpy(buf1, (x == u.ux && y == u.uy) ?
Strcpy(buf2, (x == u.ux && y == u.uy) ? xname(obj) : distant_name(obj, xname));
xname(obj) : distant_name(obj, xname)); obj->quan = 2L;
obj->quan = scrquan; Strcpy(buf2, (x == u.ux && y == u.uy) ?
} xname(obj) : distant_name(obj, xname));
/* useupf(), which charges, only if hero caused damage */ obj->quan = scrquan;
if (u_caused) useupf(obj, delquan); }
else if (delquan < scrquan) obj->quan -= delquan; /* useupf(), which charges, only if hero caused damage */
else delobj(obj); if (u_caused) useupf(obj, delquan);
cnt += delquan; else if (delquan < scrquan) obj->quan -= delquan;
if (give_feedback) { else delobj(obj);
if (delquan > 1L) cnt += delquan;
pline("%ld %s burn.", delquan, buf2); if (give_feedback) {
else if (delquan > 1L)
pline("%s burns.", An(buf1)); pline("%ld %s burn.", delquan, buf2);
} else
} pline("%s burns.", An(buf1));
}
}
} }
} }
return cnt; return cnt;
@@ -4253,7 +4258,7 @@ short exploding_wand_typ;
} }
if(OBJ_AT(x, y) && abstype == ZT_FIRE) if(OBJ_AT(x, y) && abstype == ZT_FIRE)
if (burn_floor_paper(x, y, FALSE, type > 0) && couldsee(x, y)) { if (burn_floor_objects(x, y, FALSE, type > 0) && couldsee(x, y)) {
newsym(x,y); newsym(x,y);
You("%s of smoke.", You("%s of smoke.",
!Blind ? "see a puff" : "smell a whiff"); !Blind ? "see a puff" : "smell a whiff");
@@ -4363,129 +4368,137 @@ const char * const destroy_strings[][3] = { /* also used in trap.c */
void void
destroy_item(osym, dmgtyp) destroy_item(osym, dmgtyp)
register int osym, dmgtyp; register int osym, dmgtyp;
{ {
register struct obj *obj, *obj2; register struct obj *obj, *obj2;
register int dmg, xresist, skip; register int dmg, xresist, skip;
register long i, cnt, quan; register long i, cnt, quan;
register int dindx; register int dindx;
const char *mult; const char *mult;
boolean physical_damage; boolean physical_damage;
for(obj = invent; obj; obj = obj2) { for(obj = invent; obj; obj = obj2) {
obj2 = obj->nobj; obj2 = obj->nobj;
physical_damage = FALSE; physical_damage = FALSE;
if(obj->oclass != osym) continue; /* test only objs of type osym */ if(obj->oclass != osym) continue; /* test only objs of type osym */
if(obj->oartifact) continue; /* don't destroy artifacts */ if(obj->oartifact) continue; /* don't destroy artifacts */
if(obj->in_use && obj->quan == 1L) continue; /* not available */ if(obj->in_use && obj->quan == 1L) continue; /* not available */
xresist = skip = 0; xresist = skip = 0;
/* lint suppression */ /* lint suppression */
dmg = dindx = 0; dmg = dindx = 0;
quan = 0L; quan = 0L;
switch(dmgtyp) { switch(dmgtyp) {
case AD_COLD: case AD_COLD:
if(osym == POTION_CLASS && obj->otyp != POT_OIL) { if(osym == POTION_CLASS && obj->otyp != POT_OIL) {
quan = obj->quan; quan = obj->quan;
dindx = 0; dindx = 0;
dmg = rnd(4); dmg = rnd(4);
} else skip++; } else skip++;
break; break;
case AD_FIRE: case AD_FIRE:
xresist = (Fire_resistance && obj->oclass != POTION_CLASS); xresist = (Fire_resistance
&& obj->oclass != POTION_CLASS
&& obj->otyp != GLOB_OF_GREEN_SLIME);
if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL) if (obj->otyp == SCR_FIRE || obj->otyp == SPE_FIREBALL)
skip++; skip++;
if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
skip++; skip++;
if (!Blind) if (!Blind)
pline("%s glows a strange %s, but remains intact.", pline("%s glows a strange %s, but remains intact.",
The(xname(obj)), hcolor("dark red")); The(xname(obj)), hcolor("dark red"));
} }
quan = obj->quan; quan = obj->quan;
switch(osym) { switch(osym) {
case POTION_CLASS: case POTION_CLASS:
dindx = (obj->otyp != POT_OIL) ? 1 : 2; dindx = (obj->otyp != POT_OIL) ? 1 : 2;
dmg = rnd(6); dmg = rnd(6);
break; break;
case SCROLL_CLASS: case SCROLL_CLASS:
dindx = 3; dindx = 3;
dmg = 1; dmg = 1;
break; break;
case SPBOOK_CLASS: case SPBOOK_CLASS:
dindx = 4; dindx = 4;
dmg = 1; dmg = 1;
break; break;
default: case FOOD_CLASS:
skip++; if (obj->otyp == GLOB_OF_GREEN_SLIME) {
break; dindx = obj->owt / 20;
} dmg = 1;
break; } else { skip++; }
case AD_ELEC: break;
xresist = (Shock_resistance && obj->oclass != RING_CLASS); default:
quan = obj->quan; skip++;
switch(osym) { break;
case RING_CLASS: }
if(obj->otyp == RIN_SHOCK_RESISTANCE) break;
{ skip++; break; } case AD_ELEC:
dindx = 5; xresist = (Shock_resistance && obj->oclass != RING_CLASS);
dmg = 0; quan = obj->quan;
break; switch(osym) {
case WAND_CLASS: case RING_CLASS:
if(obj->otyp == WAN_LIGHTNING) { skip++; break; } if(obj->otyp == RIN_SHOCK_RESISTANCE)
{ skip++; break; }
dindx = 5;
dmg = 0;
break;
case WAND_CLASS:
if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
#if 0 #if 0
if (obj == current_wand) { skip++; break; } if (obj == current_wand) { skip++; break; }
#endif #endif
dindx = 6; dindx = 6;
dmg = rnd(10); dmg = rnd(10);
break; break;
default: default:
skip++; skip++;
break; break;
} }
break; break;
default: default:
skip++; skip++;
break; break;
} }
if(!skip) { if(!skip) {
if (obj->in_use) --quan; /* one will be used up elsewhere */ if (obj->in_use) --quan; /* one will be used up elsewhere */
for(i = cnt = 0L; i < quan; i++) for(i = cnt = 0L; i < quan; i++)
if(!rn2(3)) cnt++; if(!rn2(3)) cnt++;
if(!cnt) continue; if(!cnt) continue;
mult = (cnt == quan) ? "Your" : mult = (cnt == quan) ? (quan > 1) ? "All of your " : "Your" :
(cnt == 1L) ? "One of your" : "Some of your"; (cnt == 1L) ? "One of your" : "Some of your";
pline("%s %s %s!", mult, xname(obj), pline("%s %s %s!", mult, xname(obj),
destroy_strings[dindx][(cnt > 1L)]); destroy_strings[dindx][(cnt > 1L)]);
if(osym == POTION_CLASS && dmgtyp != AD_COLD) { if(osym == POTION_CLASS && dmgtyp != AD_COLD) {
if (!breathless(youmonst.data) || haseyes(youmonst.data)) if (!breathless(youmonst.data) || haseyes(youmonst.data))
potionbreathe(obj); potionbreathe(obj);
} }
if (obj->owornmask) { if (obj->owornmask) {
if (obj->owornmask & W_RING) /* ring being worn */ if (obj->owornmask & W_RING) /* ring being worn */
Ring_gone(obj); Ring_gone(obj);
else else
setnotworn(obj); setnotworn(obj);
} }
if (obj == current_wand) current_wand = 0; /* destroyed */ if (obj == current_wand) current_wand = 0; /* destroyed */
for (i = 0; i < cnt; i++) for (i = 0; i < cnt; i++)
useup(obj); useup(obj);
if(dmg) { if(dmg) {
if(xresist) You("aren't hurt!"); if(xresist) You("aren't hurt!");
else { else {
const char *how = destroy_strings[dindx][2]; const char *how = destroy_strings[dindx][2];
boolean one = (cnt == 1L); boolean one = (cnt == 1L);
if (physical_damage) dmg = Maybe_Half_Phys(dmg); if (physical_damage) dmg = Maybe_Half_Phys(dmg);
losehp(dmg, one ? how : (const char *)makeplural(how), losehp(dmg, one ? how : (const char *)makeplural(how),
one ? KILLED_BY_AN : KILLED_BY); one ? KILLED_BY_AN : KILLED_BY);
exercise(A_STR, FALSE); exercise(A_STR, FALSE);
} }
} }
} }
} }
return; return;
} }
int int
@@ -4544,6 +4557,12 @@ int osym, dmgtyp;
dindx = 4; dindx = 4;
tmp++; tmp++;
break; break;
case FOOD_CLASS:
if (obj->otyp == GLOB_OF_GREEN_SLIME) {
dindx = obj->owt / 20;
tmp++;
} else { skip++; }
break;
default: default:
skip++; skip++;
break; break;