1
0
Fork 0
mirror of https://github.com/galaxyhaxz/devilution synced 2025-02-22 12:34:59 +00:00
devilution/2020_03_31/Source/spells.cpp
PrisonOfMirrors b720183846 initial up
2020-11-28 18:24:54 -06:00

265 lines
5.1 KiB
C++

#include "diablo.h"
int GetManaAmount(int id, int sn)
{
int i, sl, ma, adj;
adj = 0;
sl = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1;
if(sl < 0) {
sl = 0;
}
for(i = sl; i > 0; i--) {
adj += spelldata[sn].sManaAdj;
}
if(sn == SPL_FIREBOLT) {
adj >>= 1;
}
if(sn == SPL_RESURRECT && sl > 0) {
adj = 0;
for(i = sl; i > 0; i--) {
adj += spelldata[SPL_RESURRECT].sManaCost >> 3;
}
}
if(spelldata[sn].sManaCost == 255) {
ma = ((BYTE)plr[id]._pMaxManaBase - adj) << 6;
} else {
ma = (spelldata[sn].sManaCost - adj) << 6;
}
if(sn == SPL_HEAL) {
ma = (spelldata[SPL_HEAL].sManaCost + 2 * plr[id]._pLevel - adj) << 6;
}
if(sn == SPL_HEALOTHER) {
ma = (spelldata[SPL_HEAL].sManaCost + 2 * plr[id]._pLevel - adj) << 6;
}
if(sn == SPL_RESURRECT) { /// BUGFIX: optimized away, 'adj' has no purpose now
adj = 0;
for(i = sl; i > 0; i--) {
adj += spelldata[SPL_RESURRECT].sManaCost;
}
}
if(plr[id]._pClass == PC_ROGUE) {
ma -= ma >> 2;
}
if(spelldata[sn].sMinMana > ma >> 6) {
ma = spelldata[sn].sMinMana << 6;
}
ma = ma * (100 - plr[id]._pISplCost) / 100;
return ma;
}
void UseMana(int id, int sn)
{
int ma;
if(id != myplr) {
return;
}
switch(plr[id]._pSplType) {
case RSPLTYPE_SKILL:
case RSPLTYPE_INVALID:
break;
case RSPLTYPE_SCROLL:
RemoveScroll(id);
break;
case RSPLTYPE_CHARGES:
UseStaffCharge(id);
break;
case RSPLTYPE_SPELL:
#ifdef _DEBUG
if(debug_mode_key_inverted_v) {
break;
}
#endif
ma = GetManaAmount(id, sn);
plr[id]._pMana -= ma;
plr[id]._pManaBase -= ma;
drawmanaflag = 1;
break;
}
}
BOOL CheckSpell(int id, int sn, char st, BOOL manaonly)
{
int ma;
#ifdef _DEBUG
if(debug_mode_key_inverted_v) {
return TRUE;
}
#endif
if(!manaonly && pcurs != CURSOR_HAND) {
return FALSE;
}
if(st == RSPLTYPE_SKILL) {
return TRUE;
}
if(GetSpellLevel(id, sn) <= 0) {
return FALSE;
}
ma = GetManaAmount(id, sn);
if(plr[id]._pMana < ma) {
return FALSE;
}
return TRUE;
}
void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl)
{
int i, dir;
switch(caster) {
case 0:
dir = plr[id]._pdir;
caster = 0;
if(spl == SPL_FIREWALL) {
dir = plr[id]._pVar3;
}
break;
case 1:
dir = monster[id]._mdir;
break;
}
for(i = 0; spelldata[spl].sMissiles[i] != 0 && i < 3; i++) {
AddMissile(sx, sy, dx, dy, dir, spelldata[spl].sMissiles[i], caster, id, 0, spllvl);
}
if(spelldata[spl].sMissiles[0] == MIS_TOWN) {
UseMana(id, SPL_TOWN);
}
if(spelldata[spl].sMissiles[0] == MIS_CBOLT) {
UseMana(id, SPL_CBOLT);
for(i = (spllvl >> 1) + 3; i > 0; i--) {
AddMissile(sx, sy, dx, dy, dir, MIS_CBOLT, caster, id, 0, spllvl);
}
}
}
static void PlacePlayer(int pnum)
{
int i, j, l, xx, yy;
BOOL done;
if(plr[pnum].plrlevel != currlevel) {
return;
}
for(i = 0; (DWORD)i < 8; i++) {
xx = plr[pnum].WorldX + plrxoff2[i];
yy = plr[pnum].WorldY + plryoff2[i];
if(PosOkPlayer(pnum, xx, yy)) {
break;
}
}
if(!PosOkPlayer(pnum, xx, yy)) {
done = FALSE;
for(l = 1; l < 50 && !done; l++) {
for(j = -l; j <= l && !done; j++) {
yy = j + plr[pnum].WorldY;
for(i = -l; i <= l && !done; i++) {
xx = i + plr[pnum].WorldX;
if(PosOkPlayer(pnum, xx, yy)) {
done = TRUE;
}
}
}
}
}
plr[pnum].WorldX = xx;
plr[pnum].WorldY = yy;
dPlayer[xx][yy] = pnum + 1;
if(pnum == myplr) {
ViewX = xx;
ViewY = yy;
}
}
void DoResurrect(int pnum, int rid)
{
int hp;
if((BYTE)rid != 255) {
AddMissile(plr[rid].WorldX, plr[rid].WorldY, plr[rid].WorldX, plr[rid].WorldY, 0, MIS_RESURRECTBEAM, 0, pnum, 0, 0);
}
if(pnum == myplr) {
SetCursor_(CURSOR_HAND);
}
if((BYTE)rid != 255) {
if(plr[rid]._pHitPoints != 0) {
return;
}
if(rid == myplr) {
deathflag = 0;
gamemenu_off();
drawhpflag = 1;
drawmanaflag = 1;
}
ClrPlrPath(rid);
plr[rid].destAction = -1;
plr[rid]._pInvincible = 0;
PlacePlayer(rid);
hp = 640;
if(plr[rid]._pMaxHPBase < hp) {
hp = plr[rid]._pMaxHPBase;
}
SetPlayerHitPoints(rid, hp);
plr[rid]._pHPBase = plr[rid]._pHitPoints - (plr[rid]._pMaxHP - plr[rid]._pMaxHPBase);
plr[rid]._pMana = 0;
plr[rid]._pManaBase = plr[rid]._pMana - (plr[rid]._pMaxMana - plr[rid]._pMaxManaBase);
CalcPlrInv(rid, TRUE);
if(plr[rid].plrlevel == currlevel) {
StartStand(rid, plr[rid]._pdir);
} else {
plr[rid]._pmode = PM_STAND;
}
}
}
void DoHealOther(int pnum, int rid)
{
int i;
long l;
if(pnum == myplr) {
SetCursor_(CURSOR_HAND);
}
if((BYTE)rid != 255) {
if(plr[rid]._pHitPoints >> 6 <= 0) {
return;
}
l = (random(57, 10) + 1) << 6;
for(i = 0; i < plr[pnum]._pLevel; i++) {
l += (random(57, 4) + 1) << 6;
}
for(i = 0; i < GetSpellLevel(pnum, SPL_HEALOTHER); i++) {
l += (random(57, 6) + 1) << 6;
}
if(plr[pnum]._pClass == PC_WARRIOR) {
l <<= 1;
}
if(plr[pnum]._pClass == PC_ROGUE) {
l += l >> 1;
}
plr[rid]._pHitPoints += l;
if(plr[rid]._pHitPoints > plr[rid]._pMaxHP) {
plr[rid]._pHitPoints = plr[rid]._pMaxHP;
}
plr[rid]._pHPBase += l;
if(plr[rid]._pHPBase > plr[rid]._pMaxHPBase) {
plr[rid]._pHPBase = plr[rid]._pMaxHPBase;
}
drawhpflag = 1;
}
}