mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
LOL: - doors can now be opened and closed
- some more work on monster walk code svn-id: r39166
This commit is contained in:
parent
3753d0b5f8
commit
8639e34b41
@ -189,6 +189,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
|
||||
|
||||
memset(_activeTim, 0, 10 * sizeof(TIM*));
|
||||
memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile));
|
||||
memset(&_openDoorState, 0, sizeof(OpenDoorState) * 3);
|
||||
|
||||
_pageBuffer1 = _pageBuffer2 = 0;
|
||||
|
||||
@ -212,8 +213,8 @@ LoLEngine::~LoLEngine() {
|
||||
delete _gui;
|
||||
_gui = 0;
|
||||
delete _tim;
|
||||
_tim = 0;
|
||||
delete _txt;
|
||||
_tim = 0;
|
||||
delete _txt;
|
||||
_txt = 0;
|
||||
|
||||
delete[] _itemsInPlay;
|
||||
@ -359,7 +360,7 @@ Common::Error LoLEngine::init() {
|
||||
memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400);
|
||||
|
||||
_characters = new LoLCharacter[4];
|
||||
memset(_characters, 0, sizeof(LoLCharacter) * 3);
|
||||
memset(_characters, 0, sizeof(LoLCharacter) * 4);
|
||||
|
||||
if (!_sound->init())
|
||||
error("Couldn't init sound");
|
||||
@ -752,16 +753,6 @@ void LoLEngine::startupNew() {
|
||||
_screen->showMouse();
|
||||
}
|
||||
|
||||
void LoLEngine::enableSysTimer(int sysTimer) {
|
||||
if (sysTimer == 2)
|
||||
_timer->pause(false);
|
||||
}
|
||||
|
||||
void LoLEngine::disableSysTimer(int sysTimer) {
|
||||
if (sysTimer == 2)
|
||||
_timer->pause(true);
|
||||
}
|
||||
|
||||
void LoLEngine::runLoop() {
|
||||
enableSysTimer(2);
|
||||
|
||||
@ -790,7 +781,7 @@ void LoLEngine::runLoop() {
|
||||
checkForPartyDeath(_partyDeathFlag);
|
||||
_partyDeathFlag = -1;
|
||||
}*/
|
||||
|
||||
|
||||
delay(_tickLength);
|
||||
}
|
||||
}
|
||||
@ -1168,6 +1159,7 @@ void LoLEngine::restoreSceneAfterDialogueSequence(int redraw) {
|
||||
}
|
||||
|
||||
_hideInventory = 0;
|
||||
enableSysTimer(2);
|
||||
}
|
||||
|
||||
void LoLEngine::resetPortraitsArea() {
|
||||
@ -1175,7 +1167,7 @@ void LoLEngine::resetPortraitsArea() {
|
||||
if (!textEnabled() || (!(_hideControls & 2)))
|
||||
timerUpdatePortraitAnimations(1);
|
||||
|
||||
disableSysTimer(2);
|
||||
disableSysTimer(2);
|
||||
}
|
||||
|
||||
void LoLEngine::fadeText() {
|
||||
@ -1368,7 +1360,7 @@ void LoLEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) {
|
||||
if (block != _currentBlock) {
|
||||
static const int8 blockShiftTable[] = { -32, -31, 1, 33, 32, 31, -1, -33 };
|
||||
uint16 cbl = _currentBlock;
|
||||
|
||||
|
||||
for (int i = 3; i > 0; i--) {
|
||||
int dir = calcMonsterDirection(cbl & 0x1f, cbl >> 5, block & 0x1f, block >> 5);
|
||||
cbl += blockShiftTable[dir];
|
||||
@ -1447,7 +1439,7 @@ bool LoLEngine::characterSays(int track, int charId, bool redraw) {
|
||||
charId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool r = snd_playCharacterSpeech(track, charId, 0);
|
||||
|
||||
if (r && redraw) {
|
||||
@ -1465,7 +1457,7 @@ bool LoLEngine::characterSays(int track, int charId, bool redraw) {
|
||||
int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str, EMCState *script, const uint16 *paramList, int16 paramIndex) {
|
||||
int ch = 0;
|
||||
bool skipAnim = false;
|
||||
|
||||
|
||||
if ((charId == -1) || (!(charId & 0x70)))
|
||||
charId = ch = (charId == 1) ? (_selectedCharacter ? _characters[_selectedCharacter].id : 0) : charId;
|
||||
else
|
||||
@ -1502,7 +1494,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str
|
||||
_updatePortraitSpeechAnimDuration = strlen(str) >> 1;
|
||||
_updateCharV3 = unk1;
|
||||
}
|
||||
|
||||
|
||||
if (script)
|
||||
snd_playCharacterSpeech(script->stack[script->sp + 2], ch, 0);
|
||||
else if (paramList)
|
||||
@ -1519,7 +1511,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str
|
||||
_txt->printDialogueText(4, str, script, paramList, paramIndex);
|
||||
_screen->modifyScreenDim(4, 11, 123, 28, 47);
|
||||
|
||||
} else if (mode == 2) {
|
||||
} else if (mode == 2) {
|
||||
_screen->setScreenDim(4);
|
||||
_screen->clearDim(4);
|
||||
_screen->modifyScreenDim(4, 9, 133, 30, 60);
|
||||
@ -1536,7 +1528,7 @@ int LoLEngine::playCharacterScriptChat(int charId, int mode, int unk1, char *str
|
||||
}
|
||||
|
||||
void LoLEngine::giveItemToMonster(MonsterInPlay *monster, uint16 item) {
|
||||
uint16 *c = &monster->assignedItems;
|
||||
uint16 *c = &monster->assignedItems;
|
||||
while (*c)
|
||||
c = &_itemsInPlay[*c].next;
|
||||
*c = item;
|
||||
@ -1567,7 +1559,7 @@ bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) {
|
||||
return true;
|
||||
} else if (_spellProperties[spellNum + 1].unkArr[spellLevel] >= _characters[charNum].hitPointsCur) {
|
||||
_txt->printMessage(2, getLangString(0x4179), _characters[charNum].name);
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -127,7 +127,7 @@ struct MonsterInPlay {
|
||||
uint16 blockPropertyIndex;
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
int8 level;
|
||||
int8 shiftStep;
|
||||
uint16 destX;
|
||||
uint16 destY;
|
||||
uint8 destDirection;
|
||||
@ -306,7 +306,7 @@ private:
|
||||
void setupTimers();
|
||||
void enableTimer(int id);
|
||||
|
||||
void timerProcessOpenDoor(int timerNum);
|
||||
void timerProcessDoors(int timerNum);
|
||||
void timerProcessMonsters(int timerNum);
|
||||
void timerSub3(int timerNum);
|
||||
void timerSub4(int timerNum);
|
||||
@ -316,6 +316,9 @@ private:
|
||||
void timerUpdateLampState(int timerNum);
|
||||
void timerFadeMessageText(int timerNum);
|
||||
|
||||
static const uint8 _clock2Timers[];
|
||||
static const uint8 _numClock2Timers;
|
||||
|
||||
// sound
|
||||
void loadTalkFile(int index);
|
||||
void snd_playVoiceFile(int track) {}
|
||||
@ -530,12 +533,12 @@ private:
|
||||
int olol_loadLangFile(EMCState *script);
|
||||
int olol_playSoundEffect(EMCState *script);
|
||||
int olol_stopTimScript(EMCState *script);
|
||||
int olol_playCharacterScriptChat(EMCState *script);
|
||||
int olol_playCharacterScriptChat(EMCState *script);
|
||||
int olol_loadSoundFile(EMCState *script);
|
||||
int olol_setPaletteBrightness(EMCState *script);
|
||||
int olol_printMessage(EMCState *script);
|
||||
int olol_playDialogueTalkText(EMCState *script);
|
||||
int olol_checkForMonsterMode1(EMCState *script);
|
||||
int olol_checkForMonsterMode1(EMCState *script);
|
||||
int olol_setNextFunc(EMCState *script);
|
||||
int olol_setDoorState(EMCState *script);
|
||||
int olol_assignCustomSfx(EMCState *script);
|
||||
@ -558,6 +561,7 @@ private:
|
||||
int tlol_initDialogueSequence(const TIM *tim, const uint16 *param);
|
||||
int tlol_restoreSceneAfterDialogueSequence(const TIM *tim, const uint16 *param);
|
||||
int tlol_fadeClearWindow(const TIM *tim, const uint16 *param);
|
||||
int tlol_update(const TIM *tim, const uint16 *param);
|
||||
int tlol_playDialogueTalkText(const TIM *tim, const uint16 *param);
|
||||
|
||||
Common::Array<const TIMOpcode*> _timIngameOpcodes;
|
||||
@ -720,11 +724,10 @@ private:
|
||||
int clickedWallOnlyScript(uint16 block);
|
||||
int clickedDoorSwitch(uint16 block, uint16 direction);
|
||||
int clicked6(uint16 block, uint16 direction);
|
||||
|
||||
|
||||
bool clickedShape(int shapeIndex);
|
||||
void openDoorSub1(uint16 block, int unk);
|
||||
void openDoorSub2(uint16 block, int unk);
|
||||
int _emcDoorState;
|
||||
void processDoorSwitch(uint16 block, int unk);
|
||||
void openCloseDoor(uint16 block, int openClose);
|
||||
|
||||
void movePartySmoothScrollBlocked(int speed);
|
||||
void movePartySmoothScrollUp(int speed);
|
||||
@ -737,6 +740,15 @@ private:
|
||||
int smoothScrollDrawSpecialShape(int pageNum);
|
||||
void setLF2(int block);
|
||||
|
||||
struct OpenDoorState {
|
||||
uint16 block;
|
||||
int8 field_2;
|
||||
int8 state;
|
||||
};
|
||||
|
||||
OpenDoorState _openDoorState[3];
|
||||
int _emcDoorState;
|
||||
|
||||
uint8 *_scrollSceneBuffer;
|
||||
uint32 _smoothScrollTimer;
|
||||
int _smoothScrollModeNormal;
|
||||
@ -920,7 +932,7 @@ private:
|
||||
int checkBlockForWallsAndSufficientSpace(int block, int x, int y, int monsterWidth, int testFlag, int wallFlag);
|
||||
bool checkBlockOccupiedByParty(int x, int y, int testFlag);
|
||||
const uint16 *getCharacterOrMonsterStats(int id);
|
||||
void drawMonstersAndItems(int block);
|
||||
void drawMonstersAndItems(int block);
|
||||
void drawMonster(uint16 id);
|
||||
int getMonsterCurFrame(MonsterInPlay *m, uint16 dirFlags);
|
||||
void recalcItemMonsterPositions(uint16 direction, uint16 itemIndex, LevelBlockProperty *l, bool flag);
|
||||
@ -930,13 +942,13 @@ private:
|
||||
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 w, int h, int flags, int tblValue, bool flip);
|
||||
int calcDrawingLayerParameters(int srcX, int srcY, int16 &x2, int16 &y2, int16 &w, int16 &h, uint8 *shape, int flip);
|
||||
|
||||
|
||||
void updateMonster(MonsterInPlay *monster);
|
||||
void moveMonster(MonsterInPlay *monster);
|
||||
void walkMonster(MonsterInPlay *monster);
|
||||
int walkMonsterCalcNextStep(MonsterInPlay *monster);
|
||||
int getMonsterDistance(uint16 block1, uint16 block2);
|
||||
int walkMonster_s3(uint16 monsterBlock, int unk1, int unk2, uint16 curBlock);
|
||||
int walkMonster_s3(uint16 monsterBlock, int direction, int distance, uint16 curBlock);
|
||||
int walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk);
|
||||
void walkMonsterGetNextStepCoords(int16 monsterX, int16 monsterY, int &newX, int &newY, uint16 unk);
|
||||
|
||||
@ -953,8 +965,8 @@ private:
|
||||
|
||||
const uint16 *_monsterModifiers;
|
||||
int _monsterModifiersSize;
|
||||
const int8 *_monsterLevelOffs;
|
||||
int _monsterLevelOffsSize;
|
||||
const int8 *_monsterShiftOffs;
|
||||
int _monsterShiftOffsSize;
|
||||
const uint8 *_monsterDirFlags;
|
||||
int _monsterDirFlagsSize;
|
||||
const int8 *_monsterScaleX;
|
||||
|
@ -230,7 +230,7 @@ enum kKyraResources {
|
||||
kLolCharDefsAkshel,
|
||||
kLolExpRequirements,
|
||||
kLolMonsterModifiers,
|
||||
kLolMonsterLevelOffsets,
|
||||
kLolMonsterShiftOffsets,
|
||||
kLolMonsterDirFlags,
|
||||
kLolMonsterScaleY,
|
||||
kLolMonsterScaleX,
|
||||
|
@ -719,7 +719,7 @@ int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) {
|
||||
|
||||
if (!_emcDoorState) {
|
||||
delay(15 * _tickLength);
|
||||
openDoorSub1(block, 0);
|
||||
processDoorSwitch(block, 0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -753,12 +753,76 @@ bool LoLEngine::clickedShape(int shapeIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LoLEngine::openDoorSub1(uint16 block, int unk) {
|
||||
void LoLEngine::processDoorSwitch(uint16 block, int unk) {
|
||||
if ((block == _currentBlock) || (_levelBlockProperties[block].itemMonsterIndex & 0x8000))
|
||||
return;
|
||||
|
||||
int s = 0;
|
||||
if (!unk) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (_openDoorState[i].block != block)
|
||||
continue;
|
||||
s = -_openDoorState[i].state;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == 0)
|
||||
s = (_wllWallFlags[_levelBlockProperties[block].walls[_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8 ? 0 : 1]] & 1) ? 1 : -1;
|
||||
|
||||
openCloseDoor(block, s);
|
||||
}
|
||||
|
||||
void LoLEngine::openDoorSub2(uint16 block, int unk) {
|
||||
void LoLEngine::openCloseDoor(uint16 block, int openClose) {
|
||||
int s1 = -1;
|
||||
int s2 = -1;
|
||||
|
||||
int c = (_wllWallFlags[_levelBlockProperties[block].walls[0]] & 8) ? 0 : 1;
|
||||
int v = _levelBlockProperties[block].walls[c];
|
||||
int flg = (openClose == 1) ? 0x10 : (openClose == -1 ? 0x20 : 0);
|
||||
|
||||
if (_wllWallFlags[v] & flg)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (_openDoorState[i].block == block) {
|
||||
s1 = i;
|
||||
break;
|
||||
} else if (_openDoorState[i].block == 0 && s2 == -1) {
|
||||
s2 = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1 != -1 || s2 != -1) {
|
||||
if (s1 == -1)
|
||||
s1 = s2;
|
||||
|
||||
_openDoorState[s1].block = block;
|
||||
_openDoorState[s1].state = openClose;
|
||||
_openDoorState[s1].field_2 = c;
|
||||
|
||||
flg = (-openClose == 1) ? 0x10 : (-openClose == -1 ? 0x20 : 0);
|
||||
|
||||
if (_wllWallFlags[v] & flg) {
|
||||
_levelBlockProperties[block].walls[c] += openClose;
|
||||
_levelBlockProperties[block].walls[c ^ 2] += openClose;
|
||||
|
||||
int snd = (openClose == -1) ? 32 : 31;
|
||||
|
||||
snd_processEnvironmentalSoundEffect(snd, block);
|
||||
if (!checkSceneUpdateNeed(block))
|
||||
updateEnvironmentalSfx(0);
|
||||
}
|
||||
|
||||
enableTimer(0);
|
||||
|
||||
} else {
|
||||
while (!(flg & _wllWallFlags[v]))
|
||||
v += openClose;
|
||||
|
||||
_levelBlockProperties[block].walls[c] = _levelBlockProperties[block].walls[c ^ 2] = v;
|
||||
checkSceneUpdateNeed(block);
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::movePartySmoothScrollBlocked(int speed) {
|
||||
|
@ -35,7 +35,7 @@
|
||||
namespace Kyra {
|
||||
|
||||
void LoLEngine::runInitScript(const char *filename, int optionalFunc) {
|
||||
_suspendScript = true;
|
||||
_suspendScript = true;
|
||||
EMCData scriptData;
|
||||
EMCState scriptState;
|
||||
memset(&scriptData, 0, sizeof(EMCData));
|
||||
@ -449,7 +449,6 @@ int LoLEngine::olol_setUnkArrayVal(EMCState *script) {
|
||||
|
||||
int LoLEngine::olol_setGlobalVar(EMCState *script) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGlobalVar(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
|
||||
//uint16 a = stackPos(1);
|
||||
uint16 b = stackPos(2);
|
||||
|
||||
switch (stackPos(0)) {
|
||||
@ -539,10 +538,10 @@ int LoLEngine::olol_initMonster(EMCState *script) {
|
||||
uint16 y = 0;
|
||||
calcCoordinates(x, y, stackPos(0), stackPos(1), stackPos(2));
|
||||
uint16 w = _monsterProperties[stackPos(4)].maxWidth;
|
||||
|
||||
|
||||
if (checkBlockBeforeMonsterPlacement(x, y, w, 7, 7))
|
||||
return -1;
|
||||
|
||||
|
||||
for (uint8 i = 0; i < 30; i++) {
|
||||
MonsterInPlay *l = &_monsters[i];
|
||||
if (l->might || l->mode == 13)
|
||||
@ -577,7 +576,7 @@ int LoLEngine::olol_initMonster(EMCState *script) {
|
||||
for (int ii = 0; ii < 4; ii++)
|
||||
l->field_2A[ii] = stackPos(7 + ii);
|
||||
|
||||
checkSceneUpdateNeed(l->blockPropertyIndex);
|
||||
checkSceneUpdateNeed(l->blockPropertyIndex);
|
||||
return i;
|
||||
}
|
||||
|
||||
@ -648,11 +647,10 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) {
|
||||
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)];
|
||||
|
||||
|
||||
if (m->mode == 1 || m->mode == 2) {
|
||||
calcCoordinates(m->destX, m->destY, stackPos(1), stackPos(2), stackPos(3));
|
||||
m->destDirection = stackPos(4) << 1;
|
||||
|
||||
if (m->x != m->destX || m->y != m->destY)
|
||||
setMonsterDirection(m, calcMonsterDirection(m->x, m->y, m->destX, m->destY));
|
||||
}
|
||||
@ -954,6 +952,12 @@ int LoLEngine::tlol_fadeClearWindow(const TIM *tim, const uint16 *param) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::tlol_update(const TIM *tim, const uint16 *param) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_update(%p, %p)", (const void*)tim, (const void*)param);
|
||||
update();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoLEngine::tlol_playDialogueTalkText(const TIM *tim, const uint16 *param) {
|
||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_playDialogueTalkText(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
|
||||
if (!snd_playCharacterSpeech(param[0], 0, 0) || textEnabled())
|
||||
@ -1296,7 +1300,7 @@ void LoLEngine::setupOpcodeTable() {
|
||||
|
||||
// 0x08
|
||||
OpcodeTimUnImpl();
|
||||
OpcodeTimUnImpl();
|
||||
OpcodeTim(tlol_update);
|
||||
OpcodeTimUnImpl();
|
||||
OpcodeTimUnImpl();
|
||||
|
||||
|
@ -312,7 +312,7 @@ int LoLEngine::checkBlockBeforeMonsterPlacement(int x, int y, int monsterWidth,
|
||||
int xOffs = 0;
|
||||
int yOffs = 0;
|
||||
int flag = 0;
|
||||
|
||||
|
||||
int r = checkBlockForWallsAndSufficientSpace(calcBlockIndex(x, y), x, y, monsterWidth, testFlag, wallFlag);
|
||||
if (r)
|
||||
return r;
|
||||
@ -416,7 +416,7 @@ int LoLEngine::calcMonsterSkillLevel(int id, int a) {
|
||||
return r;
|
||||
else if (_characters[id].skillLevels[1] <= 7)
|
||||
return (r- (r >> 2));
|
||||
|
||||
|
||||
return (r- (r >> 1));
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ int LoLEngine::checkBlockForWallsAndSufficientSpace(int block, int x, int y, int
|
||||
uint16 b = _levelBlockProperties[block].itemMonsterIndex;
|
||||
while (b & 0x8000) {
|
||||
MonsterInPlay *monster = &_monsters[b & 0x7fff];
|
||||
|
||||
|
||||
if (monster->mode < 13) {
|
||||
int r = checkMonsterSpace(x, y, monster->x, monster->y);
|
||||
if ((monsterWidth + monster->properties->maxWidth) > r)
|
||||
@ -460,7 +460,7 @@ bool LoLEngine::checkBlockOccupiedByParty(int x, int y, int testFlag) {
|
||||
|
||||
void LoLEngine::drawMonstersAndItems(int block) {
|
||||
LevelBlockProperty *l = _curBlockCaps[block];
|
||||
uint16 s = l->itemMonsterIndex;
|
||||
uint16 s = l->itemMonsterIndex;
|
||||
ItemInPlay *i = findItem(s);
|
||||
|
||||
if (l->direction != _currentDirection) {
|
||||
@ -491,7 +491,7 @@ void LoLEngine::drawMonstersAndItems(int block) {
|
||||
}
|
||||
|
||||
void LoLEngine::drawMonster(uint16 id) {
|
||||
MonsterInPlay *m = &_monsters[id];
|
||||
MonsterInPlay *m = &_monsters[id];
|
||||
int16 flg = _monsterDirFlags[(_currentDirection << 2) + m->facing];
|
||||
int curFrm = getMonsterCurFrame(m, flg & 0xffef);
|
||||
|
||||
@ -505,12 +505,12 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
bool flip = m->properties->flags & 0x200 ? true : false;
|
||||
flg &= 0x10;
|
||||
uint8 *shp = _monsterShapes[(m->properties->shapeIndex << 4) + curFrm];
|
||||
|
||||
|
||||
if (m->properties->flags & 0x800)
|
||||
flg |= 0x20;
|
||||
|
||||
uint8 *ovl1 = d ? _monsterPalettes[(m->properties->shapeIndex << 4) + (curFrm & 0x0f)] + (shp[10] * (d - 1)) : 0;
|
||||
uint8 *ovl2 = drawItemOrMonster(shp, ovl1, m->x + _monsterLevelOffs[m->level << 1], m->y + _monsterLevelOffs[(m->level << 1) + 1], 0, 0, flg | 1, -1, flip);
|
||||
uint8 *ovl2 = drawItemOrMonster(shp, ovl1, m->x + _monsterShiftOffs[m->shiftStep << 1], m->y + _monsterShiftOffs[(m->shiftStep << 1) + 1], 0, 0, flg | 1, -1, flip);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int v = m->field_2A[i] - 1;
|
||||
@ -536,9 +536,9 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
int dH = _screen->getShapeScaledHeight(shp, _dmScaleH) >> 1;
|
||||
|
||||
int a = (m->mode == 13) ? (m->field_15 << 1) : (m->properties->might / (m->field_1B & 0x7fff));
|
||||
|
||||
|
||||
shp = _gameShapes[6];
|
||||
|
||||
|
||||
int cF = m->properties->flags & 0xc000;
|
||||
if (cF == 0x4000)
|
||||
cF = 63;
|
||||
@ -550,7 +550,7 @@ void LoLEngine::drawMonster(uint16 id) {
|
||||
cF = 0;
|
||||
|
||||
uint8 *tbl = new uint8[256];
|
||||
if (cF) {
|
||||
if (cF) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
tbl[i] = i;
|
||||
if (i < 2 || i > 7)
|
||||
@ -772,7 +772,7 @@ uint8 *LoLEngine::drawItemOrMonster(uint8 *shape, uint8 *table, int x, int y, in
|
||||
r = 7 - ((r / 3) - 1);
|
||||
r = CLIP(r, 0, 7);
|
||||
ovl = _screen->getLevelOverlay(r);
|
||||
} else {
|
||||
} else {
|
||||
memset (tmpOvl + 1, tblValue, 15);
|
||||
table = tmpOvl;
|
||||
ovl = _screen->getLevelOverlay(7);
|
||||
@ -829,7 +829,7 @@ int LoLEngine::calcDrawingLayerParameters(int x1, int y1, int16 &x2, int16 &y2,
|
||||
|
||||
if (flip)
|
||||
y2 = ((120 - y2) >> 1) + _screen->getShapeScaledHeight(shape, _dmScaleH);
|
||||
else
|
||||
else
|
||||
y2 -= (_screen->getShapeScaledHeight(shape, _dmScaleH) >> 1);
|
||||
|
||||
return l;
|
||||
@ -868,8 +868,12 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
if ((s & 1) && (monster->flags & 0x10))
|
||||
setMonsterMode(monster, 7);
|
||||
|
||||
////
|
||||
// TODO
|
||||
if ((monster->mode != 11) && (monster->mode != 14)) {
|
||||
if (!(_rnd.getRandomNumberRng(1, 100) & 3)) {
|
||||
monster->shiftStep = (++monster->shiftStep) & 0x0f;
|
||||
checkSceneUpdateNeed(monster->blockPropertyIndex);
|
||||
}
|
||||
}
|
||||
|
||||
switch (monster->mode) {
|
||||
case 0:
|
||||
@ -923,7 +927,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
|
||||
void LoLEngine::moveMonster(MonsterInPlay *monster) {
|
||||
static const int8 turnPos[] = { 0, 2, 6, 6, 0, 2, 4, 4, 2, 2, 4, 6, 0, 0, 4, 6, 0 };
|
||||
if (monster->x != monster->destX || monster->y != monster->destY) {
|
||||
walkMonster(monster);
|
||||
walkMonster(monster);
|
||||
} else if (monster->direction != monster->destDirection) {
|
||||
int i = (monster->facing << 2) + (monster->destDirection >> 1);
|
||||
setMonsterDirection(monster, turnPos[i]);
|
||||
@ -935,7 +939,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
return;
|
||||
|
||||
int s = walkMonsterCalcNextStep(monster);
|
||||
|
||||
|
||||
if (s == -1) {
|
||||
if (walkMonsterCheckDest(monster->x, monster->y, monster, 4) != 1)
|
||||
return;
|
||||
@ -951,7 +955,7 @@ void LoLEngine::walkMonster(MonsterInPlay *monster) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fx = 0;
|
||||
@ -973,7 +977,7 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
const int8 *tbl = _monsterShiftAlt ? walkMonsterTable2 : walkMonsterTable1;
|
||||
|
||||
int sx = monster->x;
|
||||
int sy = monster->y;
|
||||
int sy = monster->y;
|
||||
int s = monster->direction;
|
||||
int d = calcMonsterDirection(monster->x, monster->y, monster->destX, monster->destY);
|
||||
|
||||
@ -1002,10 +1006,10 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
continue;
|
||||
|
||||
uint8 w = _levelBlockProperties[_monsterCurBlock].walls[(s >> 1) ^ 2];
|
||||
|
||||
|
||||
if (_wllWallFlags[w] & 0x20) {
|
||||
if (_wllBuffer3[w] == 5)
|
||||
openDoorSub2(_monsterCurBlock, 1);
|
||||
openCloseDoor(_monsterCurBlock, 1);
|
||||
}
|
||||
|
||||
if (_wllWallFlags[w] & 8)
|
||||
@ -1017,9 +1021,9 @@ int LoLEngine::walkMonsterCalcNextStep(MonsterInPlay *monster) {
|
||||
|
||||
int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
|
||||
int8 b1x = block1 & 0x1f;
|
||||
int8 b1y = (block1 >> 8) & 0x1f;
|
||||
int8 b1y = block1 >> 5;
|
||||
int8 b2x = block2 & 0x1f;
|
||||
int8 b2y = (block2 >> 8) & 0x1f;
|
||||
int8 b2y = block2 >> 5;
|
||||
|
||||
uint8 dy = ABS(b2y - b1y);
|
||||
uint8 dx = ABS(b2x - b1x);
|
||||
@ -1030,8 +1034,36 @@ int LoLEngine::getMonsterDistance(uint16 block1, uint16 block2) {
|
||||
return (dx << 1) + dy;
|
||||
}
|
||||
|
||||
int LoLEngine::walkMonster_s3(uint16 monsterBlock, int unk1, int unk2, uint16 curBlock) {
|
||||
return 0;
|
||||
int LoLEngine::walkMonster_s3(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))
|
||||
return 5;
|
||||
|
||||
if (((monsterBlock & 0x1f) != (curBlock & 0x1f)) || ((monsterBlock & 0xffe0) != (curBlock & 0xffe0)))
|
||||
return 5;
|
||||
|
||||
if (distance < 0)
|
||||
return 5;
|
||||
|
||||
for (int i = 0; i < distance; i++) {
|
||||
int p = calcNewBlockPosition(monsterBlock, direction);
|
||||
|
||||
if (p == curBlock)
|
||||
return direction;
|
||||
|
||||
if (_wllWallFlags[_levelBlockProperties[p].walls[direction ^ 2]] & 2)
|
||||
return 5;
|
||||
|
||||
if (_levelBlockProperties[p].itemMonsterIndex & 0x8000)
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
int LoLEngine::walkMonsterCheckDest(int x, int y, MonsterInPlay *monster, int unk) {
|
||||
|
@ -391,7 +391,7 @@ bool StaticResource::init() {
|
||||
{ kLolCharDefsAkshel, kLolRawDataBe16, "CHAKSHEL.DEF" },
|
||||
{ kLolExpRequirements, kLolRawDataBe32, "EXPERIENCE.DEF" },
|
||||
{ kLolMonsterModifiers, kLolRawDataBe16, "MONSTMOD.DEF" },
|
||||
{ kLolMonsterLevelOffsets, kRawData, "MONSTLVL.DEF" },
|
||||
{ kLolMonsterShiftOffsets, kRawData, "MONSTLVL.DEF" },
|
||||
{ kLolMonsterDirFlags, kRawData, "MONSTDIR.DEF" },
|
||||
{ kLolMonsterScaleY, kRawData, "MONSTZY.DEF" },
|
||||
{ kLolMonsterScaleX, kRawData, "MONSTZX.DEF" },
|
||||
@ -1762,7 +1762,7 @@ void LoLEngine::initStaticResource() {
|
||||
_charDefsAkshel = _staticres->loadRawDataBe16(kLolCharDefsAkshel, _charDefsAkshelSize);
|
||||
_expRequirements = (const int32*)_staticres->loadRawDataBe32(kLolExpRequirements, _expRequirementsSize);
|
||||
_monsterModifiers = _staticres->loadRawDataBe16(kLolMonsterModifiers, _monsterModifiersSize);
|
||||
_monsterLevelOffs = (const int8*)_staticres->loadRawData(kLolMonsterLevelOffsets, _monsterLevelOffsSize);
|
||||
_monsterShiftOffs = (const int8*)_staticres->loadRawData(kLolMonsterShiftOffsets, _monsterShiftOffsSize);
|
||||
_monsterDirFlags = _staticres->loadRawData(kLolMonsterDirFlags, _monsterDirFlagsSize);
|
||||
_monsterScaleX = (const int8*)_staticres->loadRawData(kLolMonsterScaleX, _monsterScaleXSize);
|
||||
_monsterScaleY = (const int8*)_staticres->loadRawData(kLolMonsterScaleY, _monsterScaleYSize);
|
||||
@ -2988,6 +2988,13 @@ const uint8 LoLEngine::_charInfoFrameTable[] = {
|
||||
0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_clock2Timers[] = {
|
||||
0x00, 0x10, 0x11, 0x03, 0x04, 0x50,
|
||||
0x51, 0x52, 0x08, 0x09, 0x0A
|
||||
};
|
||||
|
||||
const uint8 LoLEngine::_numClock2Timers = ARRAYSIZE(LoLEngine::_clock2Timers);
|
||||
|
||||
#endif // ENABLE_LOL
|
||||
|
||||
} // End of namespace Kyra
|
||||
|
@ -108,6 +108,7 @@ void TimerManager::addTimer(uint8 id, TimerFunc *func, int countdown, bool enabl
|
||||
newTimer.enabled = enabled ? 1 : 0;
|
||||
newTimer.lastUpdate = newTimer.nextRun = 0;
|
||||
newTimer.func = func;
|
||||
newTimer.pauseStartTime = 0;
|
||||
|
||||
_timers.push_back(newTimer);
|
||||
}
|
||||
@ -217,6 +218,28 @@ uint32 TimerManager::getNextRun(uint8 id) const {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void TimerManager::pauseSingleTimer(uint8 id, bool p) {
|
||||
debugC(9, kDebugLevelTimer, "TimerManager::pauseSingleTimer(%d, %d)", id, (int) p);
|
||||
Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id));
|
||||
|
||||
if (timer == _timers.end()) {
|
||||
warning("TimerManager::pauseSingleTimer: No timer %d", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p) {
|
||||
timer->pauseStartTime = _system->getMillis();
|
||||
timer->enabled = 0;
|
||||
} else if (timer->pauseStartTime) {
|
||||
int32 elapsedTime = _system->getMillis() - timer->pauseStartTime;
|
||||
timer->enabled = 1;
|
||||
timer->lastUpdate += elapsedTime;
|
||||
timer->nextRun += elapsedTime;
|
||||
resync();
|
||||
timer->pauseStartTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool TimerManager::isEnabled(uint8 id) const {
|
||||
debugC(9, kDebugLevelTimer, "TimerManager::isEnabled(%d)", id);
|
||||
|
||||
|
@ -45,6 +45,8 @@ struct TimerEntry {
|
||||
uint32 nextRun;
|
||||
|
||||
TimerFunc *func;
|
||||
|
||||
uint32 pauseStartTime;
|
||||
};
|
||||
|
||||
class TimerManager {
|
||||
@ -70,12 +72,15 @@ public:
|
||||
void setNextRun(uint8 id, uint32 nextRun);
|
||||
uint32 getNextRun(uint8 id) const;
|
||||
|
||||
void pauseSingleTimer(uint8 id, bool p);
|
||||
|
||||
bool isEnabled(uint8 id) const;
|
||||
void enable(uint8 id);
|
||||
void disable(uint8 id);
|
||||
|
||||
void loadDataFromFile(Common::SeekableReadStream &file, int version);
|
||||
void saveDataToFile(Common::WriteStream &file) const;
|
||||
|
||||
private:
|
||||
void resync();
|
||||
|
||||
|
@ -35,8 +35,8 @@ namespace Kyra {
|
||||
|
||||
void LoLEngine::setupTimers() {
|
||||
debugC(9, kDebugLevelMain | kDebugLevelTimer, "LoLEngine::setupTimers()");
|
||||
|
||||
_timer->addTimer(0, TimerV2(timerProcessOpenDoor), 15, true);
|
||||
|
||||
_timer->addTimer(0, TimerV2(timerProcessDoors), 15, true);
|
||||
_timer->addTimer(0x10, TimerV2(timerProcessMonsters), 6, true);
|
||||
_timer->addTimer(0x11, TimerV2(timerProcessMonsters), 6, true);
|
||||
_timer->setNextRun(0x11, _system->getMillis() + 3 * _tickLength);
|
||||
@ -56,13 +56,56 @@ void LoLEngine::enableTimer(int id) {
|
||||
_timer->setNextRun(id, _system->getMillis() + _timer->getDelay(id) * _tickLength);
|
||||
}
|
||||
|
||||
void LoLEngine::timerProcessOpenDoor(int timerNum) {
|
||||
void LoLEngine::enableSysTimer(int sysTimer) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _numClock2Timers; i++)
|
||||
_timer->pauseSingleTimer(_clock2Timers[i], false);
|
||||
}
|
||||
|
||||
void LoLEngine::disableSysTimer(int sysTimer) {
|
||||
if (sysTimer != 2)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _numClock2Timers; i++)
|
||||
_timer->pauseSingleTimer(_clock2Timers[i], true);
|
||||
}
|
||||
|
||||
void LoLEngine::timerProcessDoors(int timerNum) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
uint16 b = _openDoorState[i].block;
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
int v = _openDoorState[i].state;
|
||||
int c = _openDoorState[i].field_2;
|
||||
|
||||
_levelBlockProperties[b].walls[c] += v;
|
||||
_levelBlockProperties[b].walls[c ^ 2] += v;
|
||||
|
||||
int snd = 31;
|
||||
|
||||
int flg = _wllWallFlags[_levelBlockProperties[b].walls[c]];
|
||||
if (flg & 0x20)
|
||||
snd = 33;
|
||||
else if (v == -1)
|
||||
snd = 32;
|
||||
|
||||
if (!(_updateFlags & 1)) {
|
||||
snd_processEnvironmentalSoundEffect(snd, b);
|
||||
if (!checkSceneUpdateNeed(b))
|
||||
updateEnvironmentalSfx(0);
|
||||
}
|
||||
|
||||
if (flg & 0x30)
|
||||
_openDoorState[i].block = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void LoLEngine::timerProcessMonsters(int timerNum) {
|
||||
//if (!_updateMonsters)
|
||||
// return;
|
||||
// if (!_updateMonsters)
|
||||
// return;
|
||||
|
||||
for (int i = timerNum & 0x0f; i < 30; i += 2)
|
||||
updateMonster(&_monsters[i]);
|
||||
|
Loading…
Reference in New Issue
Block a user