zork/demons.c

602 lines
12 KiB
C

/* FIGHTD- INTERMOVE FIGHT DEMON */
/*COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142*/
/* ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED */
/* WRITTEN BY R. M. SUPNIK */
#include "funcs.h"
#include "vars.h"
static logical infest_ P((integer));
void fightd_()
{
/* Initialized data */
const integer rout = 1;
/* System generated locals */
integer i__1, i__2;
/* Local variables */
logical f;
integer i, j, ra;
integer obj;
integer res;
integer out;
i__1 = vill_1.vlnt;
for (i = 1; i <= i__1; ++i) {
/* !LOOP THRU VILLAINS. */
vill_1.vopps[i - 1] = 0;
/* !CLEAR OPPONENT SLOT. */
obj = vill_1.villns[i - 1];
/* !GET OBJECT NO. */
ra = objcts_1.oactio[obj - 1];
/* !GET HIS ACTION. */
if (play_1.here != objcts_1.oroom[obj - 1]) {
goto L2200;
}
/* !ADVENTURER STILL HERE? */
if (obj == oindex_1.thief && findex_1.thfenf) {
goto L2400;
}
/* !THIEF ENGROSSED? */
if (objcts_1.ocapac[obj - 1] >= 0) {
goto L2050;
}
/* !YES, VILL AWAKE? */
if (vill_1.vprob[i - 1] == 0 || ! prob_(vill_1.vprob[i - 1],
vill_1.vprob[i - 1])) {
goto L2025;
}
objcts_1.ocapac[obj - 1] = (i__2 = objcts_1.ocapac[obj - 1], abs(i__2)
);
vill_1.vprob[i - 1] = 0;
if (ra == 0) {
goto L2400;
}
/* !ANYTHING TO DO? */
prsvec_1.prsa = vindex_1.inxw;
/* !YES, WAKE HIM UP. */
f = oappli_(ra, 0);
goto L2400;
/* !NOTHING ELSE HAPPENS. */
L2025:
vill_1.vprob[i - 1] += 10;
/* !INCREASE WAKEUP PROB. */
goto L2400;
/* !NOTHING ELSE. */
L2050:
if ((objcts_1.oflag2[obj - 1] & FITEBT) == 0) {
goto L2100;
}
vill_1.vopps[i - 1] = obj;
/* !FIGHTING, SET UP OPP. */
goto L2400;
L2100:
if (ra == 0) {
goto L2400;
}
/* !NOT FIGHTING, */
prsvec_1.prsa = vindex_1.frstqw;
/* !SET UP PROBABILITY */
if (! oappli_(ra, 0)) {
goto L2400;
}
/* !OF FIGHTING. */
objcts_1.oflag2[obj - 1] |= FITEBT;
vill_1.vopps[i - 1] = obj;
/* !SET UP OPP. */
goto L2400;
L2200:
if ((objcts_1.oflag2[obj - 1] & FITEBT) == 0 || ra == 0) {
goto L2300;
}
prsvec_1.prsa = vindex_1.fightw;
/* !HAVE A FIGHT. */
f = oappli_(ra, 0);
L2300:
if (obj == oindex_1.thief) {
findex_1.thfenf = FALSE_;
}
/* !TURN OFF ENGROSSED. */
advs_1.aflag[aindex_1.player - 1] &= ~ aflags_1.astag;
objcts_1.oflag2[obj - 1] &= ~ (STAGBT + FITEBT);
if (objcts_1.ocapac[obj - 1] >= 0 || ra == 0) {
goto L2400;
}
prsvec_1.prsa = vindex_1.inxw;
/* !WAKE HIM UP. */
f = oappli_(ra, 0);
objcts_1.ocapac[obj - 1] = (i__2 = objcts_1.ocapac[obj - 1], abs(i__2)
);
L2400:
;
}
/* FIGHTD, PAGE 3 */
/* NOW DO ACTUAL COUNTERBLOWS. */
out = 0;
/* !ASSUME HERO OK. */
L2600:
i__1 = vill_1.vlnt;
for (i = 1; i <= i__1; ++i) {
/* !LOOP THRU OPPS. */
j = vill_1.vopps[i - 1];
if (j == 0) {
goto L2700;
}
/* !SLOT EMPTY? */
prsvec_1.prscon = 1;
/* !STOP CMD STREAM. */
ra = objcts_1.oactio[j - 1];
if (ra == 0) {
goto L2650;
}
/* !VILLAIN ACTION? */
prsvec_1.prsa = vindex_1.fightw;
/* !SEE IF */
if (oappli_(ra, 0)) {
goto L2700;
}
/* !SPECIAL ACTION. */
L2650:
res = blow_(aindex_1.player, j, vill_1.vmelee[i - 1], 0, out);
/* !STRIKE BLOW. */
if (res < 0) {
return;
}
/* !IF HERO DEAD, EXIT. */
if (res == rout) {
out = rnd_(3) + 2;
}
/* !IF HERO OUT, SET FLG. */
L2700:
;
}
--out;
/* !DECREMENT OUT COUNT. */
if (out > 0) {
goto L2600;
}
/* !IF STILL OUT, GO AGAIN. */
return;
} /* fightd_ */
/* BLOW- STRIKE BLOW */
/* DECLARATIONS */
integer blow_(h, v, rmk, hflg, out)
integer h;
integer v;
integer rmk;
logical hflg;
integer out;
{
/* Initialized data */
const integer rmiss = 0;
const integer rout = 1;
const integer rkill = 2;
const integer rstag = 5;
const integer rlose = 6;
const integer rhes = 7;
const integer rsit = 8;
static const integer def1r[3] = { 1,2,3 };
static const integer def2r[4] = { 13,23,24,25 };
static const integer def3r[5] = { 35,36,46,47,57 };
static const integer rvectr[66] = { 0,0,0,0,5,5,1,1,2,2,2,2,0,0,0,0,0,5,
5,3,3,1,0,0,0,5,5,3,3,3,1,2,2,2,0,0,0,0,0,5,5,3,3,4,4,0,0,0,5,5,
3,3,3,4,4,4,0,5,5,3,3,3,3,4,4,4 };
static const integer rstate[45] = { 5000,3005,3008,4011,3015,3018,1021,
0,0,5022,3027,3030,4033,3037,3040,1043,0,0,4044,2048,4050,4054,
5058,4063,4067,3071,1074,4075,1079,4080,4084,4088,4092,4096,4100,
1104,4105,2109,4111,4115,4119,4123,4127,3131,3134 };
/* System generated locals */
integer ret_val, i__1, i__2;
/* Local variables */
logical f;
integer i, j, oa, ra, od, mi, dv, def;
integer tbl;
integer att, res;
integer dweap;
integer pblose;
ra = objcts_1.oactio[v - 1];
/* !GET VILLAIN ACTION, */
dv = objcts_1.odesc2[v - 1];
/* !DESCRIPTION. */
ret_val = rmiss;
/* !ASSUME NO RESULT. */
if (! (hflg)) {
goto L1000;
}
/* !HERO STRIKING BLOW? */
/* HERO IS ATTACKER, VILLAIN IS DEFENDER. */
pblose = 10;
/* !BAD LK PROB. */
objcts_1.oflag2[v - 1] |= FITEBT;
if ((advs_1.aflag[h - 1] & aflags_1.astag) == 0) {
goto L100;
}
rspeak_(591);
/* !YES, CANT FIGHT. */
advs_1.aflag[h - 1] &= ~ aflags_1.astag;
return ret_val;
L100:
att = fights_(h, 1);
/* !GET HIS STRENGTH. */
oa = att;
def = vilstr_(v);
/* !GET VILL STRENGTH. */
od = def;
dweap = 0;
/* !ASSUME NO WEAPON. */
i__1 = objcts_1.olnt;
for (i = 1; i <= i__1; ++i) {
/* !SEARCH VILLAIN. */
if (objcts_1.ocan[i - 1] == v && (objcts_1.oflag2[i - 1] &
WEAPBT) != 0) {
dweap = i;
}
/* L200: */
}
if (v == advs_1.aobj[aindex_1.player - 1]) {
goto L300;
}
/* !KILLING SELF? */
if (def != 0) {
goto L2000;
}
/* !DEFENDER ALIVE? */
rspsub_(592, dv);
/* !VILLAIN DEAD. */
return ret_val;
L300:
jigsup_(593);
/* !KILLING SELF. */
return ret_val;
/* VILLAIN IS ATTACKER, HERO IS DEFENDER. */
L1000:
pblose = 50;
/* !BAD LK PROB. */
advs_1.aflag[h - 1] &= ~ aflags_1.astag;
if ((objcts_1.oflag2[v - 1] & STAGBT) == 0) {
goto L1200;
}
objcts_1.oflag2[v - 1] &= ~ STAGBT;
rspsub_(594, dv);
/* !DESCRIBE. */
return ret_val;
L1200:
att = vilstr_(v);
/* !SET UP ATT, DEF. */
oa = att;
def = fights_(h, 1);
if (def <= 0) {
return ret_val;
}
/* !DONT ALLOW DEAD DEF. */
od = fights_(h, 0);
dweap = (i__1 = fwim_(0, WEAPBT, 0, 0, h, 1),
abs(i__1));
/* !FIND A WEAPON. */
/* BLOW, PAGE 4 */
/* PARTIES ARE NOW EQUIPPED. DEF CANNOT BE ZERO. */
/* ATT MUST BE > 0. */
L2000:
if (def > 0) {
goto L2100;
}
/* !DEF ALIVE? */
res = rkill;
if (hflg) {
rspsub_(595, dv);
}
/* !DEADER. */
goto L3000;
L2100:
if ((i__1 = def - 2) < 0) {
goto L2200;
} else if (i__1 == 0) {
goto L2300;
} else {
goto L2400;
}
/* !DEF <2,=2,>2 */
L2200:
att = min(att,3);
/* !SCALE ATT. */
tbl = def1r[att - 1];
/* !CHOOSE TABLE. */
goto L2500;
L2300:
att = min(att,4);
/* !SCALE ATT. */
tbl = def2r[att - 1];
/* !CHOOSE TABLE. */
goto L2500;
L2400:
att -= def;
/* !SCALE ATT. */
/* Computing MIN */
i__1 = 2, i__2 = max(-2,att);
att = min(i__1,i__2) + 3;
tbl = def3r[att - 1];
L2500:
res = rvectr[tbl + rnd_(10) - 1];
/* !GET RESULT. */
if (out == 0) {
goto L2600;
}
/* !WAS HE OUT? */
if (res == rstag) {
goto L2550;
}
/* !YES, STAG--> HES. */
res = rsit;
/* !OTHERWISE, SITTING. */
goto L2600;
L2550:
res = rhes;
L2600:
if (res == rstag && dweap != 0 && prob_(25, pblose)) {
res = rlose;
}
mi = rstate[(rmk - 1) * 9 + res];
/* !CHOOSE TABLE ENTRY. */
if (mi == 0) {
goto L3000;
}
i__1 = mi / 1000;
i = mi % 1000 + rnd_(i__1) + star_1.mbase + 1;
j = dv;
if (! (hflg) && dweap != 0) {
j = objcts_1.odesc2[dweap - 1];
}
rspsub_(i, j);
/* !PRESENT RESULT. */
/* BLOW, PAGE 5 */
/* NOW APPLY RESULT */
L3000:
switch (res + 1) {
case 1: goto L4000;
case 2: goto L3100;
case 3: goto L3200;
case 4: goto L3300;
case 5: goto L3400;
case 6: goto L3500;
case 7: goto L3600;
case 8: goto L4000;
case 9: goto L3200;
}
L3100:
if (hflg) {
def = -def;
}
/* !UNCONSCIOUS. */
goto L4000;
L3200:
def = 0;
/* !KILLED OR SITTING DUCK. */
goto L4000;
L3300:
/* Computing MAX */
i__1 = 0, i__2 = def - 1;
def = max(i__1,i__2);
/* !LIGHT WOUND. */
goto L4000;
L3400:
/* Computing MAX */
i__1 = 0, i__2 = def - 2;
def = max(i__1,i__2);
/* !SERIOUS WOUND. */
goto L4000;
L3500:
if (hflg) {
goto L3550;
}
/* !STAGGERED. */
advs_1.aflag[h - 1] |= aflags_1.astag;
goto L4000;
L3550:
objcts_1.oflag2[v - 1] |= STAGBT;
goto L4000;
L3600:
newsta_(dweap, 0, play_1.here, 0, 0);
/* !LOSE WEAPON. */
dweap = 0;
if (hflg) {
goto L4000;
}
/* !IF HERO, DONE. */
dweap = (i__1 = fwim_(0, WEAPBT, 0, 0, h, 1),
abs(i__1));
/* !GET NEW. */
if (dweap != 0) {
rspsub_(605, objcts_1.odesc2[dweap - 1]);
}
/* BLOW, PAGE 6 */
L4000:
ret_val = res;
/* !RETURN RESULT. */
if (! (hflg)) {
goto L4500;
}
/* !HERO? */
objcts_1.ocapac[v - 1] = def;
/* !STORE NEW CAPACITY. */
if (def != 0) {
goto L4100;
}
/* !DEAD? */
objcts_1.oflag2[v - 1] &= ~ FITEBT;
rspsub_(572, dv);
/* !HE DIES. */
newsta_(v, 0, 0, 0, 0);
/* !MAKE HIM DISAPPEAR. */
if (ra == 0) {
return ret_val;
}
/* !IF NX TO DO, EXIT. */
prsvec_1.prsa = vindex_1.deadxw;
/* !LET HIM KNOW. */
f = oappli_(ra, 0);
return ret_val;
L4100:
if (res != rout || ra == 0) {
return ret_val;
}
prsvec_1.prsa = vindex_1.outxw;
/* !LET HIM BE OUT. */
f = oappli_(ra, 0);
return ret_val;
L4500:
advs_1.astren[h - 1] = -10000;
/* !ASSUME DEAD. */
if (def != 0) {
advs_1.astren[h - 1] = def - od;
}
if (def >= od) {
goto L4600;
}
cevent_1.ctick[cindex_1.cevcur - 1] = 30;
cevent_1.cflag[cindex_1.cevcur - 1] = TRUE_;
L4600:
if (fights_(h, 1) > 0) {
return ret_val;
}
advs_1.astren[h - 1] = 1 - fights_(h, 0);
/* !HE'S DEAD. */
jigsup_(596);
ret_val = -1;
return ret_val;
} /* blow_ */
/* SWORDD- SWORD INTERMOVE DEMON */
/* DECLARATIONS */
void swordd_()
{
/* System generated locals */
integer i__1, i__2;
/* Local variables */
integer i, ng;
if (objcts_1.oadv[oindex_1.sword - 1] != aindex_1.player) {
goto L500;
}
/* !HOLDING SWORD? */
ng = 2;
/* !ASSUME VILL CLOSE. */
if (infest_(play_1.here)) {
goto L300;
}
/* !VILL HERE? */
ng = 1;
i__1 = xsrch_1.xmax;
i__2 = xsrch_1.xmin;
for (i = xsrch_1.xmin; i__2 < 0 ? i >= i__1 : i <= i__1; i += i__2) {
/* !NO, SEARCH ROOMS. */
if (! findxt_(i, play_1.here)) {
goto L200;
}
/* !ROOM THAT WAY? */
switch (curxt_1.xtype) {
case 1: goto L50;
case 2: goto L200;
case 3: goto L50;
case 4: goto L50;
}
/* !SEE IF ROOM AT ALL. */
L50:
if (infest_(curxt_1.xroom1)) {
goto L300;
}
/* !CHECK ROOM. */
L200:
;
}
ng = 0;
/* !NO GLOW. */
L300:
if (ng == hack_1.swdsta) {
return;
}
/* !ANY STATE CHANGE? */
i__2 = ng + 495;
rspeak_(i__2);
/* !YES, TELL NEW STATE. */
hack_1.swdsta = ng;
return;
L500:
hack_1.swdact = FALSE_;
/* !DROPPED SWORD, */
return;
/* !DISABLE DEMON. */
} /* swordd_ */
/* INFEST- SUBROUTINE TO TEST FOR INFESTED ROOM */
/* DECLARATIONS */
static logical infest_(r)
integer r;
{
/* System generated locals */
logical ret_val;
if (! findex_1.endgmf) {
ret_val = objcts_1.oroom[oindex_1.cyclo - 1] == r || objcts_1.oroom[
oindex_1.troll - 1] == r || objcts_1.oroom[oindex_1.thief -
1] == r && hack_1.thfact;
}
else {
ret_val = r == rindex_1.mrg || r == rindex_1.mrge || r ==
rindex_1.mrgw || r == rindex_1.inmir && findex_1.mloc ==
rindex_1.mrg;
}
return ret_val;
} /* infest_ */