diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 219a5230a..536d7fa58 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -668,24 +668,53 @@ BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLE || mor & RESIST_LIGHTNING && mir == MISR_LIGHTNING) resist = TRUE; +#ifdef HELLFIRE + if (t == MIS_HBOLT && (monster[m].MType->mtype == MT_DIABLO || monster[m].MType->mtype == MT_BONEDEMN)) + resist = TRUE; +#endif + hit = random_(69, 100); - if (!missiledata[t].mType) { - hper = plr[pnum]._pDexterity - + plr[pnum]._pIBonusToHit - + plr[pnum]._pLevel - - monster[m].mArmorClass - - (dist * dist >> 1) - + plr[pnum]._pIEnAc - + 50; - if (plr[pnum]._pClass == PC_ROGUE) - hper += 20; - if (plr[pnum]._pClass == PC_WARRIOR) - hper += 10; +#ifdef HELLFIRE + if (pnum != -1) { +#endif + if (missiledata[t].mType == 0) { + hper = plr[pnum]._pDexterity; + hper += plr[pnum]._pIBonusToHit; + hper += plr[pnum]._pLevel; + hper -= monster[m].mArmorClass; + hper -= (dist * dist) >> 1; +#ifdef HELLFIRE + hper -= plr[pnum]._pIEnAc; +#endif +#ifndef HELLFIRE + hper += plr[pnum]._pIEnAc; +#endif + hper += 50; + if (plr[pnum]._pClass == PC_ROGUE) + hper += 20; +#ifdef HELLFIRE + if (plr[pnum]._pClass == PC_WARRIOR || plr[pnum]._pClass == PC_BARD) + hper += 10; +#endif +#ifndef HELLFIRE + if (plr[pnum]._pClass == PC_WARRIOR) + hper += 10; +#endif + } else { + hper = plr[pnum]._pMagic - (monster[m].mLevel << 1) - dist + 50; + if (plr[pnum]._pClass == PC_SORCERER) + hper += 20; +#ifdef HELLFIRE + else if (plr[pnum]._pClass == PC_BARD) + hper += 10; +#endif + } +#ifdef HELLFIRE } else { - hper = plr[pnum]._pMagic - (monster[m].mLevel << 1) - dist + 50; - if (plr[pnum]._pClass == PC_SORCERER) - hper += 20; + hper = random_(71, 75) - monster[m].mLevel * 2; } +#endif + if (hper < 5) hper = 5; if (hper > 95) @@ -695,67 +724,73 @@ BOOL MonsterMHit(int pnum, int m, int mindam, int maxdam, int dist, int t, BOOLE if (CheckMonsterHit(m, &ret)) return ret; #ifdef _DEBUG - if (hit >= hper && !debug_mode_key_inverted_v && !debug_mode_dollar_sign) - return FALSE; + if (hit < hper || debug_mode_key_inverted_v || debug_mode_dollar_sign) { #else - if (hit >= hper) - return FALSE; + if (hit < hper) { #endif - if (t == MIS_BONESPIRIT) { - dam = monster[m]._mhitpoints / 3 >> 6; - } else { - dam = mindam + random_(70, maxdam - mindam + 1); - } - if (!missiledata[t].mType) { - dam = plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100 + dam; - if (plr[pnum]._pClass == PC_ROGUE) - dam += plr[pnum]._pDamageMod; - else - dam += (plr[pnum]._pDamageMod >> 1); - } - if (!shift) - dam <<= 6; - if (resist) - dam >>= 2; - if (pnum == myplr) - monster[m]._mhitpoints -= dam; - if (plr[pnum]._pIFlags & ISPL_FIRE_ARROWS) - monster[m]._mFlags |= MFLAG_NOHEAL; - - if (monster[m]._mhitpoints >> 6 <= 0) { - if (monster[m]._mmode == MM_STONE) { - M_StartKill(m, pnum); - monster[m]._mmode = MM_STONE; + if (t == MIS_BONESPIRIT) { + dam = monster[m]._mhitpoints / 3 >> 6; } else { - M_StartKill(m, pnum); + dam = mindam + random_(70, maxdam - mindam + 1); } - } else { - if (resist) { - PlayEffect(m, 1); - } else if (monster[m]._mmode == MM_STONE) { - if (m > MAX_PLRS - 1) - M_StartHit(m, pnum, dam); - monster[m]._mmode = MM_STONE; + if (missiledata[t].mType == 0) { + dam = plr[pnum]._pIBonusDamMod + dam * plr[pnum]._pIBonusDam / 100 + dam; + if (plr[pnum]._pClass == PC_ROGUE) + dam += plr[pnum]._pDamageMod; + else + dam += (plr[pnum]._pDamageMod >> 1); + } + if (!shift) + dam <<= 6; + if (resist) + dam >>= 2; + if (pnum == myplr) + monster[m]._mhitpoints -= dam; +#ifdef HELLFIRE + if (plr[pnum]._pIFlags & ISPL_NOHEALMON) +#else + if (plr[pnum]._pIFlags & ISPL_FIRE_ARROWS) +#endif + monster[m]._mFlags |= MFLAG_NOHEAL; + + if (monster[m]._mhitpoints >> 6 <= 0) { + if (monster[m]._mmode == MM_STONE) { + M_StartKill(m, pnum); + monster[m]._mmode = MM_STONE; + } else { + M_StartKill(m, pnum); + } } else { - if (!missiledata[t].mType && plr[pnum]._pIFlags & ISPL_KNOCKBACK) { - M_GetKnockback(m); + if (resist) { + PlayEffect(m, 1); + } else if (monster[m]._mmode == MM_STONE) { + if (m > MAX_PLRS - 1) + M_StartHit(m, pnum, dam); + monster[m]._mmode = MM_STONE; + } else { + if (missiledata[t].mType == 0 && plr[pnum]._pIFlags & ISPL_KNOCKBACK) { + M_GetKnockback(m); + } + if (m > MAX_PLRS - 1) + M_StartHit(m, pnum, dam); } - if (m > MAX_PLRS - 1) - M_StartHit(m, pnum, dam); } - } - if (!monster[m]._msquelch) { - monster[m]._msquelch = UCHAR_MAX; - monster[m]._lastx = plr[pnum]._px; - monster[m]._lasty = plr[pnum]._py; + if (monster[m]._msquelch == 0) { + monster[m]._msquelch = UCHAR_MAX; + monster[m]._lastx = plr[pnum]._px; + monster[m]._lasty = plr[pnum]._py; + } + return TRUE; } - return TRUE; + + return FALSE; } -BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag) +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag, BOOLEAN *blocked) { int hit, hper, tac, dam, blk, blkper, resper; + *blocked = false; if (plr[pnum]._pHitPoints >> 6 <= 0) { return FALSE; @@ -765,7 +800,7 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA return FALSE; } - if (plr[pnum]._pSpellFlags & 1 && !missiledata[mtype].mType) { + if (plr[pnum]._pSpellFlags & 1 && missiledata[mtype].mType == 0) { return FALSE; } @@ -774,7 +809,7 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA if (debug_mode_dollar_sign || debug_mode_key_inverted_v) hit = 1000; #endif - if (!missiledata[mtype].mType) { + if (missiledata[mtype].mType == 0) { tac = plr[pnum]._pIAC + plr[pnum]._pIBonusAC + plr[pnum]._pDexterity / 5; if (m != -1) { hper = monster[m].mHit @@ -815,7 +850,7 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA if (mtype == MIS_ACIDPUD) blk = 100; if (m != -1) - blkper = plr[pnum]._pBaseToBlk + (plr[pnum]._pLevel << 1) - (monster[m].mLevel << 1) + plr[pnum]._pDexterity; + blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity - ((monster[m].mLevel - plr[pnum]._pLevel) << 1); else blkper = plr[pnum]._pBaseToBlk + plr[pnum]._pDexterity; if (blkper < 0) @@ -846,19 +881,37 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA if (shift == FALSE) { dam = (mind << 6) + random_(75, (maxd - mind + 1) << 6); - if (m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) - dam >>= 1; +#ifndef HELLFIRE + if (m == -1) +#endif + if (plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) + dam >>= 1; dam += (plr[pnum]._pIGetHit * 64); } else { dam = mind + random_(75, maxd - mind + 1); - if (m == -1 && plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) - dam >>= 1; +#ifndef HELLFIRE + if (m == -1) +#endif + if (plr[pnum]._pIFlags & ISPL_ABSHALFTRAP) + dam >>= 1; dam += plr[pnum]._pIGetHit; } if (dam < 64) dam = 64; } +#ifdef HELLFIRE + if (blk < blkper) { + if (m != -1) { + tac = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[m]._mx, monster[m]._my); + } else { + tac = plr[pnum]._pdir; + } + *blocked = true; + StartPlrBlock(pnum, tac); + return TRUE; + } +#endif if (resper > 0) { dam = dam - dam * resper / 100; @@ -880,10 +933,20 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); } else if (plr[pnum]._pClass == PC_SORCERER) { PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); +#ifdef HELLFIRE + } else if (plr[pnum]._pClass == PC_MONK) { + PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + } else if (plr[pnum]._pClass == PC_BARD) { + PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + } else if (plr[pnum]._pClass == PC_BARBARIAN) { + PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); +#endif } drawhpflag = TRUE; } + return TRUE; } else { +#ifndef HELLFIRE if (blk < blkper) { if (m != -1) { tac = GetDirection(plr[pnum]._px, plr[pnum]._py, monster[m]._mx, monster[m]._my); @@ -891,7 +954,9 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA tac = plr[pnum]._pdir; } StartPlrBlock(pnum, tac); - } else { + } else +#endif + { if (pnum == myplr) { plr[pnum]._pHitPoints -= dam; plr[pnum]._pHPBase -= dam; @@ -906,15 +971,17 @@ BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEA StartPlrHit(pnum, dam, FALSE); } } + return TRUE; } - return TRUE; } return FALSE; } -BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift) +BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, BOOLEAN shift, BOOLEAN *blocked) { - int tac, resper, dam, blk, blkper, hper, hit; + int dam, blk, blkper, hper, hit, resper; + + *blocked = false; if (plr[p]._pInvincible) { return FALSE; @@ -924,7 +991,7 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B return FALSE; } - if (plr[p]._pSpellFlags & 1 && !missiledata[mtype].mType) { + if (plr[p]._pSpellFlags & 1 && missiledata[mtype].mType == 0) { return FALSE; } @@ -944,7 +1011,7 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B break; } hper = random_(69, 100); - if (!missiledata[mtype].mType) { + if (missiledata[mtype].mType == 0) { hit = plr[pnum]._pIBonusToHit + plr[pnum]._pLevel - (dist * dist >> 1) @@ -954,7 +1021,11 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B + plr[pnum]._pDexterity + 50; if (plr[pnum]._pClass == PC_ROGUE) hit += 20; +#ifdef HELLFIRE + if (plr[pnum]._pClass == PC_WARRIOR || plr[pnum]._pClass == PC_BARD) +#else if (plr[pnum]._pClass == PC_WARRIOR) +#endif hit += 10; } else { hit = plr[pnum]._pMagic @@ -963,6 +1034,10 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B + 50; if (plr[pnum]._pClass == PC_SORCERER) hit += 20; +#ifdef HELLFIRE + else if (plr[pnum]._pClass == PC_BARD) + hit += 10; +#endif } if (hit < 5) hit = 5; @@ -989,36 +1064,44 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B dam = plr[p]._pHitPoints / 3; } else { dam = mindam + random_(70, maxdam - mindam + 1); - if (!missiledata[mtype].mType) + if (missiledata[mtype].mType == 0) dam += plr[pnum]._pIBonusDamMod + plr[pnum]._pDamageMod + dam * plr[pnum]._pIBonusDam / 100; if (!shift) dam <<= 6; } - if (missiledata[mtype].mType) + if (missiledata[mtype].mType != 0) dam >>= 1; if (resper > 0) { + dam -= (dam * resper) / 100; if (pnum == myplr) - NetSendCmdDamage(TRUE, p, dam - resper * dam / 100); + NetSendCmdDamage(TRUE, p, dam); if (plr[pnum]._pClass == PC_WARRIOR) { - tac = PS_WARR69; + PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); } else if (plr[pnum]._pClass == PC_ROGUE) { - tac = PS_ROGUE69; + PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); } else if (plr[pnum]._pClass == PC_SORCERER) { - tac = PS_MAGE69; - } else { - return TRUE; + PlaySfxLoc(PS_MAGE69, plr[pnum]._px, plr[pnum]._py); +#ifdef HELLFIRE + } else if (plr[pnum]._pClass == PC_MONK) { + PlaySfxLoc(PS_MONK69, plr[pnum]._px, plr[pnum]._py); + } else if (plr[pnum]._pClass == PC_BARD) { + PlaySfxLoc(PS_ROGUE69, plr[pnum]._px, plr[pnum]._py); + } else if (plr[pnum]._pClass == PC_BARBARIAN) { + PlaySfxLoc(PS_WARR69, plr[pnum]._px, plr[pnum]._py); +#endif } - PlaySfxLoc(tac, plr[pnum]._px, plr[pnum]._py); + return TRUE; } else { if (blkper < blk) { StartPlrBlock(p, GetDirection(plr[p]._px, plr[p]._py, plr[pnum]._px, plr[pnum]._py)); + *blocked = true; } else { if (pnum == myplr) NetSendCmdDamage(TRUE, p, dam); StartPlrHit(p, dam, FALSE); } + return TRUE; } - return TRUE; } return FALSE; } @@ -1026,8 +1109,20 @@ BOOL Plr2PlrMHit(int pnum, int p, int mindam, int maxdam, int dist, int mtype, B void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, BOOLEAN nodel) { int oi; + BOOLEAN blocked; +#ifdef HELLFIRE + int dir, mAnimFAmt; + if (i >= MAXMISSILES || i < 0) + return; + if (mx >= MAXDUNX || mx < 0) + return; + if (my >= MAXDUNY || my < 0) + return; + if (missile[i]._micaster != TARGET_BOTH && missile[i]._misource != -1) { +#else if (missile[i]._miAnimType != MFILE_FIREWAL && missile[i]._misource != -1) { +#endif if (missile[i]._micaster == TARGET_MONSTERS) { if (dMonster[mx][my] > 0) { if (MonsterMHit( @@ -1067,9 +1162,24 @@ void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, maxdam, missile[i]._midist, missile[i]._mitype, - shift)) { - if (!nodel) - missile[i]._mirange = 0; + shift, + &blocked)) { +#ifdef HELLFIRE + if (blocked) { + dir = missile[i]._mimfnum + (random_(10, 2) ? 1 : -1); + mAnimFAmt = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (dir < 0) + dir = mAnimFAmt - 1; + else if (dir > mAnimFAmt) + dir = 0; + + SetMissDir(i, dir); + } else +#endif + { + if (!nodel) + missile[i]._mirange = 0; + } missile[i]._miHitFlag = TRUE; } } else { @@ -1090,15 +1200,34 @@ void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, maxdam, missile[i]._mitype, shift, - 0)) { - if (!nodel) - missile[i]._mirange = 0; + 0, + &blocked)) { +#ifdef HELLFIRE + if (blocked) { + dir = missile[i]._mimfnum + (random_(10, 2) ? 1 : -1); + mAnimFAmt = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (dir < 0) + dir = mAnimFAmt - 1; + else if (dir > mAnimFAmt) + dir = 0; + + SetMissDir(i, dir); + } else +#endif + { + if (!nodel) + missile[i]._mirange = 0; + } missile[i]._miHitFlag = TRUE; } } } else { if (dMonster[mx][my] > 0) { +#ifdef HELLFIRE + if (missile[i]._micaster == TARGET_BOTH) { +#else if (missile[i]._miAnimType == MFILE_FIREWAL) { +#endif if (MonsterMHit( missile[i]._misource, dMonster[mx][my] - 1, @@ -1118,9 +1247,28 @@ void CheckMissileCol(int i, int mindam, int maxdam, BOOL shift, int mx, int my, } } if (dPlayer[mx][my] > 0 - && PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, missile[i]._miAnimType == MFILE_FIREWAL)) { - if (!nodel) - missile[i]._mirange = 0; + && PlayerMHit(dPlayer[mx][my] - 1, -1, missile[i]._midist, mindam, maxdam, missile[i]._mitype, shift, missile[i]._miAnimType == MFILE_FIREWAL +#ifdef HELLFIRE + || missile[i]._miAnimType == MFILE_LGHNING +#endif + , + &blocked)) { +#ifdef HELLFIRE + if (blocked) { + dir = missile[i]._mimfnum + (random_(10, 2) ? 1 : -1); + mAnimFAmt = misfiledata[missile[i]._miAnimType].mAnimFAmt; + if (dir < 0) + dir = mAnimFAmt - 1; + else if (dir > mAnimFAmt) + dir = 0; + + SetMissDir(i, dir); + } else +#endif + { + if (!nodel) + missile[i]._mirange = 0; + } missile[i]._miHitFlag = TRUE; } } @@ -1567,46 +1715,48 @@ void missiles_steal_pots(int mi, int sx, int sy, int dx, int dy, int midir, char for (si = 0; si < MAXBELTITEMS; si++) { ii = -1; if (plr[pnum].SpdList[si]._itype == ITYPE_MISC) { - if (random_(205, 2) != 0) { - switch (plr[pnum].SpdList[si]._iMiscId) { - case IMISC_FULLHEAL: - ii = ItemMiscIdIdx(IMISC_HEAL); - break; - case IMISC_HEAL: - case IMISC_MANA: - RemoveSpdBarItem(pnum, si); - continue; - case IMISC_FULLMANA: + if (random_(205, 2) == 0) + continue; + switch (plr[pnum].SpdList[si]._iMiscId) { + case IMISC_FULLHEAL: + ii = ItemMiscIdIdx(IMISC_HEAL); + break; + case IMISC_HEAL: + case IMISC_MANA: + RemoveSpdBarItem(pnum, si); + continue; + case IMISC_FULLMANA: + ii = ItemMiscIdIdx(IMISC_MANA); + break; + case IMISC_REJUV: + if (random_(205, 2) != 0) { ii = ItemMiscIdIdx(IMISC_MANA); - break; - case IMISC_REJUV: - if (random_(205, 2) != 0) { - ii = ItemMiscIdIdx(IMISC_MANA); - } else { - ii = ItemMiscIdIdx(IMISC_HEAL); - } + } else { ii = ItemMiscIdIdx(IMISC_HEAL); + } + ii = ItemMiscIdIdx(IMISC_HEAL); + break; + case IMISC_FULLREJUV: + switch (random_(205, 3)) { + case 0: + ii = ItemMiscIdIdx(IMISC_FULLMANA); break; - case IMISC_FULLREJUV: - switch (random_(205, 3)) { - case 0: - ii = ItemMiscIdIdx(IMISC_FULLMANA); - break; - case 1: - ii = ItemMiscIdIdx(IMISC_FULLHEAL); - break; - default: - ii = ItemMiscIdIdx(IMISC_REJUV); - break; - } + case 1: + ii = ItemMiscIdIdx(IMISC_FULLHEAL); + break; + default: + ii = ItemMiscIdIdx(IMISC_REJUV); break; } + break; + default: + continue; } } if (ii != -1) { SetPlrHandItem(&plr[pnum].HoldItem, ii); GetPlrHandSeed(&plr[pnum].HoldItem); - plr[pnum].HoldItem._iStatFlag = 1; + plr[pnum].HoldItem._iStatFlag = TRUE; plr[pnum].SpdList[si] = plr[pnum].HoldItem; } if (!hasPlayedSFX) { @@ -2283,14 +2433,26 @@ void AddFirewall(int mi, int sx, int sy, int dx, int dy, int midir, char mienemy { int i; - missile[mi]._midam = (random_(53, 10) + random_(53, 10) + plr[id]._pLevel + 2) << 4; +#ifdef HELLFIRE + missile[mi]._midam = (random_(53, 10) + random_(53, 10) + 2 + (id > 0) ? plr[id]._pLevel : currlevel); // BUGFIX: missing parenthesis around ternary +#else + missile[mi]._midam = (random_(53, 10) + random_(53, 10) + 2 + plr[id]._pLevel); +#endif + missile[mi]._midam <<= 4; missile[mi]._midam >>= 1; GetMissileVel(mi, sx, sy, dx, dy, 16); - missile[mi]._mirange = 10; i = missile[mi]._mispllvl; + missile[mi]._mirange = 10; +#ifndef HELLFIRE if (i > 0) - missile[mi]._mirange = 10 * (i + 1); - missile[mi]._mirange += (plr[id]._pISplDur * missile[mi]._mirange) >> 7; +#endif + missile[mi]._mirange *= i + 1; +#ifdef HELLFIRE + if (mienemy != TARGET_MONSTERS || id < 0) + missile[mi]._mirange += currlevel; + else +#endif + missile[mi]._mirange += (plr[id]._pISplDur * missile[mi]._mirange) >> 7; missile[mi]._mirange <<= 4; missile[mi]._miVar1 = missile[mi]._mirange - missile[mi]._miAnimLen; missile[mi]._miVar2 = 0; @@ -4169,40 +4331,40 @@ void mi_light_arrow(int i) && monster[missile[i]._misource].MType->mtype >= MT_STORM && monster[missile[i]._misource].MType->mtype <= MT_MAEL) { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIS_LIGHTNING2, missile[i]._micaster, missile[i]._misource, - dam, + missile[i]._midam, missile[i]._mispllvl); } else { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIS_LIGHTNING, missile[i]._micaster, missile[i]._misource, - dam, + missile[i]._midam, missile[i]._mispllvl); } } else { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, MIS_LIGHTNING, missile[i]._micaster, missile[i]._misource, - dam, + missile[i]._midam, missile[i]._mispllvl); } missile[i]._miVar1 = missile[i]._mix; @@ -4519,8 +4681,8 @@ void MI_Lightctrl(int i) && monster[missile[i]._misource].MType->mtype >= MT_STORM && monster[missile[i]._misource].MType->mtype <= MT_MAEL) { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, @@ -4531,8 +4693,8 @@ void MI_Lightctrl(int i) missile[i]._mispllvl); } else { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, @@ -4544,8 +4706,8 @@ void MI_Lightctrl(int i) } } else { AddMissile( - mx, - my, + missile[i]._mix, + missile[i]._miy, missile[i]._misx, missile[i]._misy, i, @@ -5184,26 +5346,35 @@ void mi_null_32(int i) void MI_FirewallC(int i) { - int tx, ty, id; + int tx, ty, id, dp, micaster; - id = missile[i]._misource; missile[i]._mirange--; + id = missile[i]._misource; if (missile[i]._mirange == 0) { missile[i]._miDelFlag = TRUE; } else { +#ifdef HELLFIRE + micaster = TARGET_BOTH; +#else + micaster = TARGET_MONSTERS; +#endif + dp = dPiece[missile[i]._miVar1][missile[i]._miVar2]; + assert(dp <= MAXTILES && dp >= 0); tx = missile[i]._miVar1 + XDirAdd[missile[i]._miVar3]; ty = missile[i]._miVar2 + YDirAdd[missile[i]._miVar3]; - if (!nMissileTable[dPiece[missile[i]._miVar1][missile[i]._miVar2]] && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { - AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIS_FIREWALL, TARGET_MONSTERS, id, 0, missile[i]._mispllvl); + if (!nMissileTable[dp] && missile[i]._miVar8 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar1, missile[i]._miVar2, missile[i]._miVar1, missile[i]._miVar2, plr[id]._pdir, MIS_FIREWALL, micaster, id, 0, missile[i]._mispllvl); missile[i]._miVar1 = tx; missile[i]._miVar2 = ty; } else { missile[i]._miVar8 = 1; } + dp = dPiece[missile[i]._miVar5][missile[i]._miVar6]; + assert(dp <= MAXTILES && dp >= 0); tx = missile[i]._miVar5 + XDirAdd[missile[i]._miVar4]; ty = missile[i]._miVar6 + YDirAdd[missile[i]._miVar4]; - if (!nMissileTable[dPiece[missile[i]._miVar5][missile[i]._miVar6]] && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { - AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIS_FIREWALL, TARGET_MONSTERS, id, 0, missile[i]._mispllvl); + if (!nMissileTable[dp] && missile[i]._miVar7 == 0 && tx > 0 && tx < MAXDUNX && ty > 0 && ty < MAXDUNY) { + AddMissile(missile[i]._miVar5, missile[i]._miVar6, missile[i]._miVar5, missile[i]._miVar6, plr[id]._pdir, MIS_FIREWALL, micaster, id, 0, missile[i]._mispllvl); missile[i]._miVar5 = tx; missile[i]._miVar6 = ty; } else { diff --git a/Source/missiles.h b/Source/missiles.h index 781306580..c35b0fc49 100644 --- a/Source/missiles.h +++ b/Source/missiles.h @@ -22,7 +22,7 @@ void GetDamageAmt(int i, int *mind, int *maxd); int GetSpellLevel(int id, int sn); void DeleteMissile(int mi, int i); BOOL MonsterTrapHit(int m, int mindam, int maxdam, int dist, int t, BOOLEAN shift); -BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag); +BOOL PlayerMHit(int pnum, int m, int dist, int mind, int maxd, int mtype, BOOLEAN shift, int earflag, BOOLEAN *blocked); void SetMissAnim(int mi, int animtype); void SetMissDir(int mi, int dir); void LoadMissileGFX(BYTE mi); diff --git a/Source/mpqapi.cpp b/Source/mpqapi.cpp index 92f6e2e01..cb979b076 100644 --- a/Source/mpqapi.cpp +++ b/Source/mpqapi.cpp @@ -349,24 +349,26 @@ bool ReadMPQHeader(Archive *archive, _FILEHEADER *hdr) static _BLOCKENTRY *mpqapi_new_block(int *block_index) { - _BLOCKENTRY *blockEntry; - DWORD i; + _BLOCKENTRY *blockEntry = cur_archive.sgpBlockTbl; - blockEntry = cur_archive.sgpBlockTbl; + for (DWORD i = 0; i < 2048; i++, blockEntry++) { + if (blockEntry->offset != 0) + continue; + if (blockEntry->sizealloc != 0) + continue; + if (blockEntry->flags != 0) + continue; + if (blockEntry->sizefile != 0) + continue; - i = 0; - while (blockEntry->offset || blockEntry->sizealloc || blockEntry->flags || blockEntry->sizefile) { - i++; - blockEntry++; - if (i >= 2048) { - app_fatal("Out of free block entries"); - return NULL; - } + if (block_index) + *block_index = i; + + return blockEntry; } - if (block_index) - *block_index = i; - return blockEntry; + app_fatal("Out of free block entries"); + return NULL; } void mpqapi_alloc_block(uint32_t block_offset, uint32_t block_size) @@ -410,47 +412,54 @@ void mpqapi_alloc_block(uint32_t block_offset, uint32_t block_size) int mpqapi_find_free_block(uint32_t size, uint32_t *block_size) { - _BLOCKENTRY *pBlockTbl; - int i, result; + int result; + + _BLOCKENTRY *pBlockTbl = cur_archive.sgpBlockTbl; + for (int i = 2048; i--; pBlockTbl++) { + if (pBlockTbl->offset == 0) + continue; + if (pBlockTbl->flags != 0) + continue; + if (pBlockTbl->sizefile != 0) + continue; + if ((DWORD)pBlockTbl->sizealloc < size) + continue; + + result = pBlockTbl->offset; + *block_size = size; + pBlockTbl->offset += size; + pBlockTbl->sizealloc -= size; + + if (pBlockTbl->sizealloc == 0) + memset(pBlockTbl, 0, sizeof(*pBlockTbl)); - pBlockTbl = cur_archive.sgpBlockTbl; - i = 2048; - while (1) { - i--; - if (pBlockTbl->offset && !pBlockTbl->flags && !pBlockTbl->sizefile && (DWORD)pBlockTbl->sizealloc >= size) - break; - pBlockTbl++; - if (!i) { - *block_size = size; - result = cur_archive.size; - cur_archive.size += size; - return result; - } + return result; } - result = pBlockTbl->offset; *block_size = size; - pBlockTbl->offset += size; - pBlockTbl->sizealloc -= size; - - if (!pBlockTbl->sizealloc) - memset(pBlockTbl, 0, sizeof(*pBlockTbl)); - + result = cur_archive.size; + cur_archive.size += size; return result; } -static int mpqapi_get_hash_index(short index, int hash_a, int hash_b, int locale) +static int mpqapi_get_hash_index(int index, int hash_a, int hash_b, int locale) { - int idx, i; + DWORD idx, i; i = 2048; for (idx = index & 0x7FF; cur_archive.sgpHashTbl[idx].block != -1; idx = (idx + 1) & 0x7FF) { - if (!i--) + if (i-- == 0) break; - if (cur_archive.sgpHashTbl[idx].hashcheck[0] == hash_a && cur_archive.sgpHashTbl[idx].hashcheck[1] == hash_b - && cur_archive.sgpHashTbl[idx].lcid == locale - && cur_archive.sgpHashTbl[idx].block != -2) - return idx; + if (cur_archive.sgpHashTbl[idx].hashcheck[0] != hash_a) + continue; + if (cur_archive.sgpHashTbl[idx].hashcheck[1] != hash_b) + continue; + if (cur_archive.sgpHashTbl[idx].lcid != locale) + continue; + if (cur_archive.sgpHashTbl[idx].block == -2) + continue; + + return idx; } return -1; @@ -523,13 +532,12 @@ static _BLOCKENTRY *mpqapi_add_file(const char *pszName, _BLOCKENTRY *pBlk, int static BOOL mpqapi_write_file_contents(const char *pszName, const BYTE *pbData, DWORD dwLen, _BLOCKENTRY *pBlk) { - const char *str_ptr = pszName; const char *tmp; - while ((tmp = strchr(str_ptr, ':'))) - str_ptr = tmp + 1; - while ((tmp = strchr(str_ptr, '\\'))) - str_ptr = tmp + 1; - Hash(str_ptr, 3); + while ((tmp = strchr(pszName, ':'))) + pszName = tmp + 1; + while ((tmp = strchr(pszName, '\\'))) + pszName = tmp + 1; + Hash(pszName, 3); constexpr uint32_t kSectorSize = 4096; const uint32_t num_sectors = (dwLen + (kSectorSize - 1)) / kSectorSize; @@ -566,14 +574,13 @@ static BOOL mpqapi_write_file_contents(const char *pszName, const BYTE *pbData, } #endif - const BYTE *src = pbData; uint32_t destsize = offset_table_bytesize; BYTE mpq_buf[kSectorSize]; std::size_t cur_sector = 0; while (true) { uint32_t len = std::min(dwLen, kSectorSize); - memcpy(mpq_buf, src, len); - src += len; + memcpy(mpq_buf, pbData, len); + pbData += len; len = PkwareCompress(mpq_buf, len); if (!cur_archive.stream.write((char *)mpq_buf, len)) return FALSE; diff --git a/Source/objects.cpp b/Source/objects.cpp index 530cedb9b..2341738fa 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -2032,8 +2032,10 @@ void Obj_FlameTrap(int i) y = object[i]._oy; if (dMonster[x][y] > 0) MonsterTrapHit(dMonster[x][y] - 1, mindam / 2, maxdam / 2, 0, MIS_FIREWALLC, FALSE); - if (dPlayer[x][y] > 0) - PlayerMHit(dPlayer[x][y] - 1, -1, 0, mindam, maxdam, MIS_FIREWALLC, FALSE, 0); + if (dPlayer[x][y] > 0) { + BOOLEAN unused; + PlayerMHit(dPlayer[x][y] - 1, -1, 0, mindam, maxdam, MIS_FIREWALLC, FALSE, 0, &unused); + } if (object[i]._oAnimFrame == object[i]._oAnimLen) object[i]._oAnimFrame = 11; @@ -4904,8 +4906,9 @@ void BreakBarrel(int pnum, int i, int dam, BOOL forcebreak, BOOL sendmsg) for (xp = object[i]._ox - 1; xp <= object[i]._ox + 1; xp++) { if (dMonster[xp][yp] > 0) MonsterTrapHit(dMonster[xp][yp] - 1, 1, 4, 0, MIS_FIREBOLT, FALSE); + BOOLEAN unused; if (dPlayer[xp][yp] > 0) - PlayerMHit(dPlayer[xp][yp] - 1, -1, 0, 8, 16, MIS_FIREBOLT, FALSE, 0); + PlayerMHit(dPlayer[xp][yp] - 1, -1, 0, 8, 16, MIS_FIREBOLT, FALSE, 0, &unused); if (dObject[xp][yp] > 0) { oi = dObject[xp][yp] - 1; if (object[oi]._otype == OBJ_BARRELEX && object[oi]._oBreak != -1) diff --git a/Source/player.cpp b/Source/player.cpp index 56704fc3a..d7b0ac5cf 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -2116,7 +2116,6 @@ void DropHalfPlayersGold(int pnum) plr[pnum]._pGold = CalculateGold(pnum); } -#ifdef HELLFIRE void StripTopGold(int pnum) { ItemStruct tmpItem; @@ -2146,16 +2145,11 @@ void StripTopGold(int pnum) plr[pnum].HoldItem = tmpItem; } -#endif void SyncPlrKill(int pnum, int earflag) { int ma, i; -#ifdef HELLFIRE if (plr[pnum]._pHitPoints <= 0 && currlevel == 0) { -#else - if (plr[pnum]._pHitPoints == 0 && currlevel == 0) { -#endif SetPlayerHitPoints(pnum, 64); return; } @@ -3968,7 +3962,7 @@ void MakePlrPath(int pnum, int xx, int yy, BOOL endspace) void CheckPlrSpell() { - BOOL addflag; + BOOL addflag = FALSE; int rspell, sd, sl; if ((DWORD)myplr >= MAX_PLRS) { @@ -3983,6 +3977,14 @@ void CheckPlrSpell() PlaySFX(PS_ROGUE34); } else if (plr[myplr]._pClass == PC_SORCERER) { PlaySFX(PS_MAGE34); +#ifdef HELLFIRE + } else if (plr[myplr]._pClass == PC_MONK) { + PlaySFX(PS_MONK34); + } else if (plr[myplr]._pClass == PC_BARD) { + PlaySFX(PS_ROGUE34); + } else if (plr[myplr]._pClass == PC_BARBARIAN) { + PlaySFX(PS_WARR34); +#endif } return; } @@ -3994,25 +3996,38 @@ void CheckPlrSpell() PlaySFX(PS_ROGUE27); } else if (plr[myplr]._pClass == PC_SORCERER) { PlaySFX(PS_MAGE27); +#ifdef HELLFIRE + } else if (plr[myplr]._pClass == PC_MONK) { + PlaySFX(PS_MONK27); + } else if (plr[myplr]._pClass == PC_BARD) { + PlaySFX(PS_ROGUE27); + } else if (plr[myplr]._pClass == PC_BARBARIAN) { + PlaySFX(PS_WARR27); +#endif } return; } if (!sgbControllerActive) { - if (pcurs != CURSOR_HAND - || (MouseY >= PANEL_TOP && MouseX >= PANEL_LEFT && MouseX <= RIGHT_PANEL) // inside main panel - || ((chrflag || questlog) && MouseX < SPANEL_WIDTH && MouseY < SPANEL_HEIGHT) // inside left panel - || ((invflag || sbookflag) && MouseX > RIGHT_PANEL && MouseY < SPANEL_HEIGHT) // inside right panel - && rspell != SPL_HEAL - && rspell != SPL_IDENTIFY - && rspell != SPL_REPAIR - && rspell != SPL_INFRA - && rspell != SPL_RECHARGE) { + if (pcurs != CURSOR_HAND) + return; + + if (MouseY >= PANEL_TOP && MouseX >= PANEL_LEFT && MouseX <= RIGHT_PANEL) // inside main panel return; + + if ( + ((chrflag || questlog) && MouseX < SPANEL_WIDTH && MouseY < SPANEL_HEIGHT) // inside left panel + || ((invflag || sbookflag) && MouseX > RIGHT_PANEL && MouseY < SPANEL_HEIGHT) // inside right panel + ) { + if (rspell != SPL_HEAL + && rspell != SPL_IDENTIFY + && rspell != SPL_REPAIR + && rspell != SPL_INFRA + && rspell != SPL_RECHARGE) + return; } } - addflag = FALSE; switch (plr[myplr]._pRSplType) { case RSPLTYPE_SKILL: case RSPLTYPE_SPELL: @@ -4027,7 +4042,11 @@ void CheckPlrSpell() } if (addflag) { - if (plr[myplr]._pRSpell == SPL_FIREWALL) { + if (plr[myplr]._pRSpell == SPL_FIREWALL +#ifdef HELLFIRE + || plr[myplr]._pRSpell == SPL_LIGHTWALL +#endif + ) { sd = GetDirection(plr[myplr]._px, plr[myplr]._py, cursmx, cursmy); sl = GetSpellLevel(myplr, plr[myplr]._pRSpell); NetSendCmdLocParam3(TRUE, CMD_SPELLXYD, cursmx, cursmy, plr[myplr]._pRSpell, sd, sl); @@ -4051,6 +4070,14 @@ void CheckPlrSpell() PlaySFX(PS_ROGUE35); } else if (plr[myplr]._pClass == PC_SORCERER) { PlaySFX(PS_MAGE35); +#ifdef HELLFIRE + } else if (plr[myplr]._pClass == PC_MONK) { + PlaySFX(PS_MONK35); + } else if (plr[myplr]._pClass == PC_BARD) { + PlaySFX(PS_ROGUE35); + } else if (plr[myplr]._pClass == PC_BARBARIAN) { + PlaySFX(PS_WARR35); +#endif } } }