2016-08-26 22:36:31 +02:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Based on the Reverse Engineering work of Christophe Fontanel,
|
|
|
|
* maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
|
|
|
|
*/
|
|
|
|
|
2016-08-26 22:35:29 +02:00
|
|
|
#include "champion.h"
|
|
|
|
#include "dungeonman.h"
|
|
|
|
#include "eventman.h"
|
|
|
|
#include "menus.h"
|
|
|
|
#include "inventory.h"
|
|
|
|
#include "objectman.h"
|
|
|
|
#include "text.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace DM {
|
|
|
|
|
|
|
|
Box gBoxMouth = Box(55, 72, 12, 29); // @ G0048_s_Graphic562_Box_Mouth
|
|
|
|
Box gBoxEye = Box(11, 28, 12, 29); // @ G0049_s_Graphic562_Box_Eye
|
2016-07-02 01:55:48 +02:00
|
|
|
Box g54_BoxChampionIcons[4] = {
|
2016-08-26 22:35:29 +02:00
|
|
|
Box(281, 299, 0, 13),
|
|
|
|
Box(301, 319, 0, 13),
|
|
|
|
Box(301, 319, 15, 28),
|
|
|
|
Box(281, 299, 15, 28)};
|
2016-07-02 01:55:48 +02:00
|
|
|
Color g46_ChampionColor[4] = {(Color)7, (Color)11, (Color)8, (Color)14};
|
2016-08-26 22:35:29 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
int16 g39_LightPowerToLightAmount[16] = {0, 5, 12, 24, 33, 40, 46, 51, 59, 68, 76, 82, 89, 94, 97, 100};
|
2016-06-29 00:23:40 +02:00
|
|
|
|
2016-08-26 22:35:29 +02:00
|
|
|
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 = Box(0, 31, 0, 28); // @ G0047_s_Graphic562_Box_ChampionPortrait
|
|
|
|
|
|
|
|
ChampionMan::ChampionMan(DMEngine *vm) : _vm(vm) {
|
2016-07-02 01:55:48 +02:00
|
|
|
_g411_leaderIndex = kM1_ChampionNone;
|
2016-08-26 22:35:29 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
_303_partyDead = false;
|
|
|
|
_g300_partyIsSleeping = false;
|
|
|
|
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
|
|
|
|
_g415_leaderEmptyHanded = true;
|
|
|
|
_g514_magicCasterChampionIndex = kM1_ChampionNone;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
uint16 ChampionMan::getChampionPortraitX(uint16 index) {
|
|
|
|
return ((index) & 0x7) << 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 ChampionMan::getChampionPortraitY(uint16 index) {
|
|
|
|
return ((index) >> 3) * 29;
|
|
|
|
}
|
|
|
|
|
|
|
|
int16 ChampionMan::getDecodedValue(char *string, uint16 characterCount) {
|
|
|
|
int val = 0;
|
|
|
|
for (uint16 i = 0; i < characterCount; ++i) {
|
|
|
|
val = (val << 4) + (string[i] - 'A');
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChampionMan::drawHealthOrStaminaOrManaValue(int16 posY, int16 currVal, int16 maxVal) {
|
|
|
|
Common::String tmp = getStringFromInteger(currVal, true, 3).c_str();
|
2016-07-02 00:27:05 +02:00
|
|
|
_vm->_textMan->printToViewport(55, posY, k13_ColorLightestGray, tmp.c_str());
|
|
|
|
_vm->_textMan->printToViewport(73, posY, k13_ColorLightestGray, "/");
|
2016-08-26 22:35:29 +02:00
|
|
|
tmp = getStringFromInteger(maxVal, true, 3);
|
2016-07-02 00:27:05 +02:00
|
|
|
_vm->_textMan->printToViewport(79, posY, k13_ColorLightestGray, tmp.c_str());
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
2016-06-28 23:16:34 +02:00
|
|
|
uint16 ChampionMan::handSlotIndex(uint16 slotBoxIndex) {
|
|
|
|
return slotBoxIndex & 0x1;
|
|
|
|
}
|
|
|
|
|
2016-08-26 22:35:29 +02:00
|
|
|
Common::String ChampionMan::getStringFromInteger(uint16 val, bool padding, uint16 paddingCharCount) {
|
|
|
|
using namespace Common;
|
|
|
|
String valToStr = String::format("%d", val);
|
|
|
|
String result;
|
|
|
|
for (int16 i = 0, end = paddingCharCount - valToStr.size(); i < end; ++i)
|
|
|
|
result += ' ';
|
|
|
|
|
|
|
|
return result += valToStr;
|
|
|
|
}
|
|
|
|
|
2016-06-28 19:33:46 +02:00
|
|
|
void ChampionMan::applyModifiersToStatistics(Champion* champ, ChampionSlot slotIndex, IconIndice iconIndex, int16 modifierFactor, Thing thing) {
|
|
|
|
int16 statIndex;
|
|
|
|
int16 modifier = 0;
|
|
|
|
ThingType thingType = thing.getType();
|
|
|
|
if (((thingType == kWeaponThingType) || (thingType == kArmourThingType))
|
2016-07-02 01:55:48 +02:00
|
|
|
&& (slotIndex >= k0_ChampionSlotReadyHand)
|
|
|
|
&& (slotIndex <= k12_ChampionSlotQuiverLine_1_1)) {
|
2016-06-28 19:33:46 +02:00
|
|
|
Weapon *weapon = (Weapon*)_vm->_dungeonMan->getThingData(thing);
|
|
|
|
Armour *armour = (Armour*)_vm->_dungeonMan->getThingData(thing);
|
|
|
|
if (((thingType == kWeaponThingType) && weapon->getCursed())
|
|
|
|
|| ((thingType == kArmourThingType) && armour->getCursed())) {
|
2016-07-02 01:55:48 +02:00
|
|
|
statIndex = k0_ChampionStatLuck;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = -3;
|
|
|
|
goto T0299044_ApplyModifier;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
statIndex = (ChampionStatisticType)thingType; // variable sharing
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((iconIndex == k137_IconIndiceJunkRabbitsFoot) && (slotIndex < k30_ChampionSlotChest_1)) {
|
|
|
|
statIndex = k0_ChampionStatLuck;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 10;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k1_ChampionSlotActionHand) {
|
2016-06-28 19:33:46 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (iconIndex == k45_IconIndiceWeaponMaceOfOrder) {
|
|
|
|
statIndex = k1_ChampionStatStrength;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 5;
|
|
|
|
} else {
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
statIndex = k8_ChampionStatMana;
|
|
|
|
if ((iconIndex >= k20_IconIndiceWeaponStaffOfClawsEmpty) && (iconIndex <= k22_IconIndiceWeaponStaffOfClawsFull)) {
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 4;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if ((iconIndex >= k58_IconIndiceWeaponStaff) && (iconIndex <= k66_IconIndiceWeaponSceptreOfLyf)) {
|
2016-06-28 19:33:46 +02:00
|
|
|
switch (iconIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
case k58_IconIndiceWeaponStaff:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 2;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k59_IconIndiceWeaponWand:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 1;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k60_IconIndiceWeaponTeowand:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 6;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k61_IconIndiceWeaponYewStaff:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 4;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k62_IconIndiceWeaponStaffOfManarStaffOfIrra:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 10;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k63_IconIndiceWeaponSnakeStaffCrossOfNeta:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 8;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k64_IconIndiceWeaponTheConduitSerpentStaff:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 16;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k65_IconIndiceWeaponDragonSpit:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 7;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k66_IconIndiceWeaponSceptreOfLyf:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 5;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (iconIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
case k38_IconIndiceWeaponDeltaSideSplitter:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 1;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k41_IconIndiceWeaponTheInquisitorDragonFang:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 2;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k40_IconIndiceWeaponVorpalBlade:
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // end of else
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k4_ChampionSlotLegs) {
|
2016-06-28 19:33:46 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (iconIndex == k142_IconIndiceArmourPowertowers) {
|
|
|
|
statIndex = k1_ChampionStatStrength;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 10;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k2_ChampionSlotHead) {
|
2016-06-28 19:33:46 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (iconIndex == k104_IconIndiceArmourCrownOfNerra) {
|
|
|
|
statIndex = k3_ChampionStatWisdom;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 10;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (iconIndex == k140_IconIndiceArmourDexhelm) {
|
|
|
|
statIndex = k2_ChampionStatDexterity;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 10;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k3_ChampionSlotTorso) {
|
2016-06-28 19:33:46 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (iconIndex == k141_IconIndiceArmourFlamebain) {
|
|
|
|
statIndex = k6_ChampionStatAntifire;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 12;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (iconIndex == k81_IconIndiceArmourCloakOfNight) {
|
|
|
|
statIndex = k2_ChampionStatDexterity;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 8;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k10_ChampionSlotNeck) {
|
2016-06-28 19:33:46 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((iconIndex >= k10_IconIndiceJunkJewelSymalUnequipped) && (iconIndex <= k11_IconIndiceJunkJewelSymalEquipped)) {
|
|
|
|
statIndex = k5_ChampionStatAntimagic;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 15;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (iconIndex == k81_IconIndiceArmourCloakOfNight) {
|
|
|
|
statIndex = k2_ChampionStatDexterity;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 8;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (iconIndex == k122_IconIndiceJunkMoonstone) {
|
|
|
|
statIndex = k8_ChampionStatMana;
|
2016-06-28 19:33:46 +02:00
|
|
|
modifier = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
T0299044_ApplyModifier:
|
|
|
|
if (modifier) {
|
|
|
|
modifier *= modifierFactor;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (statIndex == k8_ChampionStatMana) {
|
2016-06-28 19:33:46 +02:00
|
|
|
champ->_maxMana += modifier;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (statIndex < k6_ChampionStatAntifire + 1) {
|
|
|
|
for (uint16 statValIndex = k0_ChampionStatMaximum; statValIndex <= k2_ChampionStatMinimum; ++statValIndex) {
|
2016-06-28 19:33:46 +02:00
|
|
|
champ->getStatistic((ChampionStatisticType)statIndex, (ChampionStatisticValue)statValIndex) += modifier;
|
|
|
|
warning("BUG0_38");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-06-28 20:33:04 +02:00
|
|
|
bool ChampionMan::hasObjectIconInSlotBoxChanged(int16 slotBoxIndex, Thing thing) {
|
|
|
|
ObjectMan &objMan = *_vm->_objectMan;
|
|
|
|
|
|
|
|
IconIndice currIconIndex = objMan.getIconIndexInSlotBox(slotBoxIndex);
|
2016-07-02 01:55:48 +02:00
|
|
|
if (((currIconIndex < k32_IconIndiceWeaponDagger) && (currIconIndex >= k0_IconIndiceJunkCompassNorth))
|
|
|
|
|| ((currIconIndex >= k148_IconIndicePotionMaPotionMonPotion) && (currIconIndex <= k163_IconIndicePotionWaterFlask))
|
|
|
|
|| (currIconIndex == k195_IconIndicePotionEmptyFlask)) {
|
2016-06-28 20:33:04 +02:00
|
|
|
IconIndice newIconIndex = objMan.getIconIndex(thing);
|
|
|
|
if (newIconIndex != currIconIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((slotBoxIndex < kSlotBoxInventoryFirstSlot) && !_g420_mousePointerHiddenToDrawChangedObjIconOnScreen) {
|
|
|
|
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true;
|
2016-06-28 20:33:04 +02:00
|
|
|
warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
|
|
|
|
}
|
|
|
|
objMan.drawIconInSlotBox(slotBoxIndex, newIconIndex);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-28 23:16:34 +02:00
|
|
|
void ChampionMan::drawChangedObjectIcons() {
|
|
|
|
InventoryMan &invMan = *_vm->_inventoryMan;
|
|
|
|
ObjectMan &objMan = *_vm->_objectMan;
|
|
|
|
MenuMan &menuMan = *_vm->_menuMan;
|
|
|
|
|
|
|
|
uint16 invChampOrdinal = invMan._inventoryChampionOrdinal;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g299_candidateChampionOrdinal && !invChampOrdinal)
|
2016-06-28 23:16:34 +02:00
|
|
|
return;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = false;
|
|
|
|
IconIndice leaderHandObjIconIndex = _g413_leaderHandObjectIconIndex;
|
2016-06-28 23:16:34 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (((leaderHandObjIconIndex < k32_IconIndiceWeaponDagger) && (leaderHandObjIconIndex >= k0_IconIndiceJunkCompassNorth)) // < instead of <= is correct
|
|
|
|
|| ((leaderHandObjIconIndex >= k148_IconIndicePotionMaPotionMonPotion) && (leaderHandObjIconIndex <= k163_IconIndicePotionWaterFlask))
|
|
|
|
|| (leaderHandObjIconIndex == k195_IconIndicePotionEmptyFlask)) {
|
|
|
|
IconIndice iconIndex = objMan.getIconIndex(_414_leaderHandObject);
|
2016-06-28 23:16:34 +02:00
|
|
|
if (iconIndex != leaderHandObjIconIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true;
|
2016-06-28 23:16:34 +02:00
|
|
|
warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
|
|
|
|
objMan.extractIconFromBitmap(iconIndex, objMan._objectIconForMousePointer);
|
|
|
|
warning("MISSING CODE: F0068_MOUSE_SetPointerToObject");
|
2016-07-02 01:55:48 +02:00
|
|
|
_g413_leaderHandObjectIconIndex = iconIndex;
|
|
|
|
objMan.drawLeaderObjectName(_414_leaderHandObject);
|
2016-06-28 23:16:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
for (uint16 slotBoxIndex = 0; slotBoxIndex < (_g305_partyChampionCount * 2); ++slotBoxIndex) {
|
2016-06-28 23:16:34 +02:00
|
|
|
int16 champIndex = slotBoxIndex >> 1;
|
2016-06-29 00:23:40 +02:00
|
|
|
if (invChampOrdinal == _vm->indexToOrdinal(champIndex))
|
2016-06-28 23:16:34 +02:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (hasObjectIconInSlotBoxChanged(slotBoxIndex, _champions[champIndex].getSlot((ChampionSlot)handSlotIndex(slotBoxIndex)))
|
2016-07-02 01:55:48 +02:00
|
|
|
&& (handSlotIndex(slotBoxIndex) == k1_ChampionSlotActionHand)) {
|
2016-06-28 23:16:34 +02:00
|
|
|
|
|
|
|
menuMan.drawActionIcon((ChampionIndex)champIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (invChampOrdinal) {
|
|
|
|
Champion *champ = &_champions[_vm->ordinalToIndex(invChampOrdinal)];
|
2016-07-02 01:55:48 +02:00
|
|
|
Thing *thing = &champ->getSlot(k0_ChampionSlotReadyHand);
|
2016-06-28 23:16:34 +02:00
|
|
|
uint16 drawViewport = 0;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
for (uint16 slotIndex = k0_ChampionSlotReadyHand; slotIndex < k30_ChampionSlotChest_1; slotIndex++, thing++) {
|
2016-06-28 23:16:34 +02:00
|
|
|
uint16 objIconChanged = hasObjectIconInSlotBoxChanged(slotIndex + kSlotBoxInventoryFirstSlot, *thing) ? 1 : 0;
|
|
|
|
drawViewport |= objIconChanged;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (objIconChanged && (slotIndex == k1_ChampionSlotActionHand)) {
|
2016-06-28 23:16:34 +02:00
|
|
|
menuMan.drawActionIcon((ChampionIndex)_vm->ordinalToIndex(invChampOrdinal));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (invMan._panelContent = kPanelContentChest) {
|
|
|
|
thing = invMan._chestSlots;
|
|
|
|
for (int16 slotIndex = 0; slotIndex < 8; ++slotIndex, thing++) {
|
|
|
|
drawViewport |= (hasObjectIconInSlotBoxChanged(slotIndex + kSlotBoxChestFirstSlot, *thing) ? 1 : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (drawViewport) {
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setAttributeFlag(k0x4000_ChampionAttributeViewport, true);
|
2016-06-28 23:16:34 +02:00
|
|
|
drawChampionState((ChampionIndex)_vm->ordinalToIndex(invChampOrdinal));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g420_mousePointerHiddenToDrawChangedObjIconOnScreen)
|
2016-06-28 23:16:34 +02:00
|
|
|
warning("MISSING CODE: F0078_MOUSE_ShowPointer");
|
|
|
|
}
|
|
|
|
|
2016-06-29 00:23:40 +02:00
|
|
|
void ChampionMan::addObjectInSlot(ChampionIndex champIndex, Thing thing, ChampionSlot slotIndex) {
|
|
|
|
InventoryMan &invMan = *_vm->_inventoryMan;
|
|
|
|
DungeonMan &dunMan = *_vm->_dungeonMan;
|
|
|
|
ObjectMan &objMan = *_vm->_objectMan;
|
|
|
|
MenuMan &menuMan = *_vm->_menuMan;
|
|
|
|
|
2016-06-30 13:29:42 +02:00
|
|
|
if (thing == Thing::_none)
|
2016-06-29 00:23:40 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
Champion *champ = &_champions[champIndex];
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex >= k30_ChampionSlotChest_1) {
|
|
|
|
invMan._chestSlots[slotIndex - k30_ChampionSlotChest_1] = thing;
|
2016-06-29 00:23:40 +02:00
|
|
|
} else {
|
|
|
|
champ->setSlot(slotIndex, thing);
|
|
|
|
}
|
|
|
|
|
|
|
|
champ->_load += dunMan.getObjectWeight(thing);
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setAttributeFlag(k0x0200_ChampionAttributeLoad, true);
|
2016-06-29 00:23:40 +02:00
|
|
|
IconIndice iconIndex = objMan.getIconIndex(thing);
|
|
|
|
bool isInventoryChampion = (_vm->indexToOrdinal(champIndex) == invMan._inventoryChampionOrdinal);
|
|
|
|
applyModifiersToStatistics(champ, slotIndex, iconIndex, 1, thing);
|
|
|
|
uint16 *rawObjPtr = dunMan.getThingData(thing);
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex < k2_ChampionSlotHead) {
|
2016-06-29 00:23:40 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex == k1_ChampionSlotActionHand) {
|
|
|
|
champ->setAttributeFlag(k0x8000_ChampionAttributeActionHand, true);
|
|
|
|
if (_g506_actingChampionOrdinal == _vm->indexToOrdinal(champIndex))
|
2016-06-29 00:23:40 +02:00
|
|
|
menuMan.clearActingChampion();
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((iconIndex >= k30_IconIndiceScrollOpen) && (iconIndex <= k31_IconIndiceScrollClosed)) {
|
2016-06-29 00:23:40 +02:00
|
|
|
((Scroll*)rawObjPtr)->setClosed(false);
|
|
|
|
drawChangedObjectIcons();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (iconIndex = k4_IconIndiceWeaponTorchUnlit) {
|
2016-06-29 00:23:40 +02:00
|
|
|
((Weapon*)rawObjPtr)->setLit(true);
|
|
|
|
warning("MISSING CODE: F0337_INVENTORY_SetDungeonViewPalette");
|
|
|
|
drawChangedObjectIcons();
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (isInventoryChampion && (slotIndex == k1_ChampionSlotActionHand) &&
|
|
|
|
((iconIndex == k144_IconIndiceContainerChestClosed) || ((iconIndex >= k30_IconIndiceScrollOpen) && (iconIndex <= k31_IconIndiceScrollClosed)))) {
|
|
|
|
champ->setAttributeFlag(k0x0800_ChampionAttributePanel, true);
|
2016-06-29 00:23:40 +02:00
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (slotIndex == k10_ChampionSlotNeck) {
|
2016-06-29 00:23:40 +02:00
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((iconIndex >= k12_IconIndiceJunkIllumuletUnequipped) && (iconIndex <= k13_IconIndiceJunkIllumuletEquipped)) {
|
2016-06-29 00:23:40 +02:00
|
|
|
((Junk*)rawObjPtr)->setChargeCount(1);
|
2016-07-02 01:55:48 +02:00
|
|
|
_g407_party._magicalLightAmount += g39_LightPowerToLightAmount[2];
|
2016-06-29 00:23:40 +02:00
|
|
|
warning("MISSING CODE: F0337_INVENTORY_SetDungeonViewPalette");
|
|
|
|
iconIndex = (IconIndice) (iconIndex + 1);
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if ((iconIndex >= k10_IconIndiceJunkJewelSymalUnequipped) && (iconIndex <= k11_IconIndiceJunkJewelSymalEquipped)) {
|
2016-06-29 00:23:40 +02:00
|
|
|
((Junk*)rawObjPtr)->setChargeCount(1);
|
|
|
|
iconIndex = (IconIndice) (iconIndex + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
drawSlot(champIndex, slotIndex);
|
|
|
|
if (isInventoryChampion)
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setAttributeFlag(k0x4000_ChampionAttributeViewport, true);
|
2016-06-29 00:23:40 +02:00
|
|
|
}
|
|
|
|
|
2016-08-26 22:35:29 +02:00
|
|
|
ChampionIndex ChampionMan::getIndexInCell(ViewCell cell) {
|
2016-07-02 01:55:48 +02:00
|
|
|
for (uint16 i = 0; i < _g305_partyChampionCount; ++i) {
|
2016-08-26 22:35:29 +02:00
|
|
|
if ((_champions[i]._cell == cell) && _champions[i]._currHealth)
|
|
|
|
return (ChampionIndex)i;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
return kM1_ChampionNone;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ChampionMan::resetDataToStartGame() {
|
|
|
|
if (!_vm->_dungeonMan->_messages._newGame) {
|
|
|
|
warning("MISSING CODE: stuff for resetting for loaded games");
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
_414_leaderHandObject = Thing::_none;
|
|
|
|
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
|
|
|
|
_g415_leaderEmptyHanded = true;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
|
|
|
|
DisplayMan &dispMan = *_vm->_displayMan;
|
|
|
|
DungeonMan &dunMan = *_vm->_dungeonMan;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (!_g415_leaderEmptyHanded || _g305_partyChampionCount == 4)
|
2016-08-26 22:35:29 +02:00
|
|
|
return;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
uint16 prevChampCount = _g305_partyChampionCount;
|
2016-08-26 22:35:29 +02:00
|
|
|
Champion *champ = &_champions[prevChampCount];
|
|
|
|
champ->resetToZero();
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan._g578_useByteBoxCoordinates = true;
|
2016-08-26 22:35:29 +02:00
|
|
|
{ // limit destBox scope
|
|
|
|
Box &destBox = gBoxChampionPortrait;
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.blitToBitmap(dispMan.getBitmap(k26_ChampionPortraitsIndice), 256, getChampionPortraitX(championPortraitIndex), getChampionPortraitY(championPortraitIndex),
|
|
|
|
champ->_portrait, 32, destBox._x1, destBox._x2, destBox._y1, destBox._y2, k255_ColorNoTransparency);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->_actionIndex = k255_ChampionActionNone;
|
2016-08-26 22:35:29 +02:00
|
|
|
champ->_enableActionEventIndex = -1;
|
|
|
|
champ->_hideDamageReceivedIndex = -1;
|
|
|
|
champ->_dir = dunMan._currMap._partyDir;
|
2016-07-02 00:27:05 +02:00
|
|
|
ViewCell AL_0_viewCell = k0_ViewCellFronLeft;
|
2016-07-02 01:55:48 +02:00
|
|
|
while (getIndexInCell((ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3)) != kM1_ChampionNone)
|
2016-08-26 22:35:29 +02:00
|
|
|
AL_0_viewCell = (ViewCell)(AL_0_viewCell + 1);
|
|
|
|
champ->_cell = (ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3);
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->clearAttributes(k0x0400_ChampionAttributeIcon);
|
2016-08-26 22:35:29 +02:00
|
|
|
champ->_directionMaximumDamageReceived = dunMan._currMap._partyDir;
|
|
|
|
champ->_food = 1500 + _vm->_rnd->getRandomNumber(256);
|
|
|
|
champ->_water = 1500 + _vm->_rnd->getRandomNumber(256);
|
|
|
|
int16 AL_0_slotIndex_Red;
|
2016-07-02 01:55:48 +02:00
|
|
|
for (AL_0_slotIndex_Red = k0_ChampionSlotReadyHand; AL_0_slotIndex_Red < k30_ChampionSlotChest_1; ++AL_0_slotIndex_Red) {
|
2016-06-30 13:29:42 +02:00
|
|
|
champ->setSlot((ChampionSlot)AL_0_slotIndex_Red, Thing::_none);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
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') {
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setAttributeFlag(k0x0010_ChampionAttributeMale, true);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
character_Green++;
|
|
|
|
champ->_currHealth = champ->_maxHealth = getDecodedValue(character_Green, 4);
|
|
|
|
character_Green += 4;
|
|
|
|
champ->_currStamina = champ->_maxStamina = getDecodedValue(character_Green, 4);
|
|
|
|
character_Green += 4;
|
|
|
|
champ->_currMana = champ->_maxMana = getDecodedValue(character_Green, 4);
|
|
|
|
character_Green += 4;
|
|
|
|
character_Green++;
|
|
|
|
|
|
|
|
int16 AL_0_statisticIndex;
|
2016-07-02 01:55:48 +02:00
|
|
|
for (AL_0_statisticIndex = k0_ChampionStatLuck; AL_0_statisticIndex <= k6_ChampionStatAntifire; ++AL_0_statisticIndex) {
|
|
|
|
champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, k2_ChampionStatMinimum, 30);
|
2016-08-26 22:35:29 +02:00
|
|
|
uint16 currMaxVal = getDecodedValue(character_Green, 2);
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, k1_ChampionStatCurrent, currMaxVal);
|
|
|
|
champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, k0_ChampionStatMaximum, currMaxVal);
|
2016-08-26 22:35:29 +02:00
|
|
|
character_Green += 2;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setStatistic(k0_ChampionStatLuck, k2_ChampionStatMinimum, 10);
|
2016-08-26 22:35:29 +02:00
|
|
|
character_Green++;
|
|
|
|
|
|
|
|
int16 AL_0_skillIndex;
|
|
|
|
int16 AL_2_skillValue;
|
2016-07-02 01:55:48 +02:00
|
|
|
for (AL_0_skillIndex = k4_ChampionSkillSwing; AL_0_skillIndex <= k19_ChampionSkillWater; AL_0_skillIndex++) {
|
2016-08-26 22:35:29 +02:00
|
|
|
if ((AL_2_skillValue = *character_Green++ - 'A') > 0) {
|
|
|
|
champ->setSkillExp((ChampionSkill)AL_0_skillIndex, 125L << AL_2_skillValue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
for (AL_0_skillIndex = k0_ChampionSkillFighter; AL_0_skillIndex <= k3_ChampionSkillWizard; ++AL_0_skillIndex) {
|
2016-08-26 22:35:29 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
_g299_candidateChampionOrdinal = prevChampCount + 1;
|
|
|
|
if (++_g305_partyChampionCount == 1) {
|
|
|
|
_vm->_eventMan->commandSetLeader(k0_ChampionFirst);
|
2016-08-26 22:38:51 +02:00
|
|
|
_vm->_menuMan->_refreshActionArea = true;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
_vm->_menuMan->clearActingChampion();
|
2016-07-02 01:55:48 +02:00
|
|
|
_vm->_menuMan->drawActionIcon((ChampionIndex)(_g305_partyChampionCount - 1));
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int16 mapX = _vm->_dungeonMan->_currMap._partyPosX;
|
|
|
|
int16 mapY = _vm->_dungeonMan->_currMap._partyPosY;
|
|
|
|
|
|
|
|
uint16 championObjectsCell = returnOppositeDir((direction)(dunMan._currMap._partyDir));
|
2016-06-29 22:51:40 +02:00
|
|
|
mapX += _vm->_dirIntoStepCountEast[dunMan._currMap._partyDir];
|
|
|
|
mapY += _vm->_dirIntoStepCountNorth[dunMan._currMap._partyDir];
|
2016-08-26 22:35:29 +02:00
|
|
|
thing = dunMan.getSquareFirstThing(mapX, mapY);
|
2016-07-02 01:55:48 +02:00
|
|
|
AL_0_slotIndex_Red = k13_ChampionSlotBackpackLine_1_1;
|
2016-08-26 22:35:29 +02:00
|
|
|
uint16 slotIndex_Green;
|
2016-06-30 13:29:42 +02:00
|
|
|
while (thing != Thing::_endOfList) {
|
2016-08-26 22:35:29 +02:00
|
|
|
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:
|
2016-07-02 01:55:48 +02:00
|
|
|
for (slotIndex_Green = k2_ChampionSlotHead; slotIndex_Green <= k5_ChampionSlotFeet; slotIndex_Green++) {
|
2016-08-26 22:35:29 +02:00
|
|
|
if (objectAllowedSlots & gSlotMasks[slotIndex_Green])
|
|
|
|
goto T0280048;
|
|
|
|
}
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((objectAllowedSlots & gSlotMasks[k10_ChampionSlotNeck]) && (champ->getSlot(k10_ChampionSlotNeck) == Thing::_none)) {
|
|
|
|
slotIndex_Green = k10_ChampionSlotNeck;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
goto T0280046;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case kWeaponThingType:
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champ->getSlot(k1_ChampionSlotActionHand) == Thing::_none) {
|
|
|
|
slotIndex_Green = k1_ChampionSlotActionHand;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
goto T0280046;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case kScrollThingType:
|
|
|
|
case kPotionThingType:
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champ->getSlot(k11_ChampionSlotPouch_1) == Thing::_none) {
|
|
|
|
slotIndex_Green = k11_ChampionSlotPouch_1;
|
|
|
|
} else if (champ->getSlot(k6_ChampionSlotPouch_2) == Thing::_none) {
|
|
|
|
slotIndex_Green = k6_ChampionSlotPouch_2;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
goto T0280046;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case kContainerThingType:
|
|
|
|
case kJunkThingType:
|
|
|
|
T0280046:
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((objectAllowedSlots & gSlotMasks[k10_ChampionSlotNeck]) && (champ->getSlot(k10_ChampionSlotNeck) == Thing::_none)) {
|
|
|
|
slotIndex_Green = k10_ChampionSlotNeck;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
slotIndex_Green = AL_0_slotIndex_Red++;
|
|
|
|
}
|
|
|
|
break;
|
2016-06-25 13:31:47 +02:00
|
|
|
|
2016-06-23 23:22:50 +02:00
|
|
|
default:
|
|
|
|
break;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
T0280048:
|
2016-06-30 13:29:42 +02:00
|
|
|
if (champ->getSlot((ChampionSlot)slotIndex_Green) != Thing::_none) {
|
2016-08-26 22:35:29 +02:00
|
|
|
goto T0280046;
|
|
|
|
}
|
2016-06-29 00:23:40 +02:00
|
|
|
addObjectInSlot((ChampionIndex)prevChampCount, thing, (ChampionSlot)slotIndex_Green);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
thing = dunMan.getNextThing(thing);
|
|
|
|
}
|
|
|
|
|
|
|
|
_vm->_inventoryMan->toggleInventory((ChampionIndex)prevChampCount);
|
|
|
|
_vm->_menuMan->drawDisabledMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChampionMan::drawChampionBarGraphs(ChampionIndex champIndex) {
|
|
|
|
|
|
|
|
Champion *curChampion = &_champions[champIndex];
|
|
|
|
int16 barGraphIndex = 0;
|
|
|
|
int16 barGraphHeightArray[3];
|
|
|
|
|
|
|
|
if (curChampion->_currHealth > 0) {
|
|
|
|
uint32 barGraphHeight = (((uint32)(curChampion->_currHealth) << 10) * 25) / curChampion->_maxHealth;
|
|
|
|
if (barGraphHeight & 0x3FF) {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curChampion->_currStamina > 0) {
|
|
|
|
uint32 barGraphHeight = (((uint32)(curChampion->_currStamina) << 10) * 25) / curChampion->_maxStamina;
|
|
|
|
if (barGraphHeight & 0x3FF) {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curChampion->_currMana > 0) {
|
|
|
|
uint32 barGraphHeight = (((uint32)(curChampion->_currMana) << 10) * 25) / curChampion->_maxMana;
|
|
|
|
if (barGraphHeight & 0x3FF) {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
barGraphHeightArray[barGraphIndex++] = 0;
|
|
|
|
}
|
|
|
|
warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
|
|
|
|
|
|
|
|
Box box;
|
|
|
|
box._x1 = champIndex * kChampionStatusBoxSpacing + 46;
|
|
|
|
box._x2 = box._x1 + 3 + 1;
|
|
|
|
box._y1 = 2;
|
|
|
|
box._y2 = 26 + 1;
|
|
|
|
|
|
|
|
for (int16 AL_0_barGraphIndex = 0; AL_0_barGraphIndex < 3; AL_0_barGraphIndex++) {
|
|
|
|
int16 barGraphHeight = barGraphHeightArray[AL_0_barGraphIndex];
|
|
|
|
if (barGraphHeight < 25) {
|
|
|
|
box._y1 = 2;
|
|
|
|
box._y1 = 27 - barGraphHeight + 1;
|
2016-07-02 01:55:48 +02:00
|
|
|
_vm->_displayMan->clearScreenBox(g46_ChampionColor[champIndex], box);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
if (barGraphHeight) {
|
|
|
|
box._y1 = 27 - barGraphHeight;
|
|
|
|
box._y2 = 26 + 1;
|
2016-07-02 01:55:48 +02:00
|
|
|
_vm->_displayMan->clearScreenBox(g46_ChampionColor[champIndex], box);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
box._x1 += 7;
|
|
|
|
box._x2 += 7;
|
|
|
|
}
|
|
|
|
warning("MISSING CODE: F0078_MOUSE_ShowPointer");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint16 ChampionMan::getStaminaAdjustedValue(Champion *champ, int16 val) {
|
|
|
|
int16 currStamina = champ->_currStamina;
|
|
|
|
int16 halfMaxStamina = champ->_maxStamina / 2;
|
|
|
|
if (currStamina < halfMaxStamina) {
|
|
|
|
warning("Possible undefined behavior in the original code");
|
|
|
|
val /= 2;
|
|
|
|
return val + ((uint32)val * (uint32)currStamina) / halfMaxStamina;
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 ChampionMan::getMaximumLoad(Champion *champ) {
|
2016-07-02 01:55:48 +02:00
|
|
|
uint16 maximumLoad = champ->getStatistic(k1_ChampionStatStrength, k1_ChampionStatCurrent) * 8 + 100;
|
2016-08-26 22:35:29 +02:00
|
|
|
maximumLoad = getStaminaAdjustedValue(champ, maximumLoad);
|
|
|
|
int16 wounds = champ->getWounds();
|
|
|
|
if (wounds) {
|
2016-07-02 01:55:48 +02:00
|
|
|
maximumLoad -= maximumLoad >> (champ->getWoundsFlag(k0x0010_ChampionWoundLegs) ? 2 : 3);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_vm->_objectMan->getIconIndex(champ->getSlot(k5_ChampionSlotFeet)) == k119_IconIndiceArmourElvenBoots) {
|
2016-08-26 22:35:29 +02:00
|
|
|
maximumLoad += maximumLoad * 16;
|
|
|
|
}
|
|
|
|
maximumLoad += 9;
|
|
|
|
maximumLoad -= maximumLoad % 10;
|
|
|
|
return maximumLoad;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChampionMan::drawChampionState(ChampionIndex champIndex) {
|
|
|
|
InventoryMan &invMan = *_vm->_inventoryMan;
|
|
|
|
DisplayMan &dispMan = *_vm->_displayMan;
|
|
|
|
MenuMan &menuMan = *_vm->_menuMan;
|
|
|
|
EventManager &eventMan = *_vm->_eventMan;
|
|
|
|
|
|
|
|
Box box;
|
|
|
|
int16 champStatusBoxX = champIndex * kChampionStatusBoxSpacing;
|
|
|
|
Champion *champ = &_champions[champIndex];
|
|
|
|
uint16 champAttributes = champ->getAttributes();
|
2016-07-02 01:55:48 +02:00
|
|
|
if (!((champAttributes) & (k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon |
|
|
|
|
k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport |
|
|
|
|
k0x8000_ChampionAttributeActionHand))) {
|
2016-08-26 22:35:29 +02:00
|
|
|
return;
|
|
|
|
}
|
2016-06-23 23:12:39 +02:00
|
|
|
bool isInventoryChamp = (_vm->indexToOrdinal(champIndex) == invMan._inventoryChampionOrdinal);
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan._g578_useByteBoxCoordinates = false;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x1000_ChampionAttributeStatusBox) {
|
2016-08-26 22:35:29 +02:00
|
|
|
box._y1 = 0;
|
|
|
|
box._y2 = 28 + 1;
|
|
|
|
box._x1 = champStatusBoxX;
|
|
|
|
box._x2 = box._x1 + 66 + 1;
|
|
|
|
if (champ->_currHealth) {
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.clearScreenBox(k12_ColorDarkestGray, box);
|
2016-08-26 22:35:29 +02:00
|
|
|
int16 nativeBitmapIndices[3];
|
|
|
|
for (int16 i = 0; i < 3; ++i)
|
|
|
|
nativeBitmapIndices[i] = 0;
|
|
|
|
int16 AL_0_borderCount = 0;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g407_party._fireShieldDefense > 0)
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndices[AL_0_borderCount++] = k38_BorderPartyFireshieldIndice;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g407_party._spellShieldDefense > 0)
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndices[AL_0_borderCount++] = k39_BorderPartySpellshieldIndice;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g407_party._shieldDefense > 0)
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndices[AL_0_borderCount++] = k37_BorderPartyShieldIndice;
|
2016-08-26 22:35:29 +02:00
|
|
|
while (AL_0_borderCount--) {
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(nativeBitmapIndices[AL_0_borderCount]), 80, 0, 0, box, k10_ColorFlesh);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
if (isInventoryChamp) {
|
|
|
|
invMan.drawStatusBoxPortrait(champIndex);
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x0100_ChampionAttributeStatistics;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= (k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x2000_ChampionAttributeWounds | k0x8000_ChampionAttributeActionHand);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
} else {
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(k8_StatusBoxDeadChampion), 80, 0, 0, box, k255_ColorNoTransparency);
|
|
|
|
_vm->_textMan->printTextToScreen(champStatusBoxX + 1, 5, k13_ColorLightestGray, k1_ColorDarkGary, champ->_name);
|
2016-08-26 22:35:29 +02:00
|
|
|
menuMan.drawActionIcon(champIndex);
|
|
|
|
goto T0292042_green;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!champ->_currHealth)
|
|
|
|
goto T0292042_green;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x0080_ChampionAttributeNameTitle) {
|
|
|
|
Color AL_0_colorIndex = (champIndex == _g411_leaderIndex) ? k9_ColorGold : k13_ColorLightestGray; // unused because of missing functions
|
2016-08-26 22:35:29 +02:00
|
|
|
if (isInventoryChamp) {
|
|
|
|
char *champName = champ->_name;
|
|
|
|
_vm->_textMan->printToViewport(3, 7, AL_0_colorIndex, champName);
|
|
|
|
int16 champTitleX = 6 * strlen(champName) + 3;
|
|
|
|
char champTitleFirstChar = champ->_title[0];
|
|
|
|
if ((champTitleFirstChar != ',') && (champTitleFirstChar != ';') && (champTitleFirstChar != '-')) {
|
|
|
|
champTitleX += 6;
|
|
|
|
}
|
|
|
|
_vm->_textMan->printToViewport(champTitleX, 7, AL_0_colorIndex, champ->_title);
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
|
|
|
box._y1 = 0;
|
|
|
|
box._y2 = 6 + 1;
|
|
|
|
box._x1 = champStatusBoxX;
|
|
|
|
box._x2 = box._x1 + 42 + 1;
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.clearScreenBox(k1_ColorDarkGary, box);
|
|
|
|
_vm->_textMan->printTextToScreen(champStatusBoxX + 1, 5, AL_0_colorIndex, k1_ColorDarkGary, champ->_name);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x0100_ChampionAttributeStatistics) {
|
2016-08-26 22:35:29 +02:00
|
|
|
drawChampionBarGraphs(champIndex);
|
|
|
|
if (isInventoryChamp) {
|
|
|
|
drawHealthStaminaManaValues(champ);
|
|
|
|
int16 AL_2_nativeBitmapIndex;
|
|
|
|
if ((champ->_food < 0) || (champ->_water < 0) || (champ->_poisonEventCount)) {
|
2016-07-02 00:27:05 +02:00
|
|
|
AL_2_nativeBitmapIndex = k34_SlotBoxWoundedIndice;
|
2016-08-26 22:35:29 +02:00
|
|
|
} else {
|
2016-07-02 00:27:05 +02:00
|
|
|
AL_2_nativeBitmapIndex = k33_SlotBoxNormalIndice;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
2016-07-02 01:19:53 +02:00
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxMouth, k12_ColorDarkestGray, g296_DungeonViewport);
|
2016-07-02 00:27:05 +02:00
|
|
|
AL_2_nativeBitmapIndex = k33_SlotBoxNormalIndice;
|
2016-07-02 01:55:48 +02:00
|
|
|
for (int16 AL_0_statisticIndex = k1_ChampionStatStrength; AL_0_statisticIndex <= k6_ChampionStatAntifire; AL_0_statisticIndex++) {
|
|
|
|
if (champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, k1_ChampionStatCurrent)
|
|
|
|
< champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, k0_ChampionStatMaximum)) {
|
2016-07-02 00:27:05 +02:00
|
|
|
AL_2_nativeBitmapIndex = k34_SlotBoxWoundedIndice;
|
2016-08-26 22:35:29 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2016-07-02 01:19:53 +02:00
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxEye, k12_ColorDarkestGray, g296_DungeonViewport);
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x2000_ChampionAttributeWounds) {
|
|
|
|
for (int16 AL_0_slotIndex = isInventoryChamp ? k5_ChampionSlotFeet : k1_ChampionSlotActionHand; AL_0_slotIndex >= k0_ChampionSlotReadyHand; AL_0_slotIndex--) {
|
2016-06-23 03:16:36 +02:00
|
|
|
drawSlot(champIndex, (ChampionSlot)AL_0_slotIndex);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
if (isInventoryChamp) {
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((champAttributes & k0x0200_ChampionAttributeLoad) && isInventoryChamp) {
|
2016-06-24 10:39:25 +02:00
|
|
|
Color loadColor;
|
|
|
|
int16 champMaxLoad = getMaximumLoad(champ);
|
|
|
|
if (champ->_load > champMaxLoad) {
|
2016-07-02 00:27:05 +02:00
|
|
|
loadColor = k8_ColorRed;
|
2016-06-24 10:39:25 +02:00
|
|
|
} else if (((int32)champ->_load) * 8 > ((int32)champMaxLoad) * 5) {
|
2016-07-02 00:27:05 +02:00
|
|
|
loadColor = k11_ColorYellow;
|
2016-06-24 10:39:25 +02:00
|
|
|
} else {
|
2016-07-02 00:27:05 +02:00
|
|
|
loadColor = k13_ColorLightestGray;
|
2016-06-24 10:39:25 +02:00
|
|
|
}
|
|
|
|
_vm->_textMan->printToViewport(104, 132, loadColor, "LOAD ");
|
|
|
|
|
|
|
|
int16 loadTmp = champ->_load / 10;
|
|
|
|
Common::String str = getStringFromInteger(loadTmp, true, 3);
|
|
|
|
str += '.';
|
|
|
|
loadTmp = champ->_load - (loadTmp * 10);
|
|
|
|
str += getStringFromInteger(loadTmp, false, 1);
|
|
|
|
str += '/';
|
|
|
|
loadTmp = (getMaximumLoad(champ) + 5) / 10;
|
|
|
|
str += "KG";
|
|
|
|
_vm->_textMan->printToViewport(148, 132, loadColor, str.c_str());
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
{ // block so goto won't skip AL_0_championIconIndex initialization
|
|
|
|
int16 AL_0_championIconIndex = championIconIndex(champ->_cell, _vm->_dungeonMan->_currMap._partyDir);
|
|
|
|
|
2016-07-02 00:27:05 +02:00
|
|
|
if ((champAttributes & k28_ChampionIcons) && (eventMan._useChampionIconOrdinalAsMousePointerBitmap != _vm->indexToOrdinal(AL_0_championIconIndex))) {
|
2016-07-02 01:55:48 +02:00
|
|
|
dispMan.clearScreenBox(g46_ChampionColor[champIndex], g54_BoxChampionIcons[AL_0_championIconIndex]);
|
2016-07-02 00:27:05 +02:00
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(k28_ChampionIcons), 80, championIconIndex(champ->_dir, _vm->_dungeonMan->_currMap._partyDir) * 19, 0,
|
2016-07-02 01:55:48 +02:00
|
|
|
g54_BoxChampionIcons[AL_0_championIconIndex], k12_ColorDarkestGray);
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((champAttributes & k0x0800_ChampionAttributePanel) && isInventoryChamp) {
|
2016-08-26 22:35:29 +02:00
|
|
|
if (_vm->_pressingMouth) {
|
|
|
|
invMan.drawPanelFoodWaterPoisoned();
|
|
|
|
} else if (_vm->_pressingEye) {
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g415_leaderEmptyHanded) {
|
2016-08-26 22:35:29 +02:00
|
|
|
warning("MISSING CODE: F0351_INVENTORY_DrawChampionSkillsAndStatistics");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
invMan.drawPanel();
|
|
|
|
}
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x8000_ChampionAttributeActionHand) {
|
|
|
|
drawSlot(champIndex, k1_ChampionSlotActionHand);
|
2016-08-26 22:35:29 +02:00
|
|
|
menuMan.drawActionIcon(champIndex);
|
|
|
|
if (isInventoryChamp) {
|
2016-07-02 01:55:48 +02:00
|
|
|
champAttributes |= k0x4000_ChampionAttributeViewport;
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (champAttributes & k0x4000_ChampionAttributeViewport) {
|
2016-08-26 22:35:29 +02:00
|
|
|
warning("MISSGIN CODE: F0097_DUNGEONVIEW_DrawViewport");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
T0292042_green:
|
2016-07-02 01:55:48 +02:00
|
|
|
champ->setAttributeFlag((ChampionAttribute)(k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon |
|
|
|
|
k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport |
|
|
|
|
k0x8000_ChampionAttributeActionHand), false);
|
2016-08-26 22:35:29 +02:00
|
|
|
warning("MISSING CODE: F0078_MOUSE_ShowPointer");
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 ChampionMan::championIconIndex(int16 val, direction dir) {
|
|
|
|
return ((val + 4 - dir) & 0x3);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ChampionMan::drawHealthStaminaManaValues(Champion* champ) {
|
|
|
|
drawHealthOrStaminaOrManaValue(116, champ->_currHealth, champ->_maxHealth);
|
|
|
|
drawHealthOrStaminaOrManaValue(124, champ->_currStamina, champ->_maxStamina);
|
|
|
|
drawHealthOrStaminaOrManaValue(132, champ->_currMana, champ->_maxMana);
|
|
|
|
}
|
|
|
|
|
2016-06-23 03:16:36 +02:00
|
|
|
void ChampionMan::drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
|
|
|
|
int16 nativeBitmapIndex = -1;
|
|
|
|
Champion *champ = &_champions[champIndex];
|
2016-06-23 23:12:39 +02:00
|
|
|
bool isInventoryChamp = (_vm->_inventoryMan->_inventoryChampionOrdinal == _vm->indexToOrdinal(champIndex));
|
2016-06-23 03:16:36 +02:00
|
|
|
|
|
|
|
uint16 slotBoxIndex;
|
|
|
|
if (!isInventoryChamp) { /* If drawing a slot for a champion other than the champion whose inventory is open */
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((slotIndex > k1_ChampionSlotActionHand) || (_g299_candidateChampionOrdinal == _vm->indexToOrdinal(champIndex))) {
|
2016-06-23 03:16:36 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
slotBoxIndex = (champIndex << 1) + slotIndex;
|
|
|
|
} else {
|
|
|
|
slotBoxIndex = kSlotBoxInventoryFirstSlot + slotIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
Thing thing;
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex >= k30_ChampionSlotChest_1) {
|
|
|
|
thing = _vm->_inventoryMan->_chestSlots[slotIndex - k30_ChampionSlotChest_1];
|
2016-06-23 03:16:36 +02:00
|
|
|
} else {
|
|
|
|
thing = champ->getSlot(slotIndex);
|
|
|
|
}
|
|
|
|
|
2016-08-26 22:38:06 +02:00
|
|
|
SlotBox *slotBox = &_vm->_objectMan->_slotBoxes[slotBoxIndex];
|
2016-06-23 03:16:36 +02:00
|
|
|
Box box;
|
|
|
|
box._x1 = slotBox->_x - 1;
|
|
|
|
box._y1 = slotBox->_y - 1;
|
|
|
|
box._x2 = box._x1 + 17 + 1;
|
|
|
|
box._y2 = box._y1 + 17 + 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (!isInventoryChamp) {
|
|
|
|
warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
|
|
|
|
}
|
|
|
|
|
|
|
|
int16 iconIndex;
|
2016-06-30 13:29:42 +02:00
|
|
|
if (thing == Thing::_none) {
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex <= k5_ChampionSlotFeet) {
|
|
|
|
iconIndex = k212_IconIndiceReadyHand + (slotIndex << 1);
|
2016-06-23 03:16:36 +02:00
|
|
|
if (champ->getWoundsFlag((ChampionWound)(1 << slotIndex))) {
|
|
|
|
iconIndex++;
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndex = k34_SlotBoxWoundedIndice;
|
2016-06-23 03:16:36 +02:00
|
|
|
} else {
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndex = k33_SlotBoxNormalIndice;
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
} else {
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((slotIndex >= k10_ChampionSlotNeck) && (slotIndex <= k13_ChampionSlotBackpackLine_1_1)) {
|
|
|
|
iconIndex = k208_IconIndiceNeck + (slotIndex - k10_ChampionSlotNeck);
|
2016-06-23 03:16:36 +02:00
|
|
|
} else {
|
2016-07-02 01:55:48 +02:00
|
|
|
iconIndex = k204_IconIndiceEmptyBox;
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
warning("BUG0_35");
|
|
|
|
iconIndex = _vm->_objectMan->getIconIndex(thing); // BUG0_35
|
2016-07-02 01:55:48 +02:00
|
|
|
if (isInventoryChamp && (slotIndex == k1_ChampionSlotActionHand) && ((iconIndex == k144_IconIndiceContainerChestClosed) || (iconIndex == k30_IconIndiceScrollOpen))) {
|
2016-06-23 03:16:36 +02:00
|
|
|
warning("BUG2_00");
|
|
|
|
iconIndex++;
|
|
|
|
} // BUG2_00
|
2016-07-02 01:55:48 +02:00
|
|
|
if (slotIndex <= k5_ChampionSlotFeet) {
|
2016-06-23 03:16:36 +02:00
|
|
|
if (champ->getWoundsFlag((ChampionWound)(1 << slotIndex))) {
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndex = k34_SlotBoxWoundedIndice;
|
2016-06-23 03:16:36 +02:00
|
|
|
} else {
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndex = k33_SlotBoxNormalIndice;
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((slotIndex == k1_ChampionSlotActionHand) && (_vm->indexToOrdinal(champIndex) == _g506_actingChampionOrdinal)) {
|
2016-07-02 00:27:05 +02:00
|
|
|
nativeBitmapIndex = k35_SlotBoxActingHandIndice;
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nativeBitmapIndex != -1) {
|
2016-07-02 00:27:05 +02:00
|
|
|
_vm->_displayMan->_g578_useByteBoxCoordinates = false;
|
2016-06-23 03:16:36 +02:00
|
|
|
_vm->_displayMan->blitToScreen(_vm->_displayMan->getBitmap(nativeBitmapIndex), 32, 0, 0,
|
2016-07-02 01:19:53 +02:00
|
|
|
box, k12_ColorDarkestGray, isInventoryChamp ? g296_DungeonViewport : gDefultViewPort);
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
_vm->_objectMan->drawIconInSlotBox(slotBoxIndex, iconIndex);
|
|
|
|
|
|
|
|
if (!isInventoryChamp) {
|
|
|
|
warning("MISSING CODE: F0078_MOUSE_ShowPointer");
|
|
|
|
}
|
2016-08-26 22:35:29 +02:00
|
|
|
}
|
2016-06-23 03:16:36 +02:00
|
|
|
|
2016-06-25 13:31:47 +02:00
|
|
|
void ChampionMan::renameChampion(Champion* champ) {
|
|
|
|
warning("STUB METHOD: Champion::renameChampion, F0281_CHAMPION_Rename");
|
|
|
|
|
|
|
|
DisplayMan &dispMan = *_vm->_displayMan;
|
|
|
|
TextMan &textMan = *_vm->_textMan;
|
2016-06-23 03:16:36 +02:00
|
|
|
|
2016-06-25 13:31:47 +02:00
|
|
|
Box box;
|
|
|
|
box._y1 = 3;
|
|
|
|
box._y2 = 8 + 1;
|
|
|
|
box._x1 = 3;
|
|
|
|
box._x2 = box._x1 + 167;
|
|
|
|
|
2016-07-02 01:19:53 +02:00
|
|
|
dispMan.clearScreenBox(k12_ColorDarkestGray, box, g296_DungeonViewport);
|
|
|
|
dispMan.blitToScreen(dispMan.getBitmap(k27_PanelRenameChampionIndice), 144, 0, 0, gBoxPanel, k4_ColorCyan, g296_DungeonViewport);
|
2016-07-02 00:27:05 +02:00
|
|
|
textMan.printToViewport(177, 58, k13_ColorLightestGray, "_______");
|
|
|
|
textMan.printToViewport(105, 76, k13_ColorLightestGray, "___________________");
|
2016-06-25 13:31:47 +02:00
|
|
|
Common::Point clickPos;
|
|
|
|
static Box okButtonBox(197, 215, 147, 155); // inclusive boundaries, constructor adds +1
|
|
|
|
for (;;) {
|
|
|
|
_vm->_eventMan->processInput();
|
|
|
|
if (_vm->_eventMan->hasPendingClick(clickPos, kLeftMouseButton) && okButtonBox.isPointInside(clickPos)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dispMan.updateScreen();
|
|
|
|
}
|
|
|
|
}
|
2016-06-28 01:50:02 +02:00
|
|
|
|
|
|
|
uint16 ChampionMan::getSkillLevel(ChampionIndex champIndex, ChampionSkill skillIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
if (_g300_partyIsSleeping)
|
2016-06-28 01:50:02 +02:00
|
|
|
return 1;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
bool ignoreTempExp = skillIndex & k0x8000_IgnoreTemporaryExperience;
|
|
|
|
bool ignoreObjModifiers = skillIndex & k0x4000_IgnoreObjectModifiers;
|
2016-06-28 01:50:02 +02:00
|
|
|
skillIndex = (ChampionSkill)(skillIndex & ~(ignoreTempExp | ignoreObjModifiers));
|
|
|
|
Champion *champ = &_champions[champIndex];
|
|
|
|
Skill *skill = &champ->getSkill(skillIndex);
|
|
|
|
int32 experience = skill->_experience;
|
|
|
|
|
|
|
|
if (!ignoreTempExp)
|
|
|
|
experience += skill->_temporaryExperience;
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
if (skillIndex > k3_ChampionSkillWizard) { // hidden skill
|
|
|
|
skill = &champ->getSkill((ChampionSkill)((skillIndex - k4_ChampionSkillSwing) / 4));
|
2016-06-28 01:50:02 +02:00
|
|
|
experience += skill->_experience; // add exp to the base skill
|
|
|
|
if (!ignoreTempExp)
|
|
|
|
experience += skill->_temporaryExperience;
|
|
|
|
|
|
|
|
experience /= 2; // halve the exp to get avarage of base skill + hidden skill exp
|
|
|
|
}
|
|
|
|
|
|
|
|
int16 skillLevel = 1;
|
|
|
|
while (experience >= 500) {
|
|
|
|
experience /= 2;
|
|
|
|
skillLevel++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ignoreObjModifiers) {
|
2016-07-02 01:55:48 +02:00
|
|
|
IconIndice actionHandIconIndex = _vm->_objectMan->getIconIndex(champ->getSlot(k1_ChampionSlotActionHand));
|
|
|
|
if (actionHandIconIndex == k27_IconIndiceWeaponTheFirestaff) {
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel++;
|
2016-07-02 01:55:48 +02:00
|
|
|
} else if (actionHandIconIndex == k28_IconIndiceWeaponTheFirestaffComplete) {
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel += 2;
|
|
|
|
}
|
|
|
|
|
2016-07-02 01:55:48 +02:00
|
|
|
IconIndice neckIconIndice = _vm->_objectMan->getIconIndex(champ->getSlot(k10_ChampionSlotNeck));
|
2016-06-28 01:50:02 +02:00
|
|
|
switch (skillIndex) {
|
2016-07-02 01:55:48 +02:00
|
|
|
case k3_ChampionSkillWizard:
|
|
|
|
if (neckIconIndice == k124_IconIndiceJunkPendantFeral)
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel++;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k15_ChampionSkillDefend:
|
|
|
|
if (neckIconIndice == k121_IconIndiceJunkEkkhardCross)
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel++;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k13_ChampionSkillHeal:
|
2016-06-28 01:50:02 +02:00
|
|
|
// these two are not cummulative
|
2016-07-02 01:55:48 +02:00
|
|
|
if ((neckIconIndice == k120_IconIndiceJunkGemOfAges) || (neckIconIndice == k66_IconIndiceWeaponSceptreOfLyf))
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel++;
|
|
|
|
break;
|
2016-07-02 01:55:48 +02:00
|
|
|
case k14_ChampionSkillInfluence:
|
|
|
|
if (neckIconIndice == k122_IconIndiceJunkMoonstone)
|
2016-06-28 01:50:02 +02:00
|
|
|
skillLevel++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return skillLevel;
|
|
|
|
}
|
|
|
|
|
2016-06-23 03:16:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|