aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorFlorian Kagerer2009-07-08 20:19:23 +0000
committerFlorian Kagerer2009-07-08 20:19:23 +0000
commit2950bc28c4d14b5991c9fb4e854644d1c4f93a0f (patch)
treee955053786873f32b97d8a7488900d228a4d48c9 /engines/kyra
parent5ca94c5cce2ca0b42bb678835d9e141456bbae5b (diff)
downloadscummvm-rg350-2950bc28c4d14b5991c9fb4e854644d1c4f93a0f.tar.gz
scummvm-rg350-2950bc28c4d14b5991c9fb4e854644d1c4f93a0f.tar.bz2
scummvm-rg350-2950bc28c4d14b5991c9fb4e854644d1c4f93a0f.zip
LOL: fix long standing bugs in the battle system (hit chance, damage, etc) by adapting original style random number generator
svn-id: r42269
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/lol.cpp53
-rw-r--r--engines/kyra/lol.h5
-rw-r--r--engines/kyra/scene_lol.cpp4
-rw-r--r--engines/kyra/script_lol.cpp19
-rw-r--r--engines/kyra/sprites_lol.cpp8
-rw-r--r--engines/kyra/timer_lol.cpp4
6 files changed, 60 insertions, 33 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 7c4b073f29..8f00708e43 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -214,8 +214,6 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_compassBroken = _drainMagic = 0;
_dialogueField = false;
- _rndSpecial = 0x12349876;
-
_buttonData = 0;
_activeButtons = 0;
gui_resetButtonList();
@@ -1082,7 +1080,7 @@ bool LoLEngine::addCharacter(int id) {
loadCharFaceShapes(numChars, id);
- _characters[numChars].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6;
+ _characters[numChars].nextAnimUpdateCountdown = (int16) generateRandomNumber(1, 12) + 6;
for (i = 0; i < 11; i++) {
if (_characters[numChars].items[i]) {
@@ -1176,7 +1174,7 @@ void LoLEngine::updatePortraitSpeechAnim() {
}
}
- int f = _rnd.getRandomNumberRng(1, 6) - 1;
+ int f = generateRandomNumber(1, 6) - 1;
if (f == _characters[_updateCharNum].curFaceFrame)
f++;
if (f > 5)
@@ -1404,24 +1402,24 @@ void LoLEngine::increaseExperience(int charNum, int skill, uint32 points) {
switch (skill) {
case 0:
_txt->printMessage(0x8003, getLangString(0x4023), _characters[charNum].name);
- inc = _rnd.getRandomNumberRng(4, 6);
+ inc = generateRandomNumber(4, 6);
_characters[charNum].hitPointsCur += inc;
_characters[charNum].hitPointsMax += inc;
break;
case 1:
_txt->printMessage(0x8003, getLangString(0x4025), _characters[charNum].name);
- inc = _rnd.getRandomNumberRng(2, 6);
+ inc = generateRandomNumber(2, 6);
_characters[charNum].hitPointsCur += inc;
_characters[charNum].hitPointsMax += inc;
break;
case 2:
_txt->printMessage(0x8003, getLangString(0x4024), _characters[charNum].name);
- inc = (_characters[charNum].defaultModifiers[6] * (_rnd.getRandomNumberRng(1, 8) + 17)) >> 8;
+ inc = (_characters[charNum].defaultModifiers[6] * (generateRandomNumber(1, 8) + 17)) >> 8;
_characters[charNum].magicPointsCur += inc;
_characters[charNum].magicPointsMax += inc;
- inc = _rnd.getRandomNumberRng(1, 6);
+ inc = generateRandomNumber(1, 6);
_characters[charNum].hitPointsCur += inc;
_characters[charNum].hitPointsMax += inc;
break;
@@ -1874,6 +1872,29 @@ void LoLEngine::delay(uint32 millis, bool doUpdate, bool) {
}
}
+int LoLEngine::generateRandomNumber(int min, int max) {
+ // The output produced by this random number generator
+ // differs a lot from _rnd.getRandomNumberRng(). Using
+ // _rnd.getRandomNumberRng() instead of this function
+ // here will break the fighting system!
+
+ if (min <= 0 || max <= 0)
+ return 0;
+
+ int res = 0;
+ int d = 0;
+
+ do {
+ int val = (((int)_rnd.getRandomNumber(0x7fff) * max) / 0x8000) + 1;
+ if (val > max)
+ val -= max;
+ res += val;
+ d++;
+ } while (d < min);
+
+ return res;
+}
+
void LoLEngine::updateEnvironmentalSfx(int soundId) {
snd_processEnvironmentalSoundEffect(soundId, _currentBlock);
}
@@ -2260,7 +2281,7 @@ int LoLEngine::processMagicIce(int charNum, int spellLevel) {
} else {
uint16 o = _levelBlockProperties[calcNewBlockPosition(_currentBlock, _currentDirection)].assignedObjects;
while (o & 0x8000) {
- int might = _rnd.getRandomNumberRng(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel];
+ int might = generateRandomNumber(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel];
int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2);
MonsterInPlay *m = &_monsters[o & 0x7fff];
@@ -3192,7 +3213,7 @@ int LoLEngine::battleHitSkillTest(int16 attacker, int16 target, int skill) {
evadeChanceModifier = _characters[target].defaultModifiers[3];
}
- int r = _rnd.getRandomNumberRng(1, 100);
+ int r = generateRandomNumber(1, 100);
if (r >= sk)
return 2;
@@ -3230,9 +3251,9 @@ int LoLEngine::inflictDamage(uint16 target, int damage, uint16 attacker, int ski
m->hitPoints -= damage;
m->damageReceived = 0x8000 | damage;
m->flags |= 0x10;
- m->hitOffsX = _rnd.getRandomNumberRng(1, 24);
+ m->hitOffsX = generateRandomNumber(1, 24);
m->hitOffsX -= 12;
- m->hitOffsY = _rnd.getRandomNumberRng(1, 24);
+ m->hitOffsY = generateRandomNumber(1, 24);
m->hitOffsY -= 12;
m->hitPoints = CLIP<int16>(m->hitPoints, 0, m->properties->hitPoints);
@@ -3436,7 +3457,7 @@ void LoLEngine::checkForPartyDeath() {
}
void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, int16 damage) {
- if (_rnd.getRandomNumberRng(1, 100) > monster->properties->attackSkillChance)
+ if (generateRandomNumber(1, 100) > monster->properties->attackSkillChance)
return;
int t = 0;
@@ -3506,7 +3527,7 @@ void LoLEngine::applyMonsterAttackSkill(MonsterInPlay *monster, int16 target, in
}
void LoLEngine::applyMonsterDefenseSkill(MonsterInPlay *monster, int16 attacker, int flags, int skill, int damage) {
- if (_rnd.getRandomNumberRng(1, 100) > monster->properties->defenseSkillChance)
+ if (generateRandomNumber(1, 100) > monster->properties->defenseSkillChance)
return;
int itm = 0;
@@ -3593,7 +3614,7 @@ int LoLEngine::paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFl
if (!(_characters[charNum].flags & 1) || (_characters[charNum].flags & immunityFlags))
return 0;
- if ((int)_rnd.getRandomNumberRng(1, 100) > hitChance)
+ if ((int)generateRandomNumber(1, 100) > hitChance)
return 0;
int r = 0;
@@ -3711,7 +3732,7 @@ void LoLEngine::launchMagicViper() {
_screen->copyPage(12, 0);
_screen->copyPage(12, 2);
- int t = _rnd.getRandomNumberRng(1, 4);
+ int t = generateRandomNumber(1, 4);
for (int i = 0; i < 4; i++) {
if (!(_characters[i].flags & 1)) {
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 12000c31fa..8fafa450b3 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -642,6 +642,7 @@ private:
int olol_setWallType(EMCState *script);
int olol_getWallType(EMCState *script);
int olol_drawScene(EMCState *script);
+ int olol_getRand(EMCState *script);
int olol_moveParty(EMCState *script);
int olol_delay(EMCState *script);
int olol_setGameFlag(EMCState *script);
@@ -1313,6 +1314,7 @@ private:
// misc
void delay(uint32 millis, bool doUpdate = false, bool isMainLoop = false);
+ int generateRandomNumber(int min, int max);
uint8 _compassBroken;
uint8 _drainMagic;
@@ -1320,8 +1322,7 @@ private:
uint8 *_pageBuffer1;
uint8 *_pageBuffer2;
- uint32 _rndSpecial;
-
+
// spells
typedef Common::Functor1Mem<ActiveSpell*, int, LoLEngine> SpellProc;
Common::Array<const SpellProc*> _spellProcs;
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 945495517f..403b4cc69c 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -552,14 +552,14 @@ void LoLEngine::updateLampStatus() {
if (_lampEffect == -1) {
if (_screen->_fadeFlag == 0)
setPaletteBrightness(_screen->getPalette(0), _brightness, newLampEffect);
- _lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
+ _lampStatusTimer = _system->getMillis() + (10 + generateRandomNumber(1, 30)) * _tickLength;
} else {
if ((_lampEffect & 0xfe) == (newLampEffect & 0xfe)) {
if (_system->getMillis() <= _lampStatusTimer) {
newLampEffect = _lampEffect;
} else {
newLampEffect = _lampEffect ^ 1;
- _lampStatusTimer = _system->getMillis() + (10 + _rnd.getRandomNumberRng(1, 30)) * _tickLength;
+ _lampStatusTimer = _system->getMillis() + (10 + generateRandomNumber(1, 30)) * _tickLength;
}
} else {
if (_screen->_fadeFlag == 0)
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index a606419722..18b8d81ef9 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -135,6 +135,11 @@ int LoLEngine::olol_drawScene(EMCState *script) {
return 1;
}
+int LoLEngine::olol_getRand(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
+ return generateRandomNumber(stackPos(0), stackPos(1));
+}
+
int LoLEngine::olol_moveParty(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_moveParty(%p) (%d)", (const void *)script, stackPos(0));
int mode = stackPos(0);
@@ -831,10 +836,10 @@ int LoLEngine::olol_initMonster(EMCState *script) {
l->hitPoints = (l->properties->hitPoints * _monsterModifiers[_monsterDifficulty]) >> 8;
if (_currentLevel == 12 && l->type == 2)
- l->hitPoints = (l->hitPoints * (_rnd.getRandomNumberRng(1, 128) + 192)) >> 8;
+ l->hitPoints = (l->hitPoints * (generateRandomNumber(1, 128) + 192)) >> 8;
l->numDistAttacks = l->properties->numDistAttacks;
- l->distAttackTick = _rnd.getRandomNumberRng(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1;
+ l->distAttackTick = generateRandomNumber(1, calcMonsterSkillLevel(l->id | 0x8000, 8)) - 1;
l->flyingHeight = 2;
l->flags = stackPos(5);
l->assignedItems = 0;
@@ -1366,18 +1371,18 @@ int LoLEngine::olol_characterSkillTest(EMCState *script){
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_characterSkillTest(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int skill = stackPos(0);
int n = countActiveCharacters();
- uint m = 0;
+ int m = 0;
int c = 0;
for (int i = 0; i < n ; i++) {
- uint v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25;
+ int v = _characters[i].skillModifiers[skill] + _characters[i].skillLevels[skill] + 25;
if (v > m) {
m = v;
c = i;
}
}
- return (_rnd.getRandomNumberRng(1, 100) > m) ? -1 : c;
+ return (generateRandomNumber(1, 100) > m) ? -1 : c;
}
int LoLEngine::olol_countAllMonsters(EMCState *script){
@@ -1440,7 +1445,7 @@ int LoLEngine::olol_calcInflictableDamage(EMCState *script) {
int LoLEngine::olol_getInflictedDamage(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getInflictedDamage(%p) (%d)", (const void *)script, stackPos(0));
int mx = stackPos(0);
- return mx ? _rnd.getRandomNumberRng(2, mx) : 0;
+ return generateRandomNumber(2, mx);
}
int LoLEngine::olol_checkForCertainPartyMember(EMCState *script) {
@@ -2617,7 +2622,7 @@ void LoLEngine::setupOpcodeTable() {
Opcode(olol_setWallType);
Opcode(olol_getWallType);
Opcode(olol_drawScene);
- Opcode(o1_getRand);
+ Opcode(olol_getRand);
// 0x04
Opcode(olol_moveParty);
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index 8cee1dc5fc..b1edecb318 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -1071,7 +1071,7 @@ void LoLEngine::updateMonster(MonsterInPlay *monster) {
monster->speedTick = 0;
if (monster->properties->flags & 0x40) {
- monster->hitPoints += _rnd.getRandomNumberRng(1, 8);
+ monster->hitPoints += generateRandomNumber(1, 8);
if (monster->hitPoints > monster->properties->hitPoints)
monster->hitPoints = monster->properties->hitPoints;
}
@@ -1264,7 +1264,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
int s = 0;
if (monster->flags & 0x10) {
- s = monster->properties->numDistWeapons ? _rnd.getRandomNumberRng(1, monster->properties->numDistWeapons) : 0;
+ s = monster->properties->numDistWeapons ? generateRandomNumber(1, monster->properties->numDistWeapons) : 0;
} else {
s = monster->curDistWeapon++;
if (monster->curDistWeapon >= monster->properties->numDistWeapons)
@@ -1344,7 +1344,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
if (hit) {
int mx = calcInflictableDamage(m, dst, hit);
- int dmg = mx ? _rnd.getRandomNumberRng(2, mx) : 0;
+ int dmg = generateRandomNumber(2, mx );
inflictDamage(dst, dmg, m, 0, 0);
applyMonsterAttackSkill(monster, dst, dmg);
}
@@ -1364,7 +1364,7 @@ void LoLEngine::chasePartyWithCloseAttacks(MonsterInPlay *monster) {
walkMonster(monster);
} else {
setMonsterDirection(monster, monster->destDirection);
- setMonsterMode(monster, (_rnd.getRandomNumberRng(1, 100) <= 50) ? 4 : 3);
+ setMonsterMode(monster, (generateRandomNumber(1, 100) <= 50) ? 4 : 3);
}
}
diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp
index 84c4f8b19d..0a17c0993c 100644
--- a/engines/kyra/timer_lol.cpp
+++ b/engines/kyra/timer_lol.cpp
@@ -147,7 +147,7 @@ void LoLEngine::timerSpecialCharacterUpdate(int timerNum) {
break;
case 3:
- v = _rnd.getRandomNumberRng(1, 2);
+ v = generateRandomNumber(1, 2);
if (inflictDamage(i, v, 0x8000, 0, 0x80)) {
_txt->printMessage(2, getLangString(0x4022), _characters[i].name);
_characters[i].characterUpdateDelay[ii] = 10;
@@ -241,7 +241,7 @@ void LoLEngine::timerUpdatePortraitAnimations(int skipUpdate) {
} else {
_characters[i].curFaceFrame = 0;
gui_drawCharPortraitWithStats(i);
- _characters[i].nextAnimUpdateCountdown = (int16) _rnd.getRandomNumberRng(1, 12) + 6;
+ _characters[i].nextAnimUpdateCountdown = (int16) generateRandomNumber(1, 12) + 6;
}
}
}