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"
2016-07-07 00:46:51 +02:00
# include "timeline.h"
# include "projexpl.h"
# include "group.h"
2016-07-13 19:51:14 +02:00
# include "movesens.h"
2016-08-26 22:35:29 +02:00
namespace DM {
2016-07-07 00:46:51 +02:00
const char * g417_baseSkillName [ 4 ] = { " FIGHTER " , " NINJA " , " PRIEST " , " WIZARD " } ;
2016-08-26 22:35:29 +02:00
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
2016-07-03 01:06:54 +02:00
/* 30 for champion inventory, 8 for chest */
2016-08-26 22:35:29 +02:00
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-07 00:46:51 +02:00
for ( uint16 i = 0 ; i < 4 ; + + i ) {
_g409_championPendingDamage [ i ] = 0 ;
_g410_championPendingWounds [ i ] = 0 ;
2016-08-26 22:50:01 +02:00
_gK71_champions [ i ] . resetToZero ( ) ;
2016-07-07 00:46:51 +02:00
}
2016-08-26 22:50:01 +02:00
_g305_partyChampionCount = 0 ;
_g303_partyDead = false ;
_g414_leaderHandObject = Thing ( 0 ) ;
_g411_leaderIndex = kM1_ChampionNone ;
2016-07-27 14:24:00 +02:00
_g299_candidateChampionOrdinal = 0 ;
2016-08-26 22:50:01 +02:00
_g300_partyIsSleeping = false ;
_g506_actingChampionOrdinal = 0 ;
_g413_leaderHandObjectIconIndex = ( IconIndice ) 0 ;
_g415_leaderEmptyHanded = false ;
_g407_party . resetToZero ( ) ;
_g514_magicCasterChampionIndex = kM1_ChampionNone ;
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = false ;
2016-07-07 00:46:51 +02:00
}
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 ) {
2016-07-23 19:05:25 +02:00
bool throwingLeaderHandObjectFl = false ;
Thing curThing ;
Champion * curChampion = nullptr ;
Thing actionHandThing ;
2016-07-07 00:46:51 +02:00
if ( slotIndex < 0 ) { /* Throw object in leader hand, which is temporarily placed in action hand */
2016-07-23 19:05:25 +02:00
if ( _g415_leaderEmptyHanded )
2016-07-07 00:46:51 +02:00
return false ;
2016-07-23 19:05:25 +02:00
curThing = f298_getObjectRemovedFromLeaderHand ( ) ;
curChampion = & _gK71_champions [ champIndex ] ;
actionHandThing = curChampion - > getSlot ( k1_ChampionSlotActionHand ) ;
curChampion - > setSlot ( k1_ChampionSlotActionHand , curThing ) ;
2016-07-07 00:46:51 +02:00
slotIndex = k1_ChampionSlotActionHand ;
2016-07-23 19:05:25 +02:00
throwingLeaderHandObjectFl = true ;
2016-07-07 00:46:51 +02:00
}
2016-07-23 19:05:25 +02:00
int16 kineticEnergy = f312_getStrength ( champIndex , slotIndex ) ;
if ( throwingLeaderHandObjectFl ) {
// In this case, curChampion and actionHandThing are set.
curChampion - > setSlot ( ( ChampionSlot ) slotIndex , actionHandThing ) ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-23 19:05:25 +02:00
curThing = f300_getObjectRemovedFromSlot ( champIndex , slotIndex ) ;
if ( curThing = = Thing : : _none )
2016-07-07 00:46:51 +02:00
return false ;
}
2016-07-23 19:05:25 +02:00
2016-07-23 12:54:25 +02:00
_vm - > f064_SOUND_RequestPlay_CPSD ( k16_soundCOMBAT_ATTACK_SKELETON_ANIMATED_ARMOUR_DETH_KNIGHT , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY , k1_soundModePlayIfPrioritized ) ;
2016-07-24 19:56:07 +02:00
f325_decrementStamina ( champIndex , f305_getThrowingStaminaCost ( curThing ) ) ;
2016-07-07 00:46:51 +02:00
f330_disableAction ( champIndex , 4 ) ;
2016-07-23 19:05:25 +02:00
int16 experience = 8 ;
int16 weaponKineticEnergy = 1 ;
if ( curThing . getType ( ) = = k5_WeaponThingType ) {
experience + = 4 ;
WeaponInfo * curWeapon = _vm - > _dungeonMan - > f158_getWeaponInfo ( curThing ) ;
if ( curWeapon - > _class < = k12_WeaponClassPoisinDart ) {
weaponKineticEnergy = curWeapon - > _kineticEnergy ;
experience + = weaponKineticEnergy > > 2 ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-23 19:05:25 +02:00
f304_addSkillExperience ( champIndex , k10_ChampionSkillThrow , experience ) ;
kineticEnergy + = weaponKineticEnergy ;
int16 skillLevel = f303_getSkillLevel ( ( ChampionIndex ) champIndex , k10_ChampionSkillThrow ) ;
2016-07-26 13:24:48 +02:00
kineticEnergy + = _vm - > getRandomNumber ( 16 ) + ( kineticEnergy > > 1 ) + skillLevel ;
int16 attack = f26_getBoundedValue ( ( uint16 ) 40 , ( uint16 ) ( ( skillLevel < < 3 ) + _vm - > getRandomNumber ( 32 ) ) , ( uint16 ) 200 ) ;
2016-07-23 19:05:25 +02:00
int16 stepEnergy = MAX ( 5 , 11 - skillLevel ) ;
_vm - > _projexpl - > f212_projectileCreate ( curThing , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY ,
2016-08-26 22:50:30 +02:00
M21_normalizeModulo4 ( _vm - > _dungeonMan - > _g308_partyDir + side ) ,
2016-07-23 19:05:25 +02:00
_vm - > _dungeonMan - > _g308_partyDir , kineticEnergy , attack , stepEnergy ) ;
2016-07-07 00:46:51 +02:00
_vm - > _g311_projectileDisableMovementTicks = 4 ;
_vm - > _g312_lastProjectileDisabledMovementDirection = _vm - > _dungeonMan - > _g308_partyDir ;
f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
return true ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
uint16 ChampionMan : : M27_getChampionPortraitX ( uint16 index ) {
2016-08-26 22:35:29 +02:00
return ( ( index ) & 0x7 ) < < 5 ;
}
2016-08-26 22:47:44 +02:00
uint16 ChampionMan : : M28_getChampionPortraitY ( uint16 index ) {
2016-08-26 22:35:29 +02:00
return ( ( index ) > > 3 ) * 29 ;
}
2016-08-26 22:47:44 +02:00
int16 ChampionMan : : f279_getDecodedValue ( char * string , uint16 characterCount ) {
2016-08-26 22:35:29 +02:00
int val = 0 ;
for ( uint16 i = 0 ; i < characterCount ; + + i ) {
val = ( val < < 4 ) + ( string [ i ] - ' A ' ) ;
}
return val ;
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f289_drawHealthOrStaminaOrManaValue ( int16 posY , int16 currVal , int16 maxVal ) {
2016-07-10 12:46:14 +02:00
Common : : String tmp = f288_getStringFromInteger ( currVal , true , 3 ) ;
2016-08-26 22:47:44 +02:00
_vm - > _textMan - > f52_printToViewport ( 55 , posY , k13_ColorLightestGray , tmp . c_str ( ) ) ;
_vm - > _textMan - > f52_printToViewport ( 73 , posY , k13_ColorLightestGray , " / " ) ;
tmp = f288_getStringFromInteger ( maxVal , true , 3 ) ;
_vm - > _textMan - > f52_printToViewport ( 79 , posY , k13_ColorLightestGray , tmp . c_str ( ) ) ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
uint16 ChampionMan : : M70_handSlotIndex ( uint16 slotBoxIndex ) {
2016-06-28 23:16:34 +02:00
return slotBoxIndex & 0x1 ;
}
2016-08-26 22:47:44 +02:00
Common : : String ChampionMan : : f288_getStringFromInteger ( uint16 val , bool padding , uint16 paddingCharCount ) {
2016-07-23 19:05:25 +02:00
Common : : String valToStr = Common : : String : : format ( " %d " , val ) ;
Common : : String result ;
2016-07-23 19:07:39 +02:00
if ( padding ) {
for ( int16 i = 0 , end = paddingCharCount - valToStr . size ( ) ; i < end ; + + i )
result + = ' ' ;
}
2016-08-26 22:35:29 +02:00
return result + = valToStr ;
}
2016-07-24 19:21:45 +02:00
void ChampionMan : : f299_applyModifiersToStatistics ( Champion * champ , int16 slotIndex , int16 iconIndex , int16 modifierFactor , Thing thing ) {
2016-07-23 19:39:47 +02:00
int16 statIndex = k0_ChampionStatLuck ;
2016-06-28 19:33:46 +02:00
int16 modifier = 0 ;
ThingType thingType = thing . getType ( ) ;
2016-07-23 19:39:47 +02:00
bool cursed = false ;
2016-07-28 17:53:42 +02:00
if ( ( ( thingType = = k5_WeaponThingType ) | | ( thingType = = k6_ArmourThingType ) )
2016-07-23 19:39:47 +02:00
& & ( slotIndex > = k0_ChampionSlotReadyHand ) & & ( slotIndex < = k12_ChampionSlotQuiverLine_1_1 ) ) {
if ( thingType = = k5_WeaponThingType ) {
Weapon * weapon = ( Weapon * ) _vm - > _dungeonMan - > f156_getThingData ( thing ) ;
cursed = weapon - > getCursed ( ) ;
} else {
// k6_ArmourThingType
Armour * armour = ( Armour * ) _vm - > _dungeonMan - > f156_getThingData ( thing ) ;
cursed = armour - > getCursed ( ) ;
}
if ( cursed ) {
2016-07-02 01:55:48 +02:00
statIndex = k0_ChampionStatLuck ;
2016-06-28 19:33:46 +02:00
modifier = - 3 ;
}
}
2016-07-23 19:39:47 +02:00
if ( ! cursed ) {
statIndex = ( ChampionStatisticType ) thingType ; // variable sharing
2016-06-28 19:33:46 +02:00
2016-07-23 19:39:47 +02:00
if ( ( iconIndex = = k137_IconIndiceJunkRabbitsFoot ) & & ( slotIndex < k30_ChampionSlotChest_1 ) ) {
statIndex = k0_ChampionStatLuck ;
modifier = 10 ;
} else if ( slotIndex = = k1_ChampionSlotActionHand ) {
if ( iconIndex = = k45_IconIndiceWeaponMaceOfOrder ) {
statIndex = k1_ChampionStatStrength ;
modifier = 5 ;
2016-06-28 19:33:46 +02:00
} else {
2016-07-23 19:39:47 +02:00
statIndex = k8_ChampionStatMana ;
if ( ( iconIndex > = k20_IconIndiceWeaponStaffOfClawsEmpty ) & & ( iconIndex < = k22_IconIndiceWeaponStaffOfClawsFull ) ) {
2016-06-28 19:33:46 +02:00
modifier = 4 ;
2016-07-23 19:39:47 +02:00
} else {
switch ( iconIndex ) {
case k38_IconIndiceWeaponDeltaSideSplitter :
modifier = 1 ;
break ;
case k41_IconIndiceWeaponTheInquisitorDragonFang :
modifier = 2 ;
break ;
case k40_IconIndiceWeaponVorpalBlade :
modifier = 4 ;
break ;
case k58_IconIndiceWeaponStaff :
modifier = 2 ;
break ;
case k59_IconIndiceWeaponWand :
modifier = 1 ;
break ;
case k60_IconIndiceWeaponTeowand :
modifier = 6 ;
break ;
case k61_IconIndiceWeaponYewStaff :
modifier = 4 ;
break ;
case k62_IconIndiceWeaponStaffOfManarStaffOfIrra :
modifier = 10 ;
break ;
case k63_IconIndiceWeaponSnakeStaffCrossOfNeta :
modifier = 8 ;
break ;
case k64_IconIndiceWeaponTheConduitSerpentStaff :
modifier = 16 ;
break ;
case k65_IconIndiceWeaponDragonSpit :
modifier = 7 ;
break ;
case k66_IconIndiceWeaponSceptreOfLyf :
modifier = 5 ;
break ;
default :
break ;
}
2016-06-28 19:33:46 +02:00
}
2016-07-23 19:39:47 +02:00
}
} else if ( slotIndex = = k4_ChampionSlotLegs ) {
if ( iconIndex = = k142_IconIndiceArmourPowertowers ) {
statIndex = k1_ChampionStatStrength ;
modifier = 10 ;
}
} else if ( slotIndex = = k2_ChampionSlotHead ) {
switch ( iconIndex ) {
case k104_IconIndiceArmourCrownOfNerra :
statIndex = k3_ChampionStatWisdom ;
modifier = 10 ;
break ;
case k140_IconIndiceArmourDexhelm :
statIndex = k2_ChampionStatDexterity ;
modifier = 10 ;
break ;
default :
break ;
}
} else if ( slotIndex = = k3_ChampionSlotTorso ) {
switch ( iconIndex ) {
case k141_IconIndiceArmourFlamebain :
statIndex = k6_ChampionStatAntifire ;
modifier = 12 ;
break ;
case k81_IconIndiceArmourCloakOfNight :
statIndex = k2_ChampionStatDexterity ;
modifier = 8 ;
break ;
default :
break ;
}
} else if ( slotIndex = = k10_ChampionSlotNeck ) {
switch ( iconIndex ) {
case k10_IconIndiceJunkJewelSymalUnequipped :
case k11_IconIndiceJunkJewelSymalEquipped :
statIndex = k5_ChampionStatAntimagic ;
modifier = 15 ;
break ;
case k81_IconIndiceArmourCloakOfNight :
statIndex = k2_ChampionStatDexterity ;
modifier = 8 ;
break ;
case k122_IconIndiceJunkMoonstone :
statIndex = k8_ChampionStatMana ;
modifier = 3 ;
break ;
default :
break ;
}
2016-06-28 19:33:46 +02:00
}
}
if ( modifier ) {
modifier * = modifierFactor ;
2016-07-23 19:39:47 +02:00
//statIndex is set when modifier is set
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 ;
}
}
}
}
2016-08-26 22:47:44 +02:00
bool ChampionMan : : f295_hasObjectIconInSlotBoxChanged ( int16 slotBoxIndex , Thing thing ) {
2016-06-28 20:33:04 +02:00
ObjectMan & objMan = * _vm - > _objectMan ;
2016-08-26 22:47:44 +02:00
IconIndice currIconIndex = objMan . f39_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-08-26 22:47:44 +02:00
IconIndice newIconIndex = objMan . f33_getIconIndex ( thing ) ;
2016-06-28 20:33:04 +02:00
if ( newIconIndex ! = currIconIndex ) {
2016-07-02 12:57:31 +02:00
if ( ( slotBoxIndex < k8_SlotBoxInventoryFirstSlot ) & & ! _g420_mousePointerHiddenToDrawChangedObjIconOnScreen ) {
2016-07-02 01:55:48 +02:00
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true ;
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-06-28 20:33:04 +02:00
}
2016-08-26 22:47:44 +02:00
objMan . f38_drawIconInSlotBox ( slotBoxIndex , newIconIndex ) ;
2016-06-28 20:33:04 +02:00
return true ;
}
}
return false ;
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f296_drawChangedObjectIcons ( ) {
2016-06-28 23:16:34 +02:00
InventoryMan & invMan = * _vm - > _inventoryMan ;
ObjectMan & objMan = * _vm - > _objectMan ;
MenuMan & menuMan = * _vm - > _menuMan ;
2016-07-02 12:57:31 +02:00
uint16 invChampOrdinal = invMan . _g432_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 ) ) {
2016-08-26 22:47:44 +02:00
IconIndice iconIndex = objMan . f33_getIconIndex ( _g414_leaderHandObject ) ;
2016-06-28 23:16:34 +02:00
if ( iconIndex ! = leaderHandObjIconIndex ) {
2016-07-02 01:55:48 +02:00
_g420_mousePointerHiddenToDrawChangedObjIconOnScreen = true ;
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:47:44 +02:00
objMan . f36_extractIconFromBitmap ( iconIndex , objMan . _g412_objectIconForMousePointer ) ;
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f68_setPointerToObject ( _vm - > _objectMan - > _g412_objectIconForMousePointer ) ;
2016-07-02 01:55:48 +02:00
_g413_leaderHandObjectIconIndex = iconIndex ;
2016-08-26 22:47:44 +02:00
objMan . f34_drawLeaderObjectName ( _g414_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-08-26 22:47:44 +02:00
if ( invChampOrdinal = = _vm - > M0_indexToOrdinal ( champIndex ) )
2016-06-28 23:16:34 +02:00
continue ;
2016-08-26 22:47:44 +02:00
if ( f295_hasObjectIconInSlotBoxChanged ( slotBoxIndex , _gK71_champions [ champIndex ] . getSlot ( ( ChampionSlot ) M70_handSlotIndex ( slotBoxIndex ) ) )
& & ( M70_handSlotIndex ( slotBoxIndex ) = = k1_ChampionSlotActionHand ) ) {
2016-06-28 23:16:34 +02:00
2016-08-26 22:47:44 +02:00
menuMan . f386_drawActionIcon ( ( ChampionIndex ) champIndex ) ;
2016-06-28 23:16:34 +02:00
}
}
if ( invChampOrdinal ) {
2016-08-26 22:47:44 +02:00
Champion * champ = & _gK71_champions [ _vm - > M1_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-08-26 22:47:44 +02:00
uint16 objIconChanged = f295_hasObjectIconInSlotBoxChanged ( slotIndex + k8_SlotBoxInventoryFirstSlot , * thing ) ? 1 : 0 ;
2016-06-28 23:16:34 +02:00
drawViewport | = objIconChanged ;
2016-07-02 01:55:48 +02:00
if ( objIconChanged & & ( slotIndex = = k1_ChampionSlotActionHand ) ) {
2016-08-26 22:47:44 +02:00
menuMan . f386_drawActionIcon ( ( ChampionIndex ) _vm - > M1_ordinalToIndex ( invChampOrdinal ) ) ;
2016-06-28 23:16:34 +02:00
}
}
2016-07-02 12:57:31 +02:00
if ( invMan . _g424_panelContent = k4_PanelContentChest ) {
thing = invMan . _g425_chestSlots ;
2016-06-28 23:16:34 +02:00
for ( int16 slotIndex = 0 ; slotIndex < 8 ; + + slotIndex , thing + + ) {
2016-08-26 22:47:44 +02:00
drawViewport | = ( f295_hasObjectIconInSlotBoxChanged ( slotIndex + k38_SlotBoxChestFirstSlot , * thing ) ? 1 : 0 ) ;
2016-06-28 23:16:34 +02:00
}
}
if ( drawViewport ) {
2016-07-02 01:55:48 +02:00
champ - > setAttributeFlag ( k0x4000_ChampionAttributeViewport , true ) ;
2016-08-26 22:47:44 +02:00
f292_drawChampionState ( ( ChampionIndex ) _vm - > M1_ordinalToIndex ( invChampOrdinal ) ) ;
2016-06-28 23:16:34 +02:00
}
}
2016-07-02 01:55:48 +02:00
if ( _g420_mousePointerHiddenToDrawChangedObjIconOnScreen )
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-06-28 23:16:34 +02:00
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f301_addObjectInSlot ( ChampionIndex champIndex , Thing thing , ChampionSlot slotIndex ) {
2016-06-29 00:23:40 +02:00
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 ;
2016-08-26 22:47:44 +02:00
Champion * champ = & _gK71_champions [ champIndex ] ;
2016-06-29 00:23:40 +02:00
2016-07-02 01:55:48 +02:00
if ( slotIndex > = k30_ChampionSlotChest_1 ) {
2016-07-02 12:57:31 +02:00
invMan . _g425_chestSlots [ slotIndex - k30_ChampionSlotChest_1 ] = thing ;
2016-06-29 00:23:40 +02:00
} else {
champ - > setSlot ( slotIndex , thing ) ;
}
2016-08-26 22:47:44 +02:00
champ - > _load + = dunMan . f140_getObjectWeight ( thing ) ;
2016-07-02 01:55:48 +02:00
champ - > setAttributeFlag ( k0x0200_ChampionAttributeLoad , true ) ;
2016-08-26 22:47:44 +02:00
IconIndice iconIndex = objMan . f33_getIconIndex ( thing ) ;
bool isInventoryChampion = ( _vm - > M0_indexToOrdinal ( champIndex ) = = invMan . _g432_inventoryChampionOrdinal ) ;
2016-07-03 21:12:47 +02:00
f299_applyModifiersToStatistics ( champ , slotIndex , iconIndex , 1 , thing ) ;
2016-08-26 22:47:44 +02:00
uint16 * rawObjPtr = dunMan . f156_getThingData ( thing ) ;
2016-06-29 00:23:40 +02:00
2016-07-02 01:55:48 +02:00
if ( slotIndex < k2_ChampionSlotHead ) {
if ( slotIndex = = k1_ChampionSlotActionHand ) {
champ - > setAttributeFlag ( k0x8000_ChampionAttributeActionHand , true ) ;
2016-08-26 22:47:44 +02:00
if ( _g506_actingChampionOrdinal = = _vm - > M0_indexToOrdinal ( champIndex ) )
menuMan . f388_clearActingChampion ( ) ;
2016-06-29 00:23:40 +02:00
2016-07-02 01:55:48 +02:00
if ( ( iconIndex > = k30_IconIndiceScrollOpen ) & & ( iconIndex < = k31_IconIndiceScrollClosed ) ) {
2016-07-07 23:27:13 +02:00
( ( Scroll * ) rawObjPtr ) - > setClosed ( false ) ;
2016-08-26 22:47:44 +02:00
f296_drawChangedObjectIcons ( ) ;
2016-06-29 00:23:40 +02:00
}
}
2016-07-02 01:55:48 +02:00
if ( iconIndex = k4_IconIndiceWeaponTorchUnlit ) {
2016-07-07 23:27:13 +02:00
( ( Weapon * ) rawObjPtr ) - > setLit ( true ) ;
2016-07-07 00:46:51 +02:00
_vm - > _inventoryMan - > f337_setDungeonViewPalette ( ) ;
2016-08-26 22:47:44 +02:00
f296_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 ) {
if ( ( iconIndex > = k12_IconIndiceJunkIllumuletUnequipped ) & & ( iconIndex < = k13_IconIndiceJunkIllumuletEquipped ) ) {
2016-07-07 23:27:13 +02:00
( ( Junk * ) rawObjPtr ) - > setChargeCount ( 1 ) ;
2016-07-02 01:55:48 +02:00
_g407_party . _magicalLightAmount + = g39_LightPowerToLightAmount [ 2 ] ;
2016-07-07 00:46:51 +02:00
_vm - > _inventoryMan - > f337_setDungeonViewPalette ( ) ;
2016-07-03 01:06:54 +02:00
iconIndex = ( IconIndice ) ( iconIndex + 1 ) ;
2016-07-02 01:55:48 +02:00
} else if ( ( iconIndex > = k10_IconIndiceJunkJewelSymalUnequipped ) & & ( iconIndex < = k11_IconIndiceJunkJewelSymalEquipped ) ) {
2016-07-07 23:27:13 +02:00
( ( Junk * ) rawObjPtr ) - > setChargeCount ( 1 ) ;
2016-07-03 01:06:54 +02:00
iconIndex = ( IconIndice ) ( iconIndex + 1 ) ;
2016-06-29 00:23:40 +02:00
}
}
2016-08-26 22:47:44 +02:00
f291_drawSlot ( champIndex , slotIndex ) ;
2016-06-29 00:23:40 +02:00
if ( isInventoryChampion )
2016-07-02 01:55:48 +02:00
champ - > setAttributeFlag ( k0x4000_ChampionAttributeViewport , true ) ;
2016-06-29 00:23:40 +02:00
}
2016-07-04 20:54:17 +02:00
int16 ChampionMan : : f315_getScentOrdinal ( int16 mapX , int16 mapY ) {
2016-08-26 22:50:17 +02:00
int16 scentIndex = _g407_party . _scentCount ;
2016-07-04 20:54:17 +02:00
2016-08-26 22:50:17 +02:00
if ( scentIndex ) {
Scent searchedScent ;
2016-07-04 20:54:17 +02:00
searchedScent . setMapX ( mapX ) ;
searchedScent . setMapY ( mapY ) ;
searchedScent . setMapIndex ( _vm - > _dungeonMan - > _g272_currMapIndex ) ;
2016-08-26 22:50:17 +02:00
uint16 searchedScentRedEagle = searchedScent . toUint16 ( ) ;
2016-07-24 19:21:45 +02:00
Scent * scent = & _g407_party . _scents [ scentIndex - - ] ;
2016-07-04 20:54:17 +02:00
do {
if ( ( * ( - - scent ) ) . toUint16 ( ) = = searchedScentRedEagle ) {
return _vm - > M0_indexToOrdinal ( scentIndex ) ;
}
} while ( scentIndex - - ) ;
}
return 0 ;
}
2016-07-07 00:46:51 +02:00
Thing ChampionMan : : f298_getObjectRemovedFromLeaderHand ( ) {
_g415_leaderEmptyHanded = true ;
2016-07-24 19:21:45 +02:00
Thing leaderHandObject = _g414_leaderHandObject ;
if ( leaderHandObject ! = Thing : : _none ) {
2016-07-07 00:46:51 +02:00
_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 ) {
2016-07-24 19:21:45 +02:00
_gK71_champions [ _g411_leaderIndex ] . _load - = _vm - > _dungeonMan - > f140_getObjectWeight ( leaderHandObject ) ;
2016-07-07 00:46:51 +02:00
setFlag ( _gK71_champions [ _g411_leaderIndex ] . _attributes , k0x0200_ChampionAttributeLoad ) ;
f292_drawChampionState ( _g411_leaderIndex ) ;
}
}
2016-07-24 19:21:45 +02:00
return leaderHandObject ;
2016-07-07 00:46:51 +02:00
}
uint16 ChampionMan : : f312_getStrength ( int16 champIndex , int16 slotIndex ) {
2016-07-24 19:21:45 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
2016-07-26 13:24:48 +02:00
int16 strength = _vm - > getRandomNumber ( 16 ) + curChampion - > _statistics [ k1_ChampionStatStrength ] [ k1_ChampionStatCurrent ] ;
2016-07-24 19:21:45 +02:00
Thing curThing = curChampion - > _slots [ slotIndex ] ;
uint16 objectWeight = _vm - > _dungeonMan - > f140_getObjectWeight ( curThing ) ;
uint16 oneSixteenthMaximumLoad = f309_getMaximumLoad ( curChampion ) > > 4 ;
if ( objectWeight < = oneSixteenthMaximumLoad ) {
strength + = objectWeight - 12 ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-24 19:21:45 +02:00
int16 loadThreshold = oneSixteenthMaximumLoad + ( ( oneSixteenthMaximumLoad - 12 ) > > 1 ) ;
if ( objectWeight < = loadThreshold ) {
strength + = ( objectWeight - oneSixteenthMaximumLoad ) > > 1 ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-24 19:21:45 +02:00
strength - = ( objectWeight - loadThreshold ) < < 1 ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-24 19:21:45 +02:00
if ( curThing . getType ( ) = = k5_WeaponThingType ) {
WeaponInfo * weaponInfo = _vm - > _dungeonMan - > f158_getWeaponInfo ( curThing ) ;
strength + = weaponInfo - > _strength ;
uint16 skillLevel = 0 ;
uint16 weaponClass = weaponInfo - > _class ;
if ( ( weaponClass = = k0_WeaponClassSwingWeapon ) | | ( weaponClass = = k2_WeaponClassDaggerAndAxes ) ) {
skillLevel = f303_getSkillLevel ( champIndex , k4_ChampionSkillSwing ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:21:45 +02:00
if ( ( weaponClass ! = k0_WeaponClassSwingWeapon ) & & ( weaponClass < k16_WeaponClassFirstBow ) ) {
skillLevel + = f303_getSkillLevel ( champIndex , k10_ChampionSkillThrow ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:21:45 +02:00
if ( ( weaponClass > = k16_WeaponClassFirstBow ) & & ( weaponClass < k112_WeaponClassFirstMagicWeapon ) ) {
skillLevel + = f303_getSkillLevel ( champIndex , k11_ChampionSkillShoot ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:21:45 +02:00
strength + = skillLevel < < 1 ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:21:45 +02:00
strength = f306_getStaminaAdjustedValue ( curChampion , strength ) ;
if ( getFlag ( curChampion - > _wounds , ( slotIndex = = k0_ChampionSlotReadyHand ) ? k0x0001_ChampionWoundReadHand : k0x0002_ChampionWoundActionHand ) ) {
strength > > = 1 ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:21:45 +02:00
return f26_getBoundedValue ( 0 , strength > > 1 , 100 ) ;
2016-07-07 00:46:51 +02:00
}
Thing ChampionMan : : f300_getObjectRemovedFromSlot ( uint16 champIndex , uint16 slotIndex ) {
2016-07-24 19:56:07 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
Thing curThing ;
2016-07-07 00:46:51 +02:00
if ( slotIndex > = k30_ChampionSlotChest_1 ) {
2016-07-24 19:56:07 +02:00
curThing = _vm - > _inventoryMan - > _g425_chestSlots [ slotIndex - k30_ChampionSlotChest_1 ] ;
2016-07-07 00:46:51 +02:00
_vm - > _inventoryMan - > _g425_chestSlots [ slotIndex - k30_ChampionSlotChest_1 ] = Thing : : _none ;
} else {
2016-07-24 19:56:07 +02:00
curThing = curChampion - > _slots [ slotIndex ] ;
curChampion - > _slots [ slotIndex ] = Thing : : _none ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:56:07 +02:00
if ( curThing = = Thing : : _none )
2016-07-07 00:46:51 +02:00
return Thing : : _none ;
2016-07-24 19:56:07 +02:00
bool isInventoryChampion = ( _vm - > M0_indexToOrdinal ( champIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) ;
int16 curIconIndex = _vm - > _objectMan - > f33_getIconIndex ( curThing ) ;
// Remove object modifiers
f299_applyModifiersToStatistics ( curChampion , slotIndex , curIconIndex , - 1 , curThing ) ;
Weapon * curWeapon = ( Weapon * ) _vm - > _dungeonMan - > f156_getThingData ( curThing ) ;
2016-07-07 00:46:51 +02:00
if ( slotIndex = = k10_ChampionSlotNeck ) {
2016-07-24 19:56:07 +02:00
if ( ( curIconIndex > = k12_IconIndiceJunkIllumuletUnequipped ) & & ( curIconIndex < = k13_IconIndiceJunkIllumuletEquipped ) ) {
( ( Junk * ) curWeapon ) - > setChargeCount ( 0 ) ;
2016-07-07 00:46:51 +02:00
_g407_party . _magicalLightAmount - = g39_LightPowerToLightAmount [ 2 ] ;
_vm - > _inventoryMan - > f337_setDungeonViewPalette ( ) ;
2016-07-24 19:56:07 +02:00
} else if ( ( curIconIndex > = k10_IconIndiceJunkJewelSymalUnequipped ) & & ( curIconIndex < = k11_IconIndiceJunkJewelSymalEquipped ) ) {
( ( Junk * ) curWeapon ) - > setChargeCount ( 0 ) ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-24 19:56:07 +02:00
2016-07-07 00:46:51 +02:00
f291_drawSlot ( champIndex , slotIndex ) ;
2016-07-24 19:56:07 +02:00
if ( isInventoryChampion )
setFlag ( curChampion - > _attributes , k0x4000_ChampionAttributeViewport ) ;
2016-07-07 00:46:51 +02:00
if ( slotIndex < k2_ChampionSlotHead ) {
if ( slotIndex = = k1_ChampionSlotActionHand ) {
2016-07-24 19:56:07 +02:00
setFlag ( curChampion - > _attributes , k0x8000_ChampionAttributeActionHand ) ;
if ( _g506_actingChampionOrdinal = = _vm - > M0_indexToOrdinal ( champIndex ) )
2016-07-07 00:46:51 +02:00
_vm - > _menuMan - > f388_clearActingChampion ( ) ;
2016-07-24 19:56:07 +02:00
if ( ( curIconIndex > = k30_IconIndiceScrollOpen ) & & ( curIconIndex < = k31_IconIndiceScrollClosed ) ) {
( ( Scroll * ) curWeapon ) - > setClosed ( true ) ;
2016-07-07 00:46:51 +02:00
f296_drawChangedObjectIcons ( ) ;
}
}
2016-07-24 19:56:07 +02:00
if ( ( curIconIndex > = k4_IconIndiceWeaponTorchUnlit ) & & ( curIconIndex < = k7_IconIndiceWeaponTorchLit ) ) {
curWeapon - > setLit ( false ) ;
2016-07-07 00:46:51 +02:00
_vm - > _inventoryMan - > f337_setDungeonViewPalette ( ) ;
f296_drawChangedObjectIcons ( ) ;
}
2016-07-24 19:56:07 +02:00
if ( isInventoryChampion & & ( slotIndex = = k1_ChampionSlotActionHand ) ) {
switch ( curIconIndex ) {
case k144_IconIndiceContainerChestClosed :
2016-07-07 00:46:51 +02:00
_vm - > _inventoryMan - > f334_closeChest ( ) ;
2016-07-24 19:56:07 +02:00
// No break on purpose
case k30_IconIndiceScrollOpen :
case k31_IconIndiceScrollClosed :
setFlag ( curChampion - > _attributes , k0x0800_ChampionAttributePanel ) ;
break ;
default :
break ;
2016-07-07 00:46:51 +02:00
}
}
}
2016-07-24 19:56:07 +02:00
curChampion - > _load - = _vm - > _dungeonMan - > f140_getObjectWeight ( curThing ) ;
setFlag ( curChampion - > _attributes , k0x0200_ChampionAttributeLoad ) ;
return curThing ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:56:07 +02:00
void ChampionMan : : f325_decrementStamina ( int16 championIndex , int16 decrement ) {
if ( championIndex = = kM1_ChampionNone )
return ;
2016-07-07 00:46:51 +02:00
2016-07-24 19:56:07 +02:00
Champion * curChampion = & _gK71_champions [ championIndex ] ;
curChampion - > _currStamina - = decrement ;
2016-07-07 00:46:51 +02:00
2016-07-24 19:56:07 +02:00
int16 stamina = curChampion - > _currStamina ;
if ( stamina < = 0 ) {
curChampion - > _currStamina = 0 ;
f321_addPendingDamageAndWounds_getDamage ( championIndex , ( - stamina ) > > 1 , k0x0000_ChampionWoundNone , k0_attackType_NORMAL ) ;
} else if ( stamina > curChampion - > _maxStamina ) {
curChampion - > _currStamina = curChampion - > _maxStamina ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 19:56:07 +02:00
setFlag ( curChampion - > _attributes , k0x0200_ChampionAttributeLoad | k0x0100_ChampionAttributeStatistics ) ;
2016-07-07 00:46:51 +02:00
}
int16 ChampionMan : : f321_addPendingDamageAndWounds_getDamage ( int16 champIndex , int16 attack , int16 allowedWounds , uint16 attackType ) {
if ( attack < = 0 )
return 0 ;
2016-07-24 21:18:10 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
if ( ! curChampion - > _currHealth )
2016-07-07 00:46:51 +02:00
return 0 ;
2016-07-24 19:56:07 +02:00
2016-07-24 23:57:47 +02:00
bool skipScaling = false ;
2016-07-07 00:46:51 +02:00
if ( attackType ! = k0_attackType_NORMAL ) {
2016-07-24 21:18:10 +02:00
uint16 defense = 0 ;
uint16 woundCount = 0 ;
for ( int16 woundIndex = k0_ChampionSlotReadyHand ; woundIndex < = k5_ChampionSlotFeet ; woundIndex + + ) {
if ( allowedWounds & ( 1 < < woundIndex ) ) {
woundCount + + ;
defense + = f313_getWoundDefense ( champIndex , woundIndex | ( ( attackType = = k4_attackType_SHARP ) ? k0x8000_maskUseSharpDefense : k0x0000_maskDoNotUseSharpDefense ) ) ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-24 21:18:10 +02:00
if ( woundCount )
defense / = woundCount ;
2016-07-07 00:46:51 +02:00
switch ( attackType ) {
2016-07-28 17:53:42 +02:00
case k6_attackType_PSYCHIC :
{
int16 wisdomFactor = 115 - curChampion - > _statistics [ k3_ChampionStatWisdom ] [ k1_ChampionStatCurrent ] ;
if ( wisdomFactor < = 0 ) {
attack = 0 ;
} else {
attack = _vm - > f30_getScaledProduct ( attack , 6 , wisdomFactor ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-28 17:53:42 +02:00
skipScaling = true ;
}
break ;
2016-07-07 00:46:51 +02:00
case k5_attackType_MAGIC :
2016-07-24 21:18:10 +02:00
attack = f307_getStatisticAdjustedAttack ( curChampion , k5_ChampionStatAntimagic , attack ) ;
2016-07-07 00:46:51 +02:00
attack - = _g407_party . _spellShieldDefense ;
2016-07-24 23:57:47 +02:00
skipScaling = true ;
break ;
2016-07-07 00:46:51 +02:00
case k1_attackType_FIRE :
2016-07-24 21:18:10 +02:00
attack = f307_getStatisticAdjustedAttack ( curChampion , k6_ChampionStatAntifire , attack ) ;
2016-07-07 00:46:51 +02:00
attack - = _g407_party . _fireShieldDefense ;
break ;
case k2_attackType_SELF :
2016-07-24 21:18:10 +02:00
defense > > = 1 ;
break ;
default :
break ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 21:18:10 +02:00
2016-07-24 23:57:47 +02:00
if ( ! skipScaling ) {
if ( attack < = 0 )
return 0 ;
2016-07-24 19:56:07 +02:00
2016-07-24 23:57:47 +02:00
attack = _vm - > f30_getScaledProduct ( attack , 6 , 130 - defense ) ;
}
2016-07-28 17:53:42 +02:00
/* BUG0_44
2016-07-24 21:18:10 +02:00
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
2016-07-28 17:53:42 +02:00
attack value then the resulting intermediary attack value is negative and damage should be 0.
2016-07-24 21:18:10 +02:00
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
*/
2016-07-24 23:57:47 +02:00
2016-07-07 00:46:51 +02:00
if ( attack < = 0 )
2016-07-24 19:56:07 +02:00
return 0 ;
2016-07-26 13:24:48 +02:00
int16 adjustedAttack = f307_getStatisticAdjustedAttack ( curChampion , k4_ChampionStatVitality , _vm - > getRandomNumber ( 128 ) + 10 ) ;
2016-07-24 21:18:10 +02:00
if ( attack > adjustedAttack ) {
/* 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 )
*/
2016-07-07 00:46:51 +02:00
do {
2016-07-26 13:24:48 +02:00
setFlag ( * ( uint16 * ) & _g410_championPendingWounds [ champIndex ] , ( 1 < < _vm - > getRandomNumber ( 8 ) ) & allowedWounds ) ;
2016-07-24 21:18:10 +02:00
} while ( ( attack > ( adjustedAttack < < = 1 ) ) & & adjustedAttack ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-24 21:18:10 +02:00
if ( _g300_partyIsSleeping )
2016-07-07 00:46:51 +02:00
f314_wakeUp ( ) ;
}
_g409_championPendingDamage [ champIndex ] + = attack ;
return attack ;
}
int16 ChampionMan : : f313_getWoundDefense ( int16 champIndex , uint16 woundIndex ) {
2016-07-25 00:20:23 +02:00
static const byte woundDefenseFactor [ 6 ] = { 5 , 5 , 4 , 6 , 3 , 1 } ; // @ G0050_auc_Graphic562_WoundDefenseFactor
2016-07-07 00:46:51 +02:00
2016-07-25 00:20:23 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
bool useSharpDefense = getFlag ( woundIndex , k0x8000_maskUseSharpDefense ) ;
if ( useSharpDefense )
2016-07-07 00:46:51 +02:00
clearFlag ( woundIndex , k0x8000_maskUseSharpDefense ) ;
2016-07-25 00:20:23 +02:00
uint16 armorShieldDefense = 0 ;
for ( int16 slotIndex = k0_ChampionSlotReadyHand ; slotIndex < = k1_ChampionSlotActionHand ; slotIndex + + ) {
Thing curThing = curChampion - > _slots [ slotIndex ] ;
if ( curThing . getType ( ) = = k6_ArmourThingType ) {
ArmourInfo * armorInfo = ( ArmourInfo * ) _vm - > _dungeonMan - > f156_getThingData ( curThing ) ;
armorInfo = & g239_ArmourInfo [ ( ( Armour * ) armorInfo ) - > getType ( ) ] ;
if ( getFlag ( armorInfo - > _attributes , k0x0080_ArmourAttributeIsAShield ) )
armorShieldDefense + = ( ( f312_getStrength ( champIndex , slotIndex ) + _vm - > _dungeonMan - > f143_getArmourDefense ( armorInfo , useSharpDefense ) ) * woundDefenseFactor [ woundIndex ] ) > > ( ( slotIndex = = woundIndex ) ? 4 : 5 ) ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-25 00:20:23 +02:00
int16 woundDefense = _vm - > getRandomNumber ( ( curChampion - > _statistics [ k4_ChampionStatVitality ] [ k1_ChampionStatCurrent ] > > 3 ) + 1 ) ;
if ( useSharpDefense )
woundDefense > > = 1 ;
woundDefense + = curChampion - > _actionDefense + curChampion - > _shieldDefense + _g407_party . _shieldDefense + armorShieldDefense ;
2016-07-28 17:53:42 +02:00
if ( woundIndex > k1_ChampionSlotActionHand ) {
2016-07-25 00:20:23 +02:00
Thing curThing = curChampion - > _slots [ woundIndex ] ;
if ( curThing . getType ( ) = = k6_ArmourThingType ) {
ArmourInfo * armourInfo = ( ArmourInfo * ) _vm - > _dungeonMan - > f156_getThingData ( curThing ) ;
woundDefense + = _vm - > _dungeonMan - > f143_getArmourDefense ( & g239_ArmourInfo [ ( ( Armour * ) armourInfo ) - > getType ( ) ] , useSharpDefense ) ;
}
2016-07-07 00:46:51 +02:00
}
2016-07-25 00:20:23 +02:00
if ( getFlag ( curChampion - > _wounds , 1 < < woundIndex ) )
woundDefense - = 8 + _vm - > getRandomNumber ( 4 ) ;
if ( _g300_partyIsSleeping )
woundDefense > > = 1 ;
return f26_getBoundedValue ( 0 , woundDefense > > 1 , 100 ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 00:37:44 +02:00
uint16 ChampionMan : : f307_getStatisticAdjustedAttack ( Champion * champ , uint16 statIndex , uint16 attack ) {
int16 factor = 170 - champ - > _statistics [ statIndex ] [ k1_ChampionStatCurrent ] ;
/* 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 factor = 170 in all cases
*/
if ( factor < 16 )
2016-07-07 00:46:51 +02:00
return attack > > 3 ;
2016-07-25 00:37:44 +02:00
return _vm - > f30_getScaledProduct ( attack , 7 , factor ) ;
2016-07-07 00:46:51 +02:00
}
void ChampionMan : : f314_wakeUp ( ) {
_vm - > _g321_stopWaitingForPlayerInput = true ;
_g300_partyIsSleeping = false ;
2016-07-12 11:30:25 +02:00
_vm - > _g318_waitForInputMaxVerticalBlankCount = 10 ;
2016-07-11 17:06:24 +02:00
_vm - > f22_delay ( 10 ) ;
2016-07-07 00:46:51 +02:00
_vm - > _displayMan - > f98_drawFloorAndCeiling ( ) ;
_vm - > _eventMan - > _g441_primaryMouseInput = g447_PrimaryMouseInput_Interface ;
_vm - > _eventMan - > _g442_secondaryMouseInput = g448_SecondaryMouseInput_Movement ;
2016-07-11 10:52:38 +02:00
_vm - > _eventMan - > _g443_primaryKeyboardInput = g458_primaryKeyboardInput_interface ;
_vm - > _eventMan - > _g444_secondaryKeyboardInput = g459_secondaryKeyboardInput_movement ;
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f357_discardAllInput ( ) ;
_vm - > _menuMan - > f457_drawEnabledMenus ( ) ;
}
int16 ChampionMan : : f305_getThrowingStaminaCost ( Thing thing ) {
2016-07-25 00:37:44 +02:00
int16 weight = _vm - > _dungeonMan - > f140_getObjectWeight ( thing ) > > 1 ;
int16 staminaCost = f26_getBoundedValue < int16 > ( 1 , weight , 10 ) ;
2016-07-07 00:46:51 +02:00
2016-07-25 00:37:44 +02:00
while ( ( weight - = 10 ) > 0 )
staminaCost + = weight > > 1 ;
2016-07-07 00:46:51 +02:00
2016-07-25 00:37:44 +02:00
return staminaCost ;
2016-07-07 00:46:51 +02:00
}
void ChampionMan : : f330_disableAction ( uint16 champIndex , uint16 ticks ) {
2016-07-25 00:37:44 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
int32 updatedEnableActionEventTime = _vm - > _g313_gameTime + ticks ;
TimelineEvent curEvent ;
curEvent . _type = k11_TMEventTypeEnableChampionAction ;
curEvent . _priority = champIndex ;
curEvent . _B . _slotOrdinal = 0 ;
int16 eventIndex = curChampion - > _enableActionEventIndex ;
if ( eventIndex > = 0 ) {
int32 currentEnableActionEventTime = M30_time ( _vm - > _timeline - > _g370_events [ eventIndex ] . _mapTime ) ;
if ( updatedEnableActionEventTime > = currentEnableActionEventTime ) {
updatedEnableActionEventTime + = ( currentEnableActionEventTime - _vm - > _g313_gameTime ) > > 1 ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-25 00:37:44 +02:00
updatedEnableActionEventTime = currentEnableActionEventTime + ( ticks > > 1 ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 00:37:44 +02:00
_vm - > _timeline - > f237_deleteEvent ( eventIndex ) ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-25 00:37:44 +02:00
setFlag ( curChampion - > _attributes , k0x8000_ChampionAttributeActionHand | k0x0008_ChampionAttributeDisableAction ) ;
2016-07-07 00:46:51 +02:00
f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
}
2016-07-25 00:37:44 +02:00
M33_setMapAndTime ( curEvent . _mapTime , _vm - > _dungeonMan - > _g309_partyMapIndex , updatedEnableActionEventTime ) ;
curChampion - > _enableActionEventIndex = _vm - > _timeline - > f238_addEventGetEventIndex ( & curEvent ) ;
2016-07-07 00:46:51 +02:00
}
void ChampionMan : : f304_addSkillExperience ( uint16 champIndex , uint16 skillIndex , uint16 exp ) {
2016-07-25 08:43:19 +02:00
if ( ( skillIndex > = k4_ChampionSkillSwing ) & & ( skillIndex < = k11_ChampionSkillShoot ) & & ( _vm - > _projexpl - > _g361_lastCreatureAttackTime < _vm - > _g313_gameTime - 150 ) )
2016-07-07 00:46:51 +02:00
exp > > = 1 ;
2016-07-25 08:43:19 +02:00
2016-07-07 00:46:51 +02:00
if ( exp ) {
2016-07-25 08:43:19 +02:00
if ( _vm - > _dungeonMan - > _g269_currMap - > _difficulty )
exp * = _vm - > _dungeonMan - > _g269_currMap - > _difficulty ;
Champion * curChampion = & _gK71_champions [ champIndex ] ;
uint16 baseSkillIndex ;
if ( skillIndex > = k4_ChampionSkillSwing )
baseSkillIndex = ( skillIndex - k4_ChampionSkillSwing ) > > 2 ;
else
baseSkillIndex = skillIndex ;
uint16 skillLevelBefore = f303_getSkillLevel ( champIndex , baseSkillIndex | ( k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience ) ) ;
if ( ( skillIndex > = k4_ChampionSkillSwing ) & & ( _vm - > _projexpl - > _g361_lastCreatureAttackTime > _vm - > _g313_gameTime - 25 ) )
2016-07-07 00:46:51 +02:00
exp < < = 1 ;
2016-07-25 08:43:19 +02:00
Skill * curSkill = & curChampion - > _skills [ skillIndex ] ;
curSkill - > _experience + = exp ;
if ( curSkill - > _temporaryExperience < 32000 )
curSkill - > _temporaryExperience + = f26_getBoundedValue ( 1 , exp > > 3 , 100 ) ;
curSkill = & curChampion - > _skills [ baseSkillIndex ] ;
if ( skillIndex > = k4_ChampionSkillSwing )
curSkill - > _experience + = exp ;
uint16 skillLevelAfter = f303_getSkillLevel ( champIndex , baseSkillIndex | ( k0x4000_IgnoreObjectModifiers | k0x8000_IgnoreTemporaryExperience ) ) ;
if ( skillLevelAfter > skillLevelBefore ) {
int16 newBaseSkillLevel = skillLevelAfter ;
int16 minorStatIncrease = _vm - > getRandomNumber ( 2 ) ;
int16 majorStatIncrease = 1 + _vm - > getRandomNumber ( 2 ) ;
uint16 vitalityAmount = _vm - > getRandomNumber ( 2 ) ; /* For Priest skill, the amount is 0 or 1 for all skill levels */
if ( baseSkillIndex ! = k2_ChampionSkillPriest ) {
vitalityAmount & = skillLevelAfter ; /* For non Priest skills the amount is 0 for even skill levels. The amount is 0 or 1 for odd skill levels */
2016-07-07 00:46:51 +02:00
}
2016-07-25 08:43:19 +02:00
curChampion - > _statistics [ k4_ChampionStatVitality ] [ k0_ChampionStatMaximum ] + = vitalityAmount ;
uint16 staminaAmount = curChampion - > _maxStamina ;
curChampion - > _statistics [ k6_ChampionStatAntifire ] [ k0_ChampionStatMaximum ] + = _vm - > getRandomNumber ( 2 ) & ~ skillLevelAfter ; /* The amount is 0 for odd skill levels. The amount is 0 or 1 for even skill levels */
bool increaseManaFl = false ;
switch ( baseSkillIndex ) {
2016-07-07 00:46:51 +02:00
case k0_ChampionSkillFighter :
2016-07-25 08:43:19 +02:00
staminaAmount > > = 4 ;
skillLevelAfter * = 3 ;
curChampion - > _statistics [ k1_ChampionStatStrength ] [ k0_ChampionStatMaximum ] + = majorStatIncrease ;
curChampion - > _statistics [ k2_ChampionStatDexterity ] [ k0_ChampionStatMaximum ] + = minorStatIncrease ;
2016-07-07 00:46:51 +02:00
break ;
case k1_ChampionSkillNinja :
2016-07-25 08:43:19 +02:00
staminaAmount / = 21 ;
skillLevelAfter < < = 1 ;
curChampion - > _statistics [ k1_ChampionStatStrength ] [ k0_ChampionStatMaximum ] + = minorStatIncrease ;
curChampion - > _statistics [ k2_ChampionStatDexterity ] [ k0_ChampionStatMaximum ] + = majorStatIncrease ;
2016-07-07 00:46:51 +02:00
break ;
case k3_ChampionSkillWizard :
2016-07-25 08:43:19 +02:00
staminaAmount > > = 5 ;
curChampion - > _maxMana + = skillLevelAfter + ( skillLevelAfter > > 1 ) ;
curChampion - > _statistics [ k3_ChampionStatWisdom ] [ k0_ChampionStatMaximum ] + = majorStatIncrease ;
increaseManaFl = true ;
break ;
2016-07-07 00:46:51 +02:00
case k2_ChampionSkillPriest :
2016-07-25 08:43:19 +02:00
staminaAmount / = 25 ;
curChampion - > _maxMana + = skillLevelAfter ;
skillLevelAfter + = ( skillLevelAfter + 1 ) > > 1 ;
curChampion - > _statistics [ k3_ChampionStatWisdom ] [ k0_ChampionStatMaximum ] + = minorStatIncrease ;
increaseManaFl = true ;
break ;
default :
break ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 08:43:19 +02:00
if ( increaseManaFl ) {
if ( ( curChampion - > _maxMana + = MIN ( _vm - > getRandomNumber ( 4 ) , ( uint16 ) ( newBaseSkillLevel - 1 ) ) ) > 900 )
curChampion - > _maxMana = 900 ;
curChampion - > _statistics [ k5_ChampionStatAntimagic ] [ k0_ChampionStatMaximum ] + = _vm - > getRandomNumber ( 3 ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 08:43:19 +02:00
if ( ( curChampion - > _maxHealth + = skillLevelAfter + _vm - > getRandomNumber ( ( skillLevelAfter > > 1 ) + 1 ) ) > 999 )
curChampion - > _maxHealth = 999 ;
if ( ( curChampion - > _maxStamina + = staminaAmount + _vm - > getRandomNumber ( ( staminaAmount > > 1 ) + 1 ) ) > 9999 )
curChampion - > _maxStamina = 9999 ;
setFlag ( curChampion - > _attributes , k0x0100_ChampionAttributeStatistics ) ;
2016-07-07 00:46:51 +02:00
f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
_vm - > _textMan - > f51_messageAreaPrintLineFeed ( ) ;
2016-07-25 08:43:19 +02:00
Color curChampionColor = g46_ChampionColor [ champIndex ] ;
_vm - > _textMan - > f47_messageAreaPrintMessage ( curChampionColor , curChampion - > _name ) ;
2016-07-07 00:46:51 +02:00
// TODO: localization
2016-07-25 08:43:19 +02:00
_vm - > _textMan - > f47_messageAreaPrintMessage ( curChampionColor , " JUST GAINED A " ) ;
_vm - > _textMan - > f47_messageAreaPrintMessage ( curChampionColor , g417_baseSkillName [ baseSkillIndex ] ) ;
_vm - > _textMan - > f47_messageAreaPrintMessage ( curChampionColor , " LEVEL! " ) ;
2016-07-07 00:46:51 +02:00
}
}
}
int16 ChampionMan : : f324_damageAll_getDamagedChampionCount ( uint16 attack , int16 wounds , int16 attackType ) {
2016-07-25 09:01:01 +02:00
int16 randomMax = ( attack > > 3 ) + 1 ;
uint16 reducedAttack = attack - randomMax ;
randomMax < < = 1 ;
int16 damagedChampionCount = 0 ;
for ( int16 championIndex = k0_ChampionFirst ; championIndex < _g305_partyChampionCount ; championIndex + + ) {
// Actual attack is attack +/- (attack / 8)
if ( f321_addPendingDamageAndWounds_getDamage ( championIndex , MAX ( 1 , reducedAttack + _vm - > getRandomNumber ( randomMax ) ) , wounds , attackType ) )
damagedChampionCount + + ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 09:01:01 +02:00
return damagedChampionCount ;
2016-07-07 00:46:51 +02:00
}
int16 ChampionMan : : f286_getTargetChampionIndex ( int16 mapX , int16 mapY , uint16 cell ) {
if ( _g305_partyChampionCount & & ( M38_distance ( mapX , mapY , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY ) < = 1 ) ) {
2016-07-25 09:01:01 +02:00
signed char orderedCellsToAttack [ 4 ] ;
_vm - > _groupMan - > f229_setOrderedCellsToAttack ( orderedCellsToAttack , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY , mapX , mapY , cell ) ;
for ( uint16 i = 0 ; i < 4 ; i + + ) {
int16 championIndex = f285_getIndexInCell ( orderedCellsToAttack [ i ] ) ;
if ( championIndex > = 0 )
return championIndex ;
2016-07-07 00:46:51 +02:00
}
}
return kM1_ChampionNone ;
}
int16 ChampionMan : : f311_getDexterity ( Champion * champ ) {
2016-07-25 09:01:01 +02:00
int16 dexterity = _vm - > getRandomNumber ( 8 ) + champ - > _statistics [ k2_ChampionStatDexterity ] [ k1_ChampionStatCurrent ] ;
dexterity - = ( ( int32 ) ( dexterity > > 1 ) * ( int32 ) champ - > _load ) / f309_getMaximumLoad ( champ ) ;
if ( _g300_partyIsSleeping )
dexterity > > = 1 ;
return f26_getBoundedValue ( 1 + _vm - > getRandomNumber ( 8 ) , dexterity > > 1 , 100 - _vm - > getRandomNumber ( 8 ) ) ;
2016-07-07 00:46:51 +02:00
}
bool ChampionMan : : f308_isLucky ( Champion * champ , uint16 percentage ) {
2016-07-25 09:01:01 +02:00
if ( _vm - > getRandomNumber ( 2 ) & & ( _vm - > getRandomNumber ( 100 ) > percentage ) )
2016-07-07 00:46:51 +02:00
return true ;
2016-07-25 09:01:01 +02:00
2016-07-25 12:14:38 +02:00
unsigned char * curStat = champ - > _statistics [ k0_ChampionStatLuck ] ;
2016-07-25 09:01:01 +02:00
bool isLucky = ( _vm - > getRandomNumber ( curStat [ k1_ChampionStatCurrent ] ) > percentage ) ;
curStat [ k1_ChampionStatCurrent ] = f26_getBoundedValue < char > ( curStat [ k2_ChampionStatMinimum ] , curStat [ k1_ChampionStatCurrent ] + ( isLucky ? - 2 : 2 ) , curStat [ k0_ChampionStatMaximum ] ) ;
return isLucky ;
2016-07-07 00:46:51 +02:00
}
void ChampionMan : : f322_championPoison ( int16 champIndex , uint16 attack ) {
2016-08-26 22:50:17 +02:00
if ( ( champIndex = = kM1_ChampionNone ) | | ( _vm - > M0_indexToOrdinal ( champIndex ) = = _g299_candidateChampionOrdinal ) )
2016-07-07 00:46:51 +02:00
return ;
2016-08-26 22:50:17 +02:00
2016-07-25 12:14:38 +02:00
Champion * curChampion = & _gK71_champions [ champIndex ] ;
2016-07-07 00:46:51 +02:00
f321_addPendingDamageAndWounds_getDamage ( champIndex , MAX ( 1 , attack > > 6 ) , k0x0000_ChampionWoundNone , k0_attackType_NORMAL ) ;
2016-07-25 12:14:38 +02:00
setFlag ( curChampion - > _attributes , k0x0100_ChampionAttributeStatistics ) ;
2016-07-07 00:46:51 +02:00
if ( ( _vm - > M0_indexToOrdinal ( champIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) & & ( _vm - > _inventoryMan - > _g424_panelContent = = k0_PanelContentFoodWaterPoisoned ) ) {
2016-07-25 12:14:38 +02:00
setFlag ( curChampion - > _attributes , k0x0800_ChampionAttributePanel ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 12:14:38 +02:00
2016-07-07 00:46:51 +02:00
if ( - - attack ) {
2016-07-25 12:14:38 +02:00
curChampion - > _poisonEventCount + + ;
TimelineEvent newEvent ;
newEvent . _type = k75_TMEventTypePoisonChampion ;
newEvent . _priority = champIndex ;
M33_setMapAndTime ( newEvent . _mapTime , _vm - > _dungeonMan - > _g309_partyMapIndex , _vm - > _g313_gameTime + 36 ) ;
newEvent . _B . _attack = attack ;
_vm - > _timeline - > f238_addEventGetEventIndex ( & newEvent ) ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 12:14:38 +02:00
2016-07-07 00:46:51 +02:00
f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
}
void ChampionMan : : f284_setPartyDirection ( int16 dir ) {
2016-07-25 12:14:38 +02:00
if ( dir = = _vm - > _dungeonMan - > _g308_partyDir )
2016-07-07 00:46:51 +02:00
return ;
2016-07-25 12:14:38 +02:00
int16 L0834_i_Delta = dir - _vm - > _dungeonMan - > _g308_partyDir ;
if ( L0834_i_Delta < 0 )
2016-07-07 00:46:51 +02:00
L0834_i_Delta + = 4 ;
2016-07-25 12:14:38 +02:00
Champion * curChampion = _gK71_champions ;
for ( int16 i = k0_ChampionFirst ; i < _g305_partyChampionCount ; i + + ) {
curChampion - > _cell = ( ViewCell ) M21_normalizeModulo4 ( curChampion - > _cell + L0834_i_Delta ) ;
2016-07-25 14:35:26 +02:00
curChampion - > _dir = ( Direction ) M21_normalizeModulo4 ( curChampion - > _dir + L0834_i_Delta ) ;
2016-07-25 12:14:38 +02:00
curChampion + + ;
2016-07-07 00:46:51 +02:00
}
2016-07-25 12:14:38 +02:00
2016-07-25 14:35:26 +02:00
_vm - > _dungeonMan - > _g308_partyDir = ( Direction ) dir ;
2016-07-07 00:46:51 +02:00
f296_drawChangedObjectIcons ( ) ;
}
void ChampionMan : : f316_deleteScent ( uint16 scentIndex ) {
2016-07-25 12:14:38 +02:00
uint16 count = - - _g407_party . _scentCount - scentIndex ;
2016-07-07 00:46:51 +02:00
2016-07-25 12:14:38 +02:00
if ( count ) {
for ( uint16 i = 0 ; i < count ; + + i ) {
2016-07-07 00:46:51 +02:00
_g407_party . _scents [ scentIndex + i ] = _g407_party . _scents [ scentIndex + i + 1 ] ;
_g407_party . _scentStrengths [ scentIndex + i ] = _g407_party . _scentStrengths [ scentIndex + i + 1 ] ;
}
}
2016-07-25 12:14:38 +02:00
if ( scentIndex < _g407_party . _firstScentIndex )
2016-07-07 00:46:51 +02:00
_g407_party . _firstScentIndex - - ;
2016-07-25 12:14:38 +02:00
if ( scentIndex < _g407_party . _lastScentIndex )
2016-07-07 00:46:51 +02:00
_g407_party . _lastScentIndex - - ;
}
void ChampionMan : : f317_addScentStrength ( int16 mapX , int16 mapY , int32 cycleCount ) {
2016-07-25 12:14:38 +02:00
int16 scentIndex = _vm - > _championMan - > _g407_party . _scentCount ;
if ( scentIndex ) {
bool mergeFl = getFlag ( cycleCount , k0x8000_mergeCycles ) ;
if ( mergeFl )
2016-07-07 00:46:51 +02:00
clearFlag ( cycleCount , k0x8000_mergeCycles ) ;
2016-07-25 12:14:38 +02:00
Scent newScent ; /* BUG0_00 Useless code */
newScent . setMapX ( mapX ) ; /* BUG0_00 Useless code */
newScent . setMapY ( mapY ) ; /* BUG0_00 Useless code */
newScent . setMapIndex ( _vm - > _dungeonMan - > _g272_currMapIndex ) ; /* BUG0_00 Useless code */
Scent * curScent = _vm - > _championMan - > _g407_party . _scents ; /* BUG0_00 Useless code */
bool cycleCountDefined = false ;
while ( scentIndex - - ) {
if ( & * curScent + + = = & newScent ) {
if ( ! cycleCountDefined ) {
cycleCountDefined = true ;
if ( mergeFl ) {
cycleCount = MAX < int32 > ( _g407_party . _scentStrengths [ scentIndex ] , cycleCount ) ;
2016-07-07 00:46:51 +02:00
} else {
2016-07-25 12:14:38 +02:00
cycleCount = MIN < int32 > ( 80 , _g407_party . _scentStrengths [ scentIndex ] + cycleCount ) ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-25 12:14:38 +02:00
_g407_party . _scentStrengths [ scentIndex ] = cycleCount ;
2016-07-07 00:46:51 +02:00
}
}
}
}
void ChampionMan : : f297_putObjectInLeaderHand ( Thing thing , bool setMousePointer ) {
2016-07-25 12:14:38 +02:00
if ( thing = = Thing : : _none )
2016-07-07 00:46:51 +02:00
return ;
2016-07-25 12:14:38 +02:00
2016-08-26 22:50:30 +02:00
_g415_leaderEmptyHanded = false ;
_vm - > _objectMan - > f36_extractIconFromBitmap ( _g413_leaderHandObjectIconIndex = _vm - > _objectMan - > f33_getIconIndex ( _g414_leaderHandObject = thing ) , _vm - > _objectMan - > _g412_objectIconForMousePointer ) ;
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
_vm - > _objectMan - > f34_drawLeaderObjectName ( thing ) ;
2016-07-25 12:14:38 +02:00
if ( setMousePointer )
2016-07-07 00:46:51 +02:00
_vm - > _g325_setMousePointerToObjectInMainLoop = true ;
2016-07-25 12:14:38 +02:00
else
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f68_setPointerToObject ( _vm - > _objectMan - > _g412_objectIconForMousePointer ) ;
2016-07-25 12:14:38 +02:00
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:50:30 +02:00
if ( _g411_leaderIndex ! = kM1_ChampionNone ) {
_gK71_champions [ _g411_leaderIndex ] . _load + = _vm - > _dungeonMan - > f140_getObjectWeight ( thing ) ;
setFlag ( _gK71_champions [ _g411_leaderIndex ] . _attributes , k0x0200_ChampionAttributeLoad ) ;
f292_drawChampionState ( _g411_leaderIndex ) ;
2016-07-07 00:46:51 +02:00
}
}
2016-07-25 12:14:38 +02:00
int16 ChampionMan : : f310_getMovementTicks ( Champion * champ ) {
uint16 maximumLoad = _vm - > _championMan - > f309_getMaximumLoad ( champ ) ;
uint16 curLoad = champ - > _load ;
uint16 woundTicks ;
int16 ticks ;
/* BUG0_72 - Fixed
The party moves very slowly even though no champion ' Load ' value is drawn in red .
When the Load of a champion has exactly the maximum value he can carry then the Load
is drawn in yellow but the speed is the same as when the champion is overloaded
( when the Load is drawn in red ) . The comparison operator should be > = instead of >
*/
if ( maximumLoad > = curLoad ) {
ticks = 2 ;
if ( ( ( int32 ) curLoad < < 3 ) > ( ( int32 ) maximumLoad * 5 ) )
ticks + + ;
2016-08-26 22:50:30 +02:00
2016-07-25 12:14:38 +02:00
woundTicks = 1 ;
2016-08-26 22:50:30 +02:00
} else {
2016-07-25 12:14:38 +02:00
ticks = 4 + ( ( ( curLoad - maximumLoad ) < < 2 ) / maximumLoad ) ;
woundTicks = 2 ;
2016-08-26 22:50:30 +02:00
}
2016-07-25 12:14:38 +02:00
if ( getFlag ( champ - > _wounds , k0x0020_ChampionWoundFeet ) )
ticks + = woundTicks ;
if ( _vm - > _objectMan - > f33_getIconIndex ( champ - > _slots [ k5_ChampionSlotFeet ] ) = = k194_IconIndiceArmourBootOfSpeed )
ticks - - ;
return ticks ;
2016-08-26 22:50:30 +02:00
}
2016-07-12 08:18:25 +02:00
bool ChampionMan : : f294_isAmmunitionCompatibleWithWeapon ( uint16 champIndex , uint16 weaponSlotIndex , uint16 ammunitionSlotIndex ) {
2016-07-25 12:14:38 +02:00
Champion * curChampion = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
Thing curThing = curChampion - > _slots [ weaponSlotIndex ] ;
if ( curThing . getType ( ) ! = k5_WeaponThingType )
2016-07-12 08:18:25 +02:00
return false ;
2016-07-25 12:14:38 +02:00
WeaponInfo * weaponInfo = _vm - > _dungeonMan - > f158_getWeaponInfo ( curThing ) ;
int16 weaponClass = kM1_WeaponClassNone ;
if ( ( weaponInfo - > _class > = k16_WeaponClassFirstBow ) & & ( weaponInfo - > _class < = k31_WeaponClassLastBow ) )
weaponClass = k10_WeaponClassBowAmmunition ;
else if ( ( weaponInfo - > _class > = k32_WeaponClassFirstSling ) & & ( weaponInfo - > _class < = k47_WeaponClassLastSling ) )
weaponClass = k11_WeaponClassSlingAmmunition ;
if ( weaponClass = = kM1_WeaponClassNone )
return false ;
curThing = curChampion - > _slots [ ammunitionSlotIndex ] ;
weaponInfo = _vm - > _dungeonMan - > f158_getWeaponInfo ( curThing ) ;
return ( ( curThing . getType ( ) = = k5_WeaponThingType ) & & ( weaponInfo - > _class = = weaponClass ) ) ;
2016-07-12 08:18:25 +02:00
}
2016-07-12 08:36:53 +02:00
void ChampionMan : : f293_drawAllChampionStates ( ) {
2016-07-25 14:35:26 +02:00
for ( int16 i = k0_ChampionFirst ; i < _vm - > _championMan - > _g305_partyChampionCount ; i + + )
_vm - > _championMan - > f292_drawChampionState ( ( ChampionIndex ) i ) ;
2016-07-12 08:36:53 +02:00
}
2016-07-12 08:44:15 +02:00
void ChampionMan : : f283_viAltarRebirth ( uint16 champIndex ) {
2016-07-25 14:35:26 +02:00
Champion * curChampion = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
if ( _vm - > _championMan - > f285_getIndexInCell ( curChampion - > _cell ) ! = kM1_ChampionNone ) {
uint16 numCell = k0_CellNorthWest ;
while ( _vm - > _championMan - > f285_getIndexInCell ( numCell ) ! = kM1_ChampionNone )
numCell + + ;
curChampion - > _cell = ( ViewCell ) numCell ;
2016-07-12 08:44:15 +02:00
}
2016-07-28 17:53:42 +02:00
2016-07-25 14:35:26 +02:00
uint16 maximumHealth = curChampion - > _maxHealth ;
curChampion - > _maxHealth = MAX ( 25 , maximumHealth - ( maximumHealth > > 6 ) - 1 ) ;
curChampion - > _currHealth = curChampion - > _maxHealth > > 1 ;
2016-07-12 08:44:15 +02:00
_vm - > _menuMan - > f393_drawSpellAreaControls ( _vm - > _championMan - > _g514_magicCasterChampionIndex ) ;
2016-07-25 14:35:26 +02:00
curChampion - > _dir = _vm - > _dungeonMan - > _g308_partyDir ;
setFlag ( curChampion - > _attributes , k0x8000_ChampionAttributeActionHand | k0x1000_ChampionAttributeStatusBox | k0x0400_ChampionAttributeIcon ) ;
2016-07-12 08:44:15 +02:00
_vm - > _championMan - > f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
}
2016-07-12 12:05:20 +02:00
void ChampionMan : : f302_processCommands28to65_clickOnSlotBox ( uint16 slotBoxIndex ) {
2016-07-14 20:23:09 +02:00
uint16 champIndex ;
uint16 slotIndex ;
2016-07-12 12:05:20 +02:00
if ( slotBoxIndex < k8_SlotBoxInventoryFirstSlot ) {
2016-07-25 14:35:26 +02:00
if ( _g299_candidateChampionOrdinal )
2016-07-12 12:05:20 +02:00
return ;
2016-07-25 14:35:26 +02:00
2016-07-14 20:23:09 +02:00
champIndex = slotBoxIndex > > 1 ;
2016-07-25 14:35:26 +02:00
if ( ( champIndex > = _g305_partyChampionCount ) | | ( _vm - > M0_indexToOrdinal ( champIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) | | ! _gK71_champions [ champIndex ] . _currHealth )
2016-07-12 12:05:20 +02:00
return ;
2016-07-25 14:35:26 +02:00
2016-07-14 20:23:09 +02:00
slotIndex = M70_handSlotIndex ( slotBoxIndex ) ;
2016-07-12 12:05:20 +02:00
} else {
2016-07-14 20:23:09 +02:00
champIndex = _vm - > M1_ordinalToIndex ( _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) ;
slotIndex = slotBoxIndex - k8_SlotBoxInventoryFirstSlot ;
2016-07-12 12:05:20 +02:00
}
2016-07-25 14:35:26 +02:00
2016-07-14 20:23:09 +02:00
Thing leaderHandObject = _g414_leaderHandObject ;
Thing slotThing ;
if ( slotIndex > = k30_ChampionSlotChest_1 ) {
slotThing = _vm - > _inventoryMan - > _g425_chestSlots [ slotIndex - k30_ChampionSlotChest_1 ] ;
2016-07-12 12:05:20 +02:00
} else {
2016-07-14 20:23:09 +02:00
slotThing = _gK71_champions [ champIndex ] . _slots [ slotIndex ] ;
2016-07-12 12:05:20 +02:00
}
2016-07-25 14:35:26 +02:00
if ( ( slotThing = = Thing : : _none ) & & ( leaderHandObject = = Thing : : _none ) )
2016-07-12 12:05:20 +02:00
return ;
2016-07-25 14:35:26 +02:00
2016-07-29 09:51:39 +02:00
if ( ( leaderHandObject ! = Thing : : _none ) & & ( ! ( g237_ObjectInfo [ _vm - > _dungeonMan - > f141_getObjectInfoIndex ( leaderHandObject ) ] . _allowedSlots & gSlotMasks [ slotIndex ] ) ) )
2016-07-12 12:05:20 +02:00
return ;
2016-07-25 14:35:26 +02:00
2016-07-12 12:05:20 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-07-25 14:35:26 +02:00
if ( leaderHandObject ! = Thing : : _none )
2016-07-12 12:05:20 +02:00
f298_getObjectRemovedFromLeaderHand ( ) ;
2016-07-25 14:35:26 +02:00
2016-07-14 20:23:09 +02:00
if ( slotThing ! = Thing : : _none ) {
f300_getObjectRemovedFromSlot ( champIndex , slotIndex ) ;
2016-07-19 18:04:14 +02:00
f297_putObjectInLeaderHand ( slotThing , false ) ;
2016-07-12 12:05:20 +02:00
}
2016-07-25 14:35:26 +02:00
if ( leaderHandObject ! = Thing : : _none )
2016-07-19 18:04:14 +02:00
f301_addObjectInSlot ( ( ChampionIndex ) champIndex , leaderHandObject , ( ChampionSlot ) slotIndex ) ;
2016-07-25 14:35:26 +02:00
2016-07-14 20:23:09 +02:00
f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-07-12 12:05:20 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
}
2016-07-12 14:38:52 +02:00
bool ChampionMan : : f327_isProjectileSpellCast ( uint16 champIndex , Thing thing , int16 kineticEnergy , uint16 requiredManaAmount ) {
2016-07-25 14:35:26 +02:00
Champion * curChampion = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
if ( curChampion - > _currMana < requiredManaAmount )
2016-07-12 14:38:52 +02:00
return false ;
2016-07-25 14:35:26 +02:00
curChampion - > _currMana - = requiredManaAmount ;
setFlag ( curChampion - > _attributes , k0x0100_ChampionAttributeStatistics ) ;
int16 stepEnergy = 10 - MIN ( 8 , curChampion - > _maxMana > > 3 ) ;
if ( kineticEnergy < ( stepEnergy < < 2 ) ) {
2016-07-12 14:38:52 +02:00
kineticEnergy + = 3 ;
2016-07-25 14:35:26 +02:00
stepEnergy - - ;
2016-07-12 14:38:52 +02:00
}
2016-07-25 14:35:26 +02:00
f326_championShootProjectile ( curChampion , thing , kineticEnergy , 90 , stepEnergy ) ;
2016-07-12 14:38:52 +02:00
return true ; // fix BUG_01
}
void ChampionMan : : f326_championShootProjectile ( Champion * champ , Thing thing , int16 kineticEnergy , int16 attack , int16 stepEnergy ) {
2016-07-25 14:35:26 +02:00
Direction newDirection = champ - > _dir ;
_vm - > _projexpl - > f212_projectileCreate ( thing , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY , M21_normalizeModulo4 ( ( ( ( champ - > _cell - newDirection + 1 ) & 0x0002 ) > > 1 ) + newDirection ) , newDirection , kineticEnergy , attack , stepEnergy ) ;
2016-07-12 14:38:52 +02:00
_vm - > _g311_projectileDisableMovementTicks = 4 ;
2016-07-25 14:35:26 +02:00
_vm - > _g312_lastProjectileDisabledMovementDirection = newDirection ;
2016-07-12 14:38:52 +02:00
}
2016-07-13 19:51:14 +02:00
void ChampionMan : : f320_applyAndDrawPendingDamageAndWounds ( ) {
2016-07-25 15:53:22 +02:00
Champion * championPtr = _vm - > _championMan - > _gK71_champions ;
for ( uint16 championIndex = k0_ChampionFirst ; championIndex < _vm - > _championMan - > _g305_partyChampionCount ; championIndex + + , championPtr + + ) {
int16 pendingWounds = _g410_championPendingWounds [ championIndex ] ;
setFlag ( championPtr - > _wounds , pendingWounds ) ;
_g410_championPendingWounds [ championIndex ] = 0 ;
uint16 pendingDamage = _g409_championPendingDamage [ championIndex ] ;
if ( ! pendingDamage )
2016-07-13 19:51:14 +02:00
continue ;
2016-07-25 15:53:22 +02:00
_g409_championPendingDamage [ championIndex ] = 0 ;
int16 curHealth = championPtr - > _currHealth ;
if ( ! curHealth )
2016-07-13 19:51:14 +02:00
continue ;
2016-07-25 15:53:22 +02:00
curHealth - = pendingDamage ;
if ( curHealth < = 0 ) {
_vm - > _championMan - > f319_championKill ( championIndex ) ;
2016-07-13 19:51:14 +02:00
} else {
2016-07-25 15:53:22 +02:00
championPtr - > _currHealth = curHealth ;
setFlag ( championPtr - > _attributes , k0x0100_ChampionAttributeStatistics ) ;
if ( pendingWounds ) {
setFlag ( championPtr - > _attributes , k0x2000_ChampionAttributeWounds ) ;
2016-07-13 19:51:14 +02:00
}
2016-07-25 15:53:22 +02:00
int16 textPosX = championIndex * k69_ChampionStatusBoxSpacing ;
int16 textPosY ;
Box blitBox ;
blitBox . _y1 = 0 ;
2016-07-13 19:51:14 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-07-25 15:53:22 +02:00
if ( _vm - > M0_indexToOrdinal ( championIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) {
blitBox . _y2 = 28 ;
blitBox . _x1 = textPosX + 7 ;
blitBox . _x2 = blitBox . _x1 + 31 ; /* Box is over the champion portrait in the status box */
_vm - > _displayMan - > f21_blitToScreen ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k16_damageToChampionBig ) , & blitBox , k16_byteWidth , k10_ColorFlesh , 29 ) ;
// Check the number of digits and sets the position accordingly.
if ( pendingDamage < 10 ) // 1 digit
textPosX + = 21 ;
else if ( pendingDamage < 100 ) // 2 digits
textPosX + = 18 ;
else // 3 digits
textPosX + = 15 ;
textPosY = 16 ;
2016-07-13 19:51:14 +02:00
} else {
2016-07-25 15:53:22 +02:00
blitBox . _y2 = 6 ;
blitBox . _x1 = textPosX ;
blitBox . _x2 = blitBox . _x1 + 47 ; /* Box is over the champion name in the status box */
_vm - > _displayMan - > f21_blitToScreen ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k15_damageToChampionSmallIndice ) , & blitBox , k24_byteWidth , k10_ColorFlesh , 7 ) ;
// Check the number of digits and sets the position accordingly.
if ( pendingDamage < 10 ) // 1 digit
textPosX + = 19 ;
else if ( pendingDamage < 100 ) // 2 digits
textPosX + = 16 ;
else //3 digits
textPosX + = 13 ;
textPosY = 5 ;
2016-07-13 19:51:14 +02:00
}
2016-07-25 15:53:22 +02:00
_vm - > _textMan - > f53_printToLogicalScreen ( textPosX , textPosY , k15_ColorWhite , k8_ColorRed , _vm - > _championMan - > f288_getStringFromInteger ( pendingDamage , false , 3 ) . c_str ( ) ) ;
int16 eventIndex = championPtr - > _hideDamageReceivedIndex ;
if ( eventIndex = = - 1 ) {
TimelineEvent newEvent ;
newEvent . _type = k12_TMEventTypeHideDamageReceived ;
M33_setMapAndTime ( newEvent . _mapTime , _vm - > _dungeonMan - > _g309_partyMapIndex , _vm - > _g313_gameTime + 5 ) ;
newEvent . _priority = championIndex ;
championPtr - > _hideDamageReceivedIndex = _vm - > _timeline - > f238_addEventGetEventIndex ( & newEvent ) ;
2016-07-13 19:51:14 +02:00
} else {
2016-07-25 15:53:22 +02:00
TimelineEvent * curEvent = & _vm - > _timeline - > _g370_events [ eventIndex ] ;
M33_setMapAndTime ( curEvent - > _mapTime , _vm - > _dungeonMan - > _g309_partyMapIndex , _vm - > _g313_gameTime + 5 ) ;
_vm - > _timeline - > f236_fixChronology ( _vm - > _timeline - > f235_getIndex ( eventIndex ) ) ;
2016-07-13 19:51:14 +02:00
}
2016-07-25 15:53:22 +02:00
_vm - > _championMan - > f292_drawChampionState ( ( ChampionIndex ) championIndex ) ;
2016-07-13 19:51:14 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
}
}
}
void ChampionMan : : f319_championKill ( uint16 champIndex ) {
2016-07-25 16:13:53 +02:00
Champion * curChampion = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
curChampion - > _currHealth = 0 ;
setFlag ( curChampion - > _attributes , k0x1000_ChampionAttributeStatusBox ) ;
2016-07-13 19:51:14 +02:00
if ( _vm - > M0_indexToOrdinal ( champIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) {
if ( _vm - > _g331_pressingEye ) {
_vm - > _g331_pressingEye = false ;
_vm - > _eventMan - > _g597_ignoreMouseMovements = false ;
if ( ! _vm - > _championMan - > _g415_leaderEmptyHanded ) {
_vm - > _objectMan - > f34_drawLeaderObjectName ( _vm - > _championMan - > _g414_leaderHandObject ) ;
}
_vm - > _eventMan - > _g587_hideMousePointerRequestCount = 1 ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-07-25 16:13:53 +02:00
} else if ( _vm - > _g333_pressingMouth ) {
_vm - > _g333_pressingMouth = false ;
_vm - > _eventMan - > _g597_ignoreMouseMovements = false ;
_vm - > _eventMan - > _g587_hideMousePointerRequestCount = 1 ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-07-13 19:51:14 +02:00
}
_vm - > _inventoryMan - > f355_toggleInventory ( k4_ChampionCloseInventory ) ;
}
f318_dropAllObjects ( champIndex ) ;
2016-07-25 16:13:53 +02:00
Thing unusedThing = _vm - > _dungeonMan - > f166_getUnusedThing ( k0x8000_championBones | k10_JunkThingType ) ;
uint16 curCell = 0 ;
if ( unusedThing ! = Thing : : _none ) {
Junk * L0966_ps_Junk = ( Junk * ) _vm - > _dungeonMan - > f156_getThingData ( unusedThing ) ;
2016-07-13 19:51:14 +02:00
L0966_ps_Junk - > setType ( k5_JunkTypeBones ) ;
L0966_ps_Junk - > setDoNotDiscard ( true ) ;
L0966_ps_Junk - > setChargeCount ( champIndex ) ;
2016-07-25 16:13:53 +02:00
curCell = curChampion - > _cell ;
_vm - > _moveSens - > f267_getMoveResult ( M15_thingWithNewCell ( unusedThing , curCell ) , kM1_MapXNotOnASquare , 0 , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY ) ;
2016-07-13 19:51:14 +02:00
}
2016-07-25 16:13:53 +02:00
curChampion - > _symbolStep = 0 ;
curChampion - > _symbols [ 0 ] = ' \0 ' ;
curChampion - > _dir = _vm - > _dungeonMan - > _g308_partyDir ;
curChampion - > _maximumDamageReceived = 0 ;
uint16 curChampionIconIndex = _vm - > _championMan - > M26_championIconIndex ( curCell , _vm - > _dungeonMan - > _g308_partyDir ) ;
if ( _vm - > M0_indexToOrdinal ( curChampionIconIndex ) = = _vm - > _eventMan - > _g599_useChampionIconOrdinalAsMousePointerBitmap ) {
2016-07-13 19:51:14 +02:00
_vm - > _eventMan - > _g598_mousePointerBitmapUpdated = true ;
_vm - > _eventMan - > _g599_useChampionIconOrdinalAsMousePointerBitmap = _vm - > M0_indexToOrdinal ( kM1_ChampionNone ) ;
warning ( false , " IGNORED CODE:G0592_B_BuildMousePointerScreenAreaRequested = true " ) ;
}
2016-07-25 16:13:53 +02:00
if ( curChampion - > _poisonEventCount )
2016-07-13 19:51:14 +02:00
f323_unpoison ( champIndex ) ;
2016-07-25 16:13:53 +02:00
2016-07-13 19:51:14 +02:00
_vm - > _displayMan - > _g578_useByteBoxCoordinates = false ;
2016-07-25 16:13:53 +02:00
_vm - > _displayMan - > D24_fillScreenBox ( g54_BoxChampionIcons [ curChampionIconIndex < < 2 ] , k0_ColorBlack ) ;
2016-07-13 19:51:14 +02:00
_vm - > _championMan - > f292_drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-07-28 17:53:42 +02:00
2016-07-25 16:13:53 +02:00
int16 aliveChampionIndex ;
for ( aliveChampionIndex = k0_ChampionFirst , curChampion = _vm - > _championMan - > _gK71_champions ; aliveChampionIndex < _vm - > _championMan - > _g305_partyChampionCount ; aliveChampionIndex + + , curChampion + + ) {
if ( curChampion - > _currHealth )
2016-07-13 19:51:14 +02:00
break ;
}
2016-07-25 16:13:53 +02:00
if ( aliveChampionIndex = = _vm - > _championMan - > _g305_partyChampionCount ) { /* BUG0_43 The game does not end if the last living champion in the party is killed while looking at a candidate champion in a portrait. The condition to end the game when the whole party is killed is not true because the code considers the candidate champion as alive (in the loop above) */
2016-07-13 19:51:14 +02:00
_vm - > _championMan - > _g303_partyDead = true ;
return ;
}
2016-07-25 16:13:53 +02:00
if ( champIndex = = _vm - > _championMan - > _g411_leaderIndex )
_vm - > _eventMan - > f368_commandSetLeader ( ( ChampionIndex ) aliveChampionIndex ) ;
if ( champIndex = = _vm - > _championMan - > _g514_magicCasterChampionIndex )
_vm - > _menuMan - > f394_setMagicCasterAndDrawSpellArea ( aliveChampionIndex ) ;
else
2016-07-13 19:51:14 +02:00
_vm - > _menuMan - > f393_drawSpellAreaControls ( _vm - > _championMan - > _g514_magicCasterChampionIndex ) ;
}
void ChampionMan : : f318_dropAllObjects ( uint16 champIndex ) {
2016-07-25 16:13:53 +02:00
static const int16 slotDropOrder [ 30 ] = {
2016-07-13 19:51:14 +02:00
k5_ChampionSlotFeet ,
k4_ChampionSlotLegs ,
k9_ChampionSlotQuiverLine_2_2 ,
k8_ChampionSlotQuiverLine_1_2 ,
k7_ChampionSlotQuiverLine_2_1 ,
k12_ChampionSlotQuiverLine_1_1 ,
k6_ChampionSlotPouch_2 ,
k11_ChampionSlotPouch_1 ,
k3_ChampionSlotTorso ,
k13_ChampionSlotBackpackLine_1_1 ,
k14_ChampionSlotBackpackLine_2_2 ,
k15_ChampionSlotBackpackLine_2_3 ,
k16_ChampionSlotBackpackLine_2_4 ,
k17_ChampionSlotBackpackLine_2_5 ,
k18_ChampionSlotBackpackLine_2_6 ,
k19_ChampionSlotBackpackLine_2_7 ,
k20_ChampionSlotBackpackLine_2_8 ,
k21_ChampionSlotBackpackLine_2_9 ,
k22_ChampionSlotBackpackLine_1_2 ,
k23_ChampionSlotBackpackLine_1_3 ,
k24_ChampionSlotBackpackLine_1_4 ,
k25_ChampionSlotBackpackLine_1_5 ,
k26_ChampionSlotBackpackLine_1_6 ,
k27_ChampionSlotBackpackLine_1_7 ,
k28_ChampionSlotBackpackLine_1_8 ,
k29_ChampionSlotBackpackLine_1_9 ,
k10_ChampionSlotNeck ,
k2_ChampionSlotHead ,
k0_ChampionSlotReadyHand ,
2016-07-25 16:13:53 +02:00
k1_ChampionSlotActionHand
} ;
uint16 curCell = _vm - > _championMan - > _gK71_champions [ champIndex ] . _cell ;
for ( uint16 slotIndex = k0_ChampionSlotReadyHand ; slotIndex < k30_ChampionSlotChest_1 ; slotIndex + + ) {
Thing curThing = f300_getObjectRemovedFromSlot ( champIndex , slotDropOrder [ slotIndex ] ) ;
2016-07-25 17:02:15 +02:00
if ( curThing ! = Thing : : _none )
2016-07-25 16:13:53 +02:00
_vm - > _moveSens - > f267_getMoveResult ( M15_thingWithNewCell ( curThing , curCell ) , kM1_MapXNotOnASquare , 0 , _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY ) ;
2016-07-13 19:51:14 +02:00
}
}
void ChampionMan : : f323_unpoison ( int16 champIndex ) {
2016-07-25 16:13:53 +02:00
if ( champIndex = = kM1_ChampionNone )
2016-07-13 19:51:14 +02:00
return ;
2016-07-25 16:13:53 +02:00
TimelineEvent * eventPtr = _vm - > _timeline - > _g370_events ;
for ( uint16 eventIndex = 0 ; eventIndex < _vm - > _timeline - > _g369_eventMaxCount ; eventPtr + + , eventIndex + + ) {
if ( ( eventPtr - > _type = = k75_TMEventTypePoisonChampion ) & & ( eventPtr - > _priority = = champIndex ) )
_vm - > _timeline - > f237_deleteEvent ( eventIndex ) ;
2016-07-13 19:51:14 +02:00
}
_vm - > _championMan - > _gK71_champions [ champIndex ] . _poisonEventCount = 0 ;
}
2016-07-14 14:13:41 +02:00
void ChampionMan : : f331_applyTimeEffects ( ) {
2016-07-25 17:02:15 +02:00
if ( ! _vm - > _championMan - > _g305_partyChampionCount )
2016-07-14 14:13:41 +02:00
return ;
2016-07-25 17:02:15 +02:00
Scent checkScent ;
checkScent . setMapX ( _vm - > _dungeonMan - > _g306_partyMapX ) ;
checkScent . setMapY ( _vm - > _dungeonMan - > _g307_partyMapY ) ;
checkScent . setMapIndex ( _vm - > _dungeonMan - > _g309_partyMapIndex ) ;
for ( byte loopScentIndex = 0 ; loopScentIndex + 1 < _vm - > _championMan - > _g407_party . _scentCount ; loopScentIndex + + ) {
if ( & _vm - > _championMan - > _g407_party . _scents [ loopScentIndex ] ! = & checkScent ) {
_vm - > _championMan - > _g407_party . _scentStrengths [ loopScentIndex ] = MAX ( 0 , _vm - > _championMan - > _g407_party . _scentStrengths [ loopScentIndex ] - 1 ) ;
if ( ! _vm - > _championMan - > _g407_party . _scentStrengths [ loopScentIndex ] & & ! loopScentIndex ) {
2016-07-14 14:13:41 +02:00
f316_deleteScent ( 0 ) ;
continue ;
}
}
}
2016-07-25 17:02:15 +02:00
uint16 gameTime = _vm - > _g313_gameTime & 0xFFFF ;
uint16 timeCriteria = ( ( ( gameTime & 0x0080 ) + ( ( gameTime & 0x0100 ) > > 2 ) ) + ( ( gameTime & 0x0040 ) < < 2 ) ) > > 2 ;
Champion * championPtr = _vm - > _championMan - > _gK71_champions ;
for ( uint16 championIndex = k0_ChampionFirst ; championIndex < _vm - > _championMan - > _g305_partyChampionCount ; championIndex + + , championPtr + + ) {
if ( championPtr - > _currHealth & & ( _vm - > M0_indexToOrdinal ( championIndex ) ! = _vm - > _championMan - > _g299_candidateChampionOrdinal ) ) {
uint16 wizardSkillLevel = _vm - > _championMan - > f303_getSkillLevel ( championIndex , k3_ChampionSkillWizard ) + _vm - > _championMan - > f303_getSkillLevel ( championIndex , k2_ChampionSkillPriest ) ;
if ( ( championPtr - > _currMana < championPtr - > _maxMana )
2016-07-28 17:53:42 +02:00
& & ( timeCriteria < championPtr - > _statistics [ k3_ChampionStatWisdom ] [ k1_ChampionStatCurrent ] + wizardSkillLevel ) ) {
2016-07-25 17:02:15 +02:00
int16 manaGain = championPtr - > _maxMana / 40 ;
if ( _vm - > _championMan - > _g300_partyIsSleeping )
manaGain < < = 1 ;
manaGain + + ;
f325_decrementStamina ( championIndex , manaGain * MAX ( 7 , 16 - wizardSkillLevel ) ) ;
championPtr - > _currMana + = MIN < int16 > ( manaGain , championPtr - > _maxMana - championPtr - > _currMana ) ;
} else if ( championPtr - > _currMana > championPtr - > _maxMana )
championPtr - > _currMana - - ;
for ( int16 idx = k19_ChampionSkillWater ; idx > = k0_ChampionSkillFighter ; idx - - ) {
if ( championPtr - > _skills [ idx ] . _temporaryExperience > 0 )
championPtr - > _skills [ idx ] . _temporaryExperience - - ;
2016-07-14 14:13:41 +02:00
}
2016-07-25 17:02:15 +02:00
uint16 staminaGainCycleCount = 4 ;
int16 staminaMagnitude = championPtr - > _maxStamina ;
while ( championPtr - > _currStamina < ( staminaMagnitude > > = 1 ) )
staminaGainCycleCount + = 2 ;
int16 staminaLoss = 0 ;
int16 staminaAmount = f26_getBoundedValue ( 1 , ( championPtr - > _maxStamina > > 8 ) - 1 , 6 ) ;
if ( _vm - > _championMan - > _g300_partyIsSleeping )
staminaAmount < < = 1 ;
int32 compDelay = _vm - > _g313_gameTime - _vm - > _projexpl - > _g362_lastPartyMovementTime ;
if ( compDelay > 80 ) {
staminaAmount + + ;
if ( compDelay > 250 )
staminaAmount + + ;
2016-07-14 14:13:41 +02:00
}
do {
2016-07-25 17:02:15 +02:00
bool staminaAboveHalf = ( staminaGainCycleCount < = 4 ) ;
if ( championPtr - > _food < - 512 ) {
if ( staminaAboveHalf ) {
staminaLoss + = staminaAmount ;
championPtr - > _food - = 2 ;
2016-07-14 14:13:41 +02:00
}
} else {
2016-07-25 17:02:15 +02:00
if ( championPtr - > _food > = 0 )
staminaLoss - = staminaAmount ;
championPtr - > _food - = staminaAboveHalf ? 2 : staminaGainCycleCount > > 1 ;
2016-07-14 14:13:41 +02:00
}
2016-07-25 17:02:15 +02:00
if ( championPtr - > _water < - 512 ) {
if ( staminaAboveHalf ) {
staminaLoss + = staminaAmount ;
championPtr - > _water - = 1 ;
2016-07-14 14:13:41 +02:00
}
} else {
2016-07-25 17:02:15 +02:00
if ( championPtr - > _water > = 0 )
staminaLoss - = staminaAmount ;
championPtr - > _water - = staminaAboveHalf ? 1 : staminaGainCycleCount > > 2 ;
2016-07-14 14:13:41 +02:00
}
2016-07-25 17:02:15 +02:00
} while ( - - staminaGainCycleCount & & ( ( championPtr - > _currStamina - staminaLoss ) < championPtr - > _maxStamina ) ) ;
f325_decrementStamina ( championIndex , staminaLoss ) ;
if ( championPtr - > _food < - 1024 )
championPtr - > _food = - 1024 ;
if ( championPtr - > _water < - 1024 )
championPtr - > _water = - 1024 ;
if ( ( championPtr - > _currHealth < championPtr - > _maxHealth ) & & ( championPtr - > _currStamina > = ( championPtr - > _maxStamina > > 2 ) ) & & ( timeCriteria < ( championPtr - > _statistics [ k4_ChampionStatVitality ] [ k1_ChampionStatCurrent ] + 12 ) ) ) {
int16 healthGain = ( championPtr - > _maxHealth > > 7 ) + 1 ;
if ( _vm - > _championMan - > _g300_partyIsSleeping )
healthGain < < = 1 ;
if ( _vm - > _objectMan - > f33_getIconIndex ( championPtr - > _slots [ k10_ChampionSlotNeck ] ) = = k121_IconIndiceJunkEkkhardCross )
healthGain + = ( healthGain > > 1 ) + 1 ;
championPtr - > _currHealth + = MIN ( healthGain , ( int16 ) ( championPtr - > _maxHealth - championPtr - > _currHealth ) ) ;
2016-07-14 14:13:41 +02:00
}
if ( ! ( ( int ) _vm - > _g313_gameTime & ( _vm - > _championMan - > _g300_partyIsSleeping ? 63 : 255 ) ) ) {
2016-07-25 17:02:15 +02:00
for ( uint16 i = k0_ChampionStatLuck ; i < = k6_ChampionStatAntifire ; i + + ) {
byte * curStatistic = championPtr - > _statistics [ i ] ;
uint16 statisticMaximum = curStatistic [ k0_ChampionStatMaximum ] ;
if ( curStatistic [ k1_ChampionStatCurrent ] < statisticMaximum )
curStatistic [ k1_ChampionStatCurrent ] + + ;
else if ( curStatistic [ k1_ChampionStatCurrent ] > statisticMaximum )
curStatistic [ k1_ChampionStatCurrent ] - = curStatistic [ k1_ChampionStatCurrent ] / statisticMaximum ;
2016-07-14 14:13:41 +02:00
}
}
2016-07-25 17:02:15 +02:00
if ( ! _vm - > _championMan - > _g300_partyIsSleeping & & ( championPtr - > _dir ! = _vm - > _dungeonMan - > _g308_partyDir ) & & ( _vm - > _projexpl - > _g361_lastCreatureAttackTime + 60 < _vm - > _g313_gameTime ) ) {
championPtr - > _dir = _vm - > _dungeonMan - > _g308_partyDir ;
championPtr - > _maximumDamageReceived = 0 ;
setFlag ( championPtr - > _attributes , k0x0400_ChampionAttributeIcon ) ;
2016-07-14 14:13:41 +02:00
}
2016-07-25 17:02:15 +02:00
setFlag ( championPtr - > _attributes , k0x0100_ChampionAttributeStatistics ) ;
if ( _vm - > M0_indexToOrdinal ( championIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) {
2016-07-14 14:13:41 +02:00
if ( _vm - > _g333_pressingMouth | | _vm - > _g331_pressingEye | | ( _vm - > _inventoryMan - > _g424_panelContent = = k0_PanelContentFoodWaterPoisoned ) ) {
2016-07-25 17:02:15 +02:00
setFlag ( championPtr - > _attributes , k0x0800_ChampionAttributePanel ) ;
2016-07-14 14:13:41 +02:00
}
}
}
}
f293_drawAllChampionStates ( ) ;
}
2016-07-19 18:04:14 +02:00
void ChampionMan : : save2_PartyPart ( Common : : OutSaveFile * file ) {
for ( uint16 i = 0 ; i < 4 ; + + i ) {
Champion * champ = & _gK71_champions [ i ] ;
file - > writeUint16BE ( champ - > _attributes ) ;
file - > writeUint16BE ( champ - > _wounds ) ;
for ( uint16 y = 0 ; y < 7 ; + + y )
for ( uint16 x = 0 ; x < 3 ; + + x )
file - > writeByte ( champ - > _statistics [ y ] [ x ] ) ;
for ( uint16 j = 0 ; j < 30 ; + + j )
file - > writeUint16BE ( champ - > _slots [ j ] . toUint16 ( ) ) ;
for ( uint16 j = 0 ; j < 20 ; + + j ) {
file - > writeSint16BE ( champ - > _skills [ j ] . _temporaryExperience ) ;
file - > writeSint32BE ( champ - > _skills [ j ] . _experience ) ;
}
for ( uint16 j = 0 ; j < 8 ; + + j )
file - > writeByte ( champ - > _name [ j ] ) ;
for ( uint16 j = 0 ; j < 20 ; + + j )
file - > writeByte ( champ - > _title [ j ] ) ;
file - > writeUint16BE ( champ - > _dir ) ;
file - > writeUint16BE ( champ - > _cell ) ;
file - > writeUint16BE ( champ - > _actionIndex ) ;
file - > writeUint16BE ( champ - > _symbolStep ) ;
2016-07-22 21:33:45 +02:00
for ( uint16 j = 0 ; j < 5 ; + + j )
2016-07-19 18:04:14 +02:00
file - > writeByte ( champ - > _symbols [ j ] ) ;
file - > writeUint16BE ( champ - > _directionMaximumDamageReceived ) ;
file - > writeUint16BE ( champ - > _maximumDamageReceived ) ;
file - > writeUint16BE ( champ - > _poisonEventCount ) ;
file - > writeSint16BE ( champ - > _enableActionEventIndex ) ;
file - > writeSint16BE ( champ - > _hideDamageReceivedIndex ) ;
file - > writeSint16BE ( champ - > _currHealth ) ;
file - > writeSint16BE ( champ - > _maxHealth ) ;
file - > writeSint16BE ( champ - > _currStamina ) ;
file - > writeSint16BE ( champ - > _maxStamina ) ;
file - > writeSint16BE ( champ - > _currMana ) ;
file - > writeSint16BE ( champ - > _maxMana ) ;
file - > writeSint16BE ( champ - > _actionDefense ) ;
file - > writeSint16BE ( champ - > _food ) ;
file - > writeSint16BE ( champ - > _water ) ;
file - > writeUint16BE ( champ - > _load ) ;
file - > writeSint16BE ( champ - > _shieldDefense ) ;
for ( uint16 j = 0 ; j < 928 ; + + j )
file - > writeByte ( champ - > _portrait [ j ] ) ;
}
Party & party = _g407_party ;
file - > writeSint16BE ( party . _magicalLightAmount ) ;
file - > writeByte ( party . _event73Count_ThievesEye ) ;
file - > writeByte ( party . _event79Count_Footprints ) ;
file - > writeSint16BE ( party . _shieldDefense ) ;
file - > writeSint16BE ( party . _fireShieldDefense ) ;
file - > writeSint16BE ( party . _spellShieldDefense ) ;
file - > writeByte ( party . _scentCount ) ;
file - > writeByte ( party . _freezeLifeTicks ) ;
file - > writeByte ( party . _firstScentIndex ) ;
file - > writeByte ( party . _lastScentIndex ) ;
2016-07-22 21:33:45 +02:00
for ( uint16 i = 0 ; i < 24 ; + + i )
2016-07-19 18:04:14 +02:00
file - > writeUint16BE ( party . _scents [ i ] . toUint16 ( ) ) ;
for ( uint16 i = 0 ; i < 24 ; + + i )
file - > writeByte ( party . _scentStrengths [ i ] ) ;
file - > writeByte ( party . _event71Count_Invisibility ) ;
}
2016-07-22 21:33:45 +02:00
void ChampionMan : : load2_PartyPart ( Common : : InSaveFile * file ) {
for ( uint16 i = 0 ; i < 4 ; + + i ) {
Champion * champ = & _gK71_champions [ i ] ;
champ - > _attributes = file - > readUint16BE ( ) ;
champ - > _wounds = file - > readUint16BE ( ) ;
for ( uint16 y = 0 ; y < 7 ; + + y )
for ( uint16 x = 0 ; x < 3 ; + + x )
champ - > _statistics [ y ] [ x ] = file - > readByte ( ) ;
for ( uint16 j = 0 ; j < 30 ; + + j )
champ - > _slots [ j ] = Thing ( file - > readUint16BE ( ) ) ;
2016-07-28 17:53:42 +02:00
for ( uint16 j = 0 ; j < 20 ; + + j ) {
champ - > _skills [ j ] . _temporaryExperience = file - > readSint16BE ( ) ;
champ - > _skills [ j ] . _experience = file - > readSint32BE ( ) ;
}
2016-07-22 21:33:45 +02:00
for ( uint16 j = 0 ; j < 8 ; + + j )
champ - > _name [ j ] = file - > readByte ( ) ;
for ( uint16 j = 0 ; j < 20 ; + + j )
champ - > _title [ j ] = file - > readByte ( ) ;
2016-07-25 14:35:26 +02:00
champ - > _dir = ( Direction ) file - > readUint16BE ( ) ;
2016-07-22 21:33:45 +02:00
champ - > _cell = ( ViewCell ) file - > readUint16BE ( ) ;
champ - > _actionIndex = ( ChampionAction ) file - > readUint16BE ( ) ;
champ - > _symbolStep = file - > readUint16BE ( ) ;
for ( uint16 j = 0 ; j < 5 ; + + j )
champ - > _symbols [ j ] = file - > readByte ( ) ;
champ - > _directionMaximumDamageReceived = file - > readUint16BE ( ) ;
champ - > _maximumDamageReceived = file - > readUint16BE ( ) ;
champ - > _poisonEventCount = file - > readUint16BE ( ) ;
champ - > _enableActionEventIndex = file - > readSint16BE ( ) ;
champ - > _hideDamageReceivedIndex = file - > readSint16BE ( ) ;
champ - > _currHealth = file - > readSint16BE ( ) ;
champ - > _maxHealth = file - > readSint16BE ( ) ;
champ - > _currStamina = file - > readSint16BE ( ) ;
champ - > _maxStamina = file - > readSint16BE ( ) ;
champ - > _currMana = file - > readSint16BE ( ) ;
champ - > _maxMana = file - > readSint16BE ( ) ;
champ - > _actionDefense = file - > readSint16BE ( ) ;
champ - > _food = file - > readSint16BE ( ) ;
champ - > _water = file - > readSint16BE ( ) ;
champ - > _load = file - > readUint16BE ( ) ;
champ - > _shieldDefense = file - > readSint16BE ( ) ;
for ( uint16 j = 0 ; j < 928 ; + + j )
champ - > _portrait [ j ] = file - > readByte ( ) ;
}
Party & party = _g407_party ;
party . _magicalLightAmount = file - > readSint16BE ( ) ;
party . _event73Count_ThievesEye = file - > readByte ( ) ;
party . _event79Count_Footprints = file - > readByte ( ) ;
party . _shieldDefense = file - > readSint16BE ( ) ;
party . _fireShieldDefense = file - > readSint16BE ( ) ;
party . _spellShieldDefense = file - > readSint16BE ( ) ;
party . _scentCount = file - > readByte ( ) ;
party . _freezeLifeTicks = file - > readByte ( ) ;
party . _firstScentIndex = file - > readByte ( ) ;
party . _lastScentIndex = file - > readByte ( ) ;
for ( uint16 i = 0 ; i < 24 ; + + i )
party . _scents [ i ] = Scent ( file - > readUint16BE ( ) ) ;
for ( uint16 i = 0 ; i < 24 ; + + i )
party . _scentStrengths [ i ] = file - > readByte ( ) ;
party . _event71Count_Invisibility = file - > readByte ( ) ;
}
2016-07-07 00:46:51 +02:00
ChampionIndex ChampionMan : : f285_getIndexInCell ( int16 cell ) {
2016-07-02 01:55:48 +02:00
for ( uint16 i = 0 ; i < _g305_partyChampionCount ; + + i ) {
2016-08-26 22:47:44 +02:00
if ( ( _gK71_champions [ i ] . _cell = = cell ) & & _gK71_champions [ i ] . _currHealth )
2016-08-26 22:35:29 +02:00
return ( ChampionIndex ) i ;
}
2016-07-02 01:55:48 +02:00
return kM1_ChampionNone ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f278_resetDataToStartGame ( ) {
2016-07-26 00:18:31 +02:00
if ( ! _vm - > _g298_newGame ) {
Thing L0787_T_Thing ;
if ( ( L0787_T_Thing = _g414_leaderHandObject ) = = Thing : : _none ) {
_g415_leaderEmptyHanded = true ;
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone ;
_vm - > _eventMan - > f69_setMousePointer ( ) ;
} else {
f297_putObjectInLeaderHand ( L0787_T_Thing , true ) ; /* This call will add the weight of the leader hand object to the Load of the leader a first time */
}
Champion * L0788_ps_Champion = _gK71_champions ;
int16 L0785_i_ChampionIndex ;
for ( L0785_i_ChampionIndex = k0_ChampionFirst ; L0785_i_ChampionIndex < _g305_partyChampionCount ; L0785_i_ChampionIndex + + , L0788_ps_Champion + + ) {
clearFlag ( L0788_ps_Champion - > _attributes , k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon | k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport | k0x8000_ChampionAttributeActionHand ) ;
setFlag ( L0788_ps_Champion - > _attributes , k0x8000_ChampionAttributeActionHand | k0x1000_ChampionAttributeStatusBox | k0x0400_ChampionAttributeIcon ) ;
}
f293_drawAllChampionStates ( ) ;
if ( ( L0785_i_ChampionIndex = _g411_leaderIndex ) ! = kM1_ChampionNone ) {
_g411_leaderIndex = kM1_ChampionNone ;
_vm - > _eventMan - > f368_commandSetLeader ( ( ChampionIndex ) L0785_i_ChampionIndex ) ;
}
if ( ( L0785_i_ChampionIndex = _g514_magicCasterChampionIndex ) ! = kM1_ChampionNone ) {
_g514_magicCasterChampionIndex = kM1_ChampionNone ;
_vm - > _menuMan - > f394_setMagicCasterAndDrawSpellArea ( L0785_i_ChampionIndex ) ;
}
return ;
}
2016-08-26 22:35:29 +02:00
2016-08-26 22:47:44 +02:00
_g414_leaderHandObject = Thing : : _none ;
2016-07-02 01:55:48 +02:00
_g413_leaderHandObjectIconIndex = kM1_IconIndiceNone ;
_g415_leaderEmptyHanded = true ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f280_addCandidateChampionToParty ( uint16 championPortraitIndex ) {
2016-07-26 00:13:06 +02:00
if ( ! _vm - > _championMan - > _g415_leaderEmptyHanded )
2016-08-26 22:50:13 +02:00
return ;
2016-07-26 00:13:06 +02:00
if ( _vm - > _championMan - > _g305_partyChampionCount = = 4 )
2016-08-26 22:50:30 +02:00
return ;
2016-07-26 00:13:06 +02:00
uint16 previousPartyChampionCount = _vm - > _championMan - > _g305_partyChampionCount ;
Champion * championPtr = & _vm - > _championMan - > _gK71_champions [ previousPartyChampionCount ] ;
championPtr - > resetToZero ( ) ;
2016-07-26 14:40:04 +02:00
// Strangerke - TODO: Check if the new code is possible to run on the older version (example: the portraits could be missing in the data)
2016-08-26 22:50:30 +02:00
_vm - > _displayMan - > _g578_useByteBoxCoordinates = true ;
2016-07-26 00:13:06 +02:00
_vm - > _displayMan - > f132_blitToBitmap ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k26_ChampionPortraitsIndice ) , championPtr - > _portrait , gBoxChampionPortrait , _vm - > _championMan - > M27_getChampionPortraitX ( championPortraitIndex ) , _vm - > _championMan - > M28_getChampionPortraitY ( championPortraitIndex ) , k128_byteWidth , k16_byteWidth , kM1_ColorNoTransparency ) ;
championPtr - > _actionIndex = k255_ChampionActionNone ;
championPtr - > _enableActionEventIndex = - 1 ;
championPtr - > _hideDamageReceivedIndex = - 1 ;
championPtr - > _dir = _vm - > _dungeonMan - > _g308_partyDir ;
uint16 viewCell = k0_ViewCellFronLeft ;
2016-07-26 14:40:04 +02:00
while ( _vm - > _championMan - > f285_getIndexInCell ( M21_normalizeModulo4 ( viewCell + _vm - > _dungeonMan - > _g308_partyDir ) ) ! = kM1_ChampionNone )
2016-07-26 00:13:06 +02:00
viewCell + + ;
2016-07-26 14:40:04 +02:00
2016-07-26 00:13:06 +02:00
championPtr - > _cell = ( ViewCell ) M21_normalizeModulo4 ( viewCell + _vm - > _dungeonMan - > _g308_partyDir ) ;
championPtr - > _attributes = k0x0400_ChampionAttributeIcon ;
championPtr - > _directionMaximumDamageReceived = _vm - > _dungeonMan - > _g308_partyDir ;
championPtr - > _food = 1500 + _vm - > getRandomNumber ( 256 ) ;
championPtr - > _water = 1500 + _vm - > getRandomNumber ( 256 ) ;
for ( int16 slotIdx = k0_ChampionSlotReadyHand ; slotIdx < k30_ChampionSlotChest_1 ; slotIdx + + )
championPtr - > _slots [ slotIdx ] = Thing : : _none ;
Thing curThing = _vm - > _dungeonMan - > f161_getSquareFirstThing ( _vm - > _dungeonMan - > _g306_partyMapX , _vm - > _dungeonMan - > _g307_partyMapY ) ;
while ( curThing . getType ( ) ! = k2_TextstringType )
curThing = _vm - > _dungeonMan - > f159_getNextThing ( curThing ) ;
char L0807_ac_DecodedChampionText [ 77 ] ;
char * decodedStringPtr = L0807_ac_DecodedChampionText ;
_vm - > _dungeonMan - > f168_decodeText ( decodedStringPtr , curThing , ( TextType ) ( k2_TextTypeScroll | k0x8000_DecodeEvenIfInvisible ) ) ;
uint16 charIdx = 0 ;
char tmpChar ;
2016-07-26 14:40:04 +02:00
while ( ( tmpChar = * decodedStringPtr + + ) ! = ' \n ' )
2016-07-26 00:13:06 +02:00
championPtr - > _name [ charIdx + + ] = tmpChar ;
championPtr - > _name [ charIdx ] = ' \0 ' ;
charIdx = 0 ;
bool championTitleCopiedFl = false ;
2016-08-26 22:50:30 +02:00
for ( ; ; ) { /*_Infinite loop_*/
2016-07-26 00:13:06 +02:00
tmpChar = * decodedStringPtr + + ;
if ( tmpChar = = ' \n ' ) { /* New line */
if ( championTitleCopiedFl )
2016-08-26 22:50:30 +02:00
break ;
2016-07-26 00:13:06 +02:00
championTitleCopiedFl = true ;
2016-07-26 14:40:04 +02:00
} else
2016-07-26 00:13:06 +02:00
championPtr - > _title [ charIdx + + ] = tmpChar ;
2016-08-26 22:50:30 +02:00
}
2016-07-26 00:13:06 +02:00
championPtr - > _title [ charIdx ] = ' \0 ' ;
2016-07-26 14:40:04 +02:00
if ( * decodedStringPtr + + = = ' M ' )
2016-07-26 00:13:06 +02:00
setFlag ( championPtr - > _attributes , k0x0010_ChampionAttributeMale ) ;
2016-07-26 14:40:04 +02:00
2016-07-26 00:13:06 +02:00
decodedStringPtr + + ;
championPtr - > _currHealth = championPtr - > _maxHealth = _vm - > _championMan - > f279_getDecodedValue ( decodedStringPtr , 4 ) ;
decodedStringPtr + = 4 ;
championPtr - > _currStamina = championPtr - > _maxStamina = _vm - > _championMan - > f279_getDecodedValue ( decodedStringPtr , 4 ) ;
decodedStringPtr + = 4 ;
championPtr - > _currMana = championPtr - > _maxMana = _vm - > _championMan - > f279_getDecodedValue ( decodedStringPtr , 4 ) ;
decodedStringPtr + = 4 ;
decodedStringPtr + + ;
for ( int16 statIdx = k0_ChampionStatLuck ; statIdx < = k6_ChampionStatAntifire ; statIdx + + ) {
championPtr - > _statistics [ statIdx ] [ k2_ChampionStatMinimum ] = 30 ;
championPtr - > _statistics [ statIdx ] [ k1_ChampionStatCurrent ] = championPtr - > _statistics [ statIdx ] [ k0_ChampionStatMaximum ] = _vm - > _championMan - > f279_getDecodedValue ( decodedStringPtr , 2 ) ;
decodedStringPtr + = 2 ;
}
championPtr - > _statistics [ k0_ChampionStatLuck ] [ k2_ChampionStatMinimum ] = 10 ;
decodedStringPtr + + ;
for ( uint16 skillIdx = k4_ChampionSkillSwing ; skillIdx < = k19_ChampionSkillWater ; skillIdx + + ) {
int skillValue = * decodedStringPtr + + - ' A ' ;
if ( skillValue > 0 )
championPtr - > _skills [ skillIdx ] . _experience = 125L < < skillValue ;
}
for ( uint16 skillIdx = k0_ChampionSkillFighter ; skillIdx < = k3_ChampionSkillWizard ; skillIdx + + ) {
int32 baseSkillExperience = 0 ;
int16 hiddenSkillIndex = ( skillIdx + 1 ) < < 2 ;
for ( uint16 hiddenIdx = 0 ; hiddenIdx < 4 ; hiddenIdx + + )
baseSkillExperience + = championPtr - > _skills [ hiddenSkillIndex + hiddenIdx ] . _experience ;
championPtr - > _skills [ skillIdx ] . _experience = baseSkillExperience ;
}
_vm - > _championMan - > _g299_candidateChampionOrdinal = previousPartyChampionCount + 1 ;
2016-08-26 22:50:30 +02:00
if ( + + _vm - > _championMan - > _g305_partyChampionCount = = 1 ) {
2016-08-26 22:47:44 +02:00
_vm - > _eventMan - > f368_commandSetLeader ( k0_ChampionFirst ) ;
2016-07-02 12:57:31 +02:00
_vm - > _menuMan - > _g508_refreshActionArea = true ;
2016-08-26 22:50:17 +02:00
} else {
2016-08-26 22:47:44 +02:00
_vm - > _menuMan - > f388_clearActingChampion ( ) ;
2016-08-26 22:50:30 +02:00
_vm - > _menuMan - > f386_drawActionIcon ( ( ChampionIndex ) ( _vm - > _championMan - > _g305_partyChampionCount - 1 ) ) ;
}
2016-07-26 00:13:06 +02:00
int16 curMapX = _vm - > _dungeonMan - > _g306_partyMapX ;
int16 curMapY = _vm - > _dungeonMan - > _g307_partyMapY ;
uint16 championObjectsCell = returnOppositeDir ( _vm - > _dungeonMan - > _g308_partyDir ) ;
curMapX + = _vm - > _dirIntoStepCountEast [ _vm - > _dungeonMan - > _g308_partyDir ] , curMapY + = _vm - > _dirIntoStepCountNorth [ _vm - > _dungeonMan - > _g308_partyDir ] ;
curThing = _vm - > _dungeonMan - > f161_getSquareFirstThing ( curMapX , curMapY ) ;
int16 slotIdx = k13_ChampionSlotBackpackLine_1_1 ;
while ( curThing ! = Thing : : _endOfList ) {
ThingType thingType = curThing . getType ( ) ;
if ( ( thingType > k3_SensorThingType ) & & ( curThing . getCell ( ) = = championObjectsCell ) ) {
int16 objectAllowedSlots = g237_ObjectInfo [ _vm - > _dungeonMan - > f141_getObjectInfoIndex ( curThing ) ] . _allowedSlots ;
uint16 curSlotIndex ;
switch ( thingType ) {
2016-07-26 11:43:44 +02:00
case k6_ArmourThingType : {
bool skipCheck = false ;
2016-07-26 00:13:06 +02:00
for ( curSlotIndex = k2_ChampionSlotHead ; curSlotIndex < = k5_ChampionSlotFeet ; curSlotIndex + + ) {
2016-07-26 11:43:44 +02:00
if ( objectAllowedSlots & gSlotMasks [ curSlotIndex ] ) {
skipCheck = true ;
break ;
}
2016-08-26 22:35:29 +02:00
}
2016-07-26 11:43:44 +02:00
if ( skipCheck )
break ;
if ( ( objectAllowedSlots & gSlotMasks [ k10_ChampionSlotNeck ] ) & & ( championPtr - > _slots [ k10_ChampionSlotNeck ] = = Thing : : _none ) )
2016-07-26 00:13:06 +02:00
curSlotIndex = k10_ChampionSlotNeck ;
2016-07-26 11:43:44 +02:00
else
curSlotIndex = slotIdx + + ;
2016-08-26 22:35:29 +02:00
break ;
2016-07-28 17:53:42 +02:00
}
2016-08-26 22:43:17 +02:00
case k5_WeaponThingType :
2016-07-26 11:43:44 +02:00
if ( championPtr - > _slots [ k1_ChampionSlotActionHand ] = = Thing : : _none )
2016-07-26 00:13:06 +02:00
curSlotIndex = k1_ChampionSlotActionHand ;
2016-07-26 11:43:44 +02:00
else if ( ( objectAllowedSlots & gSlotMasks [ k10_ChampionSlotNeck ] ) & & ( championPtr - > _slots [ k10_ChampionSlotNeck ] = = Thing : : _none ) )
curSlotIndex = k10_ChampionSlotNeck ;
else
curSlotIndex = slotIdx + + ;
2016-08-26 22:35:29 +02:00
break ;
2016-08-26 22:43:17 +02:00
case k7_ScrollThingType :
case k8_PotionThingType :
2016-07-26 11:43:44 +02:00
if ( championPtr - > _slots [ k11_ChampionSlotPouch_1 ] = = Thing : : _none )
2016-07-26 00:13:06 +02:00
curSlotIndex = k11_ChampionSlotPouch_1 ;
2016-07-26 11:43:44 +02:00
else if ( championPtr - > _slots [ k6_ChampionSlotPouch_2 ] = = Thing : : _none )
curSlotIndex = k6_ChampionSlotPouch_2 ;
else if ( ( objectAllowedSlots & gSlotMasks [ k10_ChampionSlotNeck ] ) & & ( championPtr - > _slots [ k10_ChampionSlotNeck ] = = Thing : : _none ) )
curSlotIndex = k10_ChampionSlotNeck ;
else
curSlotIndex = slotIdx + + ;
2016-08-26 22:35:29 +02:00
break ;
2016-08-26 22:43:17 +02:00
case k9_ContainerThingType :
case k10_JunkThingType :
2016-07-26 11:43:44 +02:00
if ( ( objectAllowedSlots & gSlotMasks [ k10_ChampionSlotNeck ] ) & & ( championPtr - > _slots [ k10_ChampionSlotNeck ] = = Thing : : _none ) )
2016-07-26 00:13:06 +02:00
curSlotIndex = k10_ChampionSlotNeck ;
2016-07-26 11:43:44 +02:00
else
2016-07-26 00:13:06 +02:00
curSlotIndex = slotIdx + + ;
2016-07-26 11:43:44 +02:00
break ;
2016-07-26 11:56:15 +02:00
default :
break ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 11:43:44 +02:00
while ( championPtr - > _slots [ curSlotIndex ] ! = Thing : : _none ) {
if ( ( objectAllowedSlots & gSlotMasks [ k10_ChampionSlotNeck ] ) & & ( championPtr - > _slots [ k10_ChampionSlotNeck ] = = Thing : : _none ) )
curSlotIndex = k10_ChampionSlotNeck ;
else
curSlotIndex = slotIdx + + ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 00:13:06 +02:00
_vm - > _championMan - > f301_addObjectInSlot ( ( ChampionIndex ) previousPartyChampionCount , curThing , ( ChampionSlot ) curSlotIndex ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 00:13:06 +02:00
curThing = _vm - > _dungeonMan - > f159_getNextThing ( curThing ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 00:13:06 +02:00
_vm - > _inventoryMan - > f355_toggleInventory ( ( ChampionIndex ) previousPartyChampionCount ) ;
2016-08-26 22:50:30 +02:00
_vm - > _menuMan - > f456_drawDisabledMenu ( ) ; ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f287_drawChampionBarGraphs ( ChampionIndex champIndex ) {
2016-07-14 17:04:53 +02:00
int16 barGraphHeights [ 3 ] ;
Champion * champ = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
2016-07-26 09:57:39 +02:00
int16 barGraphIdx = 0 ;
2016-07-14 17:04:53 +02:00
if ( champ - > _currHealth > 0 ) {
int32 barGraphHeight = ( ( ( int32 ) champ - > _currHealth < < 10 ) * 25 ) / champ - > _maxHealth ;
2016-07-27 13:58:02 +02:00
barGraphHeights [ barGraphIdx + + ] = ( barGraphHeight > > 10 ) + ( ( barGraphHeight & 0x000003FF ) ? 1 : 0 ) ;
2016-07-26 11:56:15 +02:00
} else
2016-07-26 09:57:39 +02:00
barGraphHeights [ barGraphIdx + + ] = 0 ;
2016-07-26 11:56:15 +02:00
2016-07-14 17:04:53 +02:00
if ( champ - > _currStamina > 0 ) {
int32 barGraphHeight = ( ( ( int32 ) champ - > _currStamina < < 10 ) * 25 ) / champ - > _maxStamina ;
2016-07-27 13:58:02 +02:00
barGraphHeights [ barGraphIdx + + ] = ( barGraphHeight > > 10 ) + ( ( barGraphHeight & 0x000003FF ) ? 1 : 0 ) ;
2016-07-26 11:56:15 +02:00
} else
2016-07-26 09:57:39 +02:00
barGraphHeights [ barGraphIdx + + ] = 0 ;
2016-07-26 11:56:15 +02:00
2016-07-14 17:04:53 +02:00
if ( champ - > _currMana > 0 ) {
2016-07-26 11:56:15 +02:00
if ( champ - > _currMana > champ - > _maxMana )
2016-07-26 09:57:39 +02:00
barGraphHeights [ barGraphIdx ] = 25 ;
2016-07-26 11:56:15 +02:00
else {
2016-07-14 17:04:53 +02:00
int32 barGraphHeight = ( ( ( int32 ) champ - > _currMana < < 10 ) * 25 ) / champ - > _maxMana ;
2016-07-27 13:58:02 +02:00
barGraphHeights [ barGraphIdx ] = ( barGraphHeight > > 10 ) + ( ( barGraphHeight & 0x000003FF ) ? 1 : 0 ) ;
2016-08-26 22:35:29 +02:00
}
} else {
2016-07-26 09:57:39 +02:00
barGraphHeights [ barGraphIdx ] = 0 ;
2016-08-26 22:35:29 +02:00
}
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-08-26 22:35:29 +02:00
2016-07-14 17:04:53 +02:00
// Strangerke - TO CHECK: if portraits, maybe the old (assembly) code is required for older versions
2016-08-26 22:35:29 +02:00
Box box ;
2016-07-02 12:57:31 +02:00
box . _x1 = champIndex * k69_ChampionStatusBoxSpacing + 46 ;
2016-07-03 03:07:38 +02:00
box . _x2 = box . _x1 + 3 ;
2016-08-26 22:35:29 +02:00
box . _y1 = 2 ;
2016-07-03 03:07:38 +02:00
box . _y2 = 26 ;
2016-07-14 17:04:53 +02:00
for ( int16 barGraphIndex = 0 ; barGraphIndex < 3 ; barGraphIndex + + ) {
int16 barGraphHeight = barGraphHeights [ barGraphIndex ] ;
2016-08-26 22:35:29 +02:00
if ( barGraphHeight < 25 ) {
box . _y1 = 2 ;
2016-07-14 17:04:53 +02:00
box . _y2 = 27 - barGraphHeight ;
_vm - > _displayMan - > D24_fillScreenBox ( box , k12_ColorDarkestGray ) ;
2016-08-26 22:35:29 +02:00
}
if ( barGraphHeight ) {
box . _y1 = 27 - barGraphHeight ;
2016-07-03 03:07:38 +02:00
box . _y2 = 26 ;
2016-07-03 01:15:10 +02:00
_vm - > _displayMan - > D24_fillScreenBox ( box , g46_ChampionColor [ champIndex ] ) ;
2016-08-26 22:35:29 +02:00
}
box . _x1 + = 7 ;
box . _x2 + = 7 ;
}
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:35:29 +02:00
}
2016-08-26 22:47:44 +02:00
uint16 ChampionMan : : f306_getStaminaAdjustedValue ( Champion * champ , int16 val ) {
2016-08-26 22:35:29 +02:00
int16 currStamina = champ - > _currStamina ;
int16 halfMaxStamina = champ - > _maxStamina / 2 ;
if ( currStamina < halfMaxStamina ) {
2016-07-11 11:37:01 +02:00
warning ( false , " Possible undefined behavior in the original code " ) ;
2016-08-26 22:35:29 +02:00
val / = 2 ;
return val + ( ( uint32 ) val * ( uint32 ) currStamina ) / halfMaxStamina ;
}
return val ;
}
2016-08-26 22:47:44 +02:00
uint16 ChampionMan : : f309_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:47:44 +02:00
maximumLoad = f306_getStaminaAdjustedValue ( champ , maximumLoad ) ;
2016-08-26 22:35:29 +02:00
int16 wounds = champ - > getWounds ( ) ;
2016-07-26 11:43:44 +02:00
if ( wounds )
2016-07-02 01:55:48 +02:00
maximumLoad - = maximumLoad > > ( champ - > getWoundsFlag ( k0x0010_ChampionWoundLegs ) ? 2 : 3 ) ;
2016-07-26 11:43:44 +02:00
if ( _vm - > _objectMan - > f33_getIconIndex ( champ - > getSlot ( k5_ChampionSlotFeet ) ) = = k119_IconIndiceArmourElvenBoots )
2016-08-26 22:35:29 +02:00
maximumLoad + = maximumLoad * 16 ;
2016-07-26 11:43:44 +02:00
2016-08-26 22:35:29 +02:00
maximumLoad + = 9 ;
maximumLoad - = maximumLoad % 10 ;
return maximumLoad ;
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f292_drawChampionState ( ChampionIndex champIndex ) {
2016-07-26 14:40:04 +02:00
int16 championStatusBoxX = champIndex * k69_ChampionStatusBoxSpacing ;
Champion * curChampion = & _gK71_champions [ champIndex ] ;
uint16 championAttributes = curChampion - > _attributes ;
if ( ! getFlag ( championAttributes , 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-07-26 14:40:04 +02:00
bool isInventoryChampion = ( _vm - > M0_indexToOrdinal ( champIndex ) = = _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal ) ;
2016-07-07 20:15:38 +02:00
_vm - > _displayMan - > _g578_useByteBoxCoordinates = false ;
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x1000_ChampionAttributeStatusBox ) ) {
Box box ;
box . _y1 = 0 ;
box . _y2 = 28 ;
box . _x1 = championStatusBoxX ;
box . _x2 = box . _x1 + 66 ;
if ( curChampion - > _currHealth ) {
_vm - > _displayMan - > D24_fillScreenBox ( box , k12_ColorDarkestGray ) ;
int16 nativeBitmapIndices [ 3 ] ;
2016-07-07 20:15:38 +02:00
for ( uint16 i = 0 ; i < 3 ; + + i )
2016-07-26 14:40:04 +02:00
nativeBitmapIndices [ i ] = 0 ;
uint16 borderCount = 0 ;
if ( _g407_party . _fireShieldDefense > 0 )
nativeBitmapIndices [ borderCount + + ] = k38_BorderPartyFireshieldIndice ;
if ( _g407_party . _spellShieldDefense > 0 )
nativeBitmapIndices [ borderCount + + ] = k39_BorderPartySpellshieldIndice ;
if ( ( _g407_party . _shieldDefense > 0 ) | | curChampion - > _shieldDefense )
nativeBitmapIndices [ borderCount + + ] = k37_BorderPartyShieldIndice ;
while ( borderCount - - )
_vm - > _displayMan - > f21_blitToScreen ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( nativeBitmapIndices [ borderCount ] ) , & box , k40_byteWidth , k10_ColorFlesh , 29 ) ;
if ( isInventoryChampion ) {
2016-07-07 20:15:38 +02:00
_vm - > _inventoryMan - > f354_drawStatusBoxPortrait ( champIndex ) ;
2016-07-26 14:40:04 +02:00
setFlag ( championAttributes , k0x0100_ChampionAttributeStatistics ) ;
} else
setFlag ( championAttributes , k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x2000_ChampionAttributeWounds | k0x8000_ChampionAttributeActionHand ) ;
2016-08-26 22:35:29 +02:00
} else {
2016-07-26 14:40:04 +02:00
_vm - > _displayMan - > f21_blitToScreen ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k8_StatusBoxDeadChampion ) , & box , k40_byteWidth , kM1_ColorNoTransparency , 29 ) ;
_vm - > _textMan - > f53_printToLogicalScreen ( championStatusBoxX + 1 , 5 , k13_ColorLightestGray , k1_ColorDarkGary , curChampion - > _name ) ;
2016-07-07 20:15:38 +02:00
_vm - > _menuMan - > f386_drawActionIcon ( champIndex ) ;
2016-07-26 14:40:04 +02:00
clearFlag ( curChampion - > _attributes , k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon | k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport | k0x8000_ChampionAttributeActionHand ) ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
return ;
2016-07-07 20:15:38 +02:00
}
}
2016-07-26 14:40:04 +02:00
if ( ! ( curChampion - > _currHealth ) ) {
clearFlag ( curChampion - > _attributes , k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon | k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport | k0x8000_ChampionAttributeActionHand ) ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
return ;
}
if ( getFlag ( championAttributes , k0x0080_ChampionAttributeNameTitle ) ) {
Color nameColor = ( champIndex = = _g411_leaderIndex ) ? k9_ColorGold : k13_ColorLightestGray ;
if ( isInventoryChampion ) {
char * championName = curChampion - > _name ;
_vm - > _textMan - > f52_printToViewport ( 3 , 7 , nameColor , championName ) ;
int16 championTitleX = 6 * strlen ( championName ) + 3 ;
char titleFirstCharacter = curChampion - > _title [ 0 ] ;
if ( ( titleFirstCharacter ! = ' , ' ) & & ( titleFirstCharacter ! = ' ; ' ) & & ( titleFirstCharacter ! = ' - ' ) )
championTitleX + = 6 ;
_vm - > _textMan - > f52_printToViewport ( championTitleX , 7 , nameColor , curChampion - > _title ) ;
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-08-26 22:35:29 +02:00
} else {
2016-07-26 14:40:04 +02:00
Box box ;
box . _y1 = 0 ;
box . _y2 = 6 ;
box . _x1 = championStatusBoxX ;
box . _x2 = box . _x1 + 42 ;
_vm - > _displayMan - > D24_fillScreenBox ( box , k1_ColorDarkGary ) ;
_vm - > _textMan - > f53_printToLogicalScreen ( championStatusBoxX + 1 , 5 , nameColor , k1_ColorDarkGary , curChampion - > _name ) ;
2016-07-07 20:15:38 +02:00
}
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x0100_ChampionAttributeStatistics ) ) {
2016-08-26 22:50:30 +02:00
f287_drawChampionBarGraphs ( champIndex ) ;
2016-07-26 14:40:04 +02:00
if ( isInventoryChampion ) {
f290_drawHealthStaminaManaValues ( curChampion ) ;
int16 nativeBitmapIndex ;
if ( ( curChampion - > _food < 0 ) | | ( curChampion - > _water < 0 ) | | ( curChampion - > _poisonEventCount ) )
nativeBitmapIndex = k34_SlotBoxWoundedIndice ;
else
nativeBitmapIndex = k33_SlotBoxNormalIndice ;
_vm - > _displayMan - > f20_blitToViewport ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( nativeBitmapIndex ) , gBoxMouth , k16_byteWidth , k12_ColorDarkestGray , 18 ) ;
nativeBitmapIndex = k33_SlotBoxNormalIndice ;
for ( int i = k1_ChampionStatStrength ; i < = k6_ChampionStatAntifire ; i + + ) {
if ( ( curChampion - > _statistics [ i ] [ k1_ChampionStatCurrent ] < curChampion - > _statistics [ i ] [ k0_ChampionStatMaximum ] ) ) {
nativeBitmapIndex = k34_SlotBoxWoundedIndice ;
2016-08-26 22:35:29 +02:00
break ;
}
}
2016-07-26 14:40:04 +02:00
_vm - > _displayMan - > f20_blitToViewport ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( nativeBitmapIndex ) , gBoxEye , k16_byteWidth , k12_ColorDarkestGray , 18 ) ;
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-08-26 22:35:29 +02:00
}
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x2000_ChampionAttributeWounds ) ) {
for ( int i = isInventoryChampion ? k5_ChampionSlotFeet : k1_ChampionSlotActionHand ; i > = k0_ChampionSlotReadyHand ; i - - )
f291_drawSlot ( champIndex , i ) ;
if ( isInventoryChampion )
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x0200_ChampionAttributeLoad ) & & isInventoryChampion ) {
uint16 maxLoad = f309_getMaximumLoad ( curChampion ) ;
Color loadColor ;
if ( curChampion - > _load > maxLoad )
loadColor = k8_ColorRed ;
else if ( ( ( long ) curChampion - > _load < < 3 ) > ( ( long ) maxLoad * 5 ) )
loadColor = k11_ColorYellow ;
else
loadColor = k13_ColorLightestGray ;
_vm - > _textMan - > f52_printToViewport ( 104 , 132 , loadColor , " LOAD " ) ;
maxLoad = curChampion - > _load / 10 ;
strcpy ( _vm - > _g353_stringBuildBuffer , f288_getStringFromInteger ( maxLoad , true , 3 ) . c_str ( ) ) ;
2016-07-07 20:15:38 +02:00
strcat ( _vm - > _g353_stringBuildBuffer , " . " ) ;
2016-07-26 14:40:04 +02:00
maxLoad = curChampion - > _load - ( maxLoad * 10 ) ;
strcat ( _vm - > _g353_stringBuildBuffer , f288_getStringFromInteger ( maxLoad , false , 1 ) . c_str ( ) ) ;
2016-07-07 20:15:38 +02:00
strcat ( _vm - > _g353_stringBuildBuffer , " / " ) ;
2016-07-26 14:40:04 +02:00
maxLoad = ( f309_getMaximumLoad ( curChampion ) + 5 ) / 10 ;
strcat ( _vm - > _g353_stringBuildBuffer , f288_getStringFromInteger ( maxLoad , true , 3 ) . c_str ( ) ) ;
2016-07-07 20:15:38 +02:00
strcat ( _vm - > _g353_stringBuildBuffer , " KG " ) ;
2016-07-26 14:40:04 +02:00
_vm - > _textMan - > f52_printToViewport ( 148 , 132 , loadColor , _vm - > _g353_stringBuildBuffer ) ;
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-07-07 20:15:38 +02:00
}
2016-07-26 14:40:04 +02:00
uint16 championIconIndex = M26_championIconIndex ( curChampion - > _cell , _vm - > _dungeonMan - > _g308_partyDir ) ;
if ( getFlag ( championAttributes , k0x0400_ChampionAttributeIcon ) & & ( _vm - > _eventMan - > _g599_useChampionIconOrdinalAsMousePointerBitmap ! = _vm - > M0_indexToOrdinal ( championIconIndex ) ) ) {
_vm - > _displayMan - > D24_fillScreenBox ( g54_BoxChampionIcons [ championIconIndex ] , g46_ChampionColor [ champIndex ] ) ;
_vm - > _displayMan - > f132_blitToBitmap ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k28_ChampionIcons ) , _vm - > _displayMan - > _g348_bitmapScreen , g54_BoxChampionIcons [ championIconIndex ] , _vm - > _championMan - > M26_championIconIndex ( curChampion - > _dir , _vm - > _dungeonMan - > _g308_partyDir ) * 19 , 0 , k40_byteWidth , k160_byteWidthScreen , k12_ColorDarkestGray , 14 , k200_heightScreen ) ;
2016-07-07 20:15:38 +02:00
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x0800_ChampionAttributePanel ) & & isInventoryChampion ) {
if ( _vm - > _g333_pressingMouth )
2016-07-07 20:15:38 +02:00
_vm - > _inventoryMan - > f345_drawPanelFoodWaterPoisoned ( ) ;
2016-07-26 14:40:04 +02:00
else if ( _vm - > _g331_pressingEye ) {
if ( _g415_leaderEmptyHanded )
_vm - > _inventoryMan - > f351_drawChampionSkillsAndStatistics ( ) ;
} else
_vm - > _inventoryMan - > f347_drawPanel ( ) ;
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x8000_ChampionAttributeActionHand ) ) {
2016-08-26 22:50:30 +02:00
f291_drawSlot ( champIndex , k1_ChampionSlotActionHand ) ;
2016-07-07 20:15:38 +02:00
_vm - > _menuMan - > f386_drawActionIcon ( champIndex ) ;
2016-07-26 14:40:04 +02:00
if ( isInventoryChampion )
setFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-26 14:40:04 +02:00
if ( getFlag ( championAttributes , k0x4000_ChampionAttributeViewport ) )
2016-07-07 20:15:38 +02:00
_vm - > _displayMan - > f97_drawViewport ( k0_viewportNotDungeonView ) ;
2016-07-26 14:40:04 +02:00
clearFlag ( curChampion - > _attributes , k0x0080_ChampionAttributeNameTitle | k0x0100_ChampionAttributeStatistics | k0x0200_ChampionAttributeLoad | k0x0400_ChampionAttributeIcon | k0x0800_ChampionAttributePanel | k0x1000_ChampionAttributeStatusBox | k0x2000_ChampionAttributeWounds | k0x4000_ChampionAttributeViewport | k0x8000_ChampionAttributeActionHand ) ;
2016-07-07 20:15:38 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-25 14:35:26 +02:00
uint16 ChampionMan : : M26_championIconIndex ( int16 val , Direction dir ) {
2016-08-26 22:35:29 +02:00
return ( ( val + 4 - dir ) & 0x3 ) ;
}
2016-08-26 22:47:44 +02:00
void ChampionMan : : f290_drawHealthStaminaManaValues ( Champion * champ ) {
f289_drawHealthOrStaminaOrManaValue ( 116 , champ - > _currHealth , champ - > _maxHealth ) ;
f289_drawHealthOrStaminaOrManaValue ( 124 , champ - > _currStamina , champ - > _maxStamina ) ;
f289_drawHealthOrStaminaOrManaValue ( 132 , champ - > _currMana , champ - > _maxMana ) ;
2016-08-26 22:35:29 +02:00
}
2016-07-07 00:46:51 +02:00
void ChampionMan : : f291_drawSlot ( uint16 champIndex , int16 slotIndex ) {
2016-06-23 03:16:36 +02:00
int16 nativeBitmapIndex = - 1 ;
2016-08-26 22:47:44 +02:00
Champion * champ = & _gK71_champions [ champIndex ] ;
bool isInventoryChamp = ( _vm - > _inventoryMan - > _g432_inventoryChampionOrdinal = = _vm - > M0_indexToOrdinal ( champIndex ) ) ;
2016-06-23 03:16:36 +02:00
uint16 slotBoxIndex ;
2016-07-29 18:09:19 +02:00
if ( ! isInventoryChamp ) {
// If drawing a slot for a champion other than the champion whose inventory is open
2016-07-26 14:40:04 +02:00
if ( ( slotIndex > k1_ChampionSlotActionHand ) | | ( _g299_candidateChampionOrdinal = = _vm - > M0_indexToOrdinal ( champIndex ) ) )
2016-06-23 03:16:36 +02:00
return ;
slotBoxIndex = ( champIndex < < 1 ) + slotIndex ;
2016-07-26 14:40:04 +02:00
} else
2016-07-02 12:57:31 +02:00
slotBoxIndex = k8_SlotBoxInventoryFirstSlot + slotIndex ;
2016-06-23 03:16:36 +02:00
Thing thing ;
2016-07-26 14:40:04 +02:00
if ( slotIndex > = k30_ChampionSlotChest_1 )
2016-07-02 12:57:31 +02:00
thing = _vm - > _inventoryMan - > _g425_chestSlots [ slotIndex - k30_ChampionSlotChest_1 ] ;
2016-07-26 14:40:04 +02:00
else
2016-07-07 00:46:51 +02:00
thing = champ - > getSlot ( ( ChampionSlot ) slotIndex ) ;
2016-06-23 03:16:36 +02:00
2016-07-02 12:57:31 +02:00
SlotBox * slotBox = & _vm - > _objectMan - > _g30_slotBoxes [ slotBoxIndex ] ;
2016-06-23 03:16:36 +02:00
Box box ;
box . _x1 = slotBox - > _x - 1 ;
box . _y1 = slotBox - > _y - 1 ;
2016-07-03 03:07:38 +02:00
box . _x2 = box . _x1 + 17 ;
box . _y2 = box . _y1 + 17 ;
2016-06-23 03:16:36 +02:00
2016-07-26 14:40:04 +02:00
if ( ! isInventoryChamp )
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-06-23 03:16:36 +02:00
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-07-26 14:40:04 +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-26 14:40:04 +02:00
if ( ( slotIndex > = k10_ChampionSlotNeck ) & & ( slotIndex < = k13_ChampionSlotBackpackLine_1_1 ) )
2016-07-02 01:55:48 +02:00
iconIndex = k208_IconIndiceNeck + ( slotIndex - k10_ChampionSlotNeck ) ;
2016-07-26 14:40:04 +02:00
else
2016-07-02 01:55:48 +02:00
iconIndex = k204_IconIndiceEmptyBox ;
2016-06-23 03:16:36 +02:00
}
} else {
2016-08-26 22:47:44 +02:00
iconIndex = _vm - > _objectMan - > f33_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
iconIndex + + ;
} // BUG2_00
2016-07-02 01:55:48 +02:00
if ( slotIndex < = k5_ChampionSlotFeet ) {
2016-07-26 14:40:04 +02:00
if ( champ - > getWoundsFlag ( ( ChampionWound ) ( 1 < < slotIndex ) ) )
2016-07-02 00:27:05 +02:00
nativeBitmapIndex = k34_SlotBoxWoundedIndice ;
2016-07-26 14:40:04 +02:00
else
2016-07-02 00:27:05 +02:00
nativeBitmapIndex = k33_SlotBoxNormalIndice ;
2016-06-23 03:16:36 +02:00
}
}
2016-07-26 14:40:04 +02:00
if ( ( slotIndex = = k1_ChampionSlotActionHand ) & & ( _vm - > M0_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-07-29 18:09:19 +02:00
if ( isInventoryChamp )
2016-07-03 21:12:47 +02:00
_vm - > _displayMan - > f132_blitToBitmap ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( nativeBitmapIndex ) ,
_vm - > _displayMan - > _g296_bitmapViewport , box , 0 , 0 , 16 , k112_byteWidthViewport , k12_ColorDarkestGray ) ;
2016-07-29 18:09:19 +02:00
else
2016-07-03 21:12:47 +02:00
_vm - > _displayMan - > f132_blitToBitmap ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( nativeBitmapIndex ) ,
_vm - > _displayMan - > _g348_bitmapScreen , box , 0 , 0 , 16 , k160_byteWidthScreen , k12_ColorDarkestGray ) ;
2016-06-23 03:16:36 +02:00
}
2016-08-26 22:47:44 +02:00
_vm - > _objectMan - > f38_drawIconInSlotBox ( slotBoxIndex , iconIndex ) ;
2016-06-23 03:16:36 +02:00
2016-07-26 14:40:04 +02:00
if ( ! isInventoryChamp )
2016-07-07 00:46:51 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-08-26 22:35:29 +02:00
}
2016-06-23 03:16:36 +02:00
2016-08-26 22:47:44 +02:00
void ChampionMan : : f281_renameChampion ( Champion * champ ) {
2016-07-28 17:53:42 +02:00
# define k1_RENAME_CHAMPION_NAME 1
# define k2_RENAME_CHAMPION_TITLE 2
2016-08-26 22:50:57 +02:00
static const char underscoreCharacterString [ 2 ] = " _ " ;
static char renameChampionInputCharacterString [ 2 ] = " " ;
static const char reincarnateSpecialCharacters [ 6 ] = { ' , ' , ' . ' , ' ; ' , ' : ' , ' ' } ;
Box displayBox ;
displayBox . _y1 = 3 ;
displayBox . _y2 = 8 ;
displayBox . _x1 = 3 ;
displayBox . _x2 = displayBox . _x1 + 167 ;
_vm - > _displayMan - > f135_fillBoxBitmap ( _vm - > _displayMan - > _g296_bitmapViewport , displayBox , k12_ColorDarkestGray , k112_byteWidthViewport , k136_heightViewport ) ;
2016-07-28 17:53:42 +02:00
_vm - > _displayMan - > f20_blitToViewport ( _vm - > _displayMan - > f489_getNativeBitmapOrGraphic ( k27_PanelRenameChampionIndice ) , g32_BoxPanel , k72_byteWidth , k4_ColorCyan , 73 ) ;
_vm - > _textMan - > f52_printToViewport ( 177 , 58 , k13_ColorLightestGray , " _______ " ) ;
_vm - > _textMan - > f52_printToViewport ( 105 , 76 , k13_ColorLightestGray , " ___________________ " ) ;
_vm - > _eventMan - > f78_showMouse ( ) ;
_vm - > _displayMan - > f97_drawViewport ( k0_viewportNotDungeonView ) ;
_vm - > _eventMan - > f67_setMousePointerToNormal ( k0_pointerArrow ) ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:50:57 +02:00
uint16 curCharacterIndex = 0 ;
champ - > _name [ curCharacterIndex ] = ' \0 ' ;
2016-07-28 17:53:42 +02:00
champ - > _title [ 0 ] = ' \0 ' ;
2016-08-26 22:50:57 +02:00
int16 renamedChampionStringMode = k1_RENAME_CHAMPION_NAME ;
char * renamedChampionString = champ - > _name ;
int16 textPosX = 177 ;
int16 textPosY = 91 ;
2016-06-25 13:31:47 +02:00
2016-07-28 17:53:42 +02:00
for ( ; ; ) { /*_Infinite loop_*/
2016-08-26 22:50:57 +02:00
bool championTitleIsFull = ( ( renamedChampionStringMode = = k2_RENAME_CHAMPION_TITLE ) & & ( curCharacterIndex = = 19 ) ) ;
if ( ! championTitleIsFull ) {
2016-07-28 17:53:42 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-08-26 22:50:57 +02:00
_vm - > _textMan - > f40_printTextToBitmap ( _vm - > _displayMan - > _g348_bitmapScreen , k160_byteWidthScreen , textPosX , textPosY , k9_ColorGold , k12_ColorDarkestGray , underscoreCharacterString , k200_heightScreen ) ;
2016-07-28 17:53:42 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
}
2016-08-26 22:50:57 +02:00
int16 curCharacter = 256 ;
while ( curCharacter = = 256 ) {
2016-07-28 17:53:42 +02:00
Common : : Event event ;
2016-08-26 22:50:57 +02:00
Common : : EventType eventType = _vm - > _eventMan - > processInput ( & event , & event ) ;
_vm - > _displayMan - > updateScreen ( ) ;
_vm - > f22_delay ( 1 ) ;
2016-07-29 18:09:19 +02:00
if ( eventType = = Common : : EVENT_LBUTTONDOWN ) {
// If left mouse button status has changed
2016-07-28 17:53:42 +02:00
Common : : Point mousePos = _vm - > _eventMan - > getMousePos ( ) ;
2016-08-26 22:50:57 +02:00
if ( ( renamedChampionStringMode = = k2_RENAME_CHAMPION_TITLE | | ( curCharacterIndex > 0 ) ) & & ( mousePos . x > = 197 ) & & ( mousePos . x < = 215 ) & & ( mousePos . y > = 147 ) & & ( mousePos . y < = 155 ) ) { /* Coordinates of 'OK' button */
int16 characterIndexBackup = curCharacterIndex ;
char L0821_ac_ChampionNameBackupString [ 8 ] ;
renamedChampionString = champ - > _name ;
strcpy ( L0821_ac_ChampionNameBackupString , renamedChampionString ) ;
curCharacterIndex = strlen ( renamedChampionString ) ;
// Replace space characters on the right of the champion name by '\0' characters
2016-07-29 18:09:19 +02:00
while ( renamedChampionString [ - - curCharacterIndex ] = = ' ' )
2016-08-26 22:50:57 +02:00
renamedChampionString [ curCharacterIndex ] = ' \0 ' ;
bool found = false ;
for ( uint16 idx = k0_ChampionFirst ; idx < _vm - > _championMan - > _g305_partyChampionCount - 1 ; idx + + ) {
if ( ! strcmp ( _vm - > _championMan - > _gK71_champions [ idx ] . _name , renamedChampionString ) ) {
2016-07-29 18:09:19 +02:00
// If an existing champion already has the specified name for the new champion
2016-08-26 22:50:57 +02:00
found = true ;
break ;
}
2016-07-28 17:53:42 +02:00
}
2016-08-26 22:50:57 +02:00
if ( ! found )
return ;
if ( renamedChampionStringMode = = k2_RENAME_CHAMPION_TITLE )
renamedChampionString = champ - > _title ;
strcpy ( renamedChampionString = champ - > _name , L0821_ac_ChampionNameBackupString ) ;
curCharacterIndex = characterIndexBackup ;
2016-07-28 17:53:42 +02:00
} else {
if ( ( mousePos . x > = 107 ) & & ( mousePos . x < = 175 ) & & ( mousePos . y > = 147 ) & & ( mousePos . y < = 155 ) ) { /* Coordinates of 'BACKSPACE' button */
2016-08-26 22:50:57 +02:00
curCharacter = ' \b ' ;
2016-07-28 17:53:42 +02:00
break ;
}
2016-07-29 18:09:19 +02:00
#if 0
2016-07-28 17:53:42 +02:00
if ( ( mousePos . x < 107 ) | | ( mousePos . x > 215 ) | | ( mousePos . y < 116 ) | | ( mousePos . y > 144 ) ) { /* Coordinates of table of all other characters */
//goto T0281023;
}
if ( ! ( ( mousePos . x + 4 ) % 10 ) | | ( ! ( ( mousePos . y + 5 ) % 10 ) & & ( ( mousePos . x < 207 ) | | ( mousePos . y ! = 135 ) ) ) ) {
//goto T0281023;
}
2016-07-29 18:09:19 +02:00
# endif
2016-08-26 22:50:57 +02:00
curCharacter = ' A ' + ( 11 * ( ( mousePos . y - 116 ) / 10 ) ) + ( ( mousePos . x - 107 ) / 10 ) ;
2016-07-29 18:09:19 +02:00
if ( ( curCharacter = = 86 ) | | ( curCharacter = = 97 ) ) {
// The 'Return' button occupies two cells in the table
2016-08-26 22:50:57 +02:00
curCharacter = ' \r ' ; /* Carriage return */
2016-07-28 17:53:42 +02:00
break ;
}
2016-07-29 18:09:19 +02:00
if ( curCharacter > = 87 )
// Compensate for the first cell occupied by 'Return' button
2016-08-26 22:50:57 +02:00
curCharacter - - ;
if ( curCharacter > ' Z ' )
curCharacter = reincarnateSpecialCharacters [ ( curCharacter - ' Z ' ) - 1 ] ;
2016-07-28 17:53:42 +02:00
break ;
}
2016-08-26 22:50:57 +02:00
} else if ( eventType = = Common : : EVENT_KEYDOWN )
curCharacter = event . kbd . ascii ;
2016-07-28 17:53:42 +02:00
}
2016-06-23 03:16:36 +02:00
2016-08-26 22:50:57 +02:00
if ( ( curCharacter > = ' a ' ) & & ( curCharacter < = ' z ' ) )
curCharacter - = 32 ; // Convert to uppercase
if ( ( ( curCharacter > = ' A ' ) & & ( curCharacter < = ' Z ' ) ) | | ( curCharacter = = ' . ' ) | | ( curCharacter = = ' , ' ) | | ( curCharacter = = ' ; ' ) | | ( curCharacter = = ' : ' ) | | ( curCharacter = = ' ' ) ) {
if ( ( curCharacter ! = ' ' ) | | curCharacterIndex ! = 0 ) {
if ( ! championTitleIsFull ) {
renameChampionInputCharacterString [ 0 ] = curCharacter ;
2016-07-28 17:53:42 +02:00
_vm - > _eventMan - > f78_showMouse ( ) ;
2016-08-26 22:50:57 +02:00
_vm - > _textMan - > f40_printTextToBitmap ( _vm - > _displayMan - > _g348_bitmapScreen , k160_byteWidthScreen , textPosX , textPosY , k13_ColorLightestGray , k12_ColorDarkestGray , renameChampionInputCharacterString , k200_heightScreen ) ;
2016-07-28 17:53:42 +02:00
_vm - > _eventMan - > f77_hideMouse ( ) ;
2016-08-26 22:50:57 +02:00
renamedChampionString [ curCharacterIndex + + ] = curCharacter ;
renamedChampionString [ curCharacterIndex ] = ' \0 ' ;
textPosX + = 6 ;
if ( ( renamedChampionStringMode = = k1_RENAME_CHAMPION_NAME ) & & ( curCharacterIndex = = 7 ) ) {
renamedChampionStringMode = k2_RENAME_CHAMPION_TITLE ;
renamedChampionString = champ - > _title ;
textPosX = 105 ;
textPosY = 109 ;
curCharacterIndex = 0 ;
}
2016-07-28 17:53:42 +02:00
}
}
2016-07-29 18:09:19 +02:00
} else if ( curCharacter = = ' \r ' ) { // Carriage return
2016-08-26 22:50:57 +02:00
if ( ( renamedChampionStringMode = = k1_RENAME_CHAMPION_NAME ) & & ( curCharacterIndex > 0 ) ) {
_vm - > _eventMan - > f78_showMouse ( ) ;
_vm - > _textMan - > f40_printTextToBitmap ( _vm - > _displayMan - > _g348_bitmapScreen , k160_byteWidthScreen , textPosX , textPosY , k13_ColorLightestGray , k12_ColorDarkestGray , underscoreCharacterString , k200_heightScreen ) ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
renamedChampionStringMode = k2_RENAME_CHAMPION_TITLE ;
renamedChampionString = champ - > _title ;
textPosX = 105 ;
textPosY = 109 ;
curCharacterIndex = 0 ;
}
2016-07-29 18:09:19 +02:00
} else if ( curCharacter = = ' \b ' ) { // Backspace
2016-08-26 22:50:57 +02:00
if ( ( renamedChampionStringMode = = k1_RENAME_CHAMPION_NAME ) & & ( curCharacterIndex = = 0 ) )
continue ;
if ( ! championTitleIsFull ) {
_vm - > _eventMan - > f78_showMouse ( ) ;
_vm - > _textMan - > f40_printTextToBitmap ( _vm - > _displayMan - > _g348_bitmapScreen , k160_byteWidthScreen , textPosX , textPosY , k13_ColorLightestGray , k12_ColorDarkestGray , underscoreCharacterString , k200_heightScreen ) ;
_vm - > _eventMan - > f77_hideMouse ( ) ;
}
if ( curCharacterIndex = = 0 ) {
renamedChampionString = champ - > _name ;
curCharacterIndex = strlen ( renamedChampionString ) - 1 ;
renamedChampionStringMode = k1_RENAME_CHAMPION_NAME ;
textPosX = 177 + ( curCharacterIndex * 6 ) ;
textPosY = 91 ;
2016-07-28 17:53:42 +02:00
} else {
2016-08-26 22:50:57 +02:00
curCharacterIndex - - ;
textPosX - = 6 ;
2016-07-28 17:53:42 +02:00
}
2016-08-26 22:50:57 +02:00
renamedChampionString [ curCharacterIndex ] = ' \0 ' ;
2016-06-25 13:31:47 +02:00
}
}
}
2016-06-28 01:50:02 +02:00
2016-07-13 17:49:49 +02:00
uint16 ChampionMan : : f303_getSkillLevel ( int16 champIndex , uint16 skillIndex ) {
2016-07-29 10:58:35 +02:00
if ( _vm - > _championMan - > _g300_partyIsSleeping )
2016-06-28 01:50:02 +02:00
return 1 ;
2016-07-29 10:58:35 +02:00
2016-07-13 17:49:49 +02:00
bool ignoreTmpExp = getFlag ( skillIndex , k0x8000_IgnoreTemporaryExperience ) ;
bool ignoreObjModifiers = getFlag ( skillIndex , k0x4000_IgnoreObjectModifiers ) ;
clearFlag ( skillIndex , k0x8000_IgnoreTemporaryExperience | k0x4000_IgnoreObjectModifiers ) ;
Champion * champ = & _vm - > _championMan - > _gK71_champions [ champIndex ] ;
Skill * skill = & champ - > _skills [ skillIndex ] ;
int32 exp = skill - > _experience ;
2016-07-29 10:58:35 +02:00
if ( ! ignoreTmpExp )
2016-07-13 17:49:49 +02:00
exp + = skill - > _temporaryExperience ;
2016-07-29 10:58:35 +02:00
2016-07-29 18:09:19 +02:00
if ( skillIndex > k3_ChampionSkillWizard ) {
// Hidden skill
2016-07-13 17:49:49 +02:00
skill = & champ - > _skills [ ( skillIndex - k4_ChampionSkillSwing ) > > 2 ] ;
2016-07-29 18:09:19 +02:00
exp + = skill - > _experience ; // Add experience in the base skill
2016-07-29 10:58:35 +02:00
if ( ! ignoreTmpExp )
2016-07-13 17:49:49 +02:00
exp + = skill - > _temporaryExperience ;
2016-07-29 10:58:35 +02:00
2016-07-29 18:09:19 +02:00
exp > > = 1 ; // Halve experience to get average of base skill + hidden skill experience
2016-07-13 17:49:49 +02:00
}
2016-06-28 01:50:02 +02:00
int16 skillLevel = 1 ;
2016-07-13 17:49:49 +02:00
while ( exp > = 500 ) {
exp > > = 1 ;
2016-06-28 01:50:02 +02:00
skillLevel + + ;
}
if ( ! ignoreObjModifiers ) {
2016-07-29 10:58:35 +02:00
int16 actionHandIconIndex = _vm - > _objectMan - > f33_getIconIndex ( champ - > _slots [ k1_ChampionSlotActionHand ] ) ;
if ( actionHandIconIndex = = k27_IconIndiceWeaponTheFirestaff )
2016-06-28 01:50:02 +02:00
skillLevel + + ;
2016-07-29 10:58:35 +02:00
else if ( actionHandIconIndex = = k28_IconIndiceWeaponTheFirestaffComplete )
skillLevel + = 2 ;
2016-07-13 17:49:49 +02:00
int16 neckIconIndex = _vm - > _objectMan - > f33_getIconIndex ( champ - > _slots [ k10_ChampionSlotNeck ] ) ;
2016-06-28 01:50:02 +02:00
switch ( skillIndex ) {
2016-07-02 01:55:48 +02:00
case k3_ChampionSkillWizard :
2016-07-29 10:58:35 +02:00
if ( neckIconIndex = = k124_IconIndiceJunkPendantFeral )
2016-07-13 17:49:49 +02:00
skillLevel + = 1 ;
2016-06-28 01:50:02 +02:00
break ;
2016-07-02 01:55:48 +02:00
case k13_ChampionSkillHeal :
2016-07-29 10:58:35 +02:00
// The skill modifiers of these two objects are not cumulative
if ( ( neckIconIndex = = k120_IconIndiceJunkGemOfAges ) | | ( actionHandIconIndex = = k66_IconIndiceWeaponSceptreOfLyf ) )
2016-07-13 17:49:49 +02:00
skillLevel + = 1 ;
2016-06-28 01:50:02 +02:00
break ;
2016-07-02 01:55:48 +02:00
case k14_ChampionSkillInfluence :
2016-07-29 10:58:35 +02:00
if ( neckIconIndex = = k122_IconIndiceJunkMoonstone )
2016-07-13 17:49:49 +02:00
skillLevel + = 1 ;
2016-07-29 10:58:35 +02:00
break ;
case k15_ChampionSkillDefend :
if ( neckIconIndex = = k121_IconIndiceJunkEkkhardCross )
skillLevel + = 1 ;
break ;
default :
break ;
2016-06-28 01:50:02 +02:00
}
}
return skillLevel ;
}
2016-06-23 03:16:36 +02:00
}