void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) { uint8 flg = _levelBlockProperties[block].flags & 7; if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4))) return; for (int i = 0; i < 30; i++) { if (_monsters[i].block != block) continue; if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30) return; } int index = -1; int maxDist = 0; for (int i = 0; i < 30; i++) { if (_monsters[i].hitPointsCur <= 0) { index = i; break; } if (_monsters[i].flags & 0x40) continue; // WORKAROUND for bug #3611077 (Dran's dragon transformation sequence triggered prematurely): // The boss level and the mindflayer level share the same monster data. If you hang around // long enough in the mindflayer level all 30 monster slots will be used up. When this // happens it will trigger the dragon transformation sequence when Dran is moved around by script. // We avoid removing Dran here by prefering monster slots occupied by monsters from another // sub level. if (_monsters[i].sub != _currentSub) { index = i; break; } int dist = getBlockDistance(_monsters[i].block, _currentBlock); if (dist > maxDist) { maxDist = dist; index = i; } } if (index == -1) return; if (_monsters[index].hitPointsCur > 0) killMonster(&_monsters[index], false); initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem); }
void DarkMoonEngine::replaceMonster(int unit, uint16 block, int pos, int dir, int type, int shpIndex, int mode, int h2, int randItem, int fixedItem) { uint8 flg = _levelBlockProperties[block].flags & 7; if (flg == 7 || _currentBlock == block || (flg && (_monsterProps[type].u30 || pos == 4))) return; for (int i = 0; i < 30; i++) { if (_monsters[i].block != block) continue; if (_monsters[i].pos == 4 || _monsterProps[_monsters[i].type].u30) return; } int index = -1; int maxDist = 0; for (int i = 0; i < 30; i++) { if (_monsters[i].hitPointsCur <= 0) { index = i; break; } if (_monsters[i].flags & 0x40) continue; int dist = getBlockDistance(_monsters[i].block, _currentBlock); if (dist > maxDist) { maxDist = dist; index = i; } } if (index == -1) return; if (_monsters[index].hitPointsCur > 0) killMonster(&_monsters[index], false); initMonster(index, unit, block, pos, dir, type, shpIndex, mode, h2, randItem, fixedItem); }
bool KyraRpgEngine::snd_processEnvironmentalSoundEffect(int soundId, int block) { if (!_sound->sfxEnabled() || shouldQuit()) return false; if (_environmentSfx) snd_playSoundEffect(_environmentSfx, _environmentSfxVol); int dist = 0; if (block) { dist = getBlockDistance(_currentBlock, block); if (dist > _envSfxDistThreshold) { _environmentSfx = 0; return false; } } _environmentSfx = soundId; _environmentSfxVol = (15 - ((block || (_flags.gameID == GI_LOL && dist < 2)) ? dist : 0)) << 4; return true; }