Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
280 lines (226 sloc) 5.46 KB
#include "diablo.h"
int GetManaAmount(int id, int sn)
{
int i; // "raw" mana cost
int ma; // mana amount
// mana adjust
int adj = 0;
// spell level
int sl = plr[id]._pSplLvl[sn] + plr[id]._pISplLvlAdd - 1;
if (sl < 0) {
sl = 0;
}
if (sl > 0) {
adj = sl * spelldata[sn].sManaAdj;
}
if (sn == SPL_FIREBOLT) {
adj >>= 1;
}
if (sn == SPL_RESURRECT && sl > 0) {
adj = sl * (spelldata[SPL_RESURRECT].sManaCost / 8);
}
if (spelldata[sn].sManaCost == 255) {
i = (BYTE)plr[id]._pMaxManaBase;
} else {
i = spelldata[sn].sManaCost;
}
ma = (i - 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 (plr[id]._pClass == PC_ROGUE) {
ma -= ma >> 2;
}
if (spelldata[sn].sMinMana > ma >> 6) {
ma = spelldata[sn].sMinMana << 6;
}
return ma * (100 - plr[id]._pISplCost) / 100;
}
void UseMana(int id, int sn)
{
int ma; // mana cost
if (id == myplr) {
switch (plr[id]._pSplType) {
case RSPLTYPE_SPELL:
#ifdef _DEBUG
if (!debug_mode_key_inverted_v) {
#endif
ma = GetManaAmount(id, sn);
plr[id]._pMana -= ma;
plr[id]._pManaBase -= ma;
drawmanaflag = TRUE;
#ifdef _DEBUG
}
#endif
break;
case RSPLTYPE_SCROLL:
RemoveScroll(id);
break;
case RSPLTYPE_CHARGES:
UseStaffCharge(id);
break;
}
}
}
BOOL CheckSpell(int id, int sn, char st, BOOL manaonly)
{
BOOL result;
#ifdef _DEBUG
if (debug_mode_key_inverted_v)
return TRUE;
#endif
result = TRUE;
if (!manaonly && pcurs != 1) {
result = FALSE;
} else {
if (st != RSPLTYPE_SKILL) {
if (GetSpellLevel(id, sn) <= 0) {
result = FALSE;
} else {
result = plr[id]._pMana >= GetManaAmount(id, sn);
}
}
}
return result;
}
void CastSpell(int id, int spl, int sx, int sy, int dx, int dy, int caster, int spllvl)
{
int i;
int dir; // missile direction
switch (caster) {
case 1:
dir = monster[id]._mdir;
break;
case 0:
// caster must be 0 already in this case, but oh well,
// it's needed to generate the right code
caster = 0;
dir = plr[id]._pdir;
if (spl == SPL_FIREWALL) {
dir = plr[id]._pVar3;
}
break;
}
for (i = 0; spelldata[spl].sMissiles[i] != MIS_ARROW && 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 = 0; i < (spllvl >> 1) + 3; i++) {
AddMissile(sx, sy, dx, dy, dir, MIS_CBOLT, caster, id, 0, spllvl);
}
}
}
/**
* @param pnum player index
* @param rid target player index
*/
void DoResurrect(int pnum, int rid)
{
int hp;
if ((char)rid != -1) {
AddMissile(plr[rid].WorldX, plr[rid].WorldY, plr[rid].WorldX, plr[rid].WorldY, 0, MIS_RESURRECTBEAM, 0, pnum, 0, 0);
}
if (pnum == myplr) {
NewCursor(CURSOR_HAND);
}
if ((char)rid != -1 && plr[rid]._pHitPoints == 0) {
if (rid == myplr) {
deathflag = FALSE;
gamemenu_off();
drawhpflag = TRUE;
drawmanaflag = TRUE;
}
ClrPlrPath(rid);
plr[rid].destAction = ACTION_NONE;
plr[rid]._pInvincible = FALSE;
PlacePlayer(rid);
hp = 640;
if (plr[rid]._pMaxHPBase < 640) {
hp = plr[rid]._pMaxHPBase;
}
SetPlayerHitPoints(rid, hp);
plr[rid]._pMana = 0;
plr[rid]._pHPBase = plr[rid]._pHitPoints + (plr[rid]._pMaxHPBase - plr[rid]._pMaxHP);
plr[rid]._pManaBase = plr[rid]._pMaxManaBase - plr[rid]._pMaxMana;
CalcPlrInv(rid, TRUE);
if (plr[rid].plrlevel == currlevel) {
StartStand(rid, plr[rid]._pdir);
} else {
plr[rid]._pmode = 0;
}
}
}
void PlacePlayer(int pnum)
{
int nx, ny, max, min, x, y;
DWORD i;
BOOL done;
if (plr[pnum].plrlevel == currlevel) {
for (i = 0; i < 8; i++) {
nx = plr[pnum].WorldX + plrxoff2[i];
ny = plr[pnum].WorldY + plryoff2[i];
if (PosOkPlayer(pnum, nx, ny)) {
break;
}
}
if (!PosOkPlayer(pnum, nx, ny)) {
done = FALSE;
for (max = 1, min = -1; min > -50 && !done; max++, min--) {
for (y = min; y <= max && !done; y++) {
ny = plr[pnum].WorldY + y;
for (x = min; x <= max && !done; x++) {
nx = plr[pnum].WorldX + x;
if (PosOkPlayer(pnum, nx, ny)) {
done = TRUE;
}
}
}
}
}
plr[pnum].WorldX = nx;
plr[pnum].WorldY = ny;
dPlayer[nx][ny] = pnum + 1;
if (pnum == myplr) {
ViewX = nx;
ViewY = ny;
}
}
}
void DoHealOther(int pnum, int rid)
{
int i, j, hp;
if (pnum == myplr) {
NewCursor(CURSOR_HAND);
}
if ((char)rid != -1 && (plr[rid]._pHitPoints >> 6) > 0) {
hp = (random(57, 10) + 1) << 6;
for (i = 0; i < plr[pnum]._pLevel; i++) {
hp += (random(57, 4) + 1) << 6;
}
for (j = 0; j < GetSpellLevel(pnum, SPL_HEALOTHER); ++j) {
hp += (random(57, 6) + 1) << 6;
}
if (plr[pnum]._pClass == PC_WARRIOR) {
hp <<= 1;
}
if (plr[pnum]._pClass == PC_ROGUE) {
hp += hp >> 1;
}
plr[rid]._pHitPoints += hp;
if (plr[rid]._pHitPoints > plr[rid]._pMaxHP) {
plr[rid]._pHitPoints = plr[rid]._pMaxHP;
}
plr[rid]._pHPBase += hp;
if (plr[rid]._pHPBase > plr[rid]._pMaxHPBase) {
plr[rid]._pHPBase = plr[rid]._pMaxHPBase;
}
drawhpflag = TRUE;
}
}
You can’t perform that action at this time.