aboutsummaryrefslogtreecommitdiff
path: root/engines/dm/champion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/dm/champion.cpp')
-rw-r--r--engines/dm/champion.cpp221
1 files changed, 219 insertions, 2 deletions
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index 01f863732f..f93a9aa405 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -1,10 +1,54 @@
#include "champion.h"
#include "dungeonman.h"
+#include "eventman.h"
+#include "menus.h"
+#include "inventory.h"
namespace DM {
-Box gBoxChampionPortrait = Box(0, 31, 0, 28); // @ G0047_s_Graphic562_Box_ChampionPortrait
+uint16 gSlotMasks[38] = { // @ G0038_ai_Graphic562_SlotMasks
+ /* 30 for champion inventory, 8 for chest */
+ 0xFFFF, /* Ready Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Action Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0x0002, /* Head Head */
+ 0x0008, /* Torso Torso */
+ 0x0010, /* Legs Legs */
+ 0x0020, /* Feet Feet */
+ 0x0100, /* Pouch 2 Pouch */
+ 0x0080, /* Quiver Line2 1 Quiver 2 */
+ 0x0080, /* Quiver Line1 2 Quiver 2 */
+ 0x0080, /* Quiver Line2 2 Quiver 2 */
+ 0x0004, /* Neck Neck */
+ 0x0100, /* Pouch 1 Pouch */
+ 0x0040, /* Quiver Line1 1 Quiver 1 */
+ 0xFFFF, /* Backpack Line1 1 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0x0400, /* Chest 1 Chest */
+ 0x0400, /* Chest 2 Chest */
+ 0x0400, /* Chest 3 Chest */
+ 0x0400, /* Chest 4 Chest */
+ 0x0400, /* Chest 5 Chest */
+ 0x0400, /* Chest 6 Chest */
+ 0x0400, /* Chest 7 Chest */
+ 0x0400}; /* Chest 8 Chest */
+
+Box gBoxChampionPortrait = {0, 31, 0, 28}; // @ G0047_s_Graphic562_Box_ChampionPortrait
ChampionMan::ChampionMan(DMEngine *vm) : _vm(vm) {
_leaderIndex = kChampionNone;
@@ -37,7 +81,7 @@ ChampionIndex ChampionMan::getIndexInCell(ViewCell cell) {
void ChampionMan::resetDataToStartGame() {
if (!_vm->_dungeonMan->_messages._newGame) {
- warning("MISSING CODE: stuff for resetting for loaded games");
+ warning("MISSING CODE: stuff for reeseting for loaded games");
assert(false);
}
@@ -46,4 +90,177 @@ void ChampionMan::resetDataToStartGame() {
_leaderEmptyHanded = true;
}
+
+void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
+ DisplayMan &dispMan = *_vm->_displayMan;
+ DungeonMan &dunMan = *_vm->_dungeonMan;
+
+ if (!_leaderEmptyHanded || _partyChampionCount == 4)
+ return;
+
+ uint16 prevChampCount = _partyChampionCount;
+ Champion *champ = &_champions[prevChampCount];
+ warning("MISSING CODE: Fill champ memory with zero bytes");
+ dispMan._useByteBoxCoordinates = true;
+ { // block on purpose
+ Box &destBox = gBoxChampionPortrait;
+ dispMan.blitToBitmap(dispMan.getBitmap(kChampionPortraitsIndice), 256, getChampionPortraitX(championPortraitIndex), getChampionPortraitY(championPortraitIndex),
+ champ->_portrait, 32, destBox._x1, destBox._x2, destBox._y1, destBox._y2, kColorNoTransparency);
+ }
+
+ champ->_actionIndex = kChampionActionNone;
+ champ->_enableActionEventIndex = -1;
+ champ->_hideDamageReceivedIndex = -1;
+ champ->_dir = dunMan._currMap._partyDir;
+ ViewCell AL_0_viewCell = kViewCellFronLeft;
+ while (getIndexInCell((ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3)) != kChampionNone)
+ AL_0_viewCell = (ViewCell)(AL_0_viewCell + 1);
+ champ->_cell = (ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3);
+ champ->clearAttributes(kChampionAttributeIcon);
+ champ->_directionMaximumDamageReceived = dunMan._currMap._partyDir;
+ champ->_food = 1500 + _vm->_rnd->getRandomNumber(256);
+ champ->_water = 1500 + _vm->_rnd->getRandomNumber(256);
+ int16 AL_0_slotIndex_Red;
+ for (AL_0_slotIndex_Red = kChampionSlotReadyHand; AL_0_slotIndex_Red < kChampionSlotChest_1; ++AL_0_slotIndex_Red) {
+ champ->setSlot((ChampionSlot)AL_0_slotIndex_Red, Thing::_thingNone);
+ }
+ Thing thing = dunMan.getSquareFirstThing(dunMan._currMap._partyPosX, dunMan._currMap._partyPosY);
+ while (thing.getType() != kTextstringType) {
+ thing = dunMan.getNextThing(thing);
+ }
+ char decodedChampionText[77];
+ char* character_Green = decodedChampionText;
+ dunMan.decodeText(character_Green, thing, (TextType)(kTextTypeScroll | kDecodeEvenIfInvisible));
+ int16 AL_0_characterIndex = 0;
+ uint16 AL_2_character;
+ while ((AL_2_character = *character_Green++) != '\n') {
+ champ->_name[AL_0_characterIndex++] = AL_2_character;
+ }
+ champ->_name[AL_0_characterIndex] = '\0';
+ AL_0_characterIndex = 0;
+ bool AL_4_champTitleCopied = false;
+ for (;;) { // infinite
+ AL_2_character = *character_Green++;
+ if (AL_2_character == '\n') {
+ if (AL_4_champTitleCopied)
+ break;
+ AL_4_champTitleCopied = true;
+ } else {
+ champ->_title[AL_0_characterIndex++] = AL_2_character;
+ }
+ }
+ champ->_title[AL_0_characterIndex] = '\0';
+ if (*character_Green++ == 'M') {
+ champ->setAttributeFlag(kChampionAttributeMale, true);
+ }
+ character_Green++;
+ champ->_currHealth = champ->_maxHealth = getDecodedValue(character_Green, 4);
+ character_Green += 4;
+ champ->_currStamina = champ->_maxStamina = getDecodedValue(character_Green, 4);
+ character_Green += 4;
+ character_Green++;
+
+ int16 AL_0_statisticIndex;
+ for (AL_0_statisticIndex = kChampionStatLuck; AL_0_statisticIndex <= kChampionStatAntifire; ++AL_0_statisticIndex) {
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMinimum, 30);
+ uint16 currMaxVal = getDecodedValue(character_Green, 2);
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatCurrent, currMaxVal);
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMaximum, currMaxVal);
+ character_Green += 2;
+ }
+
+ champ->setStatistic(kChampionStatLuck, kChampionStatMinimum, 10);
+ character_Green++;
+
+ int16 AL_0_skillIndex;
+ int16 AL_2_skillValue;
+ for (AL_0_skillIndex = kChampionSkillSwing; AL_0_skillIndex <= kChampionSkillWater; AL_0_skillIndex++) {
+ if ((AL_2_skillValue = *character_Green++ - 'A') > 0) {
+ champ->setSkillExp((ChampionSkill)AL_0_skillIndex, 125L << AL_2_skillValue);
+ }
+ }
+
+ for (AL_0_skillIndex = kChampionSkillFighter; AL_0_skillIndex <= kChampionSkillWizard; ++AL_0_skillIndex) {
+ int32 baseSkillExp = 0;
+ int16 hiddenSkillIndex = (AL_0_skillIndex + 1) << 2;
+ for (uint16 AL_4_hiddenSkillCounter = 0; AL_4_hiddenSkillCounter < 4; ++AL_4_hiddenSkillCounter) {
+ baseSkillExp += champ->getSkill((ChampionSkill)(hiddenSkillIndex + AL_4_hiddenSkillCounter))._experience;
+ }
+ champ->setSkillExp((ChampionSkill)AL_0_skillIndex, baseSkillExp);
+ }
+
+ _candidateChampionOrdinal = prevChampCount + 1;
+ if (++_partyChampionCount == 1) {
+ _vm->_eventMan->commandSetLeader(kChampionFirst);
+ _vm->_menuMan->_shouldRefreshActionArea = true;
+ } else {
+ _vm->_menuMan->clearActingChampion();
+ _vm->_menuMan->drawActionIcon((ChampionIndex)(_partyChampionCount - 1));
+ }
+
+ int16 mapX = _vm->_dungeonMan->_currMap._partyPosX;
+ int16 mapY = _vm->_dungeonMan->_currMap._partyPosY;
+
+ uint16 championObjectsCell = returnOppositeDir((direction)(dunMan._currMap._partyDir));
+ mapX += dirIntoStepCountEast[dunMan._currMap._partyDir];
+ mapY += dirIntoStepCountNorth[dunMan._currMap._partyDir];
+ thing = dunMan.getSquareFirstThing(mapX, mapY);
+ AL_0_slotIndex_Red = kChampionSlotBackpackLine_1_1;
+ uint16 slotIndex_Green;
+ while (thing != Thing::_thingNone) {
+ ThingType AL_2_thingType = thing.getType();
+ if ((AL_2_thingType > kSensorThingType) && (thing.getCell() == championObjectsCell)) {
+ int16 objectAllowedSlots = gObjectInfo[dunMan.getObjectInfoIndex(thing)].getAllowedSlots();
+ switch (AL_2_thingType) {
+ case kArmourThingType:
+ for (slotIndex_Green = kChampionSlotHead; slotIndex_Green <= kChampionSlotFeet; slotIndex_Green++) {
+ if (objectAllowedSlots & gSlotMasks[slotIndex_Green])
+ goto T0280048;
+ }
+ if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
+ slotIndex_Green = kChampionSlotNeck;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kWeaponThingType:
+ if (champ->getSlot(kChampionSlotActionHand) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotActionHand;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kScrollThingType:
+ case kPotionThingType:
+ if (champ->getSlot(kChampionSlotPouch_1) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotPouch_1;
+ } else if (champ->getSlot(kChampionSlotPouch_2) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotPouch_2;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kContainerThingType:
+ case kJunkThingType:
+T0280046:
+ if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
+ slotIndex_Green = kChampionSlotNeck;
+ } else {
+ slotIndex_Green = AL_0_slotIndex_Red++;
+ }
+ break;
+ }
+T0280048:
+ if (champ->getSlot((ChampionSlot)slotIndex_Green) != Thing::_thingNone) {
+ goto T0280046;
+ }
+ warning("MISSING CODE: F0301_CHAMPION_AddObjectInSlot");
+ }
+ thing = dunMan.getNextThing(thing);
+ }
+
+ _vm->_inventoryMan->toggleInventory((ChampionIndex)prevChampCount);
+ _vm->_menuMan->drawDisabledMenu();
+}
+
} \ No newline at end of file