mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-18 23:57:32 +00:00
LOL: The guards will now attack you when you throw certain items at them. They can't do any damage though, since this isn't implemented yet.
svn-id: r39582
This commit is contained in:
parent
bd8b94ee8a
commit
b55602180d
@ -943,7 +943,7 @@ void LoLEngine::gui_initButton(int index, int x, int y, int val) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedUpArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
moveParty(_currentDirection, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 0, 80);
|
||||
@ -952,7 +952,7 @@ int LoLEngine::clickedUpArrow(Button *button) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedDownArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
moveParty(_currentDirection ^ 2, 0, 1, 83);
|
||||
@ -961,7 +961,7 @@ int LoLEngine::clickedDownArrow(Button *button) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedLeftArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
moveParty((_currentDirection - 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 2, 82);
|
||||
@ -970,7 +970,7 @@ int LoLEngine::clickedLeftArrow(Button *button) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedRightArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
moveParty((_currentDirection + 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 3, 84);
|
||||
@ -979,7 +979,7 @@ int LoLEngine::clickedRightArrow(Button *button) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedTurnLeftArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
gui_toggleButtonDisplayMode(79, 1);
|
||||
@ -1001,7 +1001,7 @@ int LoLEngine::clickedTurnLeftArrow(Button *button) {
|
||||
}
|
||||
|
||||
int LoLEngine::clickedTurnRightArrow(Button *button) {
|
||||
if (button->data2Val2 && !(_unkGameFlag & 4))
|
||||
if (button->data2Val2 && !_floatingCursorsEnabled)
|
||||
return 0;
|
||||
|
||||
gui_toggleButtonDisplayMode(81, 1);
|
||||
|
@ -413,7 +413,7 @@ void LoLEngine::updateObjectFlightPosition(FlyingObject *t) {
|
||||
}
|
||||
|
||||
void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock) {
|
||||
int r = 0;
|
||||
uint16 r = 0;
|
||||
|
||||
if (objectOnNextBlock == 1) {
|
||||
runLevelScriptCustom(calcNewBlockPosition(_itemsInPlay[t->item].blockPropertyIndex, t->direction >> 1), 0x8000, -1, t->item, 0, 0);
|
||||
@ -432,7 +432,7 @@ void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objec
|
||||
return;
|
||||
|
||||
} else {
|
||||
r = flyingObjectHitMonsters(x, y);
|
||||
r = getClosestMonster(x, y);
|
||||
}
|
||||
|
||||
} else if (objectOnNextBlock == 4) {
|
||||
@ -445,25 +445,13 @@ void LoLEngine::objectFlightProcessHits(FlyingObject *t, int x, int y, int objec
|
||||
return;
|
||||
|
||||
} else {
|
||||
r = flyingObjectHitParty(x, y);
|
||||
r = getClosestPartyMember(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
runItemScript(t->charNum, t->item, 0x8000, r, 0);
|
||||
}
|
||||
|
||||
uint16 LoLEngine::flyingObjectHitMonsters(int x, int y) {
|
||||
////////////
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 LoLEngine::flyingObjectHitParty(int x, int y) {
|
||||
////////////
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LoLEngine::updateFlyingObjects(FlyingObject *t) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
@ -149,7 +149,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_tempBuffer5120 = 0;
|
||||
_flyingItems = 0;
|
||||
_monsters = 0;
|
||||
_unkGameFlag = 0;
|
||||
_lastMouseRegion = 0;
|
||||
_monsterLastWalkDirection = _monsterCountUnk = _monsterShiftAlt = 0;
|
||||
_monsterCurBlock = 0;
|
||||
@ -206,6 +205,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
_activeButtons = 0;
|
||||
_preserveEvents = false;
|
||||
_buttonList1 = _buttonList2 = _buttonList3 = _buttonList4 = _buttonList5 = _buttonList6 = _buttonList7 = _buttonList8 = 0;
|
||||
|
||||
_monsterDifficulty = 1;
|
||||
_smoothScrollingEnabled = true;
|
||||
_floatingCursorsEnabled = false;
|
||||
}
|
||||
|
||||
LoLEngine::~LoLEngine() {
|
||||
@ -730,7 +733,7 @@ void LoLEngine::startupNew() {
|
||||
_compassDirection = _compassDirectionIndex = -1;
|
||||
|
||||
_lastMouseRegion = -1;
|
||||
_unkGameFlag |= 0x1B;
|
||||
|
||||
/*
|
||||
_unk5 = 1;
|
||||
_unk6 = 1;
|
||||
@ -1080,7 +1083,7 @@ int LoLEngine::calculateProtection(int index) {
|
||||
if (index & 0x8000) {
|
||||
// Monster
|
||||
index &= 0x7fff;
|
||||
c = (_monsters[index].properties->itemProtection * _monsters[index].properties->protection) >> 8;
|
||||
c = (_monsters[index].properties->itemProtection * _monsters[index].properties->fightingStats[2]) >> 8;
|
||||
} else {
|
||||
// Character
|
||||
c = _characters[index].itemsProtection + _characters[index].protection;
|
||||
@ -1521,7 +1524,7 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
|
||||
}
|
||||
|
||||
void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
if (!(_unkGameFlag & 1))
|
||||
if (!_sound->sfxEnabled())
|
||||
return;
|
||||
|
||||
if (_environmentSfx)
|
||||
@ -1560,7 +1563,7 @@ void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
}
|
||||
|
||||
void LoLEngine::snd_loadSoundFile(int track) {
|
||||
if (_unkGameFlag & 2) {
|
||||
if (_sound->musicEnabled()) {
|
||||
char filename[13];
|
||||
int t = (track - 250) * 3;
|
||||
|
||||
@ -1585,7 +1588,7 @@ int LoLEngine::snd_playTrack(int track) {
|
||||
int res = _lastMusicTrack;
|
||||
_lastMusicTrack = track;
|
||||
|
||||
if (_unkGameFlag & 2) {
|
||||
if (_sound->musicEnabled()) {
|
||||
snd_loadSoundFile(track);
|
||||
int t = (track - 250) * 3;
|
||||
_sound->playTrack(_musicTrackMap[t + 2]);
|
||||
@ -1595,7 +1598,7 @@ int LoLEngine::snd_playTrack(int track) {
|
||||
}
|
||||
|
||||
int LoLEngine::snd_stopMusic() {
|
||||
if (_unkGameFlag & 2) {
|
||||
if (_sound->musicEnabled()) {
|
||||
if (_sound->isPlaying()) {
|
||||
_sound->beginFadeOut();
|
||||
_system->delayMillis(3 * _tickLength);
|
||||
@ -1716,7 +1719,7 @@ void LoLEngine::giveItemToMonster(MonsterInPlay *monster, uint16 item) {
|
||||
}
|
||||
|
||||
const uint16 *LoLEngine::getCharacterOrMonsterStats(int id) {
|
||||
return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->pos : _characters[id].defaultModifiers;
|
||||
return (id & 0x8000) ? (const uint16*)_monsters[id & 0x7fff].properties->fightingStats : _characters[id].defaultModifiers;
|
||||
}
|
||||
|
||||
void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) {
|
||||
@ -1771,6 +1774,113 @@ bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int LoLEngine::battleHitSkillTest(int16 attacker, int16 target, int skill) {
|
||||
if (target == -1)
|
||||
return 0;
|
||||
if (attacker == -1)
|
||||
return 1;
|
||||
|
||||
if (target & 0x8000) {
|
||||
if (_monsters[target & 0x7fff].mode >= 13)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 hitChanceModifier = 0;
|
||||
uint16 evadeChanceModifier = 0;
|
||||
int sk = 0;
|
||||
|
||||
if (attacker & 0x8000) {
|
||||
hitChanceModifier = _monsters[target & 0x7fff].properties->fightingStats[0];
|
||||
sk = 100 - _monsters[target & 0x7fff].properties->skillLevel;
|
||||
} else {
|
||||
hitChanceModifier = _characters[attacker].defaultModifiers[0];
|
||||
uint8 m = _characters[attacker].skillModifiers[skill];
|
||||
if (skill == 1)
|
||||
m *= 3;
|
||||
sk = 100 - (_characters[attacker].skillLevels[skill] + m);
|
||||
}
|
||||
|
||||
if (target & 0x8000) {
|
||||
evadeChanceModifier = _monsters[target & 0x7fff].properties->fightingStats[3];
|
||||
_monsters[target & 0x7fff].flags |= 0x10;
|
||||
} else {
|
||||
evadeChanceModifier = _characters[target].defaultModifiers[3];
|
||||
}
|
||||
|
||||
int r = _rnd.getRandomNumberRng(1, 100);
|
||||
if (r >= sk)
|
||||
return 2;
|
||||
|
||||
uint16 v = ((_monsterModifiers[9 + _monsterDifficulty] * evadeChanceModifier) & 0xffffff00) / hitChanceModifier;
|
||||
|
||||
if (r < v)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::calcInflictableDamage(int16 attacker, int16 target, int hitType) {
|
||||
const uint16 *s = getCharacterOrMonsterStats(attacker);
|
||||
|
||||
int res = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
res += calcInflictableDamagePerStat(attacker, target, s[2 + i], i, hitType);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void LoLEngine::battleHit_sub2(int16 target, int damageInflicted, int16 attacker, uint32 b) {
|
||||
|
||||
}
|
||||
|
||||
void LoLEngine::battleHit_sub3(MonsterInPlay *monster, int16 target, int16 damageInflicted) {
|
||||
|
||||
}
|
||||
|
||||
int LoLEngine::calcInflictableDamagePerStat(int16 attacker, int16 target, uint16 stat2m, int index, int hitType) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16 LoLEngine::getClosestMonster(int x, int y) {
|
||||
uint16 id = 0xffff;
|
||||
int minDist = 0x7fff;
|
||||
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].mode > 13)
|
||||
continue;
|
||||
|
||||
int d = ABS(x - _monsters[i].x) + ABS(y - _monsters[i].y);
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
id = 0x8000 | i;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint16 LoLEngine::getClosestPartyMember(int x, int y) {
|
||||
uint16 id = 0xffff;
|
||||
int minDist = 0x7fff;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!(_characters[i].flags & 1) || _characters[i].hitPointsCur <= 0)
|
||||
continue;
|
||||
|
||||
int16 charX = 0;
|
||||
int16 charY = 0;
|
||||
calcCoordinatesForSingleCharacter(i, charX, charY);
|
||||
|
||||
int d = ABS(x - charX) + ABS(y - charY);
|
||||
if (d < minDist) {
|
||||
minDist = d;
|
||||
id = i;
|
||||
}
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
} // end of namespace Kyra
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
@ -62,9 +62,9 @@ struct LoLCharacter {
|
||||
uint16 field_34;
|
||||
uint8 field_36;
|
||||
uint16 itemsProtection;
|
||||
uint16 hitPointsCur;
|
||||
int16 hitPointsCur;
|
||||
uint16 hitPointsMax;
|
||||
uint16 magicPointsCur;
|
||||
int16 magicPointsCur;
|
||||
uint16 magicPointsMax;
|
||||
uint8 field_41;
|
||||
uint16 damageSuffered;
|
||||
@ -100,15 +100,13 @@ struct LevelBlockProperty {
|
||||
struct MonsterProperty {
|
||||
uint8 shapeIndex;
|
||||
uint8 maxWidth;
|
||||
uint16 field2[2];
|
||||
uint16 protection;
|
||||
uint16 unk[6];
|
||||
uint16 *pos;
|
||||
uint16 fightingStats[10];
|
||||
uint16 unk2[8];
|
||||
uint16 unk3[8];
|
||||
uint16 itemProtection;
|
||||
uint16 might;
|
||||
uint8 waitTicks;
|
||||
uint8 speedTotalWaitTicks;
|
||||
uint8 skillLevel;
|
||||
uint16 flags;
|
||||
uint16 unk5;
|
||||
uint16 unk6[5];
|
||||
@ -129,10 +127,10 @@ struct MonsterInPlay {
|
||||
uint8 destDirection;
|
||||
uint8 anon8;
|
||||
uint8 anonh;
|
||||
uint8 anon9;
|
||||
uint8 currentSubFrame;
|
||||
|
||||
uint8 mode;
|
||||
uint8 field_15;
|
||||
int8 fightCurTick;
|
||||
uint8 id;
|
||||
uint8 direction;
|
||||
uint8 facing;
|
||||
@ -140,7 +138,7 @@ struct MonsterInPlay {
|
||||
uint8 field_1B;
|
||||
uint8 field_1C;
|
||||
int16 might;
|
||||
uint8 tick;
|
||||
uint8 speedTick;
|
||||
uint8 type;
|
||||
MonsterProperty *properties;
|
||||
uint8 field_25;
|
||||
@ -163,7 +161,7 @@ struct ItemInPlay {
|
||||
uint8 destDirection;
|
||||
uint8 anon8;
|
||||
uint8 anonh;
|
||||
uint8 anon9;
|
||||
uint8 currentSubFrame;
|
||||
};
|
||||
|
||||
struct ItemProperty {
|
||||
@ -266,6 +264,11 @@ private:
|
||||
void startup();
|
||||
void startupNew();
|
||||
|
||||
// options
|
||||
int _monsterDifficulty;
|
||||
bool _smoothScrollingEnabled;
|
||||
bool _floatingCursorsEnabled;
|
||||
|
||||
// main loop
|
||||
void runLoop();
|
||||
void update();
|
||||
@ -569,7 +572,9 @@ private:
|
||||
int olol_initMonster(EMCState *script);
|
||||
int olol_fadeClearSceneWindow(EMCState *script);
|
||||
int olol_fadeSequencePalette(EMCState *script);
|
||||
int olol_dummy0(EMCState *script);
|
||||
int olol_loadMonsterProperties(EMCState *script);
|
||||
int olol_battleHitSkillTest(EMCState *script);
|
||||
int olol_moveMonster(EMCState *script);
|
||||
int olol_dialogueBox(EMCState *script);
|
||||
int olol_giveTakeMoney(EMCState *script);
|
||||
@ -597,7 +602,7 @@ private:
|
||||
int olol_setPaletteBrightness(EMCState *script);
|
||||
int olol_printMessage(EMCState *script);
|
||||
int olol_playDialogueTalkText(EMCState *script);
|
||||
int olol_checkForMonsterMode1(EMCState *script);
|
||||
int olol_checkMonsterTypeHostility(EMCState *script);
|
||||
int olol_setNextFunc(EMCState *script);
|
||||
int olol_setDoorState(EMCState *script);
|
||||
int olol_processButtonClick(EMCState *script);
|
||||
@ -804,7 +809,9 @@ private:
|
||||
|
||||
uint16 calcNewBlockPosition(uint16 curBlock, uint16 direction);
|
||||
uint16 calcBlockIndex(uint16 x, uint16 y);
|
||||
void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs);
|
||||
void calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs);
|
||||
void calcCoordinatesForSingleCharacter(int charNum, int16 &x, int16 &y);
|
||||
void calcCoordinatesAddDirectionOffset(int16 &x, int16 &y, int direction);
|
||||
|
||||
int clickedWallShape(uint16 block, uint16 direction);
|
||||
int clicked2(uint16 block, uint16 direction);
|
||||
@ -906,7 +913,6 @@ private:
|
||||
|
||||
int _lastMouseRegion;
|
||||
int _seqWindowX1, _seqWindowY1, _seqWindowX2, _seqWindowY2, _seqTrigger;
|
||||
uint8 _unkGameFlag;
|
||||
|
||||
uint8 *_tempBuffer5120;
|
||||
|
||||
@ -979,8 +985,6 @@ private:
|
||||
void processObjectFlight(FlyingObject *t, int x, int y);
|
||||
void updateObjectFlightPosition(FlyingObject *t);
|
||||
void objectFlightProcessHits(FlyingObject *t, int x, int y, int objectOnNextBlock);
|
||||
uint16 flyingObjectHitMonsters(int x, int y);
|
||||
uint16 flyingObjectHitParty(int x, int y);
|
||||
void updateFlyingObjects(FlyingObject *t);
|
||||
|
||||
void assignItemToBlock(uint16 *assignedBlockObjects, int id);
|
||||
@ -1022,11 +1026,12 @@ private:
|
||||
void loadMonsterShapes(const char *file, int monsterIndex, int b);
|
||||
void releaseMonsterShapes(int monsterIndex);
|
||||
int disableMonstersForBlock(int block);
|
||||
void setMonsterMode(MonsterInPlay *monster, int a);
|
||||
void setMonsterMode(MonsterInPlay *monster, int mode);
|
||||
bool updateMonsterAdjustBlocks(MonsterInPlay *monster);
|
||||
void placeMonster(MonsterInPlay *monster, uint16 x, uint16 y);
|
||||
int calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
|
||||
void setMonsterDirection(MonsterInPlay *monster, int dir);
|
||||
void cmzS3(MonsterInPlay *monster);
|
||||
void monsterDropItems(MonsterInPlay *monster);
|
||||
void removeAssignedObjectFromBlock(LevelBlockProperty *l, int id);
|
||||
void removeDrawObjectFromBlock(LevelBlockProperty *l, int id);
|
||||
void assignMonsterToBlock(uint16 *assignedBlockObjects, int id);
|
||||
@ -1042,7 +1047,7 @@ private:
|
||||
void reassignDrawObjects(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag);
|
||||
void redrawSceneItem();
|
||||
int calcItemMonsterPosition(ItemInPlay *i, uint16 direction);
|
||||
void recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, uint16 direction);
|
||||
void calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction);
|
||||
void drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags);
|
||||
void drawDoorOrMonsterShape(uint8 *shape, uint8 *table, int x, int y, int flags, const uint8 *ovl);
|
||||
uint8 *drawItemOrMonster(uint8 *shape, uint8 *ovl, int x, int y, int fineX, int fineY, int flags, int tblValue, bool flip);
|
||||
@ -1051,11 +1056,16 @@ private:
|
||||
void updateMonster(MonsterInPlay *monster);
|
||||
void moveMonster(MonsterInPlay *monster);
|
||||
void walkMonster(MonsterInPlay *monster);
|
||||
bool chasePartyWithDistanceAttacks(MonsterInPlay *monster);
|
||||
void chasePartyWithCloseAttacks(MonsterInPlay *monster);
|
||||
int walkMonsterCalcNextStep(MonsterInPlay *monster);
|
||||
int getMonsterDistance(uint16 block1, uint16 block2);
|
||||
int walkMonster_s3(uint16 monsterBlock, int direction, int distance, uint16 curBlock);
|
||||
int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
|
||||
void getNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 direction);
|
||||
void rearrangeAttackingMonster(MonsterInPlay *monster);
|
||||
void moveStrayingMonster(MonsterInPlay *monster);
|
||||
void mode13sub(MonsterInPlay *monster);
|
||||
|
||||
MonsterInPlay *_monsters;
|
||||
MonsterProperty *_monsterProperties;
|
||||
@ -1093,6 +1103,16 @@ private:
|
||||
uint8 *_pageBuffer2;
|
||||
uint32 _rndSpecial;
|
||||
|
||||
// fight
|
||||
int battleHitSkillTest(int16 attacker, int16 target, int skill);
|
||||
int calcInflictableDamage(int16 attacker, int16 target, int hitType);
|
||||
void battleHit_sub2(int16 target, int damageInflicted, int16 attacker, uint32 b);
|
||||
void battleHit_sub3(MonsterInPlay *monster, int16 target, int16 damageInflicted);
|
||||
int calcInflictableDamagePerStat(int16 attacker, int16 target, uint16 stat2m, int index, int hitType);
|
||||
|
||||
uint16 getClosestMonster(int x, int y);
|
||||
uint16 getClosestPartyMember(int x, int y);
|
||||
|
||||
// spells
|
||||
bool notEnoughMagic(int charNum, int spellNum, int spellLevel);
|
||||
|
||||
|
@ -273,7 +273,7 @@ void LoLEngine::loadLevelCmzFile(int index) {
|
||||
}
|
||||
}
|
||||
|
||||
loadCMZ_Sub(tmpLvlVal, (_unkGameFlag & 0x30) >> 4);
|
||||
loadCMZ_Sub(tmpLvlVal, _monsterDifficulty);
|
||||
|
||||
delete[] cmzdata;
|
||||
}
|
||||
@ -654,11 +654,43 @@ uint16 LoLEngine::calcBlockIndex(uint16 x, uint16 y) {
|
||||
return ((y & 0xff00) >> 3) | (x >> 8);
|
||||
}
|
||||
|
||||
void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs) {
|
||||
void LoLEngine::calcCoordinates(uint16 &x, uint16 &y, int block, uint16 xOffs, uint16 yOffs) {
|
||||
x = (block & 0x1f) << 8 | xOffs;
|
||||
y = ((block & 0xffe0) << 3) | yOffs;
|
||||
}
|
||||
|
||||
void LoLEngine::calcCoordinatesForSingleCharacter(int charNum, int16 &x, int16 &y) {
|
||||
static const uint8 xOffsets[] = { 0x80, 0x00, 0x00, 0x40, 0xC0, 0x00, 0x40, 0x80, 0xC0 };
|
||||
int c = countActiveCharacters();
|
||||
if (!c)
|
||||
return;
|
||||
|
||||
c = (c - 1) * 3 + charNum;
|
||||
|
||||
x = xOffsets[c];
|
||||
y = 0x80;
|
||||
|
||||
calcCoordinatesAddDirectionOffset(x, y, _currentDirection);
|
||||
|
||||
x |= (_partyPosX & 0xff00);
|
||||
y |= (_partyPosY & 0xff00);
|
||||
}
|
||||
|
||||
void LoLEngine::calcCoordinatesAddDirectionOffset(int16 &x, int16 &y, int direction) {
|
||||
if (!direction)
|
||||
return;
|
||||
|
||||
if (direction & 1)
|
||||
SWAP(x, y);
|
||||
|
||||
if (direction == 1)
|
||||
y = (y - 256) * -1;
|
||||
|
||||
if (direction == 3) {
|
||||
x = (x - 256) * -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool LoLEngine::checkBlockPassability(uint16 block, uint16 direction) {
|
||||
if (testWallFlag(block, direction, 1))
|
||||
return false;
|
||||
@ -825,7 +857,7 @@ void LoLEngine::openCloseDoor(uint16 block, int openClose) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollBlocked(int speed) {
|
||||
if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory))
|
||||
if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _hideInventory))
|
||||
return;
|
||||
|
||||
_screen->backupSceneWindow(_sceneDrawPage2 == 2 ? 2 : 6, 6);
|
||||
@ -863,7 +895,7 @@ void LoLEngine::movePartySmoothScrollBlocked(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollUp(int speed) {
|
||||
if (!(_unkGameFlag & 8) || ((_unkGameFlag & 8) && _hideInventory))
|
||||
if (!_smoothScrollingEnabled || (_smoothScrollingEnabled && _hideInventory))
|
||||
return;
|
||||
|
||||
int d = 0;
|
||||
@ -908,7 +940,7 @@ void LoLEngine::movePartySmoothScrollUp(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollDown(int speed) {
|
||||
if (!(_unkGameFlag & 8))
|
||||
if (!_smoothScrollingEnabled)
|
||||
return;
|
||||
|
||||
//int d = smoothScrollDrawSpecialShape(2);
|
||||
@ -943,7 +975,7 @@ void LoLEngine::movePartySmoothScrollDown(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollLeft(int speed) {
|
||||
if (!(_unkGameFlag & 8))
|
||||
if (!_smoothScrollingEnabled)
|
||||
return;
|
||||
|
||||
speed <<= 1;
|
||||
@ -969,7 +1001,7 @@ void LoLEngine::movePartySmoothScrollLeft(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollRight(int speed) {
|
||||
if (!(_unkGameFlag & 8))
|
||||
if (!_smoothScrollingEnabled)
|
||||
return;
|
||||
|
||||
speed <<= 1;
|
||||
@ -1008,7 +1040,7 @@ void LoLEngine::movePartySmoothScrollRight(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollTurnLeft(int speed) {
|
||||
if (!(_unkGameFlag & 8))
|
||||
if (!_smoothScrollingEnabled)
|
||||
return;
|
||||
|
||||
speed <<= 1;
|
||||
@ -1052,7 +1084,7 @@ void LoLEngine::movePartySmoothScrollTurnLeft(int speed) {
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollTurnRight(int speed) {
|
||||
if (!(_unkGameFlag & 8))
|
||||
if (!_smoothScrollingEnabled)
|
||||
return;
|
||||
|
||||
speed <<= 1;
|
||||
|
@ -692,7 +692,7 @@ int LoLEngine::olol_initMonster(EMCState *script) {
|
||||
l->type = stackPos(4);
|
||||
l->properties = &_monsterProperties[l->type];
|
||||
l->direction = l->facing << 1;
|
||||
l->might = (l->properties->might * _monsterModifiers[((_unkGameFlag & 0x30) >> 4)]) >> 8;
|
||||
l->might = (l->properties->might * _monsterModifiers[_monsterDifficulty]) >> 8;
|
||||
|
||||
if (_currentLevel == 12 && l->type == 2)
|
||||
l->might = (l->might * (_rnd.getRandomNumberRng(1, 128) + 192)) >> 8;
|
||||
@ -735,6 +735,10 @@ int LoLEngine::olol_fadeSequencePalette(EMCState *script) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_dummy0(EMCState *script) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadMonsterProperties(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)",
|
||||
(const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5),
|
||||
@ -757,25 +761,25 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
|
||||
|
||||
l->maxWidth = shpWidthMax;
|
||||
|
||||
l->field2[0] = (stackPos(2) << 8) / 100;
|
||||
l->field2[1] = 256;
|
||||
l->protection = (stackPos(3) << 8) / 100;
|
||||
l->unk[0] = stackPos(4);
|
||||
l->unk[1] = (stackPos(5) << 8) / 100;
|
||||
l->unk[2] = (stackPos(6) << 8) / 100;
|
||||
l->unk[3] = (stackPos(7) << 8) / 100;
|
||||
l->unk[4] = (stackPos(8) << 8) / 100;
|
||||
l->unk[5] = 0;
|
||||
l->fightingStats[0] = (stackPos(2) << 8) / 100; // hit chance
|
||||
l->fightingStats[1] = 256; //
|
||||
l->fightingStats[2] = (stackPos(3) << 8) / 100; // protection
|
||||
l->fightingStats[3] = stackPos(4); // evade chance
|
||||
l->fightingStats[4] = (stackPos(5) << 8) / 100; // speed
|
||||
l->fightingStats[5] = (stackPos(6) << 8) / 100; //
|
||||
l->fightingStats[6] = (stackPos(7) << 8) / 100; //
|
||||
l->fightingStats[7] = (stackPos(8) << 8) / 100; //
|
||||
l->fightingStats[8] = 0;
|
||||
l->fightingStats[9] = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
l->unk2[i] = stackPos(9 + i);
|
||||
l->unk3[i] = (stackPos(17 + i) << 8) / 100;
|
||||
}
|
||||
|
||||
l->pos = &l->field2[0];
|
||||
l->itemProtection = stackPos(25);
|
||||
l->might = stackPos(26);
|
||||
l->waitTicks = 1;
|
||||
l->speedTotalWaitTicks = 1;
|
||||
l->flags = stackPos(27);
|
||||
l->unk5 = stackPos(28);
|
||||
// FIXME???
|
||||
@ -796,6 +800,11 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_battleHitSkillTest(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_battleHitSkillTest(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
|
||||
return battleHitSkillTest(stackPos(0), stackPos(1), stackPos(2));
|
||||
}
|
||||
|
||||
int LoLEngine::olol_moveMonster(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveMonster(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
|
||||
MonsterInPlay *m = &_monsters[stackPos(0)];
|
||||
@ -1022,7 +1031,8 @@ int LoLEngine::olol_playDialogueTalkText(EMCState *script) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::olol_checkForMonsterMode1(EMCState *script) {
|
||||
int LoLEngine::olol_checkMonsterTypeHostility(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_checkMonsterTypeHostility(%p) (%d)", (const void *)script, stackPos(0));
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (stackPos(0) != _monsters[i].type && stackPos(0) != -1)
|
||||
continue;
|
||||
@ -1445,11 +1455,11 @@ void LoLEngine::setupOpcodeTable() {
|
||||
// 0x3C
|
||||
OpcodeUnImpl();
|
||||
OpcodeUnImpl();
|
||||
OpcodeUnImpl();
|
||||
Opcode(olol_dummy0);
|
||||
Opcode(olol_loadMonsterProperties);
|
||||
|
||||
// 0x40
|
||||
OpcodeUnImpl();
|
||||
Opcode(olol_battleHitSkillTest);
|
||||
OpcodeUnImpl();
|
||||
OpcodeUnImpl();
|
||||
OpcodeUnImpl();
|
||||
@ -1536,7 +1546,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
OpcodeUnImpl();
|
||||
OpcodeUnImpl();
|
||||
Opcode(olol_playDialogueTalkText);
|
||||
Opcode(olol_checkForMonsterMode1);
|
||||
Opcode(olol_checkMonsterTypeHostility);
|
||||
|
||||
// 0x7C
|
||||
Opcode(olol_setNextFunc);
|
||||
|
@ -162,9 +162,10 @@ int LoLEngine::disableMonstersForBlock(int block) {
|
||||
void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
|
||||
if (monster->mode == 13 && mode != 14)
|
||||
return;
|
||||
|
||||
if (mode == 7) {
|
||||
monster->destX = _partyPosX;
|
||||
monster->destY = _partyPosX;
|
||||
monster->destY = _partyPosY;
|
||||
}
|
||||
|
||||
if (monster->mode == 1 && mode == 7) {
|
||||
@ -172,19 +173,19 @@ void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
|
||||
if (monster->mode != 1)
|
||||
continue;
|
||||
monster->mode = mode;
|
||||
monster->field_15 = 0;
|
||||
monster->fightCurTick = 0;
|
||||
monster->destX = _partyPosX;
|
||||
monster->destY = _partyPosY;
|
||||
setMonsterDirection(monster, calcMonsterDirection(monster->x, monster->y, monster->destX, monster->destY));
|
||||
}
|
||||
} else {
|
||||
monster->mode = mode;
|
||||
monster->field_15 = 0;
|
||||
monster->fightCurTick = 0;
|
||||
if (mode == 14)
|
||||
monster->might = 0;
|
||||
if (mode == 13 && (monster->flags & 0x20)) {
|
||||
monster->mode = 0;
|
||||
cmzS3(monster);
|
||||
monsterDropItems(monster);
|
||||
if (_currentLevel != 29)
|
||||
setMonsterMode(monster, 14);
|
||||
runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
|
||||
@ -195,6 +196,47 @@ void LoLEngine::setMonsterMode(MonsterInPlay *monster, int mode) {
|
||||
}
|
||||
}
|
||||
|
||||
bool LoLEngine::updateMonsterAdjustBlocks(MonsterInPlay *monster) {
|
||||
static const uint8 dims[] = { 0, 13, 9, 3 };
|
||||
if (monster->properties->flags & 8)
|
||||
return true;
|
||||
|
||||
uint16 x1 = (monster->x & 0xff00) | 0x80;
|
||||
uint16 y1 = (monster->y & 0xff00) | 0x80;
|
||||
int x2 = _partyPosX;
|
||||
int y2 = _partyPosY;
|
||||
|
||||
uint16 dir = 0;
|
||||
if (monster->properties->flags & 1) {
|
||||
dir = monster->direction >> 1;
|
||||
} else {
|
||||
dir = calcMonsterDirection(x1, y1, x2, y2);
|
||||
if ((monster->properties->flags & 2) && (dir == (monster->direction ^ 4)))
|
||||
return false;
|
||||
dir >>= 1;
|
||||
}
|
||||
|
||||
calcSpriteRelPosition(x1, y1, x2, y2, dir);
|
||||
x2 >>= 8;
|
||||
y2 >>= 8;
|
||||
|
||||
if (y2 < 0 || y2 > 3)
|
||||
return false;
|
||||
|
||||
int t = (x2 < 0) ? -x2 : x2;
|
||||
if (t > y2)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 18; i++)
|
||||
_curBlockCaps[i] = &_levelBlockProperties[(monster->blockPropertyIndex + _dscBlockIndex[dir + i]) & 0x3ff];
|
||||
|
||||
int16 fx1 = 0;
|
||||
int16 fx2 = 0;
|
||||
setLevelShapesDim(x2 + dims[y2], fx1, fx2, 13);
|
||||
|
||||
return (fx1 >= fx2) ? false : true;
|
||||
}
|
||||
|
||||
void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
bool cont = true;
|
||||
int t = monster->blockPropertyIndex;
|
||||
@ -211,7 +253,7 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
if (monster->x != x || monster->y != y) {
|
||||
monster->x = x;
|
||||
monster->y = y;
|
||||
monster->anon9 = (++monster->anon9) & 3;
|
||||
monster->currentSubFrame = (++monster->currentSubFrame) & 3;
|
||||
}
|
||||
|
||||
if (monster->blockPropertyIndex == 0)
|
||||
@ -224,7 +266,7 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
if (monster->properties->sounds[0] == 0 || cont == false)
|
||||
return;
|
||||
|
||||
if ((!(monster->properties->flags & 0x100) || ((monster->anon9 & 1) == 0)) && monster->blockPropertyIndex == t)
|
||||
if ((!(monster->properties->flags & 0x100) || ((monster->currentSubFrame & 1) == 0)) && monster->blockPropertyIndex == t)
|
||||
return;
|
||||
|
||||
if (monster->blockPropertyIndex != t)
|
||||
@ -238,6 +280,7 @@ void LoLEngine::placeMonster(MonsterInPlay *monster, uint16 x, uint16 y) {
|
||||
|
||||
int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
|
||||
int16 r = 0;
|
||||
|
||||
int16 t1 = y1 - y2;
|
||||
if (t1 < 0) {
|
||||
r++;
|
||||
@ -247,19 +290,15 @@ int LoLEngine::calcMonsterDirection(uint16 x1, uint16 y1, uint16 x2, uint16 y2)
|
||||
r <<= 1;
|
||||
|
||||
int16 t2 = x2 - x1;
|
||||
|
||||
if (t2 < 0) {
|
||||
r++;
|
||||
t2 = -t2;
|
||||
}
|
||||
|
||||
uint8 f = 1;
|
||||
uint8 f = (t1 > t2) ? 1 : 0;
|
||||
|
||||
if (t2 >= t1) {
|
||||
if (t2 > t1)
|
||||
f = 0;
|
||||
if (t2 >= t1)
|
||||
SWAP(t1, t2);
|
||||
}
|
||||
|
||||
r = (r << 1) | f;
|
||||
|
||||
@ -281,8 +320,13 @@ void LoLEngine::setMonsterDirection(MonsterInPlay *monster, int dir) {
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
}
|
||||
|
||||
void LoLEngine::cmzS3(MonsterInPlay *l) {
|
||||
// TODO
|
||||
void LoLEngine::monsterDropItems(MonsterInPlay *monster) {
|
||||
uint16 a = monster->assignedItems;
|
||||
while (a) {
|
||||
uint16 b = a;
|
||||
a = _itemsInPlay[a].nextAssignedObject;
|
||||
setItemPosition(b, monster->x, monster->y, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::removeAssignedObjectFromBlock(LevelBlockProperty *l, int id) {
|
||||
@ -459,7 +503,7 @@ int LoLEngine::calcMonsterSkillLevel(int id, int a) {
|
||||
int r = (a << 8) / c[4];
|
||||
|
||||
if (!(id & 0x8000))
|
||||
r = (r * _monsterModifiers[3 + ((_unkGameFlag & 0x30) << 4)]) >> 8;
|
||||
r = (r * _monsterModifiers[3 + _monsterDifficulty]) >> 8;
|
||||
|
||||
id &= 0x7fff;
|
||||
|
||||
@ -519,7 +563,6 @@ void LoLEngine::drawBlockObjects(int blockArrayIndex) {
|
||||
|
||||
if ((_itemProperties[i->itemPropertyIndex].flags & 0x1000) && !(i->shpCurFrame_flg & 0xC000)) {
|
||||
int shpIndex = _itemProperties[i->itemPropertyIndex].flags & 0x800 ? 7 : _itemProperties[i->itemPropertyIndex].shpIndex;
|
||||
shpIndex=12;
|
||||
int ii = 0;
|
||||
for (; ii < 8; ii++) {
|
||||
if (!_flyingItems[ii].enable)
|
||||
@ -612,7 +655,7 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
int dW = _screen->getShapeScaledWidth(shp, _dmScaleW) >> 1;
|
||||
int dH = _screen->getShapeScaledHeight(shp, _dmScaleH) >> 1;
|
||||
|
||||
int a = (m->mode == 13) ? (m->field_15 << 1) : (m->properties->might / (m->field_1B & 0x7fff));
|
||||
int a = (m->mode == 13) ? (m->fightCurTick << 1) : (m->properties->might / (m->field_1B & 0x7fff));
|
||||
|
||||
shp = _gameShapes[6];
|
||||
|
||||
@ -654,7 +697,7 @@ int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
|
||||
switch (_monsterUnk[m->properties->shapeIndex]) {
|
||||
case 0:
|
||||
if (dirFlags) {
|
||||
return (*m->properties->pos & 0xff) == 13 ? -1 : (dirFlags + m->anon9);
|
||||
return (m->properties->fightingStats[0] & 0xff) == 13 ? -1 : (dirFlags + m->currentSubFrame);
|
||||
} else {
|
||||
if (m->field_1B)
|
||||
return 12;
|
||||
@ -663,13 +706,13 @@ int LoLEngine::getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags) {
|
||||
case 0:
|
||||
return m->field_1B ? 12 : ((m->properties->flags & 4) ? 13 : 0);
|
||||
case 3:
|
||||
return (m->field_15 + 13);
|
||||
return (m->fightCurTick + 13);
|
||||
case 6:
|
||||
return 14;
|
||||
case 8:
|
||||
return -1;
|
||||
default:
|
||||
return m->field_1B ? 12 : m->anon9;
|
||||
return m->field_1B ? 12 : m->currentSubFrame;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -738,8 +781,7 @@ void LoLEngine::redrawSceneItem() {
|
||||
int t = (i << 7) + 1;
|
||||
while (s) {
|
||||
if (s & 0x8000) {
|
||||
s &= 0x7fff;
|
||||
s = _monsters[i].nextDrawObject;
|
||||
s = _monsters[s & 0x7fff].nextDrawObject;
|
||||
} else {
|
||||
ItemInPlay *item = &_itemsInPlay[s];
|
||||
|
||||
@ -769,7 +811,7 @@ int LoLEngine::calcItemMonsterPosition(ItemInPlay *i, uint16 direction) {
|
||||
int x = i->x;
|
||||
int y = i->y;
|
||||
|
||||
recalcSpritePosition(_partyPosX, _partyPosY, x, y, direction);
|
||||
calcSpriteRelPosition(_partyPosX, _partyPosY, x, y, direction);
|
||||
|
||||
if (y < 0)
|
||||
y = 0;
|
||||
@ -780,9 +822,9 @@ int LoLEngine::calcItemMonsterPosition(ItemInPlay *i, uint16 direction) {
|
||||
return res;
|
||||
}
|
||||
|
||||
void LoLEngine::recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, int &itemY, uint16 direction) {
|
||||
int a = itemX - partyX;
|
||||
int b = partyY - itemY;
|
||||
void LoLEngine::calcSpriteRelPosition(uint16 x1, uint16 y1, int &x2, int &y2, uint16 direction) {
|
||||
int a = x2 - x1;
|
||||
int b = y1 - y2;
|
||||
|
||||
if (direction) {
|
||||
if (direction != 2)
|
||||
@ -796,8 +838,8 @@ void LoLEngine::recalcSpritePosition(uint16 partyX, uint16 partyY, int &itemX, i
|
||||
}
|
||||
}
|
||||
|
||||
itemX = a;
|
||||
itemY = b;
|
||||
x2 = a;
|
||||
y2 = b;
|
||||
}
|
||||
|
||||
void LoLEngine::drawDoor(uint8 *shape, uint8 *table, int index, int unk2, int w, int h, int flags) {
|
||||
@ -938,7 +980,7 @@ uint8 *LoLEngine::drawItemOrMonster(uint8 *shape, uint8 *table, int x, int y, in
|
||||
}
|
||||
|
||||
int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int &x2, int &y2, uint16 &w, uint16 &h, uint8 *shape, int flip) {
|
||||
recalcSpritePosition(_partyPosX, _partyPosY, x1, y1, _currentDirection);
|
||||
calcSpriteRelPosition(_partyPosX, _partyPosY, x1, y1, _currentDirection);
|
||||
|
||||
if (y1 < 0) {
|
||||
w = h = x2 = y2 = 0;
|
||||
@ -965,10 +1007,10 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
return;
|
||||
|
||||
int f = flags[monster->mode];
|
||||
if ((monster->tick++ < monster->properties->waitTicks) && (!(f & 4)))
|
||||
if ((monster->speedTick++ < monster->properties->speedTotalWaitTicks) && (!(f & 4)))
|
||||
return;
|
||||
|
||||
monster->tick = 0;
|
||||
monster->speedTick = 0;
|
||||
|
||||
if (monster->properties->flags & 0x40) {
|
||||
monster->might += _rnd.getRandomNumberRng(1, 8);
|
||||
@ -982,9 +1024,10 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
}
|
||||
|
||||
if (f & 2) {
|
||||
|
||||
/////
|
||||
// TODO
|
||||
if (updateMonsterAdjustBlocks(monster)) {
|
||||
setMonsterMode(monster, 7);
|
||||
f &= 6;
|
||||
}
|
||||
}
|
||||
|
||||
if ((f & 1) && (monster->flags & 0x10))
|
||||
@ -1000,6 +1043,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
switch (monster->mode) {
|
||||
case 0:
|
||||
case 1:
|
||||
// friendly mode
|
||||
if (monster->flags & 0x10) {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
if (_monsters[i].mode == 1)
|
||||
@ -1009,28 +1053,87 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
moveMonster(monster);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
moveMonster(monster);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (updateMonsterAdjustBlocks(monster))
|
||||
setMonsterMode(monster, 7);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (calcNewBlockPosition(monster->blockPropertyIndex, i) == _currentBlock)
|
||||
setMonsterMode(monster, 7);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// straying around not tracing the party
|
||||
moveStrayingMonster(monster);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// second recovery phase after delivering an attack
|
||||
// monsters will rearrange positions in this phase so as to allow a maximum
|
||||
// number of monsters possible attacking at the same time
|
||||
_unkDrawLevelBool = true;
|
||||
monster->fightCurTick--;
|
||||
if ((monster->fightCurTick <= 0) || (checkDrawObjectSpace(_partyPosX, _partyPosY, monster->x, monster->y) > 256) || (monster->flags & 8))
|
||||
setMonsterMode(monster, 7);
|
||||
else
|
||||
rearrangeAttackingMonster(monster);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// same as mode 5, but without rearranging
|
||||
if (--monster->fightCurTick <= 0)
|
||||
setMonsterMode(monster, 7);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// monster destination is set to current party position
|
||||
// depending on the flag setting this gets updated each round
|
||||
// monster can't change mode before arriving at destination and/or attacking the party
|
||||
if (!chasePartyWithDistanceAttacks(monster))
|
||||
chasePartyWithCloseAttacks(monster);
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// first recovery phase after delivering an attack
|
||||
if (++monster->fightCurTick > 2) {
|
||||
setMonsterMode(monster, 5);
|
||||
monster->fightCurTick = (int8) ((((8 << 8) / monster->properties->fightingStats[4]) * _monsterModifiers[6 + _monsterDifficulty]) >> 8);
|
||||
}
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (--monster->fightCurTick) {
|
||||
chasePartyWithCloseAttacks(monster);
|
||||
} else {
|
||||
setMonsterMode(monster, 7);
|
||||
monster->flags &= 0xfff7;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 12:
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
if (++monster->fightCurTick > 13)
|
||||
runLevelScriptCustom(0x404, -1, monster->id, monster->id, 0, 0);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
if (++monster->fightCurTick > 2)
|
||||
mode13sub(monster);
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
monster->field_1B = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1087,6 +1190,54 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
placeMonster(monster, fx, fy);
|
||||
}
|
||||
|
||||
bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
|
||||
if (!monster->field_25)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
|
||||
if (!(monster->flags & 8)) {
|
||||
int dir = calcMonsterDirection(monster->x & 0xff00, monster->y & 0xff00, _partyPosX & 0xff00, _partyPosY & 0xff00);
|
||||
int x1 = _partyPosX;
|
||||
int y1 = _partyPosY;
|
||||
|
||||
calcSpriteRelPosition(monster->x, monster->y, x1, y1, dir >> 1);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
setMonsterMode(monster, 8);
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
|
||||
} else {
|
||||
setMonsterDirection(monster, dir);
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (monster->x != monster->destX || monster->y != monster->destY) {
|
||||
walkMonster(monster);
|
||||
} else {
|
||||
setMonsterDirection(monster, monster->destDirection);
|
||||
setMonsterMode(monster, (_rnd.getRandomNumberRng(1, 100) <= 50) ? 4 : 3);
|
||||
}
|
||||
}
|
||||
|
||||
int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
static const int8 walkMonsterTable1[] = { 7, -6, 5, -4, 3, -2, 1, 0 };
|
||||
static const int8 walkMonsterTable2[] = { -7, 6, -5, 4, -3, 2, -1, 0 };
|
||||
@ -1206,6 +1357,124 @@ void LoLEngine::getNextStepCoords(int16 srcX, int16 srcY, int &newX, int &newY,
|
||||
newY = (srcY + shiftTableY[direction]) & 0x1fff;
|
||||
}
|
||||
|
||||
void LoLEngine::rearrangeAttackingMonster(MonsterInPlay *monster) {
|
||||
int t = (monster->direction >> 1);
|
||||
uint16 mx = monster->x;
|
||||
uint16 my = monster->y;
|
||||
uint16 *c = (t & 1) ? &my : &mx;
|
||||
bool centered = (*c & 0x7f) ? false : true;
|
||||
|
||||
bool posFlag = true;
|
||||
if (monster->properties->maxWidth <= 63) {
|
||||
if (centered) {
|
||||
bool r = false;
|
||||
|
||||
if (_levelBlockProperties[monster->blockPropertyIndex].assignedObjects & 0x8000) {
|
||||
r = true;
|
||||
} else {
|
||||
uint16 id = _levelBlockProperties[monster->blockPropertyIndex].assignedObjects;
|
||||
id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
|
||||
|
||||
if (id != monster->id) {
|
||||
r = true;
|
||||
} else {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
t = (t + 1) & 3;
|
||||
calcNewBlockPosition(monster->blockPropertyIndex, t);
|
||||
id = _levelBlockProperties[monster->blockPropertyIndex].assignedObjects;
|
||||
id = (id & 0x8000) ? (id & 0x7fff) : 0xffff;
|
||||
if (id != 0xffff)
|
||||
r = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r)
|
||||
posFlag = false;
|
||||
} else {
|
||||
posFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (centered && posFlag)
|
||||
return;
|
||||
|
||||
if (posFlag) {
|
||||
if (*c & 0x80)
|
||||
*c -= 32;
|
||||
else
|
||||
*c += 32;
|
||||
} else {
|
||||
if (*c & 0x80)
|
||||
*c += 32;
|
||||
else
|
||||
*c -= 32;
|
||||
}
|
||||
|
||||
if (walkMonsterCheckDest(mx, my, monster, 4))
|
||||
return;
|
||||
|
||||
int fx = _partyPosX;
|
||||
int fy = _partyPosY;
|
||||
calcSpriteRelPosition(mx, my, fx, fy, monster->direction >> 1);
|
||||
|
||||
t = (fx < 0) ? -fx : fx;
|
||||
if (fy > 160 || t > 80)
|
||||
return;
|
||||
|
||||
placeMonster(monster, mx, my);
|
||||
}
|
||||
|
||||
void LoLEngine::moveStrayingMonster(MonsterInPlay *monster) {
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
if (monster->fightCurTick) {
|
||||
uint8 d = (monster->direction - monster->fightCurTick) & 6;
|
||||
uint8 id = monster->id;
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
getNextStepCoords(monster->x, monster->y, x, y, d);
|
||||
|
||||
if (!walkMonsterCheckDest(x, y, monster, 4)) {
|
||||
placeMonster(monster, x, y);
|
||||
setMonsterDirection(monster, d);
|
||||
if (!i) {
|
||||
if (++id > 3)
|
||||
monster->fightCurTick = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
d = (d + monster->fightCurTick) & 6;
|
||||
}
|
||||
setMonsterMode(monster, 3);
|
||||
|
||||
} else {
|
||||
monster->direction &= 6;
|
||||
getNextStepCoords(monster->x, monster->y, x, y, monster->direction);
|
||||
if (!walkMonsterCheckDest(x, y, monster, 4)) {
|
||||
placeMonster(monster, x, y);
|
||||
} else {
|
||||
monster->fightCurTick = _rnd.getRandomBit() ? 2 : -2;
|
||||
monster->direction = (monster->direction + monster->fightCurTick) & 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::mode13sub(MonsterInPlay *monster) {
|
||||
setMonsterMode(monster, 14);
|
||||
monsterDropItems(monster);
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
|
||||
uint8 w = _levelBlockProperties[monster->blockPropertyIndex].walls[0];
|
||||
uint8 f = _levelBlockProperties[monster->blockPropertyIndex].flags;
|
||||
if (_wllVmpMap[w] == 0 && _wllShapeMap[w] == 0 && !(f & 0x40) && !(monster->properties->flags & 0x1000))
|
||||
_levelBlockProperties[monster->blockPropertyIndex].flags |= 0x80;
|
||||
|
||||
placeMonster(monster, 0, 0);
|
||||
}
|
||||
|
||||
} // end of namespace Kyra
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
@ -1001,9 +1001,9 @@ bool StaticResource::loadCharData(const char *filename, void *&ptr, int &size) {
|
||||
t->field_34 = file->readUint16LE();
|
||||
t->field_36 = file->readByte();
|
||||
t->itemsProtection = file->readUint16LE();
|
||||
t->hitPointsCur = file->readUint16LE();;
|
||||
t->hitPointsCur = file->readSint16LE();;
|
||||
t->hitPointsMax = file->readUint16LE();;
|
||||
t->magicPointsCur = file->readUint16LE();;
|
||||
t->magicPointsCur = file->readSint16LE();;
|
||||
t->magicPointsMax = file->readUint16LE();;
|
||||
t->field_41 = file->readByte();
|
||||
t->damageSuffered = file->readUint16LE();
|
||||
|
Loading…
Reference in New Issue
Block a user