EFH: Refactor TeamChar

This commit is contained in:
Strangerke 2023-02-02 14:02:52 +01:00 committed by Eugene Sandulenko
parent 4e8c31e90e
commit 598a669091
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
8 changed files with 211 additions and 201 deletions

View File

@ -48,6 +48,12 @@ enum EfhReactionType {
kEfhReactionLaughs = 6
};
enum EfhStatusType {
kEfhStatusNormal = 0,
kEfhStatusSleeping = 1,
kEfhStatusFrozen = 2
};
struct Font {
uint8 _lines[8];
};

View File

@ -136,24 +136,24 @@ Common::Error EfhEngine::run() {
_imageSetSubFilesIdx = 147;
break;
case Common::KEYCODE_F1:
if (_teamCharId[0] != -1) {
handleStatusMenu(1, _teamCharId[0]);
if (_teamChar[0]._id != -1) {
handleStatusMenu(1, _teamChar[0]._id);
_tempTextPtr = nullptr;
drawGameScreenAndTempText(true);
_redrawNeededFl = true;
}
break;
case Common::KEYCODE_F2:
if (_teamCharId[1] != -1) {
handleStatusMenu(1, _teamCharId[1]);
if (_teamChar[1]._id != -1) {
handleStatusMenu(1, _teamChar[1]._id);
_tempTextPtr = nullptr;
drawGameScreenAndTempText(true);
_redrawNeededFl = true;
}
break;
case Common::KEYCODE_F3:
if (_teamCharId[2] != -1) {
handleStatusMenu(1, _teamCharId[2]);
if (_teamChar[2]._id != -1) {
handleStatusMenu(1, _teamChar[2]._id);
_tempTextPtr = nullptr;
drawGameScreenAndTempText(true);
_redrawNeededFl = true;
@ -701,9 +701,9 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
setTextColorRed();
for (int i = 0; i < 3; ++i) {
if (_teamCharId[i] == -1)
if (_teamChar[i]._id == -1)
continue;
int16 charId = _teamCharId[i];
int16 charId = _teamChar[i]._id;
int16 textPosY = 161 + 9 * i;
Common::String buffer = _npcBuf[charId]._name;
setTextPos(16, textPosY);
@ -720,8 +720,8 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
continue;
}
switch (_teamCharStatus[i]._status) {
case 0: {
switch (_teamChar[i]._status._type) {
case kEfhStatusNormal: {
uint16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
if (exclusiveItemId == 0x7FFF)
_nameBuffer = "(NONE)";
@ -729,10 +729,10 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
_nameBuffer = _items[exclusiveItemId]._name;
}
break;
case 1:
case kEfhStatusSleeping:
_nameBuffer = "* ASLEEP *";
break;
case 2:
case kEfhStatusFrozen:
_nameBuffer = "* FROZEN *";
break;
default:
@ -763,7 +763,7 @@ void EfhEngine::totalPartyKill() {
debugC(6, kDebugEngine, "totalPartyKill");
for (uint counter = 0; counter < 3; ++counter) {
if (_teamCharId[counter] != -1)
if (_teamChar[counter]._id != -1)
_npcBuf[counter]._hitPoints = 0;
}
}
@ -771,25 +771,25 @@ void EfhEngine::totalPartyKill() {
void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
debugC(6, kDebugEngine, "removeCharacterFromTeam %d", teamMemberId);
int16 charId = _teamCharId[teamMemberId];
int16 charId = _teamChar[teamMemberId]._id;
_npcBuf[charId].field12_textId = _npcBuf[charId].fieldB_textId;
_npcBuf[charId].field14_textId = _npcBuf[charId].fieldE_textId;
_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
_npcBuf[charId].field11_NpcId = _npcBuf[charId].field_D;
_teamCharId[teamMemberId] = -1;
_teamCharStatus[teamMemberId]._status = 0;
_teamCharStatus[teamMemberId]._duration = 0;
_teamChar[teamMemberId]._id = -1;
_teamChar[teamMemberId]._status._type = kEfhStatusNormal;
_teamChar[teamMemberId]._status._duration = 0;
for (int var4 = teamMemberId; var4 < 2; ++var4) {
_teamCharId[var4] = _teamCharId[var4 + 1];
_teamChar[var4]._id = _teamChar[var4 + 1]._id;
// The original isn't doing that, resulting in losing its altered status and remaining duration
_teamCharStatus[var4]._status = _teamCharStatus[var4 + 1]._status;
_teamCharStatus[var4]._duration = _teamCharStatus[var4 + 1]._duration;
_teamChar[var4]._status._type = _teamChar[var4 + 1]._status._type;
_teamChar[var4]._status._duration = _teamChar[var4 + 1]._status._duration;
//
_teamCharId[var4 + 1] = -1;
_teamChar[var4 + 1]._id = -1;
}
refreshTeamSize();
@ -800,7 +800,7 @@ void EfhEngine::refreshTeamSize() {
_teamSize = 0;
for (uint charId = 0; charId < 3; ++charId) {
if (_teamCharId[charId] != -1)
if (_teamChar[charId]._id != -1)
++_teamSize;
}
}
@ -809,7 +809,7 @@ bool EfhEngine::isNpcATeamMember(int16 id) {
debugC(6, kDebugEngine,"isNpcATeamMember %d", id);
for (int charId = 0; charId < _teamSize; ++charId) {
if (_teamCharId[charId] == id)
if (_teamChar[charId]._id == id)
return true;
}
@ -944,7 +944,7 @@ int16 EfhEngine::handleCharacterJoining() {
debugC(3, kDebugEngine, "handleCharacterJoining");
for (uint counter = 0; counter < 3; ++counter) {
if (_teamCharId[counter] == -1) {
if (_teamChar[counter]._id == -1) {
return counter;
}
}
@ -1231,12 +1231,12 @@ void EfhEngine::handleNewRoundEffects() {
debugC(6, kDebugEngine, "handleNewRoundEffects");
for (int counter = 0; counter < _teamSize; ++counter) {
CharStatus *curStatus = &_teamCharStatus[counter];
if (curStatus->_status == 0) // normal
CharStatus *curStatus = &_teamChar[counter]._status;
if (curStatus->_type == kEfhStatusNormal)
continue;
if (--curStatus->_duration <= 0) {
curStatus->_status = 0;
curStatus->_type = kEfhStatusNormal;
curStatus->_duration = 0;
}
}
@ -1245,7 +1245,7 @@ void EfhEngine::handleNewRoundEffects() {
return;
for (int counter = 0; counter < _teamSize; ++counter) {
NPCStruct *curNpc = &_npcBuf[_teamCharId[counter]];
NPCStruct *curNpc = &_npcBuf[_teamChar[counter]._id];
if (++curNpc->_hitPoints > curNpc->_maxHP)
curNpc->_hitPoints = curNpc->_maxHP;
}
@ -1823,8 +1823,8 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
case 4:
for (int charId = 0; charId < _teamSize; ++charId) {
for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
removeObject(_teamCharId[charId], inventoryId);
if (_npcBuf[_teamChar[charId]._id]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
removeObject(_teamChar[charId]._id, inventoryId);
displayMonsterAnim(monsterId);
displayImp1Text(_npcBuf[npcId].field14_textId);
displayAnimFrames(0xFE, true);
@ -1844,7 +1844,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
case 6:
for (int charId = 0; charId < _teamSize; ++charId) {
for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
if (_npcBuf[_teamChar[charId]._id]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
displayMonsterAnim(monsterId);
displayImp1Text(_npcBuf[npcId].field14_textId);
displayAnimFrames(0xFE, true);
@ -1855,7 +1855,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
break;
case 7:
for (int charId = 0; charId < _teamSize; ++charId) {
if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
removeCharacterFromTeam(charId);
displayMonsterAnim(monsterId);
displayImp1Text(_npcBuf[npcId].field14_textId);
@ -1866,10 +1866,10 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
break;
case 8:
for (int charId = 0; charId < _teamSize; ++charId) {
if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
displayMonsterAnim(monsterId);
_enemyNamePt2 = _npcBuf[npcId]._name;
_characterNamePt2 = _npcBuf[_teamCharId[charId]]._name;
_characterNamePt2 = _npcBuf[_teamChar[charId]._id]._name;
Common::String buffer = Common::String::format("%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
for (uint i = 0; i < 2; ++i) {
clearBottomTextZone(0);
@ -1893,7 +1893,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
break;
case 9:
for (int charId = 0; charId < _teamSize; ++charId) {
if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
displayMonsterAnim(monsterId);
displayImp1Text(_npcBuf[npcId].field14_textId);
displayAnimFrames(0xFE, true);
@ -2062,20 +2062,20 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFE) {
for (int counter = 0; counter < _teamSize; ++counter) {
if (_teamCharId[counter] == -1)
if (_teamChar[counter]._id == -1)
continue;
if (_teamCharId[counter] == _mapSpecialTiles[_techId][tileId]._triggerId) {
if (_teamChar[counter]._id == _mapSpecialTiles[_techId][tileId]._triggerId) {
displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
return true;
}
}
} else if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFD) {
for (int counter = 0; counter < _teamSize; ++counter) {
if (_teamCharId[counter] == -1)
if (_teamChar[counter]._id == -1)
continue;
for (uint var2 = 0; var2 < 10; ++var2) {
if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
if (_npcBuf[_teamChar[counter]._id]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
return true;
}
@ -2085,14 +2085,14 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
} else if (_mapSpecialTiles[_techId][tileId]._field3 <= 0x77) {
int16 scoreId = _mapSpecialTiles[_techId][tileId]._field3;
for (int counter = 0; counter < _teamSize; ++counter) {
if (_teamCharId[counter] == -1)
if (_teamChar[counter]._id == -1)
continue;
for (uint var2 = 0; var2 < 39; ++var2) {
// CHECKME : the whole loop doesn't make much sense as it's using scoreId instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
warning("handleInteractionText - _activeScore[%d]", scoreId);
if (_npcBuf[_teamCharId[counter]]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
if (_npcBuf[_teamChar[counter]._id]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
return true;
}
@ -2170,9 +2170,9 @@ void EfhEngine::computeInitiatives() {
debugC(6, kDebugEngine, "computeInitiatives");
for (int counter = 0; counter < 3; ++counter) {
if (counter < _teamSize && _teamCharId[counter] != -1) {
if (counter < _teamSize && _teamChar[counter]._id != -1) {
_initiatives[counter]._id = counter + 1000; // Magic value added to detect it's a member of the team
_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3]; // "Agility"
_initiatives[counter]._initiative = _npcBuf[_teamChar[counter]._id]._infoScore[3]; // "Agility"
} else {
_initiatives[counter]._id = -1;
_initiatives[counter]._initiative = -1;
@ -2406,7 +2406,7 @@ bool EfhEngine::checkMonsterCollision() {
endLoop = true;
break;
case Common::KEYCODE_s: // Status
handleStatusMenu(1, _teamCharId[0]);
handleStatusMenu(1, _teamChar[0]._id);
endLoop = true;
_tempTextPtr = nullptr;
drawGameScreenAndTempText(true);
@ -2483,13 +2483,13 @@ void EfhEngine::loadEfhGame() {
_fullPlaceId = f.readUint16LE();
_guessAnimationAmount = f.readSint16LE();
_largeMapFlag = f.readUint16LE();
_teamCharId[0] = f.readSint16LE();
_teamCharId[1] = f.readSint16LE();
_teamCharId[2] = f.readSint16LE();
_teamChar[0]._id = f.readSint16LE();
_teamChar[1]._id = f.readSint16LE();
_teamChar[2]._id = f.readSint16LE();
for (int i = 0; i < 3; ++i) {
_teamCharStatus[i]._status = f.readSint16LE();
_teamCharStatus[i]._duration = f.readSint16LE();
_teamChar[i]._status._type = f.readSint16LE();
_teamChar[i]._status._duration = f.readSint16LE();
}
_teamSize = f.readSint16LE();

View File

@ -203,7 +203,7 @@ struct BufferBM {
};
struct CharStatus {
int16 _status;
int16 _type;
int16 _duration;
};
@ -245,6 +245,16 @@ struct TileFactStruct {
void init();
};
struct TeamChar {
int16 _id;
CharStatus _status;
int16 _pctVisible;
int16 _pctDodgeMiss;
int16 _nextAttack;
int16 _lastInventoryUsed;
int16 _lastAction;
};
class EfhEngine : public Engine {
public:
EfhEngine(OSystem *syst, const ADGameDescription *gd);
@ -606,13 +616,7 @@ private:
int16 _menuDepth;
int16 _menuItemCounter;
int16 _teamCharId[3];
CharStatus _teamCharStatus[3];
int16 _teamPctVisible[3];
int16 _teamPctDodgeMiss[3];
int16 _teamNextAttack[3];
int16 _teamLastInventoryUsed[3];
int16 _teamLastAction[3];
TeamChar _teamChar[3];
int16 _teamMonsterIdArray[5];
TeamMonsterEffect _teamMonsterEffects[5];

View File

@ -111,8 +111,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
displayAnimFrames(getTeamMonsterAnimId(), true);
for (int counter = 0; counter < _teamSize; ++counter) {
_teamPctVisible[counter] = 100;
_teamPctDodgeMiss[counter] = 65;
_teamChar[counter]._pctVisible = 100;
_teamChar[counter]._pctDodgeMiss = 65;
}
if (!getTeamAttackRoundPlans()) {
@ -124,7 +124,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
}
for (int counter = 0; counter < _teamSize; ++counter) {
if (_teamLastAction[counter] == 0x52) // 'R'
if (_teamChar[counter]._lastAction == 0x52) // 'R'
mainLoopCond = true;
}
@ -140,7 +140,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
} else {
switch (_teamLastAction[monsterGroupIdOrMonsterId]) {
switch (_teamChar[monsterGroupIdOrMonsterId]._lastAction) {
case 0x41: // 'A'ttack
handleFight_lastAction_A(monsterGroupIdOrMonsterId);
break;
@ -177,21 +177,21 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
// In the original, this function is part of handleFight.
// It has been split for readability purposes.
if (_teamCharStatus[charId]._status == 0)
if (_teamChar[charId]._status._type == kEfhStatusNormal)
return;
if (--_teamCharStatus[charId]._duration != 0)
if (--_teamChar[charId]._status._duration > 0)
return;
// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
_enemyNamePt1 = getArticle(_npcBuf[_teamCharId[charId]].getPronoun());
_enemyNamePt2 = _npcBuf[_teamChar[charId]._id]._name;
_enemyNamePt1 = getArticle(_npcBuf[_teamChar[charId]._id].getPronoun());
// End of effect message depends on the type of effect
switch (_teamCharStatus[charId]._status) {
case 1:
switch (_teamChar[charId]._status._type) {
case kEfhStatusSleeping:
_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
break;
case 2:
case kEfhStatusFrozen:
_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
break;
default:
@ -200,7 +200,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
}
// The character status is back to normal
_teamCharStatus[charId]._status = 0;
_teamChar[charId]._status._type = kEfhStatusNormal;
// Finally, display the message
displayBoxWithText(_messageToBePrinted, 1, 2, true);
@ -212,10 +212,10 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
// In the original, this function is part of handleFight.
// It has been split for readability purposes.
int16 teamCharItemId = getEquippedExclusiveType(_teamCharId[teamCharId], 9, true);
int16 teamCharItemId = getEquippedExclusiveType(_teamChar[teamCharId]._id, 9, true);
if (teamCharItemId == 0x7FFF)
teamCharItemId = 0x3F;
int16 minMonsterGroupId = _teamNextAttack[teamCharId];
int16 minMonsterGroupId = _teamChar[teamCharId]._nextAttack;
if (minMonsterGroupId == 0x64)
minMonsterGroupId = 0;
@ -259,15 +259,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
noticedFl = false;
int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
int16 enemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
int16 enemyPronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
int16 monsterId = _teamMonsterIdArray[groupId];
int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
int16 charScore = getCharacterScore(_teamChar[teamCharId]._id, teamCharItemId);
int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
int16 hitCount = 0;
int16 originalDamage = 0;
int16 damagePointsAbsorbed = 0;
int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamChar[teamCharId]._id]._speed;
// Action A - Loop attackCounter - Start
for (int attackCounter = 0; attackCounter < attackSpeed; ++attackCounter) {
@ -309,7 +309,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
_enemyNamePt1 = getArticle(enemyPronoun);
_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
_nameBuffer = _items[teamCharItemId]._name;
if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
@ -322,7 +322,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
getDeathTypeDescription(groupId, teamCharId + 1000);
getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
} else {
_messageToBePrinted += "!";
}
@ -330,7 +330,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
getDeathTypeDescription(groupId, teamCharId + 1000);
getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
} else {
_messageToBePrinted += "!";
}
@ -372,7 +372,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
_messageToBePrinted += Common::String(" Your actions do not go un-noticed...");
// Action A - Check item durability - Start
int16 npcId = _teamCharId[teamCharId];
int16 npcId = _teamChar[teamCharId]._id;
// get equipped inventory slot with exclusiveType == 9
uint16 exclusiveInventoryId = getEquippedExclusiveType(npcId, 9, false);
@ -418,11 +418,11 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
// It has been split for readability purposes.
debugC(3, kDebugFight, "handleFight_lastAction_D %d", teamCharId);
_teamPctDodgeMiss[teamCharId] -= 40;
_teamChar[teamCharId]._pctDodgeMiss -= 40;
uint8 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
uint8 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
_enemyNamePt1 = getArticle(pronoun);
_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
displayBoxWithText(_messageToBePrinted, 1, 2, true);
@ -434,11 +434,11 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
// It has been split for readability purposes.
debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
_teamPctVisible[teamCharId] -= 50;
_teamChar[teamCharId]._pctVisible -= 50;
int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
int16 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
_enemyNamePt1 = getArticle(pronoun);
_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
displayBoxWithText(_messageToBePrinted, 1, 2, true);
@ -450,15 +450,15 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
// It has been split for readability purposes.
debugC(3, kDebugFight, "handleFight_lastAction_U %d", teamCharId);
int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_teamLastInventoryUsed[teamCharId]]._ref;
int16 itemId = _npcBuf[_teamChar[teamCharId]._id]._inventory[_teamChar[teamCharId]._lastInventoryUsed]._ref;
_nameBuffer = _items[itemId]._name;
int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
int16 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
_enemyNamePt1 = getArticle(pronoun);
_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
_messageToBePrinted = Common::String::format("%s%s uses %s %s! ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
bool retVal = useObject(_teamCharId[teamCharId], _teamLastInventoryUsed[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
bool retVal = useObject(_teamChar[teamCharId]._id, _teamChar[teamCharId]._lastInventoryUsed, _teamChar[teamCharId]._nextAttack, teamCharId, 0, 3);
displayBoxWithText(_messageToBePrinted, 1, 2, true);
return retVal;
@ -480,7 +480,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
if (_items[monsterWeaponItemId]._range < 3) {
for (uint attackTry = 0; attackTry < 10; ++attackTry) {
minTeamMemberId = getRandom(_teamSize) - 1;
if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamPctVisible[minTeamMemberId]) {
if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamChar[minTeamMemberId]._pctVisible) {
break;
}
minTeamMemberId = -1;
@ -496,15 +496,15 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
// handleFight - Loop on targetId - Start
for (int16 targetId = minTeamMemberId; targetId < maxTeamMemberId; ++targetId) {
if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
if (_teamChar[targetId]._id == -1 || !isTeamMemberStatusNormal(targetId))
continue;
int16 randomDefense = getRandom(getEquipmentDefense(_teamCharId[targetId]));
int16 randomDefense = getRandom(getEquipmentDefense(_teamChar[targetId]._id));
int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
int16 characterPronoun = _npcBuf[_teamCharId[targetId]].getPronoun();
int16 characterPronoun = _npcBuf[_teamChar[targetId]._id].getPronoun();
_teamPctDodgeMiss[targetId] += (_items[monsterWeaponItemId].field_13 * 5);
_teamChar[targetId]._pctDodgeMiss += (_items[monsterWeaponItemId].field_13 * 5);
int16 hitCount = 0;
int16 originalDamage = 0;
int16 damagePointsAbsorbed = 0;
@ -512,12 +512,12 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._npcId * _items[monsterWeaponItemId]._attacks;
for (int var84 = 0; var84 < var64; ++var84) {
// handleFight - Loop var84 on var64 (objectId) - Start
if (getRandom(100) > _teamPctDodgeMiss[targetId])
if (getRandom(100) > _teamChar[targetId]._pctDodgeMiss)
continue;
++hitCount;
if (hasAdequateDefenseNPC(_teamCharId[targetId], _items[monsterWeaponItemId]._attackType))
if (hasAdequateDefenseNPC(_teamChar[targetId]._id, _items[monsterWeaponItemId]._attackType))
continue;
int16 baseDamage = getRandom(_items[monsterWeaponItemId]._damage);
@ -540,7 +540,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
hitCount = 0;
if (hitCount > 0) {
_npcBuf[_teamCharId[targetId]]._hitPoints -= originalDamage;
_npcBuf[_teamChar[targetId]._id]._hitPoints -= originalDamage;
if (hitCount > 1)
_attackBuffer = Common::String::format("%d times ", hitCount);
else
@ -554,7 +554,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
_characterNamePt1 = getArticle(characterPronoun);
_characterNamePt2 = _npcBuf[_teamCharId[targetId]]._name;
_characterNamePt2 = _npcBuf[_teamChar[targetId]._id]._name;
_nameBuffer = _items[monsterWeaponItemId]._name;
if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
@ -565,13 +565,13 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
} else if (hitPoints == 1) {
_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
if (_npcBuf[_teamChar[targetId]._id]._hitPoints <= 0)
getDeathTypeDescription(targetId + 1000, groupId);
else
_messageToBePrinted += "!";
} else {
_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
if (_npcBuf[_teamChar[targetId]._id]._hitPoints <= 0)
getDeathTypeDescription(targetId + 1000, groupId);
else
_messageToBePrinted += "!";
@ -579,19 +579,19 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
// handleFight - check damages - End
// handleFight - Add reaction text - start
if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
if (_npcBuf[_teamCharId[targetId]]._hitPoints - 5 <= originalDamage) {
if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamChar[targetId]._id]._hitPoints > 0) {
if (_npcBuf[_teamChar[targetId]._id]._hitPoints - 5 <= originalDamage) {
addReactionText(kEfhReactionReels);
} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 8) {
} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 8) {
addReactionText(kEfhReactionCriesOut);
} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 4) {
} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 4) {
addReactionText(kEfhReactionFalters);
} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 2) {
} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 2) {
addReactionText(kEfhReactionWinces);
} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 3) {
} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 3) {
// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
addReactionText(kEfhReactionScreams);
} else if (_npcBuf[_teamCharId[targetId]]._maxHP / 8 >= originalDamage) {
} else if (_npcBuf[_teamChar[targetId]._id]._maxHP / 8 >= originalDamage) {
addReactionText(kEfhReactionChortles);
} else if (originalDamage == 0 && getRandom(100) < 35) {
// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
@ -601,14 +601,14 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
// handleFight - Add reaction text - end
// handleFight - Check armor - start
if (randomDefense != 0 && hitCount != 0 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
if (randomDefense != 0 && hitCount != 0 && _npcBuf[_teamChar[targetId]._id]._hitPoints > 0) {
if (damagePointsAbsorbed <= 1)
_messageToBePrinted += Common::String::format(" %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
else
_messageToBePrinted += Common::String::format(" %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
int armorDamage = (originalDamage + damagePointsAbsorbed) / 10;
handleDamageOnArmor(_teamCharId[targetId], armorDamage);
handleDamageOnArmor(_teamChar[targetId]._id, armorDamage);
}
// handleFight - Check armor - end
@ -616,15 +616,15 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
switch (_items[monsterWeaponItemId]._specialEffect) {
case 1:
if (getRandom(100) < 20) {
_teamCharStatus[targetId]._status = 1;
_teamCharStatus[targetId]._duration = getRandom(10);
_teamChar[targetId]._status._type = kEfhStatusSleeping;
_teamChar[targetId]._status._duration = getRandom(10);
_messageToBePrinted += Common::String::format(" %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
}
break;
case 2:
if (getRandom(100) < 20) {
_teamCharStatus[targetId]._status = 2;
_teamCharStatus[targetId]._duration = getRandom(10);
_teamChar[targetId]._status._type = kEfhStatusFrozen;
_teamChar[targetId]._status._duration = getRandom(10);
_messageToBePrinted += Common::String::format(" %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
}
break;
@ -632,7 +632,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
case 6:
if (getRandom(100) < 20) {
_messageToBePrinted += Common::String::format(" %s%s's life energy is gone!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
_npcBuf[_teamCharId[targetId]]._hitPoints = 0;
_npcBuf[_teamChar[targetId]._id]._hitPoints = 0;
}
break;
default:
@ -676,7 +676,7 @@ bool EfhEngine::isTPK() {
int16 zeroedChar = 0;
for (int counter = 0; counter < _teamSize; ++counter) {
if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
if (_npcBuf[_teamChar[counter]._id]._hitPoints <= 0)
++zeroedChar;
}
@ -714,7 +714,7 @@ void EfhEngine::resetTeamMonsterIdArray() {
bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
debugC(6, kDebugFight, "isTeamMemberStatusNormal %d", teamMemberId);
if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
if (_npcBuf[_teamChar[teamMemberId]._id]._hitPoints > 0 && _teamChar[teamMemberId]._status._type == kEfhStatusNormal)
return true;
return false;
@ -726,7 +726,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
uint8 pronoun;
if (victimId >= 1000) { // Magic value for team members
int16 charId = _teamCharId[victimId - 1000];
int16 charId = _teamChar[victimId - 1000]._id;
pronoun = _npcBuf[charId].getPronoun();
} else {
int16 charId = _teamMonsterIdArray[victimId];
@ -740,7 +740,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
if (getRandom(100) < 20) {
deathType = 0;
} else if (attackerId >= 1000) {
int16 charId = _teamCharId[attackerId - 1000];
int16 charId = _teamChar[attackerId - 1000]._id;
if (charId == -1)
deathType = 0;
else {
@ -1031,41 +1031,41 @@ bool EfhEngine::getTeamAttackRoundPlans() {
bool retVal = false;
for (int charId = 0; charId < _teamSize; ++charId) {
_teamLastAction[charId] = 0;
_teamChar[charId]._lastAction = 0;
if (!isTeamMemberStatusNormal(charId))
continue;
retVal = true;
do {
drawCombatScreen(_teamCharId[charId], false, true);
drawCombatScreen(_teamChar[charId]._id, false, true);
switch (handleAndMapInput(true)) {
case Common::KEYCODE_a: // Attack
_teamLastAction[charId] = 'A';
_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, true);
if (_teamNextAttack[charId] == -1)
_teamLastAction[charId] = 0;
_teamChar[charId]._lastAction = 'A';
_teamChar[charId]._nextAttack = determineTeamTarget(_teamChar[charId]._id, 9, true);
if (_teamChar[charId]._nextAttack == -1)
_teamChar[charId]._lastAction = 0;
break;
case Common::KEYCODE_d: // Defend
_teamLastAction[charId] = 'D';
_teamChar[charId]._lastAction = 'D';
break;
case Common::KEYCODE_h: // Hide
_teamLastAction[charId] = 'H';
_teamChar[charId]._lastAction = 'H';
break;
case Common::KEYCODE_r: // Run
for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
_teamLastAction[counter2] = 'R';
_teamChar[counter2]._lastAction = 'R';
}
return true;
case Common::KEYCODE_s: { // Status
int16 lastInvId = handleStatusMenu(2, _teamCharId[charId]);
redrawCombatScreenWithTempText(_teamCharId[charId]);
int16 lastInvId = handleStatusMenu(2, _teamChar[charId]._id);
redrawCombatScreenWithTempText(_teamChar[charId]._id);
if (lastInvId >= 999) {
if (lastInvId == 0x7D00) // Result of Equip, Give and Drop in combat mode(2)
_teamLastAction[charId] = 'S';
_teamChar[charId]._lastAction = 'S';
} else {
_teamLastAction[charId] = 'U';
_teamLastInventoryUsed[charId] = lastInvId;
int16 invEffect = _items[_npcBuf[_teamCharId[charId]]._inventory[lastInvId]._ref]._specialEffect;
_teamChar[charId]._lastAction = 'U';
_teamChar[charId]._lastInventoryUsed = lastInvId;
int16 invEffect = _items[_npcBuf[_teamChar[charId]._id]._inventory[lastInvId]._ref]._specialEffect;
switch (invEffect - 1) {
case 0:
case 1:
@ -1079,7 +1079,7 @@ bool EfhEngine::getTeamAttackRoundPlans() {
case 10:
case 12:
case 13:
_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, false);
_teamChar[charId]._nextAttack = determineTeamTarget(_teamChar[charId]._id, 9, false);
break;
case 9:
@ -1094,13 +1094,13 @@ bool EfhEngine::getTeamAttackRoundPlans() {
case 29:
case 30:
displayBoxWithText("Select Character:", 3, 1, false);
_teamNextAttack[charId] = selectOtherCharFromTeam();
_teamChar[charId]._nextAttack = selectOtherCharFromTeam();
break;
case 16:
case 17:
case 26:
_teamNextAttack[charId] = 0xC8;
_teamChar[charId]._nextAttack = 0xC8;
break;
case 19:
@ -1109,8 +1109,8 @@ bool EfhEngine::getTeamAttackRoundPlans() {
case 22:
case 23:
default:
_teamLastInventoryUsed[charId] = lastInvId;
_teamNextAttack[charId] = -1;
_teamChar[charId]._lastInventoryUsed = lastInvId;
_teamChar[charId]._nextAttack = -1;
break;
}
}
@ -1119,12 +1119,12 @@ bool EfhEngine::getTeamAttackRoundPlans() {
case Common::KEYCODE_t: // Terrain
redrawScreenForced();
getInputBlocking();
drawCombatScreen(_teamCharId[charId], false, true);
drawCombatScreen(_teamChar[charId]._id, false, true);
break;
default:
break;
}
} while (_teamLastAction[charId] == 0);
} while (_teamChar[charId]._lastAction == 0);
}
return retVal;

View File

@ -304,17 +304,17 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
_guessAnimationAmount = 9;
_largeMapFlag = 0xFFFF;
_alertDelay = 0;
_teamCharId[0] = 0;
_teamCharId[1] = _teamCharId[2] = -1;
_teamChar[0]._id = 0;
_teamChar[1]._id = _teamChar[2]._id = -1;
for (int i = 0; i < 3; ++i) {
_teamCharStatus[i]._status = 0;
_teamCharStatus[i]._duration = 0;
_teamPctVisible[i] = 0;
_teamPctDodgeMiss[i] = 0;
_teamNextAttack[i] = -1;
_teamLastInventoryUsed[i] = 0;
_teamLastAction[i] = 0;
_teamChar[i]._status._type = kEfhStatusNormal;
_teamChar[i]._status._duration = 0;
_teamChar[i]._pctVisible = 0;
_teamChar[i]._pctDodgeMiss = 0;
_teamChar[i]._nextAttack = -1;
_teamChar[i]._lastInventoryUsed = 0;
_teamChar[i]._lastAction = 0;
}
for (int i = 0; i < 5; ++i) {

View File

@ -745,23 +745,23 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
bool givenFl;
int16 destCharId;
do {
if (_teamCharId[2] != -1) {
if (_teamChar[2]._id != -1) {
displayStringInSmallWindowWithBorder("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
destCharId = selectOtherCharFromTeam();
var2 = false;
} else if (_teamCharId[1] == -1) {
} else if (_teamChar[1]._id == -1) {
destCharId = 0x1A;
var2 = false;
} else {
var2 = true;
if (_teamCharId[0] == charId)
if (_teamChar[0]._id == charId)
destCharId = 1;
else
destCharId = 0;
}
if (destCharId != 0x1A && destCharId != 0x1B) {
givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
givenFl = giveItemTo(_teamChar[destCharId]._id, objectId, charId);
if (!givenFl) {
displayStringInSmallWindowWithBorder("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
getLastCharAfterAnimCount(_guessAnimationAmount);
@ -1058,9 +1058,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
} else {
_messageToBePrinted += buffer1;
}
_teamPctDodgeMiss[teamCharId] -= 50;
if (_teamPctDodgeMiss[teamCharId] < 0)
_teamPctDodgeMiss[teamCharId] = 0;
_teamChar[teamCharId]._pctDodgeMiss -= 50;
if (_teamChar[teamCharId]._pctDodgeMiss < 0)
_teamChar[teamCharId]._pctDodgeMiss = 0;
}
objectUsedFl = true;
@ -1082,9 +1082,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
_messageToBePrinted += buffer1;
}
_teamPctVisible[teamCharId] -= 50;
if (_teamPctVisible[teamCharId] < 0)
_teamPctVisible[teamCharId] = 0;
_teamChar[teamCharId]._pctVisible -= 50;
if (_teamChar[teamCharId]._pctVisible < 0)
_teamChar[teamCharId]._pctVisible = 0;
}
objectUsedFl = true;
@ -1166,10 +1166,10 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
} else {
int16 teamCharId = teamMonsterId;
if (teamCharId != 0x1B) {
if (_teamCharStatus[teamCharId]._status == 2) { // frozen
if (_teamChar[teamCharId]._status._type == kEfhStatusFrozen) { // frozen
_messageToBePrinted += " The item makes a loud noise, awakening the character!";
_teamCharStatus[teamCharId]._status = 0;
_teamCharStatus[teamCharId]._duration = 0;
_teamChar[teamCharId]._status._type = kEfhStatusNormal;
_teamChar[teamCharId]._status._duration = 0;
} else {
_messageToBePrinted += " The item makes a loud noise, but has no effect!";
}
@ -1236,9 +1236,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
if (teamCharId != 0x1B) {
uint8 varAE = _items[itemId]._field17_attackTypeDefense;
uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] += effectPoints;
if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20) {
_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] = 20;
}
if (effectPoints > 1)
buffer1 = Common::String::format("%s increased %d points!", kSkillArray[varAE], effectPoints);
@ -1266,9 +1266,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
if (teamCharId != 0x1B) {
uint8 varAE = _items[itemId]._field17_attackTypeDefense;
uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] -= effectPoints;
if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20 || _npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] < 0) {
_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] = 1;
}
if (effectPoints > 1)
buffer1 = Common::String::format("%s lowered %d points!", kSkillArray[varAE], effectPoints);
@ -1306,8 +1306,8 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
}
if (teamCharId != 0x1B) {
_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
_npcBuf[_teamChar[teamCharId]._id]._hitPoints = 0;
buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamChar[teamCharId]._id]._name);
if (gameMode == 2) {
displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
} else {
@ -1324,10 +1324,10 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
} else {
int16 teamCharId = teamMonsterId;
if (teamCharId != 0x1B) {
if (_teamCharStatus[teamCharId]._status == 0) {
if (_teamChar[teamCharId]._status._type == kEfhStatusNormal) { // BUG (likely)
_messageToBePrinted += " The item makes a loud noise, awakening the character!";
_teamCharStatus[teamCharId]._status = 0;
_teamCharStatus[teamCharId]._duration = 0;
_teamChar[teamCharId]._status._type = kEfhStatusNormal;
_teamChar[teamCharId]._status._duration = 0;
} else {
_messageToBePrinted += " The item makes a loud noise, but has no effect!";
}
@ -1347,14 +1347,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
if (teamCharId != 0x1B) {
int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
_npcBuf[_teamChar[teamCharId]._id]._hitPoints += effectPoints;
if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints > _npcBuf[_teamChar[teamCharId]._id]._maxHP)
_npcBuf[_teamChar[teamCharId]._id]._hitPoints = _npcBuf[_teamChar[teamCharId]._id]._maxHP;
if (effectPoints > 1)
buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamChar[teamCharId]._id]._name, effectPoints);
else
buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamChar[teamCharId]._id]._name);
}
if (gameMode == 2) {
@ -1377,14 +1377,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
if (teamCharId != 0x1B) {
int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
_npcBuf[_teamChar[teamCharId]._id]._hitPoints -= effectPoints;
if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints < 0)
_npcBuf[_teamChar[teamCharId]._id]._hitPoints = 0;
if (effectPoints > 1)
buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamChar[teamCharId]._id]._name, effectPoints);
else
buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamChar[teamCharId]._id]._name);
}
if (gameMode == 2) {

View File

@ -128,13 +128,13 @@ void EfhEngine::synchronize(Common::Serializer &s) {
s.syncAsUint16LE(_fullPlaceId);
s.syncAsSint16LE(_guessAnimationAmount);
s.syncAsUint16LE(_largeMapFlag);
s.syncAsSint16LE(_teamCharId[0]);
s.syncAsSint16LE(_teamCharId[1]);
s.syncAsSint16LE(_teamCharId[2]);
s.syncAsSint16LE(_teamChar[0]._id);
s.syncAsSint16LE(_teamChar[1]._id);
s.syncAsSint16LE(_teamChar[2]._id);
for (int i = 0; i < 3; ++i) {
s.syncAsSint16LE(_teamCharStatus[i]._status);
s.syncAsSint16LE(_teamCharStatus[i]._duration);
s.syncAsSint16LE(_teamChar[i]._status._type);
s.syncAsSint16LE(_teamChar[i]._status._duration);
}
s.syncAsSint16LE(_teamSize);

View File

@ -184,7 +184,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
case 0x05:
buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
if (scriptExecuteFlag) {
int16 npcId = _teamCharId[scriptNumberArray[0]];
int16 npcId = _teamChar[scriptNumberArray[0]]._id;
if (npcId != -1) {
int16 scoreId = scriptNumberArray[1];
_npcBuf[npcId]._activeScore[scoreId] += scriptNumberArray[2] & 0xFF;
@ -195,7 +195,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
case 0x06:
buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
if (scriptExecuteFlag) {
int16 npcId = _teamCharId[scriptNumberArray[0]];
int16 npcId = _teamChar[scriptNumberArray[0]]._id;
if (npcId != -1) {
int16 scoreId = scriptNumberArray[1];
_npcBuf[npcId]._activeScore[scoreId] = scriptNumberArray[2] & 0xFF;
@ -210,13 +210,13 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
case 0x08:
buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
if (scriptExecuteFlag && scriptNumberArray[0] != -1) {
_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
_npcBuf[_teamChar[scriptNumberArray[0]]._id]._hitPoints = 0;
}
break;
case 0x09:
buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
if (scriptExecuteFlag) {
int16 npcId = _teamCharId[scriptNumberArray[0]];
int16 npcId = _teamChar[scriptNumberArray[0]]._id;
if (npcId != -1) {
_npcBuf[npcId]._hitPoints += getRandom(scriptNumberArray[1]);
if (_npcBuf[npcId]._hitPoints > _npcBuf[npcId]._maxHP)
@ -227,7 +227,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
case 0x0A:
buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
if (scriptExecuteFlag) {
int16 npcId = _teamCharId[scriptNumberArray[0]];
int16 npcId = _teamChar[scriptNumberArray[0]]._id;
if (npcId != -1) {
_npcBuf[npcId]._hitPoints = _npcBuf[npcId]._maxHP;
}
@ -236,7 +236,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
case 0x0B:
buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
if (scriptExecuteFlag) {
int16 npcId = _teamCharId[scriptNumberArray[0]];
int16 npcId = _teamChar[scriptNumberArray[0]]._id;
if (npcId != -1) {
_npcBuf[npcId]._hitPoints -= getRandom(scriptNumberArray[1]);
if (_npcBuf[npcId]._hitPoints < 0)
@ -251,8 +251,8 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
bool found = false;
for (int counter = 0; counter < _teamSize && !found; ++counter) {
for (uint objectId = 0; objectId < 10; ++objectId) {
if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
removeObject(_teamCharId[counter], objectId);
if (_npcBuf[_teamChar[counter]._id]._inventory[objectId]._ref == scriptItemId) {
removeObject(_teamChar[counter]._id, objectId);
found = true;
break;
}
@ -266,7 +266,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
if (scriptExecuteFlag) {
int16 scriptObjectId = scriptNumberArray[0];
for (int counter = 0; counter < _teamSize; ++counter) {
if (giveItemTo(_teamCharId[counter], scriptObjectId, 0xFF))
if (giveItemTo(_teamChar[counter]._id, scriptObjectId, 0xFF))
break;
}
}
@ -278,7 +278,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
bool found = false;
for (int counter = 0; counter < _teamSize && !found; ++counter) {
for (uint objectId = 0; objectId < 10; ++objectId) {
if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
if (_npcBuf[_teamChar[counter]._id]._inventory[objectId]._ref == scriptItemId) {
found = true;
break;
}
@ -354,7 +354,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
if (isNpcATeamMember(scriptNpcId)) {
for (uint counter = 0; counter < 3; ++counter) {
if (_teamCharId[counter] == scriptNpcId) {
if (_teamChar[counter]._id == scriptNpcId) {
removeCharacterFromTeam(counter);
break;
}
@ -376,7 +376,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
int16 scriptRandomItemId = getRandom(scriptNumberArray[1] - scriptNumberArray[0] + 1) + scriptNumberArray[0] - 1;
int16 counter;
for (counter = 0; counter < _teamSize; ++counter) {
if (giveItemTo(_teamCharId[counter], scriptRandomItemId, 0xFF)) {
if (giveItemTo(_teamChar[counter]._id, scriptRandomItemId, 0xFF)) {
found = true;
break;
}
@ -389,7 +389,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
scriptRandomItemId = displayBoxWithText("Nothing...", 1, 2, true);
displayFctFullScreen();
} else {
_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
_enemyNamePt2 = _npcBuf[_teamChar[counter]._id]._name;
_nameBuffer = _items[scriptRandomItemId]._name;
curLine = Common::String::format("%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
drawMapWindow();
@ -484,7 +484,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
displayLowStatusScreen(true);
int16 teamSlot = handleCharacterJoining();
if (teamSlot > -1) {
_teamCharId[teamSlot] = joiningNpcId;
_teamChar[teamSlot]._id = joiningNpcId;
}
refreshTeamSize();
}