Browse Source

Merge branch 'master' of github.com:diasurgical/devilution

pull/959/head
Anders Jenbo 5 years ago
parent
commit
aa3c0242e7
  1. 471
      Source/missiles.cpp
  2. 2
      Source/missiles.h
  3. 111
      Source/mpqapi.cpp
  4. 9
      Source/objects.cpp
  5. 63
      Source/player.cpp

471
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 {

2
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);

111
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;

9
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)

63
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
}
}
}

Loading…
Cancel
Save