aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/sprites_lol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra/sprites_lol.cpp')
-rw-r--r--engines/kyra/sprites_lol.cpp226
1 files changed, 150 insertions, 76 deletions
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index 7d8ca049a3..9c9038ca71 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -80,8 +80,7 @@ void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int b) {
uint8 *tmpPal2 = new uint8[256];
uint16 *tmpPal3 = new uint16[256];
memset (tmpPal1, 0, 64);
- memset (tmpPal2, 0, 256);
- memset (tmpPal3, 0xff, 512);
+ memset (tmpPal2, 0, 256);
for (int i = 0; i < 64; i++) {
tmpPal1[i] = *p;
@@ -93,6 +92,7 @@ void LoLEngine::loadMonsterShapes(const char *file, int monsterIndex, int b) {
for (int i = 0; i < 16; i++) {
int pos = (monsterIndex << 4) + i;
memcpy(tmpPal2, _monsterShapes[pos] + 10, 256);
+ memset (tmpPal3, 0xff, 512);
uint8 numCol = *tmpPal2;
for (int ii = 0; ii < numCol; ii++) {
@@ -152,7 +152,7 @@ int LoLEngine::deleteMonstersFromBlock(int block) {
cnt++;
setMonsterMode(m, 14);
- checkSceneUpdateNeed(m->blockPropertyIndex);
+ checkSceneUpdateNeed(m->block);
placeMonster(m, 0, 0);
@@ -184,14 +184,14 @@ void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
monster->mode = mode;
monster->fightCurTick = 0;
if (mode == 14)
- monster->might = 0;
+ monster->hitPoints = 0;
if (mode == 13 && (monster->flags & 0x20)) {
monster->mode = 0;
monsterDropItems(monster);
if (_currentLevel != 29)
setMonsterMode(monster, 14);
runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
if (monster->mode == 14)
placeMonster(monster, 0, 0);
}
@@ -230,7 +230,7 @@ bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
return false;
for (int i = 0; i < 18; i++)
- _visibleBlocks[i] = &_levelBlockProperties[(monster->blockPropertyIndex + _dscBlockIndex[dir + i]) & 0x3ff];
+ _visibleBlocks[i] = &_levelBlockProperties[(monster->block + _dscBlockIndex[dir + i]) & 0x3ff];
int16 fx1 = 0;
int16 fx2 = 0;
@@ -241,8 +241,8 @@ bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
bool cont = true;
- int t = monster->blockPropertyIndex;
- if (monster->blockPropertyIndex) {
+ int t = monster->block;
+ if (monster->block) {
removeAssignedObjectFromBlock(&_levelBlockProperties[t], ((uint16)monster->id) | 0x8000);
_levelBlockProperties[t].direction = 5;
checkSceneUpdateNeed(t);
@@ -250,7 +250,7 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
cont = false;
}
- monster->blockPropertyIndex = calcBlockIndex(x, y);
+ monster->block = calcBlockIndex(x, y);
if (monster->x != x || monster->y != y) {
monster->x = x;
@@ -258,26 +258,26 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
monster->currentSubFrame = (++monster->currentSubFrame) & 3;
}
- if (monster->blockPropertyIndex == 0)
+ if (monster->block == 0)
return;
- assignMonsterToBlock(&_levelBlockProperties[monster->blockPropertyIndex].assignedObjects, ((uint16)monster->id) | 0x8000);
- _levelBlockProperties[monster->blockPropertyIndex].direction = 5;
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ assignMonsterToBlock(&_levelBlockProperties[monster->block].assignedObjects, ((uint16)monster->id) | 0x8000);
+ _levelBlockProperties[monster->block].direction = 5;
+ checkSceneUpdateNeed(monster->block);
if (monster->properties->sounds[0] == 0 || cont == false)
return;
- if ((!(monster->properties->flags & 0x100) || ((monster->currentSubFrame & 1) == 0)) && monster->blockPropertyIndex == t)
+ if ((!(monster->properties->flags & 0x100) || ((monster->currentSubFrame & 1) == 0)) && monster->block == t)
return;
- if (monster->blockPropertyIndex != t)
- runLevelScriptCustom(monster->blockPropertyIndex, 0x800, -1, monster->id, 0, 0);
+ if (monster->block != t)
+ runLevelScriptCustom(monster->block, 0x800, -1, monster->id, 0, 0);
if (_updateFlags & 1)
return;
- snd_processEnvironmentalSoundEffect(monster->properties->sounds[0], monster->blockPropertyIndex);
+ snd_processEnvironmentalSoundEffect(monster->properties->sounds[0], monster->block);
}
int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
@@ -319,7 +319,7 @@ void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
if (!(dir & 1) || ((monster->direction - (monster->facing << 1)) >= 2))
monster->facing = monster->direction >> 1;
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
}
void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
@@ -651,45 +651,45 @@ void LoLEngine::drawMonster(uint16 id) {
}
}
- if (!m->field_1B)
+ if (!m->damageReceived)
return;
int dW = _screen->getShapeScaledWidth(shp, _dmScaleW) >> 1;
int dH = _screen->getShapeScaledHeight(shp, _dmScaleH) >> 1;
- int a = (m->mode == 13) ? (m->fightCurTick << 1) : (m->properties->might / (m->field_1B & 0x7fff));
+ int bloodAmount = (m->mode == 13) ? (m->fightCurTick << 1) : (m->properties->hitPoints / (m->damageReceived & 0x7fff));
shp = _gameShapes[6];
- int cF = m->properties->flags & 0xc000;
- if (cF == 0x4000)
- cF = 63;
- else if (cF == 0x8000)
- cF = 15;
- else if (cF == 0xc000)
- cF = 74;
+ int bloodType = m->properties->flags & 0xc000;
+ if (bloodType == 0x4000)
+ bloodType = 63;
+ else if (bloodType == 0x8000)
+ bloodType = 15;
+ else if (bloodType == 0xc000)
+ bloodType = 74;
else
- cF = 0;
+ bloodType = 0;
uint8 *tbl = new uint8[256];
- if (cF) {
+ if (bloodType) {
for (int i = 0; i < 256; i++) {
tbl[i] = i;
if (i < 2 || i > 7)
continue;
- tbl[i] += cF;
+ tbl[i] += bloodType;
}
}
- dW += m->anon8;
- dH += m->anonh;
+ dW += m->hitOffsX;
+ dH += m->hitOffsY;
- a = CLIP(a, 1, 4);
+ bloodAmount = CLIP(bloodAmount, 1, 4);
- int sW = _dmScaleW / a;
- int sH = _dmScaleH / a;
+ int sW = _dmScaleW / bloodAmount;
+ int sH = _dmScaleH / bloodAmount;
- _screen->drawShape(_sceneDrawPage1, shp, _shpDmX + dW, _shpDmY + dH, 13, 0x124, tbl, cF ? 1 : 0, sW, sH);
+ _screen->drawShape(_sceneDrawPage1, shp, _shpDmX + dW, _shpDmY + dH, 13, 0x124, tbl, bloodType ? 1 : 0, sW, sH);
delete[] tbl;
}
@@ -698,14 +698,14 @@ int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
switch (_monsterUnk[m->properties->shapeIndex]) {
case 0:
if (dirFlags) {
- return (m->properties->fightingStats[0] & 0xff) == 13 ? -1 : (dirFlags + m->currentSubFrame);
+ return (m->mode == 13) ? -1 : (dirFlags + m->currentSubFrame);
} else {
- if (m->field_1B)
+ if (m->damageReceived)
return 12;
switch (m->mode - 5) {
case 0:
- return m->field_1B ? 12 : ((m->properties->flags & 4) ? 13 : 0);
+ return (m->properties->flags & 4) ? 13 : 0;
case 3:
return (m->fightCurTick + 13);
case 6:
@@ -713,7 +713,7 @@ int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
case 8:
return -1;
default:
- return m->field_1B ? 12 : m->currentSubFrame;
+ return m->currentSubFrame;
}
}
break;
@@ -1013,9 +1013,9 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
monster->speedTick = 0;
if (monster->properties->flags & 0x40) {
- monster->might += _rnd.getRandomNumberRng(1, 8);
- if (monster->might > monster->properties->might)
- monster->might = monster->properties->might;
+ monster->hitPoints += _rnd.getRandomNumberRng(1, 8);
+ if (monster->hitPoints > monster->properties->hitPoints)
+ monster->hitPoints = monster->properties->hitPoints;
}
if (monster->flags & 8) {
@@ -1036,7 +1036,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
if ((monster->mode != 11) && (monster->mode != 14)) {
if (!(getRandomNumberSpecial() & 3)) {
monster->shiftStep = (++monster->shiftStep) & 0x0f;
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
}
}
@@ -1062,7 +1062,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
if (updateMonsterAdjustBlocks(monster))
setMonsterMode(monster, 7);
for (int i = 0; i < 4; i++) {
- if (calcNewBlockPosition(monster->blockPropertyIndex, i) == _currentBlock)
+ if (calcNewBlockPosition(monster->block, i) == _currentBlock)
setMonsterMode(monster, 7);
}
break;
@@ -1096,7 +1096,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
// monster can't change mode before arriving at destination and/or attacking the party
if (!chasePartyWithDistanceAttacks(monster))
chasePartyWithCloseAttacks(monster);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
break;
case 8:
@@ -1105,7 +1105,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
setMonsterMode(monster, 5);
monster->fightCurTick = (int8) ((((8 << 8) / monster->properties->fightingStats[4]) * _monsterModifiers[6 + _monsterDifficulty]) >> 8);
}
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
break;
case 9:
@@ -1119,7 +1119,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
break;
case 12:
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
if (++monster->fightCurTick > 13)
runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
break;
@@ -1128,23 +1128,23 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
// monster death
if (++monster->fightCurTick > 2)
killMonster(monster);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
break;
case 14:
- monster->field_1B = 0;
+ monster->damageReceived = 0;
break;
default:
break;
}
- if (monster->field_1B) {
- if (monster->field_1B & 0x8000)
- monster->field_1B &= 0x7fff;
+ if (monster->damageReceived) {
+ if (monster->damageReceived & 0x8000)
+ monster->damageReceived &= 0x7fff;
else
- monster->field_1B = 0;
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ monster->damageReceived = 0;
+ checkSceneUpdateNeed(monster->block);
}
monster->flags &= 0xffef;
@@ -1174,10 +1174,10 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
setMonsterDirection(monster, _monsterLastWalkDirection);
} else {
setMonsterDirection(monster, s);
- if (monster->field_25) {
- if (getMonsterDistance(monster->blockPropertyIndex, _currentBlock) >= 2) {
- if (walkMonster_s3(monster->blockPropertyIndex, monster->direction, 3, _currentBlock) != 5) {
- if (monster->field_27)
+ if (monster->numDistAttacks) {
+ if (getMonsterDistance(monster->block, _currentBlock) >= 2) {
+ if (checkForPossibleDistanceAttack(monster->block, monster->direction, 3, _currentBlock) != 5) {
+ if (monster->distAttackTick)
return;
}
}
@@ -1192,9 +1192,80 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
}
bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
- if (!monster->field_25)
+ if (!monster->numDistAttacks)
return false;
+ if (monster->distAttackTick > 0) {
+ monster->distAttackTick--;
+ return false;
+ }
+
+ int dir = checkForPossibleDistanceAttack(monster->block, monster->facing, 4, _currentBlock);
+ if (dir == 5)
+ return false;
+
+ int s = 0;
+
+ if (monster->flags & 0x10) {
+ s = monster->properties->numDistWeapons ? _rnd.getRandomNumberRng(1, monster->properties->numDistWeapons) : 0;
+ } else {
+ s = monster->curDistWeapon++;
+ if (monster->curDistWeapon == monster->properties->numDistWeapons)
+ monster->curDistWeapon = 0;
+ }
+
+ int flyingObject = monster->properties->distWeapons[s];
+
+ if (flyingObject & 0xc000) {
+ if (getMonsterDistance(monster->block, _currentBlock) > 1) {
+ int type = flyingObject & 0x4000 ? 0 : 1;
+ flyingObject = makeItem(flyingObject & 0x3fff, 0, 0);
+
+ if (flyingObject) {
+ if (!launchObject(type, flyingObject, monster->x, monster->y, 12, dir << 1, -1, monster->id | 0x8000, 0x3f))
+ deleteItem(flyingObject);
+ }
+ }
+ } else if (!(flyingObject & 0x2000)) {
+ if (getMonsterDistance(monster->block, _currentBlock) > 1)
+ return false;
+
+ if (flyingObject == 1) {
+ snd_playSoundEffect(147, -1);
+ distObj1Sub(10, 2, 2, 1);
+
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1))
+ continue;
+
+ int item = removeCharacterItem(i, 15);
+ if (item)
+ setItemPosition(item, _partyPosX, _partyPosY, 0, 1);
+
+ inflictDamage(i, 20, -1, 0, 2);
+ }
+
+ } else if (flyingObject == 3) {
+ // shriek
+ for (int i = 0; i < 30; i++) {
+ if (getMonsterDistance(monster->block, _monsters[i].block) < 7)
+ setMonsterMode(monster, 7);
+ }
+ _txt->printMessage(2, getLangString(0x401a));
+
+ } else if (flyingObject == 4) {
+ launchMagicViper();
+
+ } else {
+ return false;
+ }
+ }
+
+ if (monster->numDistAttacks != 255)
+ monster->numDistAttacks--;
+
+ monster->distAttackTick = (monster->properties->fightingStats[4] * 8) >> 8;
+
return true;
}
@@ -1209,23 +1280,24 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
int t = (x1 < 0) ? -x1 : x1;
if (y1 <= 160 && t <= 80) {
if ((monster->direction == dir) && (monster->facing == (dir >> 1))) {
- int dst = getClosestPartyMember(monster->x, monster->y);
+ int dst = getNearestPartyMemberFromPos(monster->x, monster->y);
snd_playSoundEffect(monster->properties->sounds[1], -1);
int m = monster->id | 0x8000;
int hit = battleHitSkillTest(m, dst, 0);
if (hit) {
- int dmg = _rnd.getRandomNumberRng(2, calcInflictableDamage(m, dst, hit));
- battleHit_sub2(dst, dmg, m, 0);
- battleHit_sub3(monster, dst, dmg);
+ int mx = calcInflictableDamage(m, dst, hit);
+ int dmg = mx ? _rnd.getRandomNumberRng(2, mx) : 0;
+ inflictDamage(dst, dmg, m, 0, 0);
+ applyMonsterAttackSkill(monster, dst, dmg);
}
setMonsterMode(monster, 8);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
} else {
setMonsterDirection(monster, dir);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
}
return;
}
@@ -1308,24 +1380,26 @@ int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
return (dx << 1) + dy;
}
-int LoLEngine::walkMonster_s3(uint16 monsterBlock, int direction, int distance, uint16 curBlock) {
+int LoLEngine::checkForPossibleDistanceAttack(uint16 monsterBlock, int direction, int distance, uint16 curBlock) {
int mdist = getMonsterDistance(curBlock, monsterBlock);
if (mdist > distance)
return 5;
int dir = calcMonsterDirection(monsterBlock & 0x1f, monsterBlock >> 5, curBlock & 0x1f, curBlock >> 5);
- if ((dir & 1) || ((dir << 1) != direction))
+ if ((dir & 1) || (dir != direction << 1))
return 5;
- if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) || ((monsterBlock & 0xffe0) != (curBlock & 0xffe0)))
+ if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) && ((monsterBlock & 0xffe0) != (curBlock & 0xffe0)))
return 5;
if (distance < 0)
return 5;
+ int p = monsterBlock;
+
for (int i = 0; i < distance; i++) {
- int p = calcNewBlockPosition(monsterBlock, direction);
+ p = calcNewBlockPosition(p, direction);
if (p == curBlock)
return direction;
@@ -1373,7 +1447,7 @@ void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
if (monster->nextAssignedObject & 0x8000) {
r = true;
} else {
- uint16 id = _levelBlockProperties[monster->blockPropertyIndex].assignedObjects;
+ uint16 id = _levelBlockProperties[monster->block].assignedObjects;
id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
if (id != monster->id) {
@@ -1381,7 +1455,7 @@ void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
} else {
for (int i = 0; i < 3; i++) {
t = (t + 1) & 3;
- id = _levelBlockProperties[calcNewBlockPosition(monster->blockPropertyIndex, t)].assignedObjects;
+ id = _levelBlockProperties[calcNewBlockPosition(monster->block, t)].assignedObjects;
id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
if (id != 0xffff)
r = true;
@@ -1465,12 +1539,12 @@ void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
void LoLEngine::killMonster(MonsterInPlay *monster) {
setMonsterMode(monster, 14);
monsterDropItems(monster);
- checkSceneUpdateNeed(monster->blockPropertyIndex);
+ checkSceneUpdateNeed(monster->block);
- uint8 w = _levelBlockProperties[monster->blockPropertyIndex].walls[0];
- uint8 f = _levelBlockProperties[monster->blockPropertyIndex].flags;
+ uint8 w = _levelBlockProperties[monster->block].walls[0];
+ uint8 f = _levelBlockProperties[monster->block].flags;
if (_wllVmpMap[w] == 0 && _wllShapeMap[w] == 0 && !(f & 0x40) && !(monster->properties->flags & 0x1000))
- _levelBlockProperties[monster->blockPropertyIndex].flags |= 0x80;
+ _levelBlockProperties[monster->block].flags |= 0x80;
placeMonster(monster, 0, 0);
}