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.cpp737
1 files changed, 717 insertions, 20 deletions
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index b35e0d8f5a..5c1f5466a7 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -32,10 +32,15 @@
#include "inventory.h"
#include "objectman.h"
#include "text.h"
+#include "timeline.h"
+#include "projexpl.h"
+#include "group.h"
namespace DM {
+const char *g417_baseSkillName[4] = {"FIGHTER", "NINJA", "PRIEST", "WIZARD"};
+
Box gBoxMouth = Box(55, 72, 12, 29); // @ G0048_s_Graphic562_Box_Mouth
Box gBoxEye = Box(11, 28, 12, 29); // @ G0049_s_Graphic562_Box_Eye
Box g54_BoxChampionIcons[4] = {
@@ -98,6 +103,81 @@ ChampionMan::ChampionMan(DMEngine *vm) : _vm(vm) {
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
_g415_leaderEmptyHanded = true;
_g514_magicCasterChampionIndex = kM1_ChampionNone;
+ for (uint16 i = 0; i < 4; ++i) {
+ _g409_championPendingDamage[i] = 0;
+ _g410_championPendingWounds[i] = 0;
+ }
+
+}
+
+bool ChampionMan::f329_isLeaderHandObjectThrown(int16 side) {
+ if (_g411_leaderIndex == kM1_ChampionNone) {
+ return false;
+ }
+ return f328_isObjectThrown(_g411_leaderIndex, kM1_ChampionSlotLeaderHand, side);
+}
+
+bool ChampionMan::f328_isObjectThrown(uint16 champIndex, int16 slotIndex, int16 side) {
+ int16 L0993_i_KineticEnergy;
+ int16 L0994_i_Multiple;
+#define AL0994_i_Experience L0994_i_Multiple
+#define AL0994_i_Attack L0994_i_Multiple
+ int16 L0995_i_Multiple;
+#define AL0995_i_WeaponKineticEnergy L0995_i_Multiple
+#define AL0995_i_SkillLevel L0995_i_Multiple
+#define AL0995_i_StepEnergy L0995_i_Multiple
+ Thing L0996_T_Thing;
+ Champion* L0997_ps_Champion = nullptr;
+ WeaponInfo* L0998_ps_WeaponInfo;
+ Thing L0999_T_ActionHandThing;
+ bool L1000_B_ThrowingLeaderHandObject;
+
+
+ L1000_B_ThrowingLeaderHandObject = false;
+ if (slotIndex < 0) { /* Throw object in leader hand, which is temporarily placed in action hand */
+ if (_g415_leaderEmptyHanded) {
+ return false;
+ }
+ L0996_T_Thing = f298_getObjectRemovedFromLeaderHand();
+ L0997_ps_Champion = &_gK71_champions[champIndex];
+ L0999_T_ActionHandThing = L0997_ps_Champion->getSlot(k1_ChampionSlotActionHand);
+ L0997_ps_Champion->setSlot(k1_ChampionSlotActionHand, L0996_T_Thing);
+ slotIndex = k1_ChampionSlotActionHand;
+ L1000_B_ThrowingLeaderHandObject = true;
+ }
+ L0993_i_KineticEnergy = f312_getStrength(champIndex, slotIndex);
+ if (L1000_B_ThrowingLeaderHandObject) {
+ L0997_ps_Champion->setSlot((ChampionSlot)slotIndex, L0999_T_ActionHandThing);
+ } else {
+ if ((L0996_T_Thing = f300_getObjectRemovedFromSlot(champIndex, slotIndex)) == Thing::_none) {
+ return false;
+ }
+ }
+ warning("MISSING CODE: F0064_SOUND_RequestPlay_CPSD");
+ f325_decrementStamine(champIndex, f305_getThrowingStaminaCost(L0996_T_Thing));
+ f330_disableAction(champIndex, 4);
+ AL0994_i_Experience = 8;
+ AL0995_i_WeaponKineticEnergy = 1;
+ if (L0996_T_Thing.getType() == k5_WeaponThingType) {
+ AL0994_i_Experience += 4;
+ L0998_ps_WeaponInfo = _vm->_dungeonMan->f158_getWeaponInfo(L0996_T_Thing);
+ if (L0998_ps_WeaponInfo->_class <= k12_WeaponClassPoisinDart) {
+ AL0994_i_Experience += (AL0995_i_WeaponKineticEnergy = L0998_ps_WeaponInfo->_kineticEnergy) >> 2;
+ }
+ }
+ f304_addSkillExperience(champIndex, k10_ChampionSkillThrow, AL0994_i_Experience);
+ L0993_i_KineticEnergy += AL0995_i_WeaponKineticEnergy;
+ AL0995_i_SkillLevel = f303_getSkillLevel((ChampionIndex)champIndex, k10_ChampionSkillThrow);
+ L0993_i_KineticEnergy += _vm->_rnd->getRandomNumber(16) + (L0993_i_KineticEnergy >> 1) + AL0995_i_SkillLevel;
+ AL0994_i_Attack = f26_getBoundedValue((uint16)40, (uint16)((AL0995_i_SkillLevel << 3) + _vm->_rnd->getRandomNumber(31)), (uint16)200);
+ AL0995_i_StepEnergy = MAX(5, 11 - AL0995_i_SkillLevel);
+ _vm->_projexpl->f212_projectileCreate(L0996_T_Thing, _vm->_dungeonMan->_g306_partyMapX, _vm->_dungeonMan->_g307_partyMapY,
+ M21_normalizeModulo4(_vm->_dungeonMan->_g308_partyDir + side),
+ _vm->_dungeonMan->_g308_partyDir, L0993_i_KineticEnergy, AL0994_i_Attack, AL0995_i_StepEnergy);
+ _vm->_g311_projectileDisableMovementTicks = 4;
+ _vm->_g312_lastProjectileDisabledMovementDirection = _vm->_dungeonMan->_g308_partyDir;
+ f292_drawChampionState((ChampionIndex)champIndex);
+ return true;
}
uint16 ChampionMan::M27_getChampionPortraitX(uint16 index) {
@@ -138,7 +218,7 @@ Common::String ChampionMan::f288_getStringFromInteger(uint16 val, bool padding,
return result += valToStr;
}
-void ChampionMan::f299_applyModifiersToStatistics(Champion* champ, ChampionSlot slotIndex, IconIndice iconIndex, int16 modifierFactor, Thing thing) {
+void ChampionMan::f299_applyModifiersToStatistics(Champion* champ, int16 slotIndex, int16 iconIndex, int16 modifierFactor, Thing thing) {
int16 statIndex;
int16 modifier = 0;
ThingType thingType = thing.getType();
@@ -266,7 +346,6 @@ T0299044_ApplyModifier:
} else if (statIndex < k6_ChampionStatAntifire + 1) {
for (uint16 statValIndex = k0_ChampionStatMaximum; statValIndex <= k2_ChampionStatMinimum; ++statValIndex) {
champ->getStatistic((ChampionStatisticType)statIndex, (ChampionStatisticValue)statValIndex) += modifier;
- warning("BUG0_38");
}
}
}
@@ -284,7 +363,7 @@ bool ChampionMan::f295_hasObjectIconInSlotBoxChanged(int16 slotBoxIndex, Thing t
if (newIconIndex != currIconIndex) {
if ((slotBoxIndex < k8_SlotBoxInventoryFirstSlot) && !_g420_mousePointerHiddenToDrawChangedObjIconOnScreen) {
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true;
- warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
+ _vm->_eventMan->f77_hideMouse();
}
objMan.f38_drawIconInSlotBox(slotBoxIndex, newIconIndex);
return true;
@@ -312,9 +391,9 @@ void ChampionMan::f296_drawChangedObjectIcons() {
IconIndice iconIndex = objMan.f33_getIconIndex(_g414_leaderHandObject);
if (iconIndex != leaderHandObjIconIndex) {
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true;
- warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
+ _vm->_eventMan->f77_hideMouse();
objMan.f36_extractIconFromBitmap(iconIndex, objMan._g412_objectIconForMousePointer);
- warning("MISSING CODE: F0068_MOUSE_SetPointerToObject");
+ _vm->_eventMan->f68_setPointerToObject(_vm->_objectMan->_g412_objectIconForMousePointer);
_g413_leaderHandObjectIconIndex = iconIndex;
objMan.f34_drawLeaderObjectName(_g414_leaderHandObject);
}
@@ -359,7 +438,7 @@ void ChampionMan::f296_drawChangedObjectIcons() {
}
if (_g420_mousePointerHiddenToDrawChangedObjIconOnScreen)
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+ _vm->_eventMan->f78_showMouse();
}
void ChampionMan::f301_addObjectInSlot(ChampionIndex champIndex, Thing thing, ChampionSlot slotIndex) {
@@ -401,7 +480,7 @@ void ChampionMan::f301_addObjectInSlot(ChampionIndex champIndex, Thing thing, Ch
if (iconIndex = k4_IconIndiceWeaponTorchUnlit) {
((Weapon*)rawObjPtr)->setLit(true);
- warning("MISSING CODE: F0337_INVENTORY_SetDungeonViewPalette");
+ _vm->_inventoryMan->f337_setDungeonViewPalette();
f296_drawChangedObjectIcons();
} else if (isInventoryChampion && (slotIndex == k1_ChampionSlotActionHand) &&
((iconIndex == k144_IconIndiceContainerChestClosed) || ((iconIndex >= k30_IconIndiceScrollOpen) && (iconIndex <= k31_IconIndiceScrollClosed)))) {
@@ -413,7 +492,7 @@ void ChampionMan::f301_addObjectInSlot(ChampionIndex champIndex, Thing thing, Ch
if ((iconIndex >= k12_IconIndiceJunkIllumuletUnequipped) && (iconIndex <= k13_IconIndiceJunkIllumuletEquipped)) {
((Junk*)rawObjPtr)->setChargeCount(1);
_g407_party._magicalLightAmount += g39_LightPowerToLightAmount[2];
- warning("MISSING CODE: F0337_INVENTORY_SetDungeonViewPalette");
+ _vm->_inventoryMan->f337_setDungeonViewPalette();
iconIndex = (IconIndice)(iconIndex + 1);
} else if ((iconIndex >= k10_IconIndiceJunkJewelSymalUnequipped) && (iconIndex <= k11_IconIndiceJunkJewelSymalEquipped)) {
((Junk*)rawObjPtr)->setChargeCount(1);
@@ -449,7 +528,627 @@ int16 ChampionMan::f315_getScentOrdinal(int16 mapX, int16 mapY) {
return 0;
}
-ChampionIndex ChampionMan::f285_getIndexInCell(ViewCell cell) {
+Thing ChampionMan::f298_getObjectRemovedFromLeaderHand() {
+ Thing L0890_T_LeaderHandObject;
+
+
+ _g415_leaderEmptyHanded = true;
+ if ((L0890_T_LeaderHandObject = _g414_leaderHandObject) != Thing::_none) {
+ _g414_leaderHandObject = Thing::_none;
+ _g413_leaderHandObjectIconIndex = kM1_IconIndiceNone;
+ _vm->_eventMan->f78_showMouse();
+ _vm->_objectMan->f35_clearLeaderObjectName();
+ _vm->_eventMan->f69_setMousePointer();
+ _vm->_eventMan->f77_hideMouse();
+ if (_g411_leaderIndex != kM1_ChampionNone) {
+ _gK71_champions[_g411_leaderIndex]._load -= _vm->_dungeonMan->f140_getObjectWeight(L0890_T_LeaderHandObject);
+ setFlag(_gK71_champions[_g411_leaderIndex]._attributes, k0x0200_ChampionAttributeLoad);
+ f292_drawChampionState(_g411_leaderIndex);
+ }
+ }
+ return L0890_T_LeaderHandObject;
+}
+
+uint16 ChampionMan::f312_getStrength(int16 champIndex, int16 slotIndex) {
+ int16 L0935_i_Strength;
+ uint16 L0936_ui_Multiple;
+#define AL0936_ui_ObjectWeight L0936_ui_Multiple
+#define AL0936_ui_SkillLevel L0936_ui_Multiple
+ uint16 L0937_ui_Multiple;
+#define AL0937_ui_OneSixteenthMaximumLoad L0937_ui_Multiple
+#define AL0937_ui_Class L0937_ui_Multiple
+ Thing L0938_T_Thing;
+ Champion* L0939_ps_Champion;
+ WeaponInfo* L0940_ps_WeaponInfo;
+ int16 L0941_i_LoadThreshold;
+
+
+ L0939_ps_Champion = &_gK71_champions[champIndex];
+ L0935_i_Strength = _vm->_rnd->getRandomNumber(15) + L0939_ps_Champion->_statistics[k1_ChampionStatStrength][k1_ChampionStatCurrent];
+ L0938_T_Thing = L0939_ps_Champion->_slots[slotIndex];
+ if ((AL0936_ui_ObjectWeight = _vm->_dungeonMan->f140_getObjectWeight(L0938_T_Thing)) <= (AL0937_ui_OneSixteenthMaximumLoad = f309_getMaximumLoad(L0939_ps_Champion) >> 4)) {
+ L0935_i_Strength += AL0936_ui_ObjectWeight - 12;
+ } else {
+ if (AL0936_ui_ObjectWeight <= (L0941_i_LoadThreshold = AL0937_ui_OneSixteenthMaximumLoad + ((AL0937_ui_OneSixteenthMaximumLoad - 12) >> 1))) {
+ L0935_i_Strength += (AL0936_ui_ObjectWeight - AL0937_ui_OneSixteenthMaximumLoad) >> 1;
+ } else {
+ L0935_i_Strength -= (AL0936_ui_ObjectWeight - L0941_i_LoadThreshold) << 1;
+ }
+ }
+ if (L0938_T_Thing.getType() == k5_WeaponThingType) {
+ L0940_ps_WeaponInfo = _vm->_dungeonMan->f158_getWeaponInfo(L0938_T_Thing);
+ L0935_i_Strength += L0940_ps_WeaponInfo->_strength;
+ AL0936_ui_SkillLevel = 0;
+ AL0937_ui_Class = L0940_ps_WeaponInfo->_class;
+ if ((AL0937_ui_Class == k0_WeaponClassSwingWeapon) || (AL0937_ui_Class == k2_WeaponClassDaggerAndAxes)) {
+ AL0936_ui_SkillLevel = f303_getSkillLevel(champIndex, k4_ChampionSkillSwing);
+ }
+ if ((AL0937_ui_Class != k0_WeaponClassSwingWeapon) && (AL0937_ui_Class < k16_WeaponClassFirstBow)) {
+ AL0936_ui_SkillLevel += f303_getSkillLevel(champIndex, k10_ChampionSkillThrow);
+ }
+ if ((AL0937_ui_Class >= k16_WeaponClassFirstBow) && (AL0937_ui_Class < k112_WeaponClassFirstMagicWeapon)) {
+ AL0936_ui_SkillLevel += f303_getSkillLevel(champIndex, k11_ChampionSkillShoot);
+ }
+ L0935_i_Strength += AL0936_ui_SkillLevel << 1;
+ }
+ L0935_i_Strength = f306_getStaminaAdjustedValue(L0939_ps_Champion, L0935_i_Strength);
+ if (getFlag(L0939_ps_Champion->_wounds, (slotIndex == k0_ChampionSlotReadyHand) ? k0x0001_ChampionWoundReadHand : k0x0002_ChampionWoundActionHand)) {
+ L0935_i_Strength >>= 1;
+ }
+ MAX(1, 2);
+ return f26_getBoundedValue(0, L0935_i_Strength >> 1, 100);
+}
+
+Thing ChampionMan::f300_getObjectRemovedFromSlot(uint16 champIndex, uint16 slotIndex) {
+ Thing L0894_T_Thing;
+ int16 L0895_i_IconIndex;
+ Champion* L0896_ps_Champion;
+ Weapon* L0897_ps_Weapon;
+ bool L0898_B_IsInventoryChampion;
+
+
+ L0896_ps_Champion = &_gK71_champions[champIndex];
+ if (slotIndex >= k30_ChampionSlotChest_1) {
+ L0894_T_Thing = _vm->_inventoryMan->_g425_chestSlots[slotIndex - k30_ChampionSlotChest_1];
+ _vm->_inventoryMan->_g425_chestSlots[slotIndex - k30_ChampionSlotChest_1] = Thing::_none;
+ } else {
+ L0894_T_Thing = L0896_ps_Champion->_slots[slotIndex];
+ L0896_ps_Champion->_slots[slotIndex] = Thing::_none;
+ }
+ if (L0894_T_Thing == Thing::_none) {
+ return Thing::_none;
+ }
+ L0898_B_IsInventoryChampion = (_vm->M0_indexToOrdinal(champIndex) == _vm->_inventoryMan->_g432_inventoryChampionOrdinal);
+ L0895_i_IconIndex = _vm->_objectMan->f33_getIconIndex(L0894_T_Thing);
+ f299_applyModifiersToStatistics(L0896_ps_Champion, slotIndex, L0895_i_IconIndex, -1, L0894_T_Thing); /* Remove objet modifiers */
+ L0897_ps_Weapon = (Weapon*)_vm->_dungeonMan->f156_getThingData(L0894_T_Thing);
+ if (slotIndex == k10_ChampionSlotNeck) {
+ if ((L0895_i_IconIndex >= k12_IconIndiceJunkIllumuletUnequipped) && (L0895_i_IconIndex <= k13_IconIndiceJunkIllumuletEquipped)) {
+ ((Junk*)L0897_ps_Weapon)->setChargeCount(0);
+ _g407_party._magicalLightAmount -= g39_LightPowerToLightAmount[2];
+ _vm->_inventoryMan->f337_setDungeonViewPalette();
+ } else {
+ if ((L0895_i_IconIndex >= k10_IconIndiceJunkJewelSymalUnequipped) && (L0895_i_IconIndex <= k11_IconIndiceJunkJewelSymalEquipped)) {
+ ((Junk*)L0897_ps_Weapon)->setChargeCount(0);
+ }
+ }
+ }
+ f291_drawSlot(champIndex, slotIndex);
+ if (L0898_B_IsInventoryChampion) {
+ setFlag(L0896_ps_Champion->_attributes, k0x4000_ChampionAttributeViewport);
+ }
+ if (slotIndex < k2_ChampionSlotHead) {
+ if (slotIndex == k1_ChampionSlotActionHand) {
+ setFlag(L0896_ps_Champion->_attributes, k0x8000_ChampionAttributeActionHand);
+ if (_g506_actingChampionOrdinal == _vm->M0_indexToOrdinal(champIndex)) {
+ _vm->_menuMan->f388_clearActingChampion();
+ }
+ if ((L0895_i_IconIndex >= k30_IconIndiceScrollOpen) && (L0895_i_IconIndex <= k31_IconIndiceScrollClosed)) {
+ ((Scroll*)L0897_ps_Weapon)->setClosed(true);
+ f296_drawChangedObjectIcons();
+ }
+ }
+ if ((L0895_i_IconIndex >= k4_IconIndiceWeaponTorchUnlit) && (L0895_i_IconIndex <= k7_IconIndiceWeaponTorchLit)) {
+ L0897_ps_Weapon->setLit(false);
+ _vm->_inventoryMan->f337_setDungeonViewPalette();
+ f296_drawChangedObjectIcons();
+ }
+ if (L0898_B_IsInventoryChampion && (slotIndex == k1_ChampionSlotActionHand)) {
+ if (L0895_i_IconIndex == k144_IconIndiceContainerChestClosed) {
+ _vm->_inventoryMan->f334_closeChest();
+ goto T0300011;
+ }
+ if ((L0895_i_IconIndex >= k30_IconIndiceScrollOpen) && (L0895_i_IconIndex <= k31_IconIndiceScrollClosed)) {
+T0300011:
+ setFlag(L0896_ps_Champion->_attributes, k0x0800_ChampionAttributePanel);
+ }
+ }
+ }
+ L0896_ps_Champion->_load -= _vm->_dungeonMan->f140_getObjectWeight(L0894_T_Thing);
+ setFlag(L0896_ps_Champion->_attributes, k0x0200_ChampionAttributeLoad);
+ return L0894_T_Thing;
+}
+
+void ChampionMan::f325_decrementStamine(int16 championIndex, int16 decrement) {
+ int16 L0988_i_Stamina;
+ Champion* L0989_ps_Champion;
+
+
+ if (championIndex == kM1_ChampionNone) {
+ return;
+ }
+ L0989_ps_Champion = &_gK71_champions[championIndex];
+ if ((L0988_i_Stamina = (L0989_ps_Champion->_currStamina -= decrement)) <= 0) {
+ L0989_ps_Champion->_currStamina = 0;
+ f321_addPendingDamageAndWounds_getDamage(championIndex, (-L0988_i_Stamina) >> 1, k0x0000_ChampionWoundNone, k0_attackType_NORMAL);
+ } else {
+ if (L0988_i_Stamina > L0989_ps_Champion->_maxStamina) {
+ L0989_ps_Champion->_currStamina = L0989_ps_Champion->_maxStamina;
+ }
+ }
+ setFlag(L0989_ps_Champion->_attributes, k0x0200_ChampionAttributeLoad | k0x0100_ChampionAttributeStatistics);
+}
+
+int16 ChampionMan::f321_addPendingDamageAndWounds_getDamage(int16 champIndex, int16 attack, int16 allowedWounds, uint16 attackType) {
+ int16 L0976_i_Multiple;
+#define AL0976_i_WoundIndex L0976_i_Multiple
+#define AL0976_i_WisdomFactor L0976_i_Multiple
+#define AL0976_i_AdjustedAttack L0976_i_Multiple
+ uint16 L0977_ui_Defense;
+ uint16 L0978_ui_WoundCount;
+ Champion* L0979_ps_Champion;
+
+ if (attack <= 0)
+ return 0;
+
+ L0979_ps_Champion = &_gK71_champions[champIndex];
+ if (!L0979_ps_Champion->_currHealth) {
+T0321004:
+ return 0;
+ }
+ if (attackType != k0_attackType_NORMAL) {
+ for (L0978_ui_WoundCount = 0, AL0976_i_WoundIndex = k0_ChampionSlotReadyHand, L0977_ui_Defense = 0; AL0976_i_WoundIndex <= k5_ChampionSlotFeet; AL0976_i_WoundIndex++) {
+ if (allowedWounds & (1 << AL0976_i_WoundIndex)) {
+ L0978_ui_WoundCount++;
+ L0977_ui_Defense += f313_getWoundDefense(champIndex, AL0976_i_WoundIndex | ((attackType == k4_attackType_SHARP) ? k0x8000_maskUseSharpDefense : k0x0000_maskDoNotUseSharpDefense));
+ }
+ }
+ if (L0978_ui_WoundCount) {
+ L0977_ui_Defense /= L0978_ui_WoundCount;
+ }
+ switch (attackType) {
+ case k6_attackType_PSYCHIC:
+ if ((AL0976_i_WisdomFactor = 115 - L0979_ps_Champion->_statistics[k3_ChampionStatWisdom][k1_ChampionStatCurrent]) <= 0) {
+ attack = 0;
+ } else {
+ attack = _vm->f30_getScaledProduct(attack, 6, AL0976_i_WisdomFactor);
+ }
+ goto T0321024;
+ case k5_attackType_MAGIC:
+ attack = f307_getStatisticAdjustedAttack(L0979_ps_Champion, k5_ChampionStatAntimagic, attack);
+ attack -= _g407_party._spellShieldDefense;
+ goto T0321024;
+ case k1_attackType_FIRE:
+ attack = f307_getStatisticAdjustedAttack(L0979_ps_Champion, k6_ChampionStatAntifire, attack);
+ attack -= _g407_party._fireShieldDefense;
+ break;
+ case k2_attackType_SELF:
+ L0977_ui_Defense >>= 1;
+ case k3_attackType_BLUNT:
+ case k4_attackType_SHARP:
+ case k7_attackType_LIGHTNING:
+ ;
+ }
+ if (attack <= 0)
+ goto T0321004;
+ attack = _vm->f30_getScaledProduct(attack, 6, 130 - L0977_ui_Defense);
+ /* BUG0_44 A champion may take much more damage than expected after a Black Flame attack or an impact
+ with a Fireball projectile. If the party has a fire shield defense value higher than the fire attack value then the resulting intermediary
+ attack value is negative and damage should be 0. However, the negative value is still used for further computations and the result may be a very
+ high positive attack value which may kill a champion. This can occur only for k1_attackType_FIRE and if attack is negative before calling F0030_MAIN_GetScaledProduct */
+T0321024:
+ if (attack <= 0)
+ goto T0321004;
+ if (attack > (AL0976_i_AdjustedAttack = f307_getStatisticAdjustedAttack(L0979_ps_Champion, k4_ChampionStatVitality, _vm->_rnd->getRandomNumber(127) + 10))) { /* BUG0_45 This bug is not perceptible because of BUG0_41 that ignores Vitality while determining the probability of being wounded. However if it was fixed, the behavior would be the opposite of what it should: the higher the vitality of a champion, the lower the result of F0307_CHAMPION_GetStatisticAdjustedAttack and the more likely the champion could get wounded (because of more iterations in the loop below) */
+ do {
+ setFlag(*(uint16*)&_g410_championPendingWounds[champIndex], (1 << _vm->_rnd->getRandomNumber(7)) & allowedWounds);
+ } while ((attack > (AL0976_i_AdjustedAttack <<= 1)) && AL0976_i_AdjustedAttack);
+ }
+ if (_g300_partyIsSleeping) {
+ f314_wakeUp();
+ }
+ }
+ _g409_championPendingDamage[champIndex] += attack;
+ return attack;
+}
+
+int16 ChampionMan::f313_getWoundDefense(int16 champIndex, uint16 woundIndex) {
+ static byte g50_woundDefenseFactor[6] = {5, 5, 4, 6, 3, 1}; // @ G0050_auc_Graphic562_WoundDefenseFactor
+
+ int16 L0942_i_Multiple;
+#define AL0942_i_SlotIndex L0942_i_Multiple
+#define AL0942_i_WoundDefense L0942_i_Multiple
+ uint16 L0943_ui_ArmourShieldDefense;
+ bool L0944_B_UseSharpDefense;
+ Thing L0945_T_Thing;
+ Champion* L0946_ps_Champion;
+ ArmourInfo* L0947_ps_ArmourInfo;
+
+
+ L0946_ps_Champion = &_gK71_champions[champIndex];
+ if (L0944_B_UseSharpDefense = getFlag(woundIndex, k0x8000_maskUseSharpDefense)) {
+ clearFlag(woundIndex, k0x8000_maskUseSharpDefense);
+ }
+ for (L0943_ui_ArmourShieldDefense = 0, AL0942_i_SlotIndex = k0_ChampionSlotReadyHand; AL0942_i_SlotIndex <= k1_ChampionSlotActionHand; AL0942_i_SlotIndex++) {
+ if ((L0945_T_Thing = L0946_ps_Champion->_slots[AL0942_i_SlotIndex]).getType() == k6_ArmourThingType) {
+ L0947_ps_ArmourInfo = (ArmourInfo*)_vm->_dungeonMan->f156_getThingData(L0945_T_Thing);
+ L0947_ps_ArmourInfo = &g239_ArmourInfo[((Armour*)L0947_ps_ArmourInfo)->getType()];
+ if (getFlag(L0947_ps_ArmourInfo->_attributes, k0x0080_ArmourAttributeIsAShield)) {
+ L0943_ui_ArmourShieldDefense += ((f312_getStrength(champIndex, AL0942_i_SlotIndex) + _vm->_dungeonMan->f143_getArmourDefense(L0947_ps_ArmourInfo, L0944_B_UseSharpDefense)) * g50_woundDefenseFactor[woundIndex]) >> ((AL0942_i_SlotIndex == woundIndex) ? 4 : 5);
+ }
+ }
+ }
+ AL0942_i_WoundDefense = _vm->getRandomNumber((L0946_ps_Champion->_statistics[k4_ChampionStatVitality][k1_ChampionStatCurrent] >> 3) + 1);
+ if (L0944_B_UseSharpDefense) {
+ AL0942_i_WoundDefense >>= 1;
+ }
+ AL0942_i_WoundDefense += L0946_ps_Champion->_actionDefense + L0946_ps_Champion->_shieldDefense + _g407_party._shieldDefense + L0943_ui_ArmourShieldDefense;
+ if ((woundIndex > k1_ChampionSlotActionHand) && ((L0945_T_Thing = L0946_ps_Champion->_slots[woundIndex]).getType() == k6_ArmourThingType)) {
+ L0947_ps_ArmourInfo = (ArmourInfo*)_vm->_dungeonMan->f156_getThingData(L0945_T_Thing);
+ AL0942_i_WoundDefense += _vm->_dungeonMan->f143_getArmourDefense(&g239_ArmourInfo[((Armour*)L0947_ps_ArmourInfo)->getType()], L0944_B_UseSharpDefense);
+ }
+ if (getFlag(L0946_ps_Champion->_wounds, 1 << woundIndex)) {
+ AL0942_i_WoundDefense -= 8 + _vm->getRandomNumber(4);
+ }
+ if (_g300_partyIsSleeping) {
+ AL0942_i_WoundDefense >>= 1;
+ }
+ return f26_getBoundedValue(0, AL0942_i_WoundDefense >> 1, 100);
+}
+
+uint16 ChampionMan::f307_getStatisticAdjustedAttack(Champion* champ, uint16 statIndex, uint16 attack) {
+ int16 L0927_i_Factor;
+
+ if ((L0927_i_Factor = 170 - champ->_statistics[statIndex][k1_ChampionStatCurrent]) < 16) { /* BUG0_41 The Antifire and Antimagic statistics are completely ignored. The Vitality statistic is ignored against poison and to determine the probability of being wounded. Vitality is still used normally to compute the defense against wounds and the speed of health regeneration. A bug in the Megamax C compiler produces wrong machine code for this statement. It always returns 0 for the current statistic value so that L0927_i_Factor = 170 in all cases */
+ return attack >> 3;
+ }
+ return _vm->f30_getScaledProduct(attack, 7, L0927_i_Factor);
+}
+
+void ChampionMan::f314_wakeUp() {
+ _vm->_g321_stopWaitingForPlayerInput = true;
+ _g300_partyIsSleeping = false;
+ _vm->waitMs(10);
+ _vm->_displayMan->f98_drawFloorAndCeiling();
+ _vm->_eventMan->_g441_primaryMouseInput = g447_PrimaryMouseInput_Interface;
+ _vm->_eventMan->_g442_secondaryMouseInput = g448_SecondaryMouseInput_Movement;
+ warning("MISSING CODE: set G0443_ps_PrimaryKeyboardInput");
+ warning("MISSING CODE: G0444_ps_SecondaryKeyboardInput");
+ _vm->_eventMan->f357_discardAllInput();
+ _vm->_menuMan->f457_drawEnabledMenus();
+}
+
+int16 ChampionMan::f305_getThrowingStaminaCost(Thing thing) {
+ int16 L0923_i_Weight;
+ int16 L0924_i_StaminaCost;
+
+
+ L0924_i_StaminaCost = f26_getBoundedValue((int16)1, L0923_i_Weight = _vm->_dungeonMan->f140_getObjectWeight(thing) >> 1, (int16)10);
+ while ((L0923_i_Weight -= 10) > 0) {
+ L0924_i_StaminaCost += L0923_i_Weight >> 1;
+ }
+ return L0924_i_StaminaCost;
+}
+
+void ChampionMan::f330_disableAction(uint16 champIndex, uint16 ticks) {
+ int32 L1001_l_UpdatedEnableActionEventTime;
+ int32 L1002_l_CurrentEnableActionEventTime;
+ int16 L1003_i_EventIndex;
+ Champion* L1004_ps_Champion;
+ TimelineEvent L1005_s_Event;
+
+
+ L1004_ps_Champion = &_gK71_champions[champIndex];
+ L1001_l_UpdatedEnableActionEventTime = _vm->_g313_gameTime + ticks;
+ L1005_s_Event._type = k11_TMEventTypeEnableChampionAction;
+ L1005_s_Event._priority = champIndex;
+ L1005_s_Event._B._slotOrdinal = 0;
+ if ((L1003_i_EventIndex = L1004_ps_Champion->_enableActionEventIndex) >= 0) {
+ L1002_l_CurrentEnableActionEventTime = M30_time(_vm->_timeline->_g370_events[L1003_i_EventIndex]._mapTime);
+ if (L1001_l_UpdatedEnableActionEventTime >= L1002_l_CurrentEnableActionEventTime) {
+ L1001_l_UpdatedEnableActionEventTime += (L1002_l_CurrentEnableActionEventTime - _vm->_g313_gameTime) >> 1;
+ } else {
+ L1001_l_UpdatedEnableActionEventTime = L1002_l_CurrentEnableActionEventTime + (ticks >> 1);
+ }
+ _vm->_timeline->f237_deleteEvent(L1003_i_EventIndex);
+ } else {
+ setFlag(L1004_ps_Champion->_attributes, k0x8000_ChampionAttributeActionHand | k0x0008_ChampionAttributeDisableAction);
+ f292_drawChampionState((ChampionIndex)champIndex);
+ }
+ M33_setMapAndTime(L1005_s_Event._mapTime, _vm->_dungeonMan->_g309_partyMapIndex, L1001_l_UpdatedEnableActionEventTime);
+ L1004_ps_Champion->_enableActionEventIndex = _vm->_timeline->f238_addEventGetEventIndex(&L1005_s_Event);
+}
+
+void ChampionMan::f304_addSkillExperience(uint16 champIndex, uint16 skillIndex, uint16 exp) {
+#define AP0638_ui_SkillLevelAfter exp
+#define AP0638_ui_ChampionColor exp
+ uint16 L0915_ui_Multiple;
+#define AL0915_ui_MapDifficulty L0915_ui_Multiple
+#define AL0915_ui_SkillLevelBefore L0915_ui_Multiple
+#define AL0915_ui_VitalityAmount L0915_ui_Multiple
+#define AL0915_ui_StaminaAmount L0915_ui_Multiple
+ uint16 L0916_ui_BaseSkillIndex;
+ Skill* L0918_ps_Skill;
+ Champion* L0919_ps_Champion;
+ int16 L0920_i_MinorStatisticIncrease;
+ int16 L0921_i_MajorStatisticIncrease;
+ int16 L0922_i_BaseSkillLevel;
+
+
+ warning("potaneitally dangerous cast of uint32 below");
+ if ((skillIndex >= k4_ChampionSkillSwing) && (skillIndex <= k11_ChampionSkillShoot) && ((uint32)_vm->_projexpl->_g361_lastCreatureAttackTime < (_vm->_g313_gameTime - 150))) {
+ exp >>= 1;
+ }
+ if (exp) {
+ if (AL0915_ui_MapDifficulty = _vm->_dungeonMan->_g269_currMap->_difficulty) {
+ exp *= AL0915_ui_MapDifficulty;
+ }
+ L0919_ps_Champion = &_gK71_champions[champIndex];
+ if (skillIndex >= k4_ChampionSkillSwing) {
+ L0916_ui_BaseSkillIndex = (skillIndex - k4_ChampionSkillSwing) >> 2;
+ } else {
+ L0916_ui_BaseSkillIndex = skillIndex;
+ }
+ AL0915_ui_SkillLevelBefore = f303_getSkillLevel(champIndex, L0916_ui_BaseSkillIndex | (k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience));
+ warning("potentially dangerous cast of uint32 below");
+ if ((skillIndex >= k4_ChampionSkillSwing) && ((uint32)_vm->_projexpl->_g361_lastCreatureAttackTime > (_vm->_g313_gameTime - 25))) {
+ exp <<= 1;
+ }
+ L0918_ps_Skill = &L0919_ps_Champion->_skills[skillIndex];
+ L0918_ps_Skill->_experience += exp;
+ if (L0918_ps_Skill->_temporaryExperience < 32000) {
+ L0918_ps_Skill->_temporaryExperience += f26_getBoundedValue(1, exp >> 3, 100);
+ }
+ L0918_ps_Skill = &L0919_ps_Champion->_skills[L0916_ui_BaseSkillIndex];
+ if (skillIndex >= k4_ChampionSkillSwing) {
+ L0918_ps_Skill->_experience += exp;
+ }
+ AP0638_ui_SkillLevelAfter = f303_getSkillLevel(champIndex, L0916_ui_BaseSkillIndex | (k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience));
+ if (AP0638_ui_SkillLevelAfter > AL0915_ui_SkillLevelBefore) {
+ L0922_i_BaseSkillLevel = AP0638_ui_SkillLevelAfter;
+ L0920_i_MinorStatisticIncrease = _vm->getRandomNumber(2);
+ L0921_i_MajorStatisticIncrease = 1 + _vm->getRandomNumber(2);
+ AL0915_ui_VitalityAmount = _vm->getRandomNumber(2); /* For Priest skill, the amount is 0 or 1 for all skill levels */
+ if (L0916_ui_BaseSkillIndex != k2_ChampionSkillPriest) {
+ AL0915_ui_VitalityAmount &= AP0638_ui_SkillLevelAfter; /* For non Priest skills the amount is 0 for even skill levels. The amount is 0 or 1 for odd skill levels */
+ }
+ L0919_ps_Champion->_statistics[k4_ChampionStatVitality][k0_ChampionStatMaximum] += AL0915_ui_VitalityAmount;
+ AL0915_ui_StaminaAmount = L0919_ps_Champion->_maxStamina;
+ L0919_ps_Champion->_statistics[k6_ChampionStatAntifire][k0_ChampionStatMaximum] += _vm->getRandomNumber(2) & ~AP0638_ui_SkillLevelAfter; /* The amount is 0 for odd skill levels. The amount is 0 or 1 for even skill levels */
+ switch (L0916_ui_BaseSkillIndex) {
+ case k0_ChampionSkillFighter:
+ AL0915_ui_StaminaAmount >>= 4;
+ AP0638_ui_SkillLevelAfter *= 3;
+ L0919_ps_Champion->_statistics[k1_ChampionStatStrength][k0_ChampionStatMaximum] += L0921_i_MajorStatisticIncrease;
+ L0919_ps_Champion->_statistics[k2_ChampionStatDexterity][k0_ChampionStatMaximum] += L0920_i_MinorStatisticIncrease;
+ break;
+ case k1_ChampionSkillNinja:
+ AL0915_ui_StaminaAmount /= 21;
+ AP0638_ui_SkillLevelAfter <<= 1;
+ L0919_ps_Champion->_statistics[k1_ChampionStatStrength][k0_ChampionStatMaximum] += L0920_i_MinorStatisticIncrease;
+ L0919_ps_Champion->_statistics[k2_ChampionStatDexterity][k0_ChampionStatMaximum] += L0921_i_MajorStatisticIncrease;
+ break;
+ case k3_ChampionSkillWizard:
+ AL0915_ui_StaminaAmount >>= 5;
+ L0919_ps_Champion->_maxMana += AP0638_ui_SkillLevelAfter + (AP0638_ui_SkillLevelAfter >> 1);
+ L0919_ps_Champion->_statistics[k3_ChampionStatWisdom][k0_ChampionStatMaximum] += L0921_i_MajorStatisticIncrease;
+ goto T0304016;
+ case k2_ChampionSkillPriest:
+ AL0915_ui_StaminaAmount /= 25;
+ L0919_ps_Champion->_maxMana += AP0638_ui_SkillLevelAfter;
+ AP0638_ui_SkillLevelAfter += (AP0638_ui_SkillLevelAfter + 1) >> 1;
+ L0919_ps_Champion->_statistics[k3_ChampionStatWisdom][k0_ChampionStatMaximum] += L0920_i_MinorStatisticIncrease;
+T0304016:
+ if ((L0919_ps_Champion->_maxMana += MIN(_vm->getRandomNumber(4), (uint16)(L0922_i_BaseSkillLevel - 1))) > 900) {
+ L0919_ps_Champion->_maxMana = 900;
+ }
+ L0919_ps_Champion->_statistics[k5_ChampionStatAntimagic][k0_ChampionStatMaximum] += _vm->getRandomNumber(3);
+ }
+ if ((L0919_ps_Champion->_maxHealth += AP0638_ui_SkillLevelAfter + _vm->getRandomNumber((AP0638_ui_SkillLevelAfter >> 1) + 1)) > 999) {
+ L0919_ps_Champion->_maxHealth = 999;
+ }
+ if ((L0919_ps_Champion->_maxStamina += AL0915_ui_StaminaAmount + _vm->getRandomNumber((AL0915_ui_StaminaAmount >> 1) + 1)) > 9999) {
+ L0919_ps_Champion->_maxStamina = 9999;
+ }
+ setFlag(L0919_ps_Champion->_attributes, k0x0100_ChampionAttributeStatistics);
+ f292_drawChampionState((ChampionIndex)champIndex);
+ _vm->_textMan->f51_messageAreaPrintLineFeed();
+ _vm->_textMan->f47_messageAreaPrintMessage((Color)(AP0638_ui_ChampionColor = g46_ChampionColor[champIndex]), L0919_ps_Champion->_name);
+ // TODO: localization
+ _vm->_textMan->f47_messageAreaPrintMessage((Color)AP0638_ui_ChampionColor, " JUST GAINED A ");
+ _vm->_textMan->f47_messageAreaPrintMessage((Color)AP0638_ui_ChampionColor, g417_baseSkillName[L0916_ui_BaseSkillIndex]);
+ _vm->_textMan->f47_messageAreaPrintMessage((Color)AP0638_ui_ChampionColor, " LEVEL!");
+ }
+ }
+}
+
+int16 ChampionMan::f324_damageAll_getDamagedChampionCount(uint16 attack, int16 wounds, int16 attackType) {
+ int16 L0984_i_ChampionIndex;
+ int16 L0985_i_RandomAttack;
+ int16 L0986_i_DamagedChampionCount;
+
+ attack -= (L0985_i_RandomAttack = (attack >> 3) + 1);
+ L0985_i_RandomAttack <<= 1;
+ for (L0986_i_DamagedChampionCount = 0, L0984_i_ChampionIndex = k0_ChampionFirst; L0984_i_ChampionIndex < _g305_partyChampionCount; L0984_i_ChampionIndex++) {
+ if (f321_addPendingDamageAndWounds_getDamage(L0984_i_ChampionIndex, MAX(1, attack + _vm->getRandomNumber(L0985_i_RandomAttack)), wounds, attackType)) { /* Actual attack is attack +/- (attack / 8) */
+ L0986_i_DamagedChampionCount++;
+ }
+ }
+ return L0986_i_DamagedChampionCount;
+}
+
+int16 ChampionMan::f286_getTargetChampionIndex(int16 mapX, int16 mapY, uint16 cell) {
+ uint16 L0838_ui_Counter;
+ int16 L0839_i_ChampionIndex;
+ signed char L0840_auc_OrderedCellsToAttack[4];
+
+
+ if (_g305_partyChampionCount && (M38_distance(mapX, mapY, _vm->_dungeonMan->_g306_partyMapX, _vm->_dungeonMan->_g307_partyMapY) <= 1)) {
+ _vm->_groupMan->f229_setOrderedCellsToAttack(L0840_auc_OrderedCellsToAttack, _vm->_dungeonMan->_g306_partyMapX, _vm->_dungeonMan->_g307_partyMapY, mapX, mapY, cell);
+ for (L0838_ui_Counter = 0; L0838_ui_Counter < 4; L0838_ui_Counter++) {
+ if ((L0839_i_ChampionIndex = f285_getIndexInCell(L0840_auc_OrderedCellsToAttack[L0838_ui_Counter])) >= 0) {
+ return L0839_i_ChampionIndex;
+ }
+ }
+ }
+ return kM1_ChampionNone;
+}
+
+int16 ChampionMan::f311_getDexterity(Champion* champ) {
+ int16 L0934_i_Dexterity;
+
+
+ L0934_i_Dexterity = _vm->getRandomNumber(8) + champ->_statistics[k2_ChampionStatDexterity][k1_ChampionStatCurrent];
+ L0934_i_Dexterity -= ((int32)(L0934_i_Dexterity >> 1) * (int32)champ->_load) / f309_getMaximumLoad(champ);
+ if (_g300_partyIsSleeping) {
+ L0934_i_Dexterity >>= 1;
+ }
+ return f26_getBoundedValue(1 + _vm->getRandomNumber(8), L0934_i_Dexterity >> 1, 100 - _vm->getRandomNumber(8));
+}
+
+bool ChampionMan::f308_isLucky(Champion* champ, uint16 percentage) {
+#define AP0646_ui_IsLucky percentage
+ register unsigned char* L0928_puc_Statistic;
+
+
+ if (_vm->getRandomNumber(2) && (_vm->getRandomNumber(100) > percentage)) {
+ return true;
+ }
+ L0928_puc_Statistic = champ->_statistics[k0_ChampionStatLuck];
+ AP0646_ui_IsLucky = (_vm->getRandomNumber(L0928_puc_Statistic[k1_ChampionStatCurrent]) > percentage);
+ L0928_puc_Statistic[k1_ChampionStatCurrent] = f26_getBoundedValue((int32)L0928_puc_Statistic[k2_ChampionStatMinimum], (int32)L0928_puc_Statistic[k1_ChampionStatCurrent] + (AP0646_ui_IsLucky ? -2 : 2), (int32)L0928_puc_Statistic[k0_ChampionStatMaximum]);
+ return AP0646_ui_IsLucky;
+}
+
+void ChampionMan::f322_championPoison(int16 champIndex, uint16 attack) {
+ TimelineEvent L0980_s_Event;
+ Champion* L0981_ps_Champion;
+
+
+ if ((champIndex == kM1_ChampionNone) || (_vm->M0_indexToOrdinal(champIndex) == _g299_candidateChampionOrdinal)) {
+ return;
+ }
+ L0981_ps_Champion = &_gK71_champions[champIndex];
+ f321_addPendingDamageAndWounds_getDamage(champIndex, MAX(1, attack >> 6), k0x0000_ChampionWoundNone, k0_attackType_NORMAL);
+ setFlag(L0981_ps_Champion->_attributes, k0x0100_ChampionAttributeStatistics);
+ if ((_vm->M0_indexToOrdinal(champIndex) == _vm->_inventoryMan->_g432_inventoryChampionOrdinal) && (_vm->_inventoryMan->_g424_panelContent == k0_PanelContentFoodWaterPoisoned)) {
+ setFlag(L0981_ps_Champion->_attributes, k0x0800_ChampionAttributePanel);
+ }
+ if (--attack) {
+ L0981_ps_Champion->_poisonEventCount++;
+ L0980_s_Event._type = k75_TMEventTypePoisonChampion;
+ L0980_s_Event._priority = champIndex;
+ M33_setMapAndTime(L0980_s_Event._mapTime, _vm->_dungeonMan->_g309_partyMapIndex, _vm->_g313_gameTime + 36);
+ L0980_s_Event._B._attack = attack;
+ _vm->_timeline->f238_addEventGetEventIndex(&L0980_s_Event);
+ }
+ f292_drawChampionState((ChampionIndex)champIndex);
+}
+
+void ChampionMan::f284_setPartyDirection(int16 dir) {
+ int16 L0833_i_ChampionIndex;
+ int16 L0834_i_Delta;
+ Champion* L0835_ps_Champion;
+
+
+ if (dir == _vm->_dungeonMan->_g308_partyDir) {
+ return;
+ }
+ if ((L0834_i_Delta = dir - _vm->_dungeonMan->_g308_partyDir) < 0) {
+ L0834_i_Delta += 4;
+ }
+ L0835_ps_Champion = _gK71_champions;
+ for (L0833_i_ChampionIndex = k0_ChampionFirst; L0833_i_ChampionIndex < _g305_partyChampionCount; L0833_i_ChampionIndex++) {
+ L0835_ps_Champion->_cell = (ViewCell)M21_normalizeModulo4(L0835_ps_Champion->_cell + L0834_i_Delta);
+ L0835_ps_Champion->_dir = (direction)M21_normalizeModulo4(L0835_ps_Champion->_dir + L0834_i_Delta);
+ L0835_ps_Champion++;
+ }
+ _vm->_dungeonMan->_g308_partyDir = (direction)dir;
+ f296_drawChangedObjectIcons();
+}
+
+void ChampionMan::f316_deleteScent(uint16 scentIndex) {
+ uint16 L0953_ui_Count;
+
+ if (L0953_ui_Count = --_g407_party._scentCount - scentIndex) {
+ for (uint16 i = 0; i < L0953_ui_Count; ++i) {
+ _g407_party._scents[scentIndex + i] = _g407_party._scents[scentIndex + i + 1];
+ _g407_party._scentStrengths[scentIndex + i] = _g407_party._scentStrengths[scentIndex + i + 1];
+ }
+ }
+ if (scentIndex < _g407_party._firstScentIndex) {
+ _g407_party._firstScentIndex--;
+ }
+ if (scentIndex < _g407_party._lastScentIndex) {
+ _g407_party._lastScentIndex--;
+ }
+}
+
+void ChampionMan::f317_addScentStrength(int16 mapX, int16 mapY, int32 cycleCount) {
+ int16 L0954_i_ScentIndex;
+ bool L0955_B_Merge;
+ bool L0956_B_CycleCountDefined;
+ Scent* L0957_ps_Scent; /* BUG0_00 Useless code */
+ Scent L0958_s_Scent; /* BUG0_00 Useless code */
+
+
+ if (L0954_i_ScentIndex = _vm->_championMan->_g407_party._scentCount) {
+ if (L0955_B_Merge = getFlag(cycleCount, k0x8000_mergeCycles)) {
+ clearFlag(cycleCount, k0x8000_mergeCycles);
+ }
+ L0958_s_Scent.setMapX(mapX); /* BUG0_00 Useless code */
+ L0958_s_Scent.setMapY(mapY); /* BUG0_00 Useless code */
+ L0958_s_Scent.setMapIndex(_vm->_dungeonMan->_g272_currMapIndex); /* BUG0_00 Useless code */
+ L0957_ps_Scent = _vm->_championMan->_g407_party._scents; /* BUG0_00 Useless code */
+ L0956_B_CycleCountDefined = false;
+ while (L0954_i_ScentIndex--) {
+ if (&*L0957_ps_Scent++ == &L0958_s_Scent) {
+ if (!L0956_B_CycleCountDefined) {
+ L0956_B_CycleCountDefined = true;
+ if (L0955_B_Merge) {
+ cycleCount = MAX((int32)_vm->_championMan->_g407_party._scentStrengths[L0954_i_ScentIndex], cycleCount);
+ } else {
+ cycleCount = MIN(80, _vm->_championMan->_g407_party._scentStrengths[L0954_i_ScentIndex] + cycleCount);
+ }
+ }
+ _vm->_championMan->_g407_party._scentStrengths[L0954_i_ScentIndex] = cycleCount;
+ }
+ }
+ }
+}
+
+void ChampionMan::f297_putObjectInLeaderHand(Thing thing, bool setMousePointer) {
+ if (thing == Thing::_none) {
+ return;
+ }
+ _vm->_championMan->_g415_leaderEmptyHanded = false;
+ _vm->_objectMan->f36_extractIconFromBitmap(_vm->_championMan->_g413_leaderHandObjectIconIndex = _vm->_objectMan->f33_getIconIndex(_vm->_championMan->_g414_leaderHandObject = thing), _vm->_objectMan->_g412_objectIconForMousePointer);
+ _vm->_eventMan->f78_showMouse();
+ _vm->_objectMan->f34_drawLeaderObjectName(thing);
+ if (setMousePointer) {
+ _vm->_g325_setMousePointerToObjectInMainLoop = true;
+ } else {
+ _vm->_eventMan->f68_setPointerToObject(_vm->_objectMan->_g412_objectIconForMousePointer);
+ }
+ _vm->_eventMan->f77_hideMouse();
+ if (_vm->_championMan->_g411_leaderIndex != kM1_ChampionNone) {
+ _vm->_championMan->_gK71_champions[_vm->_championMan->_g411_leaderIndex]._load += _vm->_dungeonMan->f140_getObjectWeight(thing);
+ setFlag(_vm->_championMan->_gK71_champions[_vm->_championMan->_g411_leaderIndex]._attributes, k0x0200_ChampionAttributeLoad);
+ _vm->_championMan->f292_drawChampionState(_vm->_championMan->_g411_leaderIndex);
+ }
+}
+
+ChampionIndex ChampionMan::f285_getIndexInCell(int16 cell) {
for (uint16 i = 0; i < _g305_partyChampionCount; ++i) {
if ((_gK71_champions[i]._cell == cell) && _gK71_champions[i]._currHealth)
return (ChampionIndex)i;
@@ -685,7 +1384,7 @@ void ChampionMan::f287_drawChampionBarGraphs(ChampionIndex champIndex) {
} else {
barGraphHeightArray[barGraphIndex++] = 0;
}
- warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
+ _vm->_eventMan->f78_showMouse();
Box box;
box._x1 = champIndex * k69_ChampionStatusBoxSpacing + 46;
@@ -708,7 +1407,7 @@ void ChampionMan::f287_drawChampionBarGraphs(ChampionIndex champIndex) {
box._x1 += 7;
box._x2 += 7;
}
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+ _vm->_eventMan->f77_hideMouse();
}
@@ -918,7 +1617,7 @@ T0292042_green:
champ->setAttributeFlag((ChampionAttribute)(k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon |
k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport |
k0x8000_ChampionAttributeActionHand), false);
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+ _vm->_eventMan->f78_showMouse();
}
uint16 ChampionMan::M26_championIconIndex(int16 val, direction dir) {
@@ -931,7 +1630,7 @@ void ChampionMan::f290_drawHealthStaminaManaValues(Champion* champ) {
f289_drawHealthOrStaminaOrManaValue(132, champ->_currMana, champ->_maxMana);
}
-void ChampionMan::f291_drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
+void ChampionMan::f291_drawSlot(uint16 champIndex, int16 slotIndex) {
int16 nativeBitmapIndex = -1;
Champion *champ = &_gK71_champions[champIndex];
bool isInventoryChamp = (_vm->_inventoryMan->_g432_inventoryChampionOrdinal == _vm->M0_indexToOrdinal(champIndex));
@@ -950,7 +1649,7 @@ void ChampionMan::f291_drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
if (slotIndex >= k30_ChampionSlotChest_1) {
thing = _vm->_inventoryMan->_g425_chestSlots[slotIndex - k30_ChampionSlotChest_1];
} else {
- thing = champ->getSlot(slotIndex);
+ thing = champ->getSlot((ChampionSlot)slotIndex);
}
SlotBox *slotBox = &_vm->_objectMan->_g30_slotBoxes[slotBoxIndex];
@@ -962,7 +1661,7 @@ void ChampionMan::f291_drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
if (!isInventoryChamp) {
- warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
+ _vm->_eventMan->f77_hideMouse();
}
int16 iconIndex;
@@ -983,10 +1682,8 @@ void ChampionMan::f291_drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
}
}
} else {
- warning("BUG0_35");
iconIndex = _vm->_objectMan->f33_getIconIndex(thing); // BUG0_35
if (isInventoryChamp && (slotIndex == k1_ChampionSlotActionHand) && ((iconIndex == k144_IconIndiceContainerChestClosed) || (iconIndex == k30_IconIndiceScrollOpen))) {
- warning("BUG2_00");
iconIndex++;
} // BUG2_00
if (slotIndex <= k5_ChampionSlotFeet) {
@@ -1016,7 +1713,7 @@ void ChampionMan::f291_drawSlot(uint16 champIndex, ChampionSlot slotIndex) {
_vm->_objectMan->f38_drawIconInSlotBox(slotBoxIndex, iconIndex);
if (!isInventoryChamp) {
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+ _vm->_eventMan->f78_showMouse();
}
}
@@ -1049,7 +1746,7 @@ void ChampionMan::f281_renameChampion(Champion* champ) {
}
}
-uint16 ChampionMan::f303_getSkillLevel(ChampionIndex champIndex, ChampionSkill skillIndex) {
+uint16 ChampionMan::f303_getSkillLevel(int16 champIndex, int16 skillIndex) {
if (_g300_partyIsSleeping)
return 1;
@@ -1057,7 +1754,7 @@ uint16 ChampionMan::f303_getSkillLevel(ChampionIndex champIndex, ChampionSkill s
bool ignoreObjModifiers = skillIndex & k0x4000_IgnoreObjectModifiers;
skillIndex = (ChampionSkill)(skillIndex & ~(ignoreTempExp | ignoreObjModifiers));
Champion *champ = &_gK71_champions[champIndex];
- Skill *skill = &champ->getSkill(skillIndex);
+ Skill *skill = &champ->getSkill((ChampionSkill)skillIndex);
int32 experience = skill->_experience;
if (!ignoreTempExp)