2016-08-09 12:17:18 +00: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-09-03 08:38:43 +00:00
# include "dm/menus.h"
# include "dm/gfx.h"
# include "dm/champion.h"
# include "dm/dungeonman.h"
# include "dm/objectman.h"
# include "dm/inventory.h"
# include "dm/text.h"
# include "dm/eventman.h"
# include "dm/timeline.h"
# include "dm/movesens.h"
# include "dm/group.h"
# include "dm/projexpl.h"
# include "dm/sounds.h"
2016-08-09 12:17:18 +00:00
namespace DM {
2016-08-22 21:24:49 +00:00
void MenuMan : : initConstants ( ) {
static unsigned char actionSkillIndex [ 44 ] = { // @ G0496_auc_Graphic560_ActionSkillIndex
0 , /* N */
7 , /* BLOCK */
6 , /* CHOP */
0 , /* X */
14 , /* BLOW HORN */
12 , /* FLIP */
9 , /* PUNCH */
9 , /* KICK */
7 , /* WAR CRY Atari ST Versions 1.0 1987-12-08 1987-12-11 1.1: 14 */
9 , /* STAB */
8 , /* CLIMB DOWN */
14 , /* FREEZE LIFE */
9 , /* HIT */
4 , /* SWING */
5 , /* STAB */
5 , /* THRUST */
5 , /* JAB */
7 , /* PARRY */
4 , /* HACK */
4 , /* BERZERK */
16 , /* FIREBALL */
17 , /* DISPELL */
14 , /* CONFUSE */
17 , /* LIGHTNING */
17 , /* DISRUPT */
6 , /* MELEE */
8 , /* X */
3 , /* INVOKE */
4 , /* SLASH */
4 , /* CLEAVE */
6 , /* BASH */
6 , /* STUN */
11 , /* SHOOT */
15 , /* SPELLSHIELD */
15 , /* FIRESHIELD */
3 , /* FLUXCAGE */
13 , /* HEAL */
14 , /* CALM */
17 , /* LIGHT */
18 , /* WINDOW */
16 , /* SPIT */
14 , /* BRANDISH */
10 , /* THROW */
2016-09-03 19:42:58 +00:00
3 /* FUSE */
2016-08-22 21:24:49 +00:00
} ;
2016-09-04 09:24:22 +00:00
static unsigned char actionDisabledTicks [ 44 ] = {
0 , /* N */
6 , /* BLOCK */
8 , /* CHOP */
0 , /* X */
6 , /* BLOW HORN */
3 , /* FLIP */
1 , /* PUNCH */
5 , /* KICK */
3 , /* WAR CRY */
5 , /* STAB */
35 , /* CLIMB DOWN */
20 , /* FREEZE LIFE */
4 , /* HIT */
6 , /* SWING */
10 , /* STAB */
16 , /* THRUST */
2 , /* JAB */
18 , /* PARRY */
8 , /* HACK */
30 , /* BERZERK */
42 , /* FIREBALL */
31 , /* DISPELL */
10 , /* CONFUSE */
38 , /* LIGHTNING */
9 , /* DISRUPT */
20 , /* MELEE */
10 , /* X */
16 , /* INVOKE */
4 , /* SLASH */
12 , /* CLEAVE */
20 , /* BASH */
7 , /* STUN */
14 , /* SHOOT */
30 , /* SPELLSHIELD */
35 , /* FIRESHIELD */
2 , /* FLUXCAGE */
19 , /* HEAL */
9 , /* CALM */
10 , /* LIGHT */
15 , /* WINDOW */
22 , /* SPIT */
10 , /* BRANDISH */
0 , /* THROW */
2 /* FUSE */
} ;
2016-08-22 21:24:49 +00:00
2016-08-25 19:59:02 +00:00
_boxActionArea1ActionMenu = Box ( 224 , 319 , 77 , 97 ) ; // @ G0501_s_Graphic560_Box_ActionArea1ActionMenu
_boxActionArea2ActionMenu = Box ( 224 , 319 , 77 , 109 ) ; // @ G0500_s_Graphic560_Box_ActionArea2ActionsMenu
_boxActionArea3ActionMenu = Box ( 224 , 319 , 77 , 121 ) ; // @ G0499_s_Graphic560_Box_ActionArea3ActionsMenu
2016-09-10 19:50:57 +00:00
_boxActionArea = Box ( 224 , 319 , 77 , 121 ) ; // @ G0001_s_Graphic562_Box_ActionArea
2016-08-25 19:59:02 +00:00
_boxSpellArea = Box ( 224 , 319 , 42 , 74 ) ;
2016-08-22 21:24:49 +00:00
2016-09-04 09:24:22 +00:00
for ( int i = 0 ; i < 44 ; i + + ) {
2016-08-25 19:59:02 +00:00
_actionSkillIndex [ i ] = actionSkillIndex [ i ] ;
2016-09-04 09:24:22 +00:00
_actionDisabledTicks [ i ] = actionDisabledTicks [ i ] ;
}
2016-08-22 21:24:49 +00:00
}
2016-08-09 12:17:18 +00:00
MenuMan : : MenuMan ( DMEngine * vm ) : _vm ( vm ) {
2016-08-25 19:59:02 +00:00
_refreshActionArea = false ;
_actionAreaContainsIcons = false ;
_actionDamage = 0 ;
_actionList . resetToZero ( ) ;
_bitmapSpellAreaLine = new byte [ 96 * 12 ] ;
_bitmapSpellAreaLines = new byte [ 3 * 96 * 12 ] ;
_actionTargetGroupThing = Thing ( 0 ) ;
_actionCount = 0 ;
2016-08-22 21:24:49 +00:00
initConstants ( ) ;
2016-08-09 12:17:18 +00:00
}
MenuMan : : ~ MenuMan ( ) {
2016-08-25 19:59:02 +00:00
delete [ ] _bitmapSpellAreaLine ;
2016-09-20 21:26:23 +00:00
delete [ ] _bitmapSpellAreaLines ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawMovementArrows ( ) {
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-21 05:53:54 +00:00
_vm - > _displayMan - > blitToScreen ( _vm - > _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxMovementArrows ) ,
2016-09-16 05:46:10 +00:00
& _vm - > _displayMan - > _boxMovementArrows , k48_byteWidth , kDMColorNoTransparency , 45 ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : clearActingChampion ( ) {
2016-08-09 12:17:18 +00:00
ChampionMan & cm = * _vm - > _championMan ;
2016-08-23 05:54:16 +00:00
if ( cm . _actingChampionOrdinal ) {
cm . _actingChampionOrdinal - - ;
2016-09-09 05:32:32 +00:00
cm . _champions [ cm . _actingChampionOrdinal ] . setAttributeFlag ( kDMAttributeActionHand , true ) ;
2016-08-23 05:54:16 +00:00
cm . drawChampionState ( ( ChampionIndex ) cm . _actingChampionOrdinal ) ;
2016-09-09 05:12:36 +00:00
cm . _actingChampionOrdinal = _vm - > indexToOrdinal ( kDMChampionNone ) ;
2016-08-25 19:59:02 +00:00
_refreshActionArea = true ;
2016-08-09 12:17:18 +00:00
}
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawActionIcon ( ChampionIndex championIndex ) {
2016-08-22 21:24:49 +00:00
static byte palChangesActionAreaObjectIcon [ 16 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 40 , 0 , 0 , 0 } ; // @ G0498_auc_Graphic560_PaletteChanges_ActionAreaObjectIcon
2016-08-25 19:59:02 +00:00
if ( ! _actionAreaContainsIcons )
2016-08-09 12:17:18 +00:00
return ;
DisplayMan & dm = * _vm - > _displayMan ;
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
2016-09-26 19:12:51 +00:00
Champion & champion = championMan . _champions [ championIndex ] ;
2016-08-09 12:17:18 +00:00
Box box ;
2016-09-16 19:17:02 +00:00
box . _rect . left = championIndex * 22 + 233 ;
box . _rect . right = box . _rect . left + 19 ;
box . _rect . top = 86 ;
box . _rect . bottom = 120 ;
2016-08-25 16:32:03 +00:00
dm . _useByteBoxCoordinates = false ;
2016-08-09 12:17:18 +00:00
if ( ! champion . _currHealth ) {
2016-09-16 05:46:10 +00:00
dm . fillScreenBox ( box , kDMColorBlack ) ;
2016-08-09 12:17:18 +00:00
return ;
}
2016-08-25 16:32:03 +00:00
byte * bitmapIcon = dm . _tmpBitmap ;
2016-09-10 09:47:36 +00:00
Thing thing = champion . getSlot ( kDMSlotActionHand ) ;
2016-08-09 12:17:18 +00:00
IconIndice iconIndex ;
if ( thing = = Thing : : _none ) {
2016-09-08 23:09:25 +00:00
iconIndex = kDMIconIndiceActionEmptyHand ;
2016-09-27 22:29:07 +00:00
} else if ( dungeon . _objectInfos [ dungeon . getObjectInfoIndex ( thing ) ] . _actionSetIndex ) {
2016-08-25 20:19:34 +00:00
iconIndex = _vm - > _objectMan - > getIconIndex ( thing ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-16 05:46:10 +00:00
dm . fillBitmap ( bitmapIcon , kDMColorCyan , 16 , 16 ) ;
2016-08-09 12:17:18 +00:00
goto T0386006 ;
}
2016-08-25 20:19:34 +00:00
_vm - > _objectMan - > extractIconFromBitmap ( iconIndex , bitmapIcon ) ;
2016-08-25 16:32:03 +00:00
dm . blitToBitmapShrinkWithPalChange ( bitmapIcon , bitmapIcon , 16 , 16 , 16 , 16 , palChangesActionAreaObjectIcon ) ;
2016-08-09 12:17:18 +00:00
T0386006 :
2016-09-16 05:46:10 +00:00
dm . fillScreenBox ( box , kDMColorCyan ) ;
2016-08-09 12:17:18 +00:00
Box box2 ;
2016-09-16 19:17:02 +00:00
box2 . _rect . left = box . _rect . left + 2 ;
box2 . _rect . right = box . _rect . right - 2 ;
box2 . _rect . top = 95 ;
box2 . _rect . bottom = 110 ;
2016-09-16 05:46:10 +00:00
dm . blitToScreen ( bitmapIcon , & box2 , k8_byteWidth , kDMColorNoTransparency , 16 ) ;
2016-09-26 19:12:51 +00:00
if ( champion . getAttributes ( kDMAttributeDisableAction ) | | championMan . _candidateChampionOrdinal | | championMan . _partyIsSleeping )
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > shadeScreenBox ( & box , kDMColorBlack ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawDisabledMenu ( ) {
2016-09-26 19:12:51 +00:00
InventoryMan & inventory = * _vm - > _inventoryMan ;
2016-08-23 05:54:16 +00:00
if ( ! _vm - > _championMan - > _partyIsSleeping ) {
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightBoxDisable ( ) ;
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-26 19:12:51 +00:00
if ( inventory . _inventoryChampionOrdinal ) {
if ( inventory . _panelContent = = kDMPanelContentChest ) {
inventory . closeChest ( ) ;
2016-08-09 12:17:18 +00:00
}
} else {
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > shadeScreenBox ( & _vm - > _displayMan - > _boxMovementArrows , kDMColorBlack ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > shadeScreenBox ( & _boxSpellArea , kDMColorBlack ) ;
_vm - > _displayMan - > shadeScreenBox ( & _boxActionArea , kDMColorBlack ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > setMousePointerToNormal ( k0_pointerArrow ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-08-25 19:59:02 +00:00
void MenuMan : : refreshActionAreaAndSetChampDirMaxDamageReceived ( ) {
2016-08-09 12:17:18 +00:00
ChampionMan & champMan = * _vm - > _championMan ;
2016-08-23 05:54:16 +00:00
if ( ! champMan . _partyChampionCount )
2016-08-09 12:17:18 +00:00
return ;
Champion * champ = nullptr ;
2016-08-23 05:54:16 +00:00
if ( champMan . _partyIsSleeping | | champMan . _candidateChampionOrdinal ) {
if ( champMan . _actingChampionOrdinal ) {
2016-08-25 19:59:02 +00:00
clearActingChampion ( ) ;
2016-08-09 12:17:18 +00:00
return ;
}
2016-08-23 05:54:16 +00:00
if ( ! champMan . _candidateChampionOrdinal )
2016-08-09 12:17:18 +00:00
return ;
} else {
2016-08-23 05:54:16 +00:00
champ = champMan . _champions ;
2016-09-09 05:12:36 +00:00
int16 champIndex = kDMChampionFirst ;
2016-08-09 12:17:18 +00:00
do {
2016-08-23 05:54:16 +00:00
if ( ( champIndex ! = champMan . _leaderIndex )
2016-08-23 21:36:18 +00:00
& & ( _vm - > indexToOrdinal ( champIndex ) ! = champMan . _actingChampionOrdinal )
2016-08-09 12:17:18 +00:00
& & ( champ - > _maximumDamageReceived )
& & ( champ - > _dir ! = champ - > _directionMaximumDamageReceived ) ) {
champ - > _dir = ( Direction ) champ - > _directionMaximumDamageReceived ;
2016-09-09 05:32:32 +00:00
champ - > setAttributeFlag ( kDMAttributeIcon , true ) ;
2016-08-23 05:54:16 +00:00
champMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-08-09 12:17:18 +00:00
}
champ - > _maximumDamageReceived = 0 ;
champ + + ;
champIndex + + ;
2016-08-23 05:54:16 +00:00
} while ( champIndex < champMan . _partyChampionCount ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
if ( _refreshActionArea ) {
2016-08-23 05:54:16 +00:00
if ( ! champMan . _actingChampionOrdinal ) {
2016-08-25 19:59:02 +00:00
if ( _actionDamage ) {
drawActionDamage ( _actionDamage ) ;
_actionDamage = 0 ;
2016-08-09 12:17:18 +00:00
} else {
2016-08-25 19:59:02 +00:00
_actionAreaContainsIcons = true ;
drawActionArea ( ) ;
2016-08-09 12:17:18 +00:00
}
} else {
2016-08-25 19:59:02 +00:00
_actionAreaContainsIcons = false ;
2016-09-09 05:32:32 +00:00
champ - > setAttributeFlag ( kDMAttributeActionHand , true ) ;
2016-08-23 21:36:18 +00:00
champMan . drawChampionState ( ( ChampionIndex ) _vm - > ordinalToIndex ( champMan . _actingChampionOrdinal ) ) ;
2016-08-25 19:59:02 +00:00
drawActionArea ( ) ;
2016-08-09 12:17:18 +00:00
}
}
}
# define k7_ChampionNameMaximumLength 7 // @ C007_CHAMPION_NAME_MAXIMUM_LENGTH
# define k12_ActionNameMaximumLength 12 // @ C012_ACTION_NAME_MAXIMUM_LENGTH
2016-08-25 19:59:02 +00:00
void MenuMan : : drawActionArea ( ) {
2016-08-09 12:17:18 +00:00
DisplayMan & dispMan = * _vm - > _displayMan ;
ChampionMan & champMan = * _vm - > _championMan ;
TextMan & textMan = * _vm - > _textMan ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-25 16:32:03 +00:00
dispMan . _useByteBoxCoordinates = false ;
2016-09-16 05:46:10 +00:00
dispMan . fillScreenBox ( _boxActionArea , kDMColorBlack ) ;
2016-08-25 19:59:02 +00:00
if ( _actionAreaContainsIcons ) {
2016-09-09 05:12:36 +00:00
for ( uint16 champIndex = kDMChampionFirst ; champIndex < champMan . _partyChampionCount ; + + champIndex )
2016-08-25 19:59:02 +00:00
drawActionIcon ( ( ChampionIndex ) champIndex ) ;
2016-08-23 05:54:16 +00:00
} else if ( champMan . _actingChampionOrdinal ) {
2016-08-25 19:59:02 +00:00
Box box = _boxActionArea3ActionMenu ;
2016-09-10 12:31:49 +00:00
if ( _actionList . _actionIndices [ 2 ] = = kDMActionNone )
2016-08-25 19:59:02 +00:00
box = _boxActionArea2ActionMenu ;
2016-09-10 12:31:49 +00:00
if ( _actionList . _actionIndices [ 1 ] = = kDMActionNone )
2016-08-25 19:59:02 +00:00
box = _boxActionArea1ActionMenu ;
2016-09-21 05:53:54 +00:00
dispMan . blitToScreen ( _vm - > _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxMenuActionArea ) ,
2016-09-16 05:46:10 +00:00
& box , k48_byteWidth , kDMColorNoTransparency , 45 ) ;
2016-08-25 20:38:03 +00:00
textMan . printWithTrailingSpaces ( dispMan . _bitmapScreen , k160_byteWidthScreen ,
2016-09-16 05:46:10 +00:00
235 , 83 , kDMColorBlack , kDMColorCyan , champMan . _champions [ _vm - > ordinalToIndex ( champMan . _actingChampionOrdinal ) ] . _name ,
2016-08-09 12:17:18 +00:00
k7_ChampionNameMaximumLength , k200_heightScreen ) ;
for ( uint16 actionListIndex = 0 ; actionListIndex < 3 ; actionListIndex + + ) {
2016-09-16 05:46:10 +00:00
textMan . printWithTrailingSpaces ( dispMan . _bitmapScreen , k160_byteWidthScreen , 241 , 93 + actionListIndex * 12 , kDMColorCyan , kDMColorBlack ,
2016-08-25 19:59:02 +00:00
getActionName ( _actionList . _actionIndices [ actionListIndex ] ) ,
2016-08-09 12:17:18 +00:00
k12_ActionNameMaximumLength , k200_heightScreen ) ;
}
}
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-08-25 19:59:02 +00:00
_refreshActionArea = false ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
const char * MenuMan : : getActionName ( ChampionAction actionIndex ) {
2016-09-04 06:47:13 +00:00
const char * championActionNames [ 44 ] = { // @ G0490_ac_Graphic560_ActionNames
2016-08-23 20:08:51 +00:00
" N " , " BLOCK " , " CHOP " , " X " , " BLOW HORN " , " FLIP " , " PUNCH " ,
" KICK " , " WAR CRY " , " STAB " , " CLIMB DOWN " , " FREEZE LIFE " ,
" HIT " , " SWING " , " STAB " , " THRUST " , " JAB " , " PARRY " , " HACK " ,
" BERZERK " , " FIREBALL " , " DISPELL " , " CONFUSE " , " LIGHTNING " ,
" DISRUPT " , " MELEE " , " X " , " INVOKE " , " SLASH " , " CLEAVE " ,
" BASH " , " STUN " , " SHOOT " , " SPELLSHIELD " , " FIRESHIELD " ,
" FLUXCAGE " , " HEAL " , " CALM " , " LIGHT " , " WINDOW " , " SPIT " ,
" BRANDISH " , " THROW " , " FUSE "
} ;
2016-09-10 12:31:49 +00:00
return ( actionIndex = = kDMActionNone ) ? " " : championActionNames [ actionIndex ] ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawSpellAreaControls ( ChampionIndex champIndex ) {
2016-09-10 19:50:57 +00:00
static Box boxSpellAreaControls ( 233 , 319 , 42 , 49 ) ; // @ G0504_s_Graphic560_Box_SpellAreaControls
2016-08-12 10:48:44 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Champion * champ = & championMan . _champions [ champIndex ] ;
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-26 19:12:51 +00:00
int16 champHP0 = championMan . _champions [ 0 ] . _currHealth ;
int16 champHP1 = championMan . _champions [ 1 ] . _currHealth ;
int16 champHP2 = championMan . _champions [ 2 ] . _currHealth ;
int16 champHP3 = championMan . _champions [ 3 ] . _currHealth ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > fillScreenBox ( boxSpellAreaControls , kDMColorBlack ) ;
2016-09-04 06:47:13 +00:00
2016-08-12 10:48:44 +00:00
switch ( champIndex ) {
case 0 :
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 233 , 277 , 42 , 49 ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( 235 , 48 , kDMColorBlack , kDMColorCyan , champ - > _name ) ;
2016-09-26 19:12:51 +00:00
if ( championMan . _partyChampionCount > 1 ) {
2016-09-04 06:47:13 +00:00
if ( champHP1 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 280 , 291 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
2016-09-26 19:12:51 +00:00
if ( championMan . _partyChampionCount > 2 ) {
2016-09-04 06:47:13 +00:00
if ( champHP2 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 294 , 305 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
2016-09-26 19:12:51 +00:00
if ( ( championMan . _partyChampionCount > 3 ) & & champHP3 )
2016-09-04 06:47:13 +00:00
_vm - > _eventMan - > highlightScreenBox ( 308 , 319 , 42 , 48 ) ;
2016-08-12 10:48:44 +00:00
}
}
break ;
case 1 :
2016-09-04 06:47:13 +00:00
if ( champHP0 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 233 , 244 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 247 , 291 , 42 , 49 ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( 249 , 48 , kDMColorBlack , kDMColorCyan , champ - > _name ) ;
2016-09-26 19:12:51 +00:00
if ( championMan . _partyChampionCount > 2 ) {
2016-09-04 06:47:13 +00:00
if ( champHP2 )
_vm - > _eventMan - > highlightScreenBox ( 294 , 305 , 42 , 48 ) ;
2016-09-26 19:12:51 +00:00
if ( ( championMan . _partyChampionCount > 3 ) & & champHP3 )
2016-09-04 06:47:13 +00:00
_vm - > _eventMan - > highlightScreenBox ( 308 , 319 , 42 , 48 ) ;
}
break ;
2016-08-12 10:48:44 +00:00
case 2 :
2016-09-04 06:47:13 +00:00
if ( champHP0 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 233 , 244 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
if ( champHP1 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 247 , 258 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 261 , 305 , 42 , 49 ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( 263 , 48 , kDMColorBlack , kDMColorCyan , champ - > _name ) ;
2016-09-26 19:12:51 +00:00
if ( ( championMan . _partyChampionCount > 3 ) & & champHP3 )
2016-09-04 06:47:13 +00:00
_vm - > _eventMan - > highlightScreenBox ( 308 , 319 , 42 , 48 ) ;
break ;
2016-08-12 10:48:44 +00:00
case 3 :
2016-09-04 06:47:13 +00:00
if ( champHP0 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 233 , 244 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
if ( champHP1 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 247 , 258 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
if ( champHP2 )
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 261 , 272 , 42 , 48 ) ;
2016-09-04 06:47:13 +00:00
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > highlightScreenBox ( 275 , 319 , 42 , 49 ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( 277 , 48 , kDMColorBlack , kDMColorCyan , champ - > _name ) ;
2016-08-23 20:08:51 +00:00
break ;
default :
break ;
2016-08-12 10:48:44 +00:00
}
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : buildSpellAreaLine ( int16 spellAreaBitmapLine ) {
2016-09-10 19:50:57 +00:00
static Box boxSpellAreaLine ( 0 , 95 , 0 , 11 ) ; // @ K0074_s_Box_SpellAreaLine
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-08-22 21:24:49 +00:00
2016-09-04 06:47:13 +00:00
char spellSymbolString [ 2 ] = { ' \0 ' , ' \0 ' } ;
2016-09-26 19:12:51 +00:00
Champion * magicChampion = & championMan . _champions [ championMan . _magicCasterChampionIndex ] ;
2016-09-18 20:15:51 +00:00
if ( spellAreaBitmapLine = = kDMSpellAreaAvailableSymbols ) {
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > blitToBitmap ( _bitmapSpellAreaLines , _bitmapSpellAreaLine , boxSpellAreaLine , 0 , 12 , k48_byteWidth , k48_byteWidth , kDMColorNoTransparency , 36 , 12 ) ;
2016-08-09 12:17:18 +00:00
int16 x = 1 ;
2016-09-04 06:47:13 +00:00
char character = 96 + ( 6 * magicChampion - > _symbolStep ) ;
2016-08-09 12:17:18 +00:00
for ( uint16 symbolIndex = 0 ; symbolIndex < 6 ; symbolIndex + + ) {
2016-09-04 06:47:13 +00:00
spellSymbolString [ 0 ] = character + + ;
x + = 14 ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printTextToBitmap ( _bitmapSpellAreaLine , 48 , x , 8 , kDMColorCyan , kDMColorBlack , spellSymbolString , 12 ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-18 20:15:51 +00:00
} else if ( spellAreaBitmapLine = = kDMSpellAreaChampionSymbols ) {
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > blitToBitmap ( _bitmapSpellAreaLines , _bitmapSpellAreaLine , boxSpellAreaLine , 0 , 24 , k48_byteWidth , k48_byteWidth , kDMColorNoTransparency , 36 , 12 ) ;
2016-08-09 12:17:18 +00:00
int16 x = 8 ;
for ( uint16 symbolIndex = 0 ; symbolIndex < 4 ; symbolIndex + + ) {
2016-09-04 06:47:13 +00:00
if ( ( spellSymbolString [ 0 ] = magicChampion - > _symbols [ symbolIndex ] ) = = ' \0 ' )
2016-08-09 12:17:18 +00:00
break ;
2016-09-04 06:47:13 +00:00
x + = 9 ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printTextToBitmap ( _bitmapSpellAreaLine , 48 , x , 8 , kDMColorCyan , kDMColorBlack , spellSymbolString , 12 ) ;
2016-08-09 12:17:18 +00:00
}
}
}
2016-09-04 06:47:13 +00:00
void MenuMan : : setMagicCasterAndDrawSpellArea ( ChampionIndex champIndex ) {
2016-09-10 19:50:57 +00:00
static Box boxSpellAreaLine2 ( 224 , 319 , 50 , 61 ) ; // @ K0075_s_Box_SpellAreaLine2
static Box boxSpellAreaLine3 ( 224 , 319 , 62 , 73 ) ; // @ K0076_s_Box_SpellAreaLine3
2016-08-22 21:24:49 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
if ( ( champIndex = = championMan . _magicCasterChampionIndex )
| | ( ( champIndex ! = kDMChampionNone ) & & ! championMan . _champions [ champIndex ] . _currHealth ) )
2016-08-09 12:17:18 +00:00
return ;
2016-09-04 06:47:13 +00:00
2016-09-26 19:12:51 +00:00
if ( championMan . _magicCasterChampionIndex = = kDMChampionNone ) {
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-21 05:53:54 +00:00
_vm - > _displayMan - > blitToScreen ( _vm - > _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxMenuSpellAreaBackground ) , & _boxSpellArea , k48_byteWidth , kDMColorNoTransparency , 33 ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-09 05:12:36 +00:00
if ( champIndex = = kDMChampionNone ) {
2016-09-26 19:12:51 +00:00
championMan . _magicCasterChampionIndex = kDMChampionNone ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > fillScreenBox ( _boxSpellArea , kDMColorBlack ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
return ;
}
2016-09-26 19:12:51 +00:00
championMan . _magicCasterChampionIndex = champIndex ;
2016-09-18 20:15:51 +00:00
buildSpellAreaLine ( kDMSpellAreaAvailableSymbols ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-04 07:38:59 +00:00
drawSpellAreaControls ( champIndex ) ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > blitToScreen ( _bitmapSpellAreaLine , & boxSpellAreaLine2 , k48_byteWidth , kDMColorNoTransparency , 12 ) ;
2016-09-18 20:15:51 +00:00
buildSpellAreaLine ( kDMSpellAreaChampionSymbols ) ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > blitToScreen ( _bitmapSpellAreaLine , & boxSpellAreaLine3 , k48_byteWidth , kDMColorNoTransparency , 12 ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawEnabledMenus ( ) {
2016-09-26 19:12:51 +00:00
InventoryMan & inventory = * _vm - > _inventoryMan ;
ChampionMan & championMan = * _vm - > _championMan ;
if ( championMan . _partyIsSleeping ) {
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > drawSleepScreen ( ) ;
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > drawViewport ( k0_viewportNotDungeonView ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-26 19:12:51 +00:00
ChampionIndex casterChampionIndex = championMan . _magicCasterChampionIndex ;
championMan . _magicCasterChampionIndex = kDMChampionNone ; /* Force next function to draw the spell area */
2016-09-04 06:47:13 +00:00
setMagicCasterAndDrawSpellArea ( casterChampionIndex ) ;
2016-09-26 19:12:51 +00:00
if ( ! championMan . _actingChampionOrdinal )
2016-08-25 19:59:02 +00:00
_actionAreaContainsIcons = true ;
2016-09-04 06:56:14 +00:00
2016-08-25 19:59:02 +00:00
drawActionArea ( ) ;
2016-09-26 19:12:51 +00:00
int16 AL1462_i_InventoryChampionOrdinal = inventory . _inventoryChampionOrdinal ;
2016-08-23 20:08:51 +00:00
if ( AL1462_i_InventoryChampionOrdinal ) {
2016-09-26 19:12:51 +00:00
inventory . _inventoryChampionOrdinal = _vm - > indexToOrdinal ( kDMChampionNone ) ;
inventory . toggleInventory ( ( ChampionIndex ) _vm - > ordinalToIndex ( AL1462_i_InventoryChampionOrdinal ) ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > drawFloorAndCeiling ( ) ;
2016-08-25 19:59:02 +00:00
drawMovementArrows ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > setMousePointer ( ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-08-25 19:59:02 +00:00
int16 MenuMan : : getClickOnSpellCastResult ( ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Champion * casterChampion = & championMan . _champions [ championMan . _magicCasterChampionIndex ] ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
_vm - > _eventMan - > highlightBoxDisable ( ) ;
2016-09-04 06:56:14 +00:00
2016-09-26 19:12:51 +00:00
int16 spellCastResult = getChampionSpellCastResult ( championMan . _magicCasterChampionIndex ) ;
2016-09-10 12:31:49 +00:00
if ( spellCastResult ! = kDMSpellCastFailureNeedsFlask ) {
2016-09-04 06:56:14 +00:00
casterChampion - > _symbols [ 0 ] = ' \0 ' ;
drawAvailableSymbols ( casterChampion - > _symbolStep = 0 ) ;
drawChampionSymbols ( casterChampion ) ;
} else
2016-09-10 12:31:49 +00:00
spellCastResult = kDMSpellCastFailure ;
2016-09-04 06:56:14 +00:00
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-09-04 06:56:14 +00:00
return spellCastResult ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
int16 MenuMan : : getChampionSpellCastResult ( uint16 champIndex ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
2016-09-26 19:12:51 +00:00
if ( champIndex > = championMan . _partyChampionCount )
2016-09-10 12:31:49 +00:00
return kDMSpellCastFailure ;
2016-09-04 07:38:59 +00:00
2016-09-26 19:12:51 +00:00
Champion * curChampion = & championMan . _champions [ champIndex ] ;
2016-09-04 07:38:59 +00:00
if ( ! curChampion - > _currHealth )
2016-09-10 12:31:49 +00:00
return kDMSpellCastFailure ;
2016-09-04 07:38:59 +00:00
Spell * curSpell = getSpellFromSymbols ( ( unsigned char * ) curChampion - > _symbols ) ;
if ( ! curSpell ) {
2016-09-10 12:31:49 +00:00
menusPrintSpellFailureMessage ( curChampion , kDMSpellCastSuccess , 0 ) ;
return kDMSpellCastFailure ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 07:38:59 +00:00
int16 powerSymbolOrdinal = curChampion - > _symbols [ 0 ] - ' _ ' ; /* Values 1 to 6 */
uint16 requiredSkillLevel = curSpell - > _baseRequiredSkillLevel + powerSymbolOrdinal ;
uint16 experience = _vm - > getRandomNumber ( 8 ) + ( requiredSkillLevel < < 4 ) + ( ( _vm - > ordinalToIndex ( powerSymbolOrdinal ) * curSpell - > _baseRequiredSkillLevel ) < < 3 ) + ( requiredSkillLevel * requiredSkillLevel ) ;
2016-09-26 19:12:51 +00:00
uint16 skillLevel = championMan . getSkillLevel ( champIndex , curSpell - > _skillIndex ) ;
2016-09-04 08:18:36 +00:00
if ( skillLevel < requiredSkillLevel ) {
int16 missingSkillLevelCount = requiredSkillLevel - skillLevel ;
2016-09-04 07:38:59 +00:00
while ( missingSkillLevelCount - - ) {
2016-09-09 05:32:32 +00:00
if ( _vm - > getRandomNumber ( 128 ) > MIN ( curChampion - > _statistics [ kDMStatWisdom ] [ kDMStatCurrent ] + 15 , 115 ) ) {
2016-09-26 19:12:51 +00:00
championMan . addSkillExperience ( champIndex , curSpell - > _skillIndex , experience > > ( requiredSkillLevel - skillLevel ) ) ;
2016-09-10 12:31:49 +00:00
menusPrintSpellFailureMessage ( curChampion , kDMFailureNeedsMorePractice , curSpell - > _skillIndex ) ;
return kDMSpellCastFailure ;
2016-08-09 12:17:18 +00:00
}
}
}
2016-09-04 07:38:59 +00:00
switch ( curSpell - > getKind ( ) ) {
2016-09-10 12:53:10 +00:00
case kDMSpellKindPotion : {
2016-09-04 07:38:59 +00:00
Thing newObject ;
Potion * newPotion = getEmptyFlaskInHand ( curChampion , & newObject ) ;
if ( ! newPotion ) {
2016-09-10 12:31:49 +00:00
menusPrintSpellFailureMessage ( curChampion , kDMFailureNeedsFlaskInHand , 0 ) ;
return kDMSpellCastFailureNeedsFlask ;
2016-08-09 12:17:18 +00:00
}
2016-09-27 22:29:07 +00:00
uint16 emptyFlaskWeight = dungeon . getObjectWeight ( newObject ) ;
2016-09-04 07:38:59 +00:00
newPotion - > setType ( ( PotionType ) curSpell - > getType ( ) ) ;
newPotion - > setPower ( _vm - > getRandomNumber ( 16 ) + ( powerSymbolOrdinal * 40 ) ) ;
2016-09-27 22:29:07 +00:00
curChampion - > _load + = dungeon . getObjectWeight ( newObject ) - emptyFlaskWeight ;
2016-09-26 19:12:51 +00:00
championMan . drawChangedObjectIcons ( ) ;
2016-08-25 19:25:18 +00:00
if ( _vm - > _inventoryMan - > _inventoryChampionOrdinal = = _vm - > indexToOrdinal ( champIndex ) ) {
2016-09-09 05:32:32 +00:00
setFlag ( curChampion - > _attributes , kDMAttributeLoad ) ;
2016-09-26 19:12:51 +00:00
championMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 07:38:59 +00:00
}
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellKindProjectile :
2016-09-27 22:29:07 +00:00
if ( curChampion - > _dir ! = dungeon . _partyDir ) {
curChampion - > _dir = dungeon . _partyDir ;
2016-09-09 05:32:32 +00:00
setFlag ( curChampion - > _attributes , kDMAttributeIcon ) ;
2016-09-26 19:12:51 +00:00
championMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-10 12:53:10 +00:00
if ( curSpell - > getType ( ) = = kDMSpellTypeProjectileOpenDoor )
2016-09-04 08:18:36 +00:00
skillLevel < < = 1 ;
2016-09-26 19:12:51 +00:00
championMan . isProjectileSpellCast ( champIndex , Thing ( curSpell - > getType ( ) + Thing : : _firstExplosion . toUint16 ( ) ) , CLIP ( 21 , ( powerSymbolOrdinal + 2 ) * ( 4 + ( skillLevel < < 1 ) ) , 255 ) , 0 ) ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellKindOther : {
2016-09-04 07:38:59 +00:00
TimelineEvent newEvent ;
newEvent . _priority = 0 ;
2016-09-04 08:18:36 +00:00
uint16 spellPower = ( powerSymbolOrdinal + 1 ) < < 2 ;
2016-09-04 07:38:59 +00:00
uint16 ticks ;
switch ( curSpell - > getType ( ) ) {
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherLight : {
2016-09-04 08:18:36 +00:00
ticks = 10000 + ( ( spellPower - 8 ) < < 9 ) ;
uint16 lightPower = ( spellPower > > 1 ) ;
lightPower - - ;
2016-09-26 19:12:51 +00:00
championMan . _party . _magicalLightAmount + = championMan . _lightPowerToLightAmount [ lightPower ] ;
2016-09-04 08:18:36 +00:00
createEvent70_light ( - lightPower , ticks ) ;
}
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherMagicTorch : {
2016-09-04 08:18:36 +00:00
ticks = 2000 + ( ( spellPower - 3 ) < < 7 ) ;
uint16 lightPower = ( spellPower > > 2 ) ;
lightPower + + ;
2016-09-26 19:12:51 +00:00
championMan . _party . _magicalLightAmount + = championMan . _lightPowerToLightAmount [ lightPower ] ;
2016-09-04 08:18:36 +00:00
createEvent70_light ( - lightPower , ticks ) ;
}
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherDarkness : {
2016-09-04 08:18:36 +00:00
uint16 lightPower = ( spellPower > > 2 ) ;
2016-09-26 19:12:51 +00:00
championMan . _party . _magicalLightAmount - = championMan . _lightPowerToLightAmount [ lightPower ] ;
2016-09-04 08:18:36 +00:00
createEvent70_light ( lightPower , 98 ) ;
}
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherThievesEye : {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeThievesEye ;
2016-09-26 19:12:51 +00:00
championMan . _party . _event73Count_ThievesEye + + ;
2016-09-04 08:18:36 +00:00
spellPower = ( spellPower > > 1 ) ;
uint16 spellTicks = spellPower * spellPower ;
2016-09-27 22:29:07 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( dungeon . _partyMapIndex , _vm - > _gameTime + spellTicks ) ;
2016-09-04 08:18:36 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
}
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherInvisibility : {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeInvisibility ;
2016-09-26 19:12:51 +00:00
championMan . _party . _event71Count_Invisibility + + ;
2016-09-04 08:18:36 +00:00
uint16 spellTicks = spellPower ;
2016-09-27 22:29:07 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( dungeon . _partyMapIndex , _vm - > _gameTime + spellTicks ) ;
2016-09-04 08:18:36 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
}
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherPartyShield : {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypePartyShield ;
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _defense = spellPower ;
2016-09-26 19:12:51 +00:00
if ( championMan . _party . _shieldDefense > 50 )
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _defense > > = 2 ;
2016-09-04 08:18:36 +00:00
2016-09-26 19:12:51 +00:00
championMan . _party . _shieldDefense + = newEvent . _Bu . _defense ;
2016-08-25 20:38:03 +00:00
_vm - > _timeline - > refreshAllChampionStatusBoxes ( ) ;
2016-09-04 08:18:36 +00:00
uint16 spellTicks = spellPower * spellPower ;
2016-09-27 22:29:07 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( dungeon . _partyMapIndex , _vm - > _gameTime + spellTicks ) ;
2016-09-04 08:18:36 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
}
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherFootprints : {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeFootprints ;
2016-09-26 19:12:51 +00:00
championMan . _party . _event79Count_Footprints + + ;
championMan . _party . _firstScentIndex = championMan . _party . _scentCount ;
2016-09-04 08:18:36 +00:00
if ( powerSymbolOrdinal < 3 )
2016-09-26 19:12:51 +00:00
championMan . _party . _lastScentIndex = championMan . _party . _firstScentIndex ;
2016-09-04 08:18:36 +00:00
else
2016-09-26 19:12:51 +00:00
championMan . _party . _lastScentIndex = 0 ;
2016-09-04 08:18:36 +00:00
uint16 spellTicks = spellPower * spellPower ;
2016-09-27 22:29:07 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( dungeon . _partyMapIndex , _vm - > _gameTime + spellTicks ) ;
2016-09-04 07:38:59 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
2016-09-04 08:18:36 +00:00
}
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherZokathra : {
2016-09-27 22:29:07 +00:00
Thing unusedObject = dungeon . getUnusedThing ( kDMThingTypeJunk ) ;
2016-09-04 07:38:59 +00:00
if ( unusedObject = = Thing : : _none )
2016-08-09 12:17:18 +00:00
break ;
2016-09-04 07:38:59 +00:00
2016-09-27 22:29:07 +00:00
Junk * junkData = ( Junk * ) dungeon . getThingData ( unusedObject ) ;
2016-09-12 20:20:31 +00:00
junkData - > setType ( kDMJunkTypeZokathra ) ;
2016-09-04 08:18:36 +00:00
ChampionSlot slotIndex ;
2016-09-10 09:47:36 +00:00
if ( curChampion - > _slots [ kDMSlotReadyHand ] = = Thing : : _none )
slotIndex = kDMSlotReadyHand ;
else if ( curChampion - > _slots [ kDMSlotActionHand ] = = Thing : : _none )
slotIndex = kDMSlotActionHand ;
2016-09-04 07:38:59 +00:00
else
2016-09-10 09:47:36 +00:00
slotIndex = kDMSlotLeaderHand ;
2016-09-04 07:38:59 +00:00
2016-09-10 09:47:36 +00:00
if ( ( slotIndex = = kDMSlotReadyHand ) | | ( slotIndex = = kDMSlotActionHand ) ) {
2016-09-26 19:12:51 +00:00
championMan . addObjectInSlot ( ( ChampionIndex ) champIndex , unusedObject , slotIndex ) ;
championMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-09-04 07:38:59 +00:00
} else
2016-09-27 22:29:07 +00:00
_vm - > _moveSens - > getMoveResult ( unusedObject , kDMMapXNotOnASquare , 0 , dungeon . _partyMapX , dungeon . _partyMapY ) ;
2016-09-04 07:38:59 +00:00
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 12:53:10 +00:00
case kDMSpellTypeOtherFireshield :
2016-09-04 08:18:36 +00:00
isPartySpellOrFireShieldSuccessful ( curChampion , false , ( spellPower * spellPower ) + 100 , false ) ;
2016-09-04 07:38:59 +00:00
break ;
default :
break ;
}
2016-08-09 12:17:18 +00:00
}
}
2016-09-26 19:12:51 +00:00
championMan . addSkillExperience ( champIndex , curSpell - > _skillIndex , experience ) ;
championMan . disableAction ( champIndex , curSpell - > getDuration ( ) ) ;
2016-09-10 12:31:49 +00:00
return kDMSpellCastSuccess ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
Spell * MenuMan : : getSpellFromSymbols ( byte * symbols ) {
2016-09-04 08:53:26 +00:00
static Spell SpellsArray [ 25 ] = {
2016-08-09 12:17:18 +00:00
/* { Symbols, BaseRequiredSkillLevel, SkillIndex, Attributes } */
Spell ( 0x00666F00 , 2 , 15 , 0x7843 ) ,
Spell ( 0x00667073 , 1 , 18 , 0x4863 ) ,
Spell ( 0x00686D77 , 3 , 17 , 0xB433 ) ,
Spell ( 0x00686C00 , 3 , 19 , 0x6C72 ) ,
Spell ( 0x00686D76 , 3 , 18 , 0x8423 ) ,
Spell ( 0x00686E76 , 4 , 17 , 0x7822 ) ,
Spell ( 0x00686F76 , 4 , 17 , 0x5803 ) ,
Spell ( 0x00690000 , 1 , 16 , 0x3C53 ) ,
Spell ( 0x00696F00 , 3 , 16 , 0xA802 ) ,
Spell ( 0x00697072 , 4 , 13 , 0x3C71 ) ,
Spell ( 0x00697075 , 4 , 15 , 0x7083 ) ,
Spell ( 0x006A6D00 , 1 , 18 , 0x5032 ) ,
Spell ( 0x006A6C00 , 1 , 19 , 0x4062 ) ,
Spell ( 0x006A6F77 , 1 , 15 , 0x3013 ) ,
Spell ( 0x006B0000 , 1 , 17 , 0x3C42 ) ,
Spell ( 0x00667000 , 2 , 15 , 0x64C1 ) ,
Spell ( 0x00660000 , 2 , 13 , 0x3CB1 ) ,
Spell ( 0x00667074 , 4 , 13 , 0x3C81 ) ,
Spell ( 0x00667075 , 4 , 13 , 0x3C91 ) ,
Spell ( 0x00670000 , 1 , 13 , 0x80E1 ) ,
Spell ( 0x00677000 , 1 , 13 , 0x68A1 ) ,
Spell ( 0x00687073 , 4 , 13 , 0x3C61 ) ,
Spell ( 0x006B7076 , 3 , 2 , 0xFCD1 ) ,
Spell ( 0x006B6C00 , 2 , 19 , 0x7831 ) ,
Spell ( 0x006B6E76 , 0 , 3 , 0x3C73 )
} ;
if ( * ( symbols + 1 ) ) {
2016-09-04 08:53:26 +00:00
int16 bitShiftCount = 24 ;
int32 curSymbols = 0 ;
do
curSymbols | = ( long ) * symbols + + < < bitShiftCount ;
while ( * symbols & & ( ( bitShiftCount - = 8 ) > = 0 ) ) ;
Spell * curSpell = SpellsArray ;
int16 spellIndex = 25 ;
while ( spellIndex - - ) {
if ( curSpell - > _symbols & 0xFF000000 ) { /* If byte 1 of spell is not 0 then the spell includes the power symbol */
if ( curSymbols = = curSpell - > _symbols ) { /* Compare champion symbols, including power symbol, with spell (never used with actual spells) */
return curSpell ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 08:53:26 +00:00
} else if ( ( curSymbols & 0x00FFFFFF ) = = curSpell - > _symbols ) /* Compare champion symbols, except power symbol, with spell */
return curSpell ;
curSpell + + ;
2016-08-09 12:17:18 +00:00
}
}
2016-09-04 08:53:26 +00:00
return nullptr ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
void MenuMan : : menusPrintSpellFailureMessage ( Champion * champ , uint16 failureType , uint16 skillIndex ) {
2016-09-12 19:20:45 +00:00
Common : : String messagesEN [ 4 ] = {
" NEEDS MORE PRACTICE WITH THIS " ,
" SPELL. " ,
" MUMBLES A MEANINGLESS SPELL. " ,
" NEEDS AN EMPTY FLASK IN HAND FOR POTION. "
} ;
Common : : String messagesDE [ 4 ] = {
" BRAUCHT MEHR UEBUNG MIT DIESEM " ,
" ZAUBERSPRUCH. " ,
" MURMELT EINEN SINNLOSEN ZAUBERSPRUCH. " ,
" MUSS FUER DEN TRANK EINE LEERE FLASCHE BEREITHALTEN. "
} ;
Common : : String messagesFR [ 5 ] = {
" DOIT PRATIQUER DAVANTAGE SON " ,
" ENVOUTEMENT. " ,
" MARMONNE UNE CONJURATION IMCOMPREHENSIBLE. " ,
" DOIT AVOIR UN FLACON VIDE EN MAIN POUR LA POTION. " ,
" EXORCISME. "
} ;
2016-08-09 12:17:18 +00:00
2016-09-09 05:32:32 +00:00
if ( skillIndex > kDMSkillWizard )
2016-08-09 12:17:18 +00:00
skillIndex = ( skillIndex - 4 ) / 4 ;
2016-08-21 12:25:06 +00:00
2016-08-25 20:38:03 +00:00
_vm - > _textMan - > printLineFeed ( ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printMessage ( kDMColorCyan , champ - > _name ) ;
2016-08-15 18:25:40 +00:00
2016-09-12 19:20:45 +00:00
Common : : String * messages ;
2016-08-15 18:25:40 +00:00
switch ( _vm - > getGameLanguage ( ) ) { // localized
2016-08-16 07:28:57 +00:00
case Common : : DE_DEU :
2016-09-04 08:53:26 +00:00
messages = messagesDE ;
break ;
2016-08-15 18:25:40 +00:00
case Common : : FR_FRA :
2016-09-04 08:53:26 +00:00
messages = messagesFR ;
break ;
default :
messages = messagesEN ;
break ;
2016-08-15 18:25:40 +00:00
}
2016-09-12 19:20:45 +00:00
Common : : String message ;
2016-08-09 12:17:18 +00:00
switch ( failureType ) {
2016-09-10 12:31:49 +00:00
case kDMFailureNeedsMorePractice :
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printMessage ( kDMColorCyan , messages [ 0 ] . c_str ( ) ) ;
_vm - > _textMan - > printMessage ( kDMColorCyan , _vm - > _championMan - > _baseSkillName [ skillIndex ] ) ;
2016-09-09 05:32:32 +00:00
if ( _vm - > getGameLanguage ( ) ! = Common : : FR_FRA | | skillIndex = = kDMSkillWizard )
2016-09-04 08:53:26 +00:00
message = messages [ 1 ] ;
2016-08-21 12:25:06 +00:00
else
2016-09-04 08:53:26 +00:00
message = messages [ 4 ] ;
2016-08-21 12:25:06 +00:00
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMFailureMeaninglessSpell :
2016-09-04 08:53:26 +00:00
message = messages [ 2 ] ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMFailureNeedsFlaskInHand :
2016-09-04 08:53:26 +00:00
message = messages [ 3 ] ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
default :
break ;
2016-08-09 12:17:18 +00:00
}
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printMessage ( kDMColorCyan , message . c_str ( ) ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
Potion * MenuMan : : getEmptyFlaskInHand ( Champion * champ , Thing * potionThing ) {
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
2016-09-10 09:47:36 +00:00
for ( int16 slotIndex = kDMSlotHead ; - - slotIndex > = kDMSlotReadyHand ; ) {
2016-09-04 08:53:26 +00:00
Thing curThing = champ - > _slots [ slotIndex ] ;
2016-09-08 23:09:25 +00:00
if ( ( curThing ! = Thing : : _none ) & & ( _vm - > _objectMan - > getIconIndex ( curThing ) = = kDMIconIndicePotionEmptyFlask ) ) {
2016-09-04 08:53:26 +00:00
* potionThing = curThing ;
2016-09-27 22:29:07 +00:00
return ( Potion * ) dungeon . getThingData ( curThing ) ;
2016-08-09 12:17:18 +00:00
}
}
return nullptr ;
}
2016-08-25 19:59:02 +00:00
void MenuMan : : createEvent70_light ( int16 lightPower , int16 ticks ) {
2016-09-04 08:53:26 +00:00
TimelineEvent newEvent ;
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeLight ;
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _lightPower = lightPower ;
2016-09-19 05:05:37 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( _vm - > _dungeonMan - > _partyMapIndex , _vm - > _gameTime + ticks ) ;
2016-09-04 08:53:26 +00:00
newEvent . _priority = 0 ;
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
2016-08-25 19:25:18 +00:00
_vm - > _inventoryMan - > setDungeonViewPalette ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
bool MenuMan : : isPartySpellOrFireShieldSuccessful ( Champion * champ , bool spellShield , uint16 ticks , bool useMana ) {
2016-09-04 08:53:26 +00:00
bool isPartyMagicShieldSuccessful = true ;
2016-08-09 12:17:18 +00:00
if ( useMana ) {
2016-09-04 08:53:26 +00:00
if ( champ - > _currMana = = 0 )
2016-08-09 12:17:18 +00:00
return false ;
2016-09-04 08:53:26 +00:00
2016-08-09 12:17:18 +00:00
if ( champ - > _currMana < 4 ) {
ticks > > = 1 ;
champ - > _currMana = 0 ;
2016-09-04 08:53:26 +00:00
isPartyMagicShieldSuccessful = false ;
} else
2016-08-09 12:17:18 +00:00
champ - > _currMana - = 4 ;
}
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-09-04 08:53:26 +00:00
TimelineEvent newEvent ;
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _defense = ticks > > 5 ;
2016-08-09 12:17:18 +00:00
if ( spellShield ) {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeSpellShield ;
2016-09-26 19:12:51 +00:00
if ( championMan . _party . _spellShieldDefense > 50 )
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _defense > > = 2 ;
2016-09-04 08:53:26 +00:00
2016-09-26 19:12:51 +00:00
championMan . _party . _spellShieldDefense + = newEvent . _Bu . _defense ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeFireShield ;
2016-09-26 19:12:51 +00:00
if ( championMan . _party . _fireShieldDefense > 50 )
2016-09-10 19:50:57 +00:00
newEvent . _Bu . _defense > > = 2 ;
2016-09-04 08:53:26 +00:00
2016-09-26 19:12:51 +00:00
championMan . _party . _fireShieldDefense + = newEvent . _Bu . _defense ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 08:53:26 +00:00
newEvent . _priority = 0 ;
2016-09-19 05:05:37 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( _vm - > _dungeonMan - > _partyMapIndex , _vm - > _gameTime + ticks ) ;
2016-09-04 08:53:26 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
2016-08-25 20:38:03 +00:00
_vm - > _timeline - > refreshAllChampionStatusBoxes ( ) ;
2016-09-04 08:53:26 +00:00
return isPartyMagicShieldSuccessful ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawAvailableSymbols ( uint16 symbolStep ) {
2016-09-04 08:53:26 +00:00
char displayBuffer [ 2 ] ;
displayBuffer [ 1 ] = ' \0 ' ;
char curCharacter = 96 + 6 * symbolStep ;
int16 textPosX = 225 ;
for ( uint16 L1214_ui_Counter = 0 ; L1214_ui_Counter < 6 ; L1214_ui_Counter + + ) {
displayBuffer [ 0 ] = curCharacter + + ;
textPosX + = 14 ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( textPosX , 58 , kDMColorCyan , kDMColorBlack , displayBuffer ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-09-03 19:42:58 +00:00
void MenuMan : : drawChampionSymbols ( Champion * champ ) {
2016-09-04 08:53:26 +00:00
uint16 symbolCount = strlen ( champ - > _symbols ) ;
int16 textPosX = 232 ;
char displayBuffer [ 2 ] ;
displayBuffer [ 1 ] = ' \0 ' ;
for ( uint16 symbolIndex = 0 ; symbolIndex < 4 ; symbolIndex + + ) {
if ( symbolIndex > = symbolCount )
displayBuffer [ 0 ] = ' ' ;
else
displayBuffer [ 0 ] = champ - > _symbols [ symbolIndex ] ;
textPosX + = 9 ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( textPosX , 70 , kDMColorCyan , kDMColorBlack , displayBuffer ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-08-25 19:59:02 +00:00
void MenuMan : : addChampionSymbol ( int16 symbolIndex ) {
2016-09-04 08:53:26 +00:00
static byte symbolBaseManaCost [ 4 ] [ 6 ] = {
2016-08-09 12:17:18 +00:00
{ 1 , 2 , 3 , 4 , 5 , 6 } , /* Power 1 */
{ 2 , 3 , 4 , 5 , 6 , 7 } , /* Power 2 */
{ 4 , 5 , 6 , 7 , 7 , 9 } , /* Power 3 */
2016-09-03 11:53:52 +00:00
{ 2 , 2 , 3 , 4 , 6 , 7 } /* Power 4 */
} ;
2016-09-04 08:53:26 +00:00
static byte symbolManaCostMultiplier [ 6 ] = { 8 , 12 , 16 , 20 , 24 , 28 } ;
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Champion * casterChampion = & championMan . _champions [ championMan . _magicCasterChampionIndex ] ;
2016-09-04 08:53:26 +00:00
uint16 symbolStep = casterChampion - > _symbolStep ;
uint16 manaCost = symbolBaseManaCost [ symbolStep ] [ symbolIndex ] ;
if ( symbolStep ) {
2016-09-11 21:24:44 +00:00
uint16 symbolIndex1 = casterChampion - > _symbols [ 0 ] - 96 ;
manaCost = ( manaCost * symbolManaCostMultiplier [ symbolIndex1 ] ) > > 3 ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 08:53:26 +00:00
if ( manaCost < = casterChampion - > _currMana ) {
casterChampion - > _currMana - = manaCost ;
2016-09-09 05:32:32 +00:00
setFlag ( casterChampion - > _attributes , kDMAttributeStatistics ) ;
2016-09-04 08:53:26 +00:00
casterChampion - > _symbols [ symbolStep ] = 96 + ( symbolStep * 6 ) + symbolIndex ;
casterChampion - > _symbols [ symbolStep + 1 ] = ' \0 ' ;
2016-09-11 08:45:20 +00:00
casterChampion - > _symbolStep = symbolStep = _vm - > turnDirRight ( symbolStep ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-04 08:53:26 +00:00
drawAvailableSymbols ( symbolStep ) ;
drawChampionSymbols ( casterChampion ) ;
2016-09-26 19:12:51 +00:00
championMan . drawChampionState ( championMan . _magicCasterChampionIndex ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-08-25 19:59:02 +00:00
void MenuMan : : deleteChampionSymbol ( ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Champion * casterChampion = & championMan . _champions [ championMan . _magicCasterChampionIndex ] ;
2016-09-04 08:53:26 +00:00
if ( ! strlen ( casterChampion - > _symbols ) )
2016-08-09 12:17:18 +00:00
return ;
2016-09-04 08:53:26 +00:00
2016-09-11 08:45:20 +00:00
int16 symbolStep = _vm - > turnDirLeft ( casterChampion - > _symbolStep ) ;
2016-09-04 08:53:26 +00:00
casterChampion - > _symbolStep = symbolStep ;
casterChampion - > _symbols [ symbolStep ] = ' \0 ' ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-09-04 08:53:26 +00:00
drawAvailableSymbols ( symbolStep ) ;
drawChampionSymbols ( casterChampion ) ;
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
bool MenuMan : : didClickTriggerAction ( int16 actionListIndex ) {
2016-09-04 08:53:26 +00:00
bool retVal = false ;
2016-08-09 12:17:18 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
if ( ! championMan . _actingChampionOrdinal | | ( actionListIndex ! = - 1 & & ( _actionList . _actionIndices [ actionListIndex ] = = kDMActionNone ) ) )
2016-09-04 08:53:26 +00:00
return retVal ;
2016-09-26 19:12:51 +00:00
uint16 championIndex = _vm - > ordinalToIndex ( championMan . _actingChampionOrdinal ) ;
Champion * curChampion = & championMan . _champions [ championIndex ] ;
2016-09-04 08:53:26 +00:00
if ( actionListIndex = = - 1 )
retVal = true ;
else {
2016-09-04 09:24:22 +00:00
uint16 actionIndex = _actionList . _actionIndices [ actionListIndex ] ;
// Fix original bug - When disabled ticks is equal to zero, increasing the defense leads
// to a permanent increment.
if ( _actionDisabledTicks [ actionIndex ] )
2016-09-07 19:28:53 +00:00
curChampion - > _actionDefense + = _vm - > _timeline - > _actionDefense [ actionIndex ] ;
2016-09-04 09:24:22 +00:00
2016-09-09 05:32:32 +00:00
setFlag ( curChampion - > _attributes , kDMAttributeStatistics ) ;
2016-09-04 09:24:22 +00:00
retVal = isActionPerformed ( championIndex , actionIndex ) ;
curChampion - > _actionIndex = ( ChampionAction ) actionIndex ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
clearActingChampion ( ) ;
2016-09-04 08:53:26 +00:00
return retVal ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
bool MenuMan : : isActionPerformed ( uint16 champIndex , int16 actionIndex ) {
2016-09-04 10:07:31 +00:00
static unsigned char actionStaminaArray [ 44 ] = {
2016-08-09 12:17:18 +00:00
0 , /* N */
4 , /* BLOCK */
10 , /* CHOP */
0 , /* X */
1 , /* BLOW HORN */
0 , /* FLIP */
1 , /* PUNCH */
3 , /* KICK */
1 , /* WAR CRY */
3 , /* STAB */
40 , /* CLIMB DOWN */
3 , /* FREEZE LIFE */
3 , /* HIT */
2 , /* SWING */
4 , /* STAB */
17 , /* THRUST */
3 , /* JAB */
1 , /* PARRY */
6 , /* HACK */
40 , /* BERZERK */
5 , /* FIREBALL */
2 , /* DISPELL */
2 , /* CONFUSE */
4 , /* LIGHTNING */
5 , /* DISRUPT */
25 , /* MELEE */
1 , /* X */
2 , /* INVOKE */
2 , /* SLASH */
10 , /* CLEAVE */
9 , /* BASH */
2 , /* STUN */
3 , /* SHOOT */
1 , /* SPELLSHIELD */
2 , /* FIRESHIELD */
6 , /* FLUXCAGE */
1 , /* HEAL */
1 , /* CALM */
3 , /* LIGHT */
2 , /* WINDOW */
3 , /* SPIT */
2 , /* BRANDISH */
0 , /* THROW */
2016-09-03 19:42:58 +00:00
2 /* FUSE */
} ;
2016-09-04 10:07:31 +00:00
static unsigned char actionExperienceGainArray [ 44 ] = {
2016-08-09 12:17:18 +00:00
0 , /* N */
8 , /* BLOCK */
10 , /* CHOP */
0 , /* X */
0 , /* BLOW HORN */
0 , /* FLIP */
8 , /* PUNCH */
13 , /* KICK */
7 , /* WAR CRY */
15 , /* STAB */
15 , /* CLIMB DOWN */
22 , /* FREEZE LIFE */
10 , /* HIT */
6 , /* SWING */
12 , /* STAB */
19 , /* THRUST */
11 , /* JAB */
17 , /* PARRY */
9 , /* HACK */
40 , /* BERZERK */
35 , /* FIREBALL */
25 , /* DISPELL */
0 , /* CONFUSE */
30 , /* LIGHTNING */
10 , /* DISRUPT */
24 , /* MELEE */
0 , /* X */
25 , /* INVOKE */
9 , /* SLASH */
12 , /* CLEAVE */
11 , /* BASH */
10 , /* STUN */
20 , /* SHOOT Atari ST Versions 1.0 1987-12-08 1987-12-11: 9 */
20 , /* SPELLSHIELD */
20 , /* FIRESHIELD */
12 , /* FLUXCAGE */
0 , /* HEAL */
0 , /* CALM */
20 , /* LIGHT */
30 , /* WINDOW */
25 , /* SPIT */
0 , /* BRANDISH */
5 , /* THROW */
2016-09-03 19:42:58 +00:00
1 /* FUSE */
} ;
2016-09-04 10:07:31 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
if ( champIndex > = championMan . _partyChampionCount )
2016-08-09 12:17:18 +00:00
return false ;
2016-09-04 10:07:31 +00:00
2016-09-26 19:12:51 +00:00
Champion * curChampion = & championMan . _champions [ champIndex ] ;
2016-09-04 10:07:31 +00:00
if ( ! curChampion - > _currHealth )
2016-08-09 12:17:18 +00:00
return false ;
2016-09-04 10:07:31 +00:00
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
Weapon * weaponInHand = ( Weapon * ) dungeon . getThingData ( curChampion - > _slots [ kDMSlotActionHand ] ) ;
2016-09-04 10:07:31 +00:00
2016-09-27 22:29:07 +00:00
int16 nextMapX = dungeon . _partyMapX ;
int16 nextMapY = dungeon . _partyMapY ;
2016-09-04 10:07:31 +00:00
nextMapX + = _vm - > _dirIntoStepCountEast [ curChampion - > _dir ] ;
nextMapY + = _vm - > _dirIntoStepCountNorth [ curChampion - > _dir ] ;
_actionTargetGroupThing = _vm - > _groupMan - > groupGetThing ( nextMapX , nextMapY ) ;
uint16 actionDisabledTicks = _actionDisabledTicks [ actionIndex ] ;
int16 actionSkillIndex = _actionSkillIndex [ actionIndex ] ;
int16 actionStamina = actionStaminaArray [ actionIndex ] + _vm - > getRandomNumber ( 2 ) ;
int16 actionExperienceGain = actionExperienceGainArray [ actionIndex ] ;
2016-09-27 22:29:07 +00:00
uint16 targetSquare = dungeon . getSquare ( nextMapX , nextMapY ) . toByte ( ) ;
2016-09-04 11:03:32 +00:00
int16 requiredManaAmount = 0 ;
2016-09-09 05:32:32 +00:00
if ( ( ( actionSkillIndex > = kDMSkillFire ) & & ( actionSkillIndex < = kDMSkillWater ) ) | | ( actionSkillIndex = = kDMSkillWizard ) )
2016-09-26 19:12:51 +00:00
requiredManaAmount = 7 - MIN < uint16 > ( 6 , championMan . getSkillLevel ( champIndex , actionSkillIndex ) ) ;
2016-09-04 11:03:32 +00:00
bool setDirectionFl = false ;
int16 kineticEnergy = 0 ;
Thing explosionThing = Thing : : _none ;
bool actionPerformed = true ;
2016-08-09 12:17:18 +00:00
switch ( actionIndex ) {
2016-09-10 12:31:49 +00:00
case kDMActionLightning :
2016-09-04 11:03:32 +00:00
kineticEnergy = 180 ;
explosionThing = Thing : : _explLightningBolt ;
setDirectionFl = true ;
break ;
2016-09-10 12:31:49 +00:00
case kDMActionDispel :
2016-09-04 11:03:32 +00:00
kineticEnergy = 150 ;
explosionThing = Thing : : _explHarmNonMaterial ;
setDirectionFl = true ;
break ;
2016-09-10 12:31:49 +00:00
case kDMActionFireball :
2016-09-04 11:03:32 +00:00
kineticEnergy = 150 ;
explosionThing = Thing : : _explFireBall ;
setDirectionFl = true ;
break ;
2016-09-10 12:31:49 +00:00
case kDMActionSpit :
2016-09-04 11:03:32 +00:00
kineticEnergy = 250 ;
explosionThing = Thing : : _explFireBall ;
setDirectionFl = true ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionBash :
case kDMActionHack :
case kDMActionBerzerk :
case kDMActionKick :
case kDMActionSwing :
case kDMActionChop :
2016-09-14 19:27:09 +00:00
if ( ( Square ( targetSquare ) . getType ( ) = = kDMElementTypeDoor ) & & ( Square ( targetSquare ) . getDoorState ( ) = = kDMDoorStateClosed ) ) {
2016-09-27 22:29:07 +00:00
_vm - > _sound - > requestPlay ( kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight , dungeon . _partyMapX , dungeon . _partyMapY , kDMSoundModePlayIfPrioritized ) ;
2016-09-04 10:07:31 +00:00
actionDisabledTicks = 6 ;
2016-09-26 19:12:51 +00:00
_vm - > _groupMan - > groupIsDoorDestoryedByAttack ( nextMapX , nextMapY , championMan . getStrength ( champIndex , kDMSlotActionHand ) , false , 2 ) ;
2016-09-27 22:29:07 +00:00
_vm - > _sound - > requestPlay ( kDMSoundIndexWoodenThudAttackTrolinAntmanStoneGolem , dungeon . _partyMapX , dungeon . _partyMapY , kDMSoundModePlayOneTickLater ) ;
2016-08-09 12:17:18 +00:00
break ;
}
2016-09-10 12:31:49 +00:00
case kDMActionDisrupt :
case kDMActionJab :
case kDMActionParry :
case kDMActionStab14 :
case kDMActionStab9 :
case kDMActionStun :
case kDMActionThrust :
case kDMActionMelee :
case kDMActionSlash :
case kDMActionCleave :
case kDMActionPunch :
2016-09-04 11:03:32 +00:00
if ( ! ( actionPerformed = isMeleeActionPerformed ( champIndex , curChampion , actionIndex , nextMapX , nextMapY , actionSkillIndex ) ) ) {
2016-09-04 10:07:31 +00:00
actionExperienceGain > > = 1 ;
actionDisabledTicks > > = 1 ;
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 12:31:49 +00:00
case kDMActionConfuse :
2016-09-04 10:07:31 +00:00
decrementCharges ( curChampion ) ;
// No break on purpose
2016-09-10 12:31:49 +00:00
case kDMActionWarCry :
case kDMActionCalm :
case kDMActionBrandish :
case kDMActionBlowHorn :
if ( actionIndex = = kDMActionWarCry )
2016-09-18 22:17:36 +00:00
_vm - > _sound - > requestPlay ( kDMSoundIndexWarCry , nextMapX , nextMapY , kDMSoundModePlayImmediately ) ;
2016-09-10 12:31:49 +00:00
else if ( actionIndex = = kDMActionBlowHorn )
2016-09-18 22:17:36 +00:00
_vm - > _sound - > requestPlay ( kDMSoundIndexBlowHorn , nextMapX , nextMapY , kDMSoundModePlayImmediately ) ;
2016-09-04 10:07:31 +00:00
2016-09-04 11:03:32 +00:00
actionPerformed = isGroupFrightenedByAction ( champIndex , actionIndex , nextMapX , nextMapY ) ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionShoot : {
2016-09-10 22:33:54 +00:00
if ( Thing ( curChampion - > _slots [ kDMSlotReadyHand ] ) . getType ( ) ! = kDMThingTypeWeapon ) {
2016-09-18 20:15:51 +00:00
_actionDamage = kDMDamageNoAmmunition ;
2016-09-04 10:07:31 +00:00
actionExperienceGain = 0 ;
2016-09-04 11:03:32 +00:00
actionPerformed = false ;
2016-09-04 10:07:31 +00:00
break ;
}
2016-09-27 22:29:07 +00:00
WeaponInfo * weaponInfoActionHand = & dungeon . _weaponInfos [ weaponInHand - > getType ( ) ] ;
WeaponInfo * weaponInfoReadyHand = dungeon . getWeaponInfo ( curChampion - > _slots [ kDMSlotReadyHand ] ) ;
2016-09-04 11:03:32 +00:00
int16 actionHandWeaponClass = weaponInfoActionHand - > _class ;
int16 readyHandWeaponClass = weaponInfoReadyHand - > _class ;
int16 stepEnergy = actionHandWeaponClass ;
2016-09-11 21:06:29 +00:00
if ( ( actionHandWeaponClass > = kDMWeaponClassFirstBow ) & & ( actionHandWeaponClass < = kDMWeaponClassLastBow ) ) {
if ( readyHandWeaponClass ! = kDMWeaponClassBowAmmunition ) {
2016-09-18 20:15:51 +00:00
_actionDamage = kDMDamageNoAmmunition ;
2016-09-04 10:07:31 +00:00
actionExperienceGain = 0 ;
2016-09-04 11:03:32 +00:00
actionPerformed = false ;
2016-09-04 10:07:31 +00:00
break ;
}
2016-09-11 21:06:29 +00:00
stepEnergy - = kDMWeaponClassFirstBow ;
} else if ( ( actionHandWeaponClass > = kDMWeaponClassFirstSling ) & & ( actionHandWeaponClass < = kDMWeaponClassLastSling ) ) {
if ( readyHandWeaponClass ! = kDMWeaponClassSlingAmmunition ) {
2016-09-18 20:15:51 +00:00
_actionDamage = kDMDamageNoAmmunition ;
2016-09-04 10:07:31 +00:00
actionExperienceGain = 0 ;
2016-09-04 11:03:32 +00:00
actionPerformed = false ;
2016-09-04 10:07:31 +00:00
break ;
2016-08-09 12:17:18 +00:00
}
2016-09-11 21:06:29 +00:00
stepEnergy - = kDMWeaponClassFirstSling ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 10:07:31 +00:00
setChampionDirectionToPartyDirection ( curChampion ) ;
2016-09-26 19:12:51 +00:00
Thing removedObject = championMan . getObjectRemovedFromSlot ( champIndex , kDMSlotReadyHand ) ;
2016-09-27 22:29:07 +00:00
_vm - > _sound - > requestPlay ( kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight , dungeon . _partyMapX , dungeon . _partyMapY , kDMSoundModePlayIfPrioritized ) ;
2016-09-26 19:12:51 +00:00
championMan . championShootProjectile ( curChampion , removedObject , weaponInfoActionHand - > _kineticEnergy + weaponInfoReadyHand - > _kineticEnergy , ( weaponInfoActionHand - > getShootAttack ( ) + championMan . getSkillLevel ( champIndex , kDMSkillShoot ) ) < < 1 , stepEnergy ) ;
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 12:31:49 +00:00
case kDMActionFlip : {
2016-09-04 10:07:31 +00:00
const char * messagesEN [ 2 ] = { " IT COMES UP HEADS. " , " IT COMES UP TAILS. " } ;
const char * messagesDE [ 2 ] = { " DIE KOPFSEITE IST OBEN. " , " DIE ZAHL IST OBEN. " } ;
const char * messagesFR [ 2 ] = { " C'EST FACE. " , " C'EST PILE. " } ;
2016-08-22 22:08:10 +00:00
const char * * message ;
2016-08-15 18:25:40 +00:00
switch ( _vm - > getGameLanguage ( ) ) { // localized
default :
2016-09-04 10:07:31 +00:00
case Common : : EN_ANY :
message = messagesEN ;
break ;
case Common : : DE_DEU :
message = messagesDE ;
break ;
case Common : : FR_FRA :
message = messagesFR ;
break ;
2016-08-15 18:25:40 +00:00
}
2016-09-04 10:07:31 +00:00
if ( _vm - > getRandomNumber ( 2 ) )
2016-08-25 19:59:02 +00:00
printMessageAfterReplacements ( message [ 0 ] ) ;
2016-09-04 10:07:31 +00:00
else
2016-08-25 19:59:02 +00:00
printMessageAfterReplacements ( message [ 1 ] ) ;
2016-09-04 10:07:31 +00:00
2016-08-09 12:17:18 +00:00
}
2016-09-04 10:07:31 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionSpellshield :
case kDMActionFireshield :
if ( ! isPartySpellOrFireShieldSuccessful ( curChampion , actionIndex = = kDMActionSpellshield , 280 , true ) ) {
2016-09-04 10:07:31 +00:00
actionExperienceGain > > = 2 ;
actionDisabledTicks > > = 1 ;
2016-09-04 11:03:32 +00:00
} else
2016-09-04 10:07:31 +00:00
decrementCharges ( curChampion ) ;
2016-09-04 11:03:32 +00:00
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionInvoke :
2016-09-04 11:03:32 +00:00
kineticEnergy = _vm - > getRandomNumber ( 128 ) + 100 ;
2016-08-09 12:17:18 +00:00
switch ( _vm - > getRandomNumber ( 6 ) ) {
case 0 :
2016-09-04 11:03:32 +00:00
explosionThing = Thing : : _explPoisonBolt ;
2016-09-04 10:07:31 +00:00
break ;
2016-08-09 12:17:18 +00:00
case 1 :
2016-09-04 11:03:32 +00:00
explosionThing = Thing : : _explPoisonCloud ;
2016-09-04 10:07:31 +00:00
break ;
2016-08-09 12:17:18 +00:00
case 2 :
2016-09-04 11:03:32 +00:00
explosionThing = Thing : : _explHarmNonMaterial ;
2016-09-04 10:07:31 +00:00
break ;
2016-08-09 12:17:18 +00:00
default :
2016-09-04 11:03:32 +00:00
explosionThing = Thing : : _explFireBall ;
2016-09-04 10:07:31 +00:00
break ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 11:03:32 +00:00
setDirectionFl = true ;
break ;
2016-09-04 10:07:31 +00:00
2016-09-10 12:31:49 +00:00
case kDMActionFluxcage :
2016-09-04 10:07:31 +00:00
setChampionDirectionToPartyDirection ( curChampion ) ;
_vm - > _groupMan - > fluxCageAction ( nextMapX , nextMapY ) ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionFuse :
2016-09-04 10:07:31 +00:00
setChampionDirectionToPartyDirection ( curChampion ) ;
2016-09-27 22:29:07 +00:00
nextMapX = dungeon . _partyMapX ;
nextMapY = dungeon . _partyMapY ;
nextMapX + = _vm - > _dirIntoStepCountEast [ dungeon . _partyDir ] , nextMapY + = _vm - > _dirIntoStepCountNorth [ dungeon . _partyDir ] ;
2016-09-04 10:07:31 +00:00
_vm - > _groupMan - > fuseAction ( nextMapX , nextMapY ) ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionHeal : {
2016-08-09 12:17:18 +00:00
/* CHANGE2_17_IMPROVEMENT Heal action is much more effective
Heal cycles occur as long as the champion has missing health and enough mana . Cycle count = Min ( Current Mana / 2 , Missing health / Min ( 10 , Heal skill level ) )
Healing amount is Min ( Missing health , Min ( 10 , Heal skill level ) ) * heal cycle count
Mana cost is 2 * heal cycle count
Experience gain is 2 + 2 * heal cycle count */
2016-09-04 11:03:32 +00:00
int16 missingHealth = curChampion - > _maxHealth - curChampion - > _currHealth ;
if ( ( missingHealth > 0 ) & & curChampion - > _currMana ) {
2016-09-26 19:12:51 +00:00
int16 healingCapability = MIN ( ( uint16 ) 10 , championMan . getSkillLevel ( champIndex , kDMSkillHeal ) ) ;
2016-09-04 10:07:31 +00:00
actionExperienceGain = 2 ;
uint16 healingAmount ;
2016-08-09 12:17:18 +00:00
do {
2016-09-04 11:03:32 +00:00
healingAmount = MIN ( missingHealth , healingCapability ) ;
2016-09-04 10:07:31 +00:00
curChampion - > _currHealth + = healingAmount ;
actionExperienceGain + = 2 ;
curChampion - > _currMana = curChampion - > _currMana - 2 ;
if ( curChampion - > _currMana > 0 )
2016-09-04 11:03:32 +00:00
missingHealth - = healingAmount ;
} while ( ( curChampion - > _currMana > 0 ) & & missingHealth ) ;
2016-09-04 10:07:31 +00:00
if ( curChampion - > _currMana < 0 )
curChampion - > _currMana = 0 ;
2016-09-09 05:32:32 +00:00
setFlag ( curChampion - > _attributes , kDMAttributeStatistics ) ;
2016-09-04 11:03:32 +00:00
actionPerformed = true ;
}
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 12:31:49 +00:00
case kDMActionWindow : {
2016-09-26 19:12:51 +00:00
int16 windowTicks = _vm - > getRandomNumber ( championMan . getSkillLevel ( champIndex , actionSkillIndex ) + 8 ) + 5 ;
2016-09-04 10:07:31 +00:00
TimelineEvent newEvent ;
newEvent . _priority = 0 ;
2016-09-20 19:51:42 +00:00
newEvent . _type = kDMEventTypeThievesEye ;
2016-09-27 22:29:07 +00:00
newEvent . _mapTime = _vm - > setMapAndTime ( dungeon . _partyMapIndex , _vm - > _gameTime + windowTicks ) ;
2016-09-04 10:07:31 +00:00
_vm - > _timeline - > addEventGetEventIndex ( & newEvent ) ;
2016-09-26 19:12:51 +00:00
championMan . _party . _event73Count_ThievesEye + + ;
2016-09-04 11:03:32 +00:00
decrementCharges ( curChampion ) ;
2016-09-04 10:07:31 +00:00
}
2016-09-04 11:03:32 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionClimbDown :
2016-09-27 22:29:07 +00:00
nextMapX = dungeon . _partyMapX ;
nextMapY = dungeon . _partyMapY ;
nextMapX + = _vm - > _dirIntoStepCountEast [ dungeon . _partyDir ] ;
nextMapY + = _vm - > _dirIntoStepCountNorth [ dungeon . _partyDir ] ;
2016-08-09 12:17:18 +00:00
/* CHANGE6_00_FIX The presence of a group over the pit is checked so that you cannot climb down a pit with the rope if there is a group levitating over it */
2016-09-27 22:29:07 +00:00
if ( ( dungeon . getSquare ( nextMapX , nextMapY ) . getType ( ) = = kDMElementTypePit ) & & ( _vm - > _groupMan - > groupGetThing ( nextMapX , nextMapY ) = = Thing : : _endOfList ) ) {
2016-09-04 11:03:32 +00:00
/* BUG0_77 The party moves forward when using the rope in front of a closed pit. The engine does not check whether
the pit is open before moving the party over the pit . This is not consistent with the behavior when using the
rope in front of a corridor where nothing happens */
2016-08-25 20:09:30 +00:00
_vm - > _moveSens - > _useRopeToClimbDownPit = true ;
2016-09-27 22:29:07 +00:00
_vm - > _moveSens - > getMoveResult ( Thing : : _party , dungeon . _partyMapX , dungeon . _partyMapY , nextMapX , nextMapY ) ;
2016-08-25 20:09:30 +00:00
_vm - > _moveSens - > _useRopeToClimbDownPit = false ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 10:07:31 +00:00
actionDisabledTicks = 0 ;
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 12:31:49 +00:00
case kDMActionFreezeLife : {
2016-09-04 11:03:32 +00:00
int16 freezeTicks ;
2016-09-12 20:20:31 +00:00
if ( weaponInHand - > getType ( ) = = ( int ) kDMJunkTypeMagicalBoxBlue ) {
2016-09-04 11:03:32 +00:00
freezeTicks = 30 ;
2016-09-26 19:12:51 +00:00
championMan . getObjectRemovedFromSlot ( champIndex , kDMSlotActionHand ) ;
2016-09-04 10:07:31 +00:00
weaponInHand - > setNextThing ( Thing : : _none ) ;
2016-09-12 20:20:31 +00:00
} else if ( weaponInHand - > getType ( ) = = ( int ) kDMJunkTypeMagicalBoxGreen ) {
2016-09-04 11:03:32 +00:00
freezeTicks = 125 ;
2016-09-26 19:12:51 +00:00
championMan . getObjectRemovedFromSlot ( champIndex , kDMSlotActionHand ) ;
2016-09-04 10:07:31 +00:00
weaponInHand - > setNextThing ( Thing : : _none ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 11:03:32 +00:00
freezeTicks = 70 ;
2016-09-04 10:07:31 +00:00
decrementCharges ( curChampion ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-26 19:12:51 +00:00
championMan . _party . _freezeLifeTicks = MIN ( 200 , championMan . _party . _freezeLifeTicks + freezeTicks ) ;
2016-09-04 11:03:32 +00:00
}
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionLight :
2016-09-26 19:12:51 +00:00
championMan . _party . _magicalLightAmount + = championMan . _lightPowerToLightAmount [ 2 ] ;
2016-08-25 19:59:02 +00:00
createEvent70_light ( - 2 , 2500 ) ;
2016-09-04 10:07:31 +00:00
decrementCharges ( curChampion ) ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionThrow :
2016-09-04 10:07:31 +00:00
setChampionDirectionToPartyDirection ( curChampion ) ;
2016-09-27 22:29:07 +00:00
actionPerformed = championMan . isObjectThrown ( champIndex , kDMSlotActionHand , ( curChampion - > _cell = = ( ViewCell ) _vm - > turnDirRight ( dungeon . _partyDir ) ) | | ( curChampion - > _cell = = ( ViewCell ) _vm - > returnOppositeDir ( dungeon . _partyDir ) ) ) ;
2016-09-04 11:03:32 +00:00
if ( actionPerformed )
2016-09-10 19:50:57 +00:00
_vm - > _timeline - > _events [ curChampion - > _enableActionEventIndex ] . _Bu . _slotOrdinal = _vm - > indexToOrdinal ( kDMSlotActionHand ) ;
2016-09-04 11:03:32 +00:00
break ;
}
if ( setDirectionFl ) {
setChampionDirectionToPartyDirection ( curChampion ) ;
if ( curChampion - > _currMana < requiredManaAmount ) {
2016-09-12 18:58:21 +00:00
// Fix potential divide by zero
if ( ! requiredManaAmount )
requiredManaAmount = 1 ;
2016-09-04 11:03:32 +00:00
kineticEnergy = MAX ( 2 , curChampion - > _currMana * kineticEnergy / requiredManaAmount ) ;
requiredManaAmount = curChampion - > _currMana ;
2016-08-09 12:17:18 +00:00
}
2016-09-26 19:12:51 +00:00
actionPerformed = championMan . isProjectileSpellCast ( champIndex , explosionThing , kineticEnergy , requiredManaAmount ) ;
2016-09-04 11:03:32 +00:00
if ( ! actionPerformed )
actionExperienceGain > > = 1 ;
decrementCharges ( curChampion ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 11:03:32 +00:00
if ( actionDisabledTicks )
2016-09-26 19:12:51 +00:00
championMan . disableAction ( champIndex , actionDisabledTicks ) ;
2016-09-04 11:03:32 +00:00
if ( actionStamina )
2016-09-26 19:12:51 +00:00
championMan . decrementStamina ( champIndex , actionStamina ) ;
2016-09-04 11:03:32 +00:00
if ( actionExperienceGain )
2016-09-26 19:12:51 +00:00
championMan . addSkillExperience ( champIndex , actionSkillIndex , actionExperienceGain ) ;
2016-09-04 11:03:32 +00:00
2016-09-26 19:12:51 +00:00
championMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-09-04 11:03:32 +00:00
return actionPerformed ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
void MenuMan : : setChampionDirectionToPartyDirection ( Champion * champ ) {
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
if ( champ - > _dir ! = dungeon . _partyDir ) {
champ - > _dir = dungeon . _partyDir ;
2016-09-09 05:32:32 +00:00
setFlag ( champ - > _attributes , kDMAttributeIcon ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-09-03 19:42:58 +00:00
void MenuMan : : decrementCharges ( Champion * champ ) {
2016-09-10 09:47:36 +00:00
Thing slotActionThing = champ - > _slots [ kDMSlotActionHand ] ;
2016-09-04 13:44:40 +00:00
Junk * slotActionData = ( Junk * ) _vm - > _dungeonMan - > getThingData ( slotActionThing ) ;
switch ( slotActionThing . getType ( ) ) {
2016-09-10 22:33:54 +00:00
case kDMThingTypeWeapon :
2016-09-04 13:44:40 +00:00
if ( ( ( Weapon * ) slotActionData ) - > getChargeCount ( ) ) {
( ( Weapon * ) slotActionData ) - > setChargeCount ( ( ( Weapon * ) slotActionData ) - > getChargeCount ( ) - 1 ) ;
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 22:33:54 +00:00
case kDMThingTypeArmour :
2016-09-04 13:44:40 +00:00
if ( ( ( Armour * ) slotActionData ) - > getChargeCount ( ) ) {
( ( Armour * ) slotActionData ) - > setChargeCount ( ( ( Armour * ) slotActionData ) - > getChargeCount ( ) - 1 ) ;
2016-08-09 12:17:18 +00:00
}
break ;
2016-09-10 22:33:54 +00:00
case kDMThingTypeJunk :
2016-09-04 13:44:40 +00:00
if ( slotActionData - > getChargeCount ( ) ) {
slotActionData - > setChargeCount ( slotActionData - > getChargeCount ( ) - 1 ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-23 20:08:51 +00:00
break ;
default :
break ;
2016-08-09 12:17:18 +00:00
}
2016-08-23 05:54:16 +00:00
_vm - > _championMan - > drawChangedObjectIcons ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
bool MenuMan : : isMeleeActionPerformed ( int16 champIndex , Champion * champ , int16 actionIndex , int16 targetMapX , int16 targetMapY , int16 skillIndex ) {
2016-09-04 13:44:40 +00:00
static unsigned char actionDamageFactorArray [ 44 ] = {
2016-08-09 12:17:18 +00:00
0 , /* N */
15 , /* BLOCK */
48 , /* CHOP */
0 , /* X */
0 , /* BLOW HORN */
0 , /* FLIP */
32 , /* PUNCH */
48 , /* KICK */
0 , /* WAR CRY */
48 , /* STAB */
0 , /* CLIMB DOWN */
0 , /* FREEZE LIFE */
20 , /* HIT */
16 , /* SWING */
60 , /* STAB */
66 , /* THRUST */
8 , /* JAB */
8 , /* PARRY */
25 , /* HACK */
96 , /* BERZERK */
0 , /* FIREBALL */
0 , /* DISPELL */
0 , /* CONFUSE */
0 , /* LIGHTNING */
55 , /* DISRUPT */
60 , /* MELEE */
0 , /* X */
0 , /* INVOKE */
16 , /* SLASH */
48 , /* CLEAVE */
50 , /* BASH */
16 , /* STUN */
0 , /* SHOOT */
0 , /* SPELLSHIELD */
0 , /* FIRESHIELD */
0 , /* FLUXCAGE */
0 , /* HEAL */
0 , /* CALM */
0 , /* LIGHT */
0 , /* WINDOW */
0 , /* SPIT */
0 , /* BRANDISH */
0 , /* THROW */
2016-09-03 19:42:58 +00:00
0 /* FUSE */
} ;
2016-09-04 13:44:40 +00:00
static unsigned char actionHitProbabilityArray [ 44 ] = {
2016-08-09 12:17:18 +00:00
0 , /* N */
22 , /* BLOCK */
48 , /* CHOP */
0 , /* X */
0 , /* BLOW HORN */
0 , /* FLIP */
38 , /* PUNCH */
28 , /* KICK */
0 , /* WAR CRY */
30 , /* STAB */
0 , /* CLIMB DOWN */
0 , /* FREEZE LIFE */
20 , /* HIT */
32 , /* SWING */
42 , /* STAB */
57 , /* THRUST */
70 , /* JAB */
18 , /* PARRY */
27 , /* HACK */
46 , /* BERZERK */
0 , /* FIREBALL */
0 , /* DISPELL */
0 , /* CONFUSE */
0 , /* LIGHTNING */
46 , /* DISRUPT */
64 , /* MELEE */
0 , /* X */
0 , /* INVOKE */
26 , /* SLASH */
40 , /* CLEAVE */
32 , /* BASH */
50 , /* STUN */
0 , /* SHOOT */
0 , /* SPELLSHIELD */
0 , /* FIRESHIELD */
0 , /* FLUXCAGE */
0 , /* HEAL */
0 , /* CALM */
0 , /* LIGHT */
0 , /* WINDOW */
0 , /* SPIT */
0 , /* BRANDISH */
0 , /* THROW */
2016-09-03 19:42:58 +00:00
0 /* FUSE */
} ;
2016-08-09 12:17:18 +00:00
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
_vm - > _sound - > requestPlay ( kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight , dungeon . _partyMapX , dungeon . _partyMapY , kDMSoundModePlayIfPrioritized ) ;
2016-08-25 19:59:02 +00:00
if ( _actionTargetGroupThing = = Thing : : _endOfList )
2016-09-04 13:44:40 +00:00
return false ;
uint16 championCell = champ - > _cell ;
2016-09-27 22:29:07 +00:00
int16 targetCreatureOrdinal = _vm - > _groupMan - > getMeleeTargetCreatureOrdinal ( targetMapX , targetMapY , dungeon . _partyMapX , dungeon . _partyMapY , championCell ) ;
2016-09-04 13:44:40 +00:00
if ( targetCreatureOrdinal ) {
2016-09-11 07:46:35 +00:00
uint16 viewCell = _vm - > normalizeModulo4 ( championCell + 4 - champ - > _dir ) ;
2016-09-04 13:44:40 +00:00
switch ( viewCell ) {
2016-09-16 05:46:10 +00:00
case kDMViewCellBackRight : /* Champion is on the back right of the square and tries to attack a creature in the front right of its square */
case kDMViewCellBackLeft : /* Champion is on the back left of the square and tries to attack a creature in the front left of its square */
uint16 cellDelta = ( viewCell = = kDMViewCellBackRight ) ? 3 : 1 ;
2016-09-04 13:44:40 +00:00
/* Check if there is another champion in front */
2016-09-11 07:46:35 +00:00
if ( _vm - > _championMan - > getIndexInCell ( _vm - > normalizeModulo4 ( championCell + cellDelta ) ) ! = kDMChampionNone ) {
2016-09-18 20:15:51 +00:00
_actionDamage = kDMDamageCantReach ;
2016-09-04 13:44:40 +00:00
return false ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 13:44:40 +00:00
break ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 13:44:40 +00:00
2016-09-27 22:29:07 +00:00
if ( ( actionIndex = = kDMActionDisrupt ) & & ! getFlag ( dungeon . getCreatureAttributes ( _actionTargetGroupThing ) , kDMCreatureMaskNonMaterial ) )
2016-09-04 13:44:40 +00:00
return false ;
uint16 actionHitProbability = actionHitProbabilityArray [ actionIndex ] ;
uint16 actionDamageFactor = actionDamageFactorArray [ actionIndex ] ;
2016-09-10 12:31:49 +00:00
if ( ( _vm - > _objectMan - > getIconIndex ( champ - > _slots [ kDMSlotActionHand ] ) = = kDMIconIndiceWeaponVorpalBlade ) | | ( actionIndex = = kDMActionDisrupt ) ) {
2016-09-18 20:15:51 +00:00
setFlag ( actionHitProbability , kDMActionMaskHitNonMaterialCreatures ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-27 22:29:07 +00:00
_actionDamage = _vm - > _groupMan - > getMeleeActionDamage ( champ , champIndex , ( Group * ) dungeon . getThingData ( _actionTargetGroupThing ) , _vm - > ordinalToIndex ( targetCreatureOrdinal ) , targetMapX , targetMapY , actionHitProbability , actionDamageFactor , skillIndex ) ;
2016-08-09 12:17:18 +00:00
return true ;
}
2016-09-04 13:44:40 +00:00
2016-08-09 12:17:18 +00:00
return false ;
}
2016-08-25 19:59:02 +00:00
bool MenuMan : : isGroupFrightenedByAction ( int16 champIndex , uint16 actionIndex , int16 mapX , int16 mapY ) {
2016-09-13 20:07:02 +00:00
bool retVal = false ;
2016-09-04 13:44:40 +00:00
if ( _actionTargetGroupThing = = Thing : : _endOfList )
2016-09-13 20:07:02 +00:00
return retVal ;
2016-08-09 12:17:18 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
2016-09-26 19:12:51 +00:00
2016-09-04 13:44:40 +00:00
uint16 experience = 0 ;
int16 frightAmount = 0 ;
2016-08-09 12:17:18 +00:00
switch ( actionIndex ) {
2016-09-10 12:31:49 +00:00
case kDMActionWarCry :
2016-09-04 13:44:40 +00:00
frightAmount = 3 ;
experience = 12 ; /* War Cry gives experience in priest skill k14_ChampionSkillInfluence below. The War Cry action also has an experience gain of 7 defined in G0497_auc_Graphic560_ActionExperienceGain in the same skill (versions 1.1 and below) or in the fighter skill k7_ChampionSkillParry (versions 1.2 and above). In versions 1.2 and above, this is the only action that gives experience in two skills */
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionCalm :
2016-09-04 13:44:40 +00:00
frightAmount = 7 ;
experience = 35 ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionBrandish :
2016-09-04 13:44:40 +00:00
frightAmount = 6 ;
experience = 30 ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionBlowHorn :
2016-09-04 13:44:40 +00:00
frightAmount = 6 ;
experience = 20 ;
2016-08-09 12:17:18 +00:00
break ;
2016-09-10 12:31:49 +00:00
case kDMActionConfuse :
2016-09-04 13:44:40 +00:00
frightAmount = 12 ;
experience = 45 ;
break ;
2016-08-09 12:17:18 +00:00
}
2016-09-27 22:29:07 +00:00
2016-09-26 19:12:51 +00:00
frightAmount + = championMan . getSkillLevel ( champIndex , kDMSkillInfluence ) ;
2016-09-27 22:29:07 +00:00
Group * targetGroup = ( Group * ) dungeon . getThingData ( _actionTargetGroupThing ) ;
CreatureInfo * creatureInfo = & dungeon . _creatureInfos [ targetGroup - > _type ] ;
2016-09-04 13:44:40 +00:00
uint16 fearResistance = creatureInfo - > getFearResistance ( ) ;
2016-09-18 10:52:01 +00:00
if ( ( fearResistance > _vm - > getRandomNumber ( frightAmount ) ) | | ( fearResistance = = kDMImmuneToFear ) ) {
2016-09-04 13:44:40 +00:00
experience > > = 1 ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 13:44:40 +00:00
ActiveGroup * activeGroup = & _vm - > _groupMan - > _activeGroups [ targetGroup - > getActiveGroupIndex ( ) ] ;
2016-09-18 10:52:01 +00:00
if ( targetGroup - > getBehaviour ( ) = = kDMBehaviorAttack ) {
2016-09-04 13:44:40 +00:00
_vm - > _groupMan - > stopAttacking ( activeGroup , mapX , mapY ) ;
2016-09-01 20:01:22 +00:00
_vm - > _groupMan - > startWandering ( mapX , mapY ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-18 10:52:01 +00:00
targetGroup - > setBehaviour ( kDMBehaviorFlee ) ;
2016-09-04 13:44:40 +00:00
activeGroup - > _delayFleeingFromTarget = ( ( 16 - fearResistance ) < < 2 ) / creatureInfo - > _movementTicks ;
2016-09-13 20:07:02 +00:00
retVal = true ;
2016-08-09 12:17:18 +00:00
}
2016-09-26 19:12:51 +00:00
championMan . addSkillExperience ( champIndex , kDMSkillInfluence , experience ) ;
2016-09-04 13:44:40 +00:00
2016-09-13 20:07:02 +00:00
return retVal ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
void MenuMan : : printMessageAfterReplacements ( const char * str ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-09-04 13:44:40 +00:00
char outputString [ 128 ] ;
char * curCharacter = outputString ;
* curCharacter + + = ' \n ' ; /* New line */
2016-09-11 21:25:22 +00:00
const char * replacementString = " " ;
2016-08-09 12:17:18 +00:00
do {
if ( * str = = ' @ ' ) {
str + + ;
2016-09-04 13:44:40 +00:00
if ( * ( curCharacter - 1 ) ! = ' \n ' ) /* New line */
* curCharacter + + = ' ' ;
if ( * str = = ' p ' ) /* '@p' in the source string is replaced by the champion name followed by a space */
2016-09-26 19:12:51 +00:00
replacementString = championMan . _champions [ _vm - > ordinalToIndex ( championMan . _actingChampionOrdinal ) ] . _name ;
2016-09-04 13:44:40 +00:00
* curCharacter = ' \0 ' ;
strcat ( outputString , replacementString ) ;
curCharacter + = strlen ( replacementString ) ;
* curCharacter + + = ' ' ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 13:44:40 +00:00
* curCharacter + + = * str ;
2016-08-09 12:17:18 +00:00
}
} while ( * str + + ) ;
2016-09-04 13:44:40 +00:00
* curCharacter = ' \0 ' ;
if ( outputString [ 1 ] ) /* If the string is not empty (the first character is a new line \n) */
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printMessage ( kDMColorCyan , outputString ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
void MenuMan : : processCommands116To119_setActingChampion ( uint16 champIndex ) {
2016-09-04 13:44:40 +00:00
static ActionSet actionSets [ 44 ] = {
2016-08-09 12:17:18 +00:00
/* { ActionIndices[0], ActionIndices[1], ActionIndices[2], ActionProperties[0], ActionProperties[1], Useless } */
ActionSet ( 255 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 27 , 43 , 35 , 0x00 , 0x00 ) ,
ActionSet ( 6 , 7 , 8 , 0x00 , 0x00 ) ,
ActionSet ( 0 , 0 , 0 , 0x00 , 0x00 ) ,
ActionSet ( 0 , 0 , 0 , 0x00 , 0x00 ) ,
ActionSet ( 13 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 13 , 20 , 255 , 0x87 , 0x00 ) ,
ActionSet ( 13 , 23 , 255 , 0x83 , 0x00 ) ,
ActionSet ( 28 , 41 , 22 , 0x02 , 0x83 ) ,
ActionSet ( 16 , 2 , 23 , 0x00 , 0x84 ) ,
ActionSet ( 2 , 25 , 20 , 0x02 , 0x86 ) ,
ActionSet ( 17 , 41 , 34 , 0x03 , 0x05 ) ,
ActionSet ( 42 , 9 , 28 , 0x00 , 0x02 ) ,
ActionSet ( 13 , 17 , 2 , 0x02 , 0x03 ) ,
ActionSet ( 16 , 17 , 15 , 0x01 , 0x05 ) ,
ActionSet ( 28 , 17 , 25 , 0x01 , 0x05 ) ,
ActionSet ( 2 , 25 , 15 , 0x05 , 0x06 ) ,
ActionSet ( 9 , 2 , 29 , 0x02 , 0x05 ) ,
ActionSet ( 16 , 29 , 24 , 0x02 , 0x04 ) ,
ActionSet ( 13 , 15 , 19 , 0x05 , 0x07 ) ,
ActionSet ( 13 , 2 , 25 , 0x00 , 0x05 ) ,
ActionSet ( 2 , 29 , 19 , 0x03 , 0x08 ) ,
ActionSet ( 13 , 30 , 31 , 0x02 , 0x04 ) ,
ActionSet ( 13 , 31 , 25 , 0x03 , 0x06 ) ,
ActionSet ( 42 , 30 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 0 , 0 , 0 , 0x00 , 0x00 ) ,
ActionSet ( 42 , 9 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 32 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 37 , 33 , 36 , 0x82 , 0x03 ) ,
ActionSet ( 37 , 33 , 34 , 0x83 , 0x84 ) ,
ActionSet ( 17 , 38 , 21 , 0x80 , 0x83 ) ,
ActionSet ( 13 , 21 , 34 , 0x83 , 0x84 ) ,
ActionSet ( 36 , 37 , 41 , 0x02 , 0x03 ) ,
ActionSet ( 13 , 23 , 39 , 0x82 , 0x84 ) ,
ActionSet ( 13 , 17 , 40 , 0x00 , 0x83 ) ,
ActionSet ( 17 , 36 , 38 , 0x03 , 0x84 ) ,
ActionSet ( 4 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 5 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 11 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 10 , 255 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 42 , 9 , 255 , 0x00 , 0x00 ) ,
ActionSet ( 1 , 12 , 255 , 0x02 , 0x00 ) ,
ActionSet ( 42 , 255 , 255 , 0x00 , 0x00 ) ,
2016-09-03 19:42:58 +00:00
ActionSet ( 6 , 11 , 255 , 0x80 , 0x00 )
} ;
2016-08-09 12:17:18 +00:00
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Champion * curChampion = & championMan . _champions [ champIndex ] ;
2016-09-09 05:32:32 +00:00
if ( getFlag ( curChampion - > _attributes , kDMAttributeDisableAction ) | | ! curChampion - > _currHealth )
2016-08-19 22:37:28 +00:00
return ;
2016-09-04 13:44:40 +00:00
2016-09-27 22:29:07 +00:00
DungeonMan & dungeon = * _vm - > _dungeonMan ;
2016-09-04 13:44:40 +00:00
uint16 actionSetIndex ;
2016-09-10 09:47:36 +00:00
Thing slotActionThing = curChampion - > _slots [ kDMSlotActionHand ] ;
2016-09-04 13:44:40 +00:00
if ( slotActionThing = = Thing : : _none )
actionSetIndex = 2 ; /* Actions Punch, Kick and War Cry */
else {
2016-09-27 22:29:07 +00:00
actionSetIndex = dungeon . _objectInfos [ dungeon . getObjectInfoIndex ( slotActionThing ) ] . _actionSetIndex ;
2016-09-04 13:44:40 +00:00
if ( actionSetIndex = = 0 )
return ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 13:44:40 +00:00
ActionSet * actionSet = & actionSets [ actionSetIndex ] ;
2016-09-26 19:12:51 +00:00
championMan . _actingChampionOrdinal = _vm - > indexToOrdinal ( champIndex ) ;
2016-09-04 13:44:40 +00:00
setActionList ( actionSet ) ;
2016-08-25 19:59:02 +00:00
_actionAreaContainsIcons = false ;
2016-09-09 05:32:32 +00:00
setFlag ( curChampion - > _attributes , kDMAttributeActionHand ) ;
2016-09-26 19:12:51 +00:00
championMan . drawChampionState ( ( ChampionIndex ) champIndex ) ;
2016-08-25 19:59:02 +00:00
drawActionArea ( ) ;
drawActionArea ( ) ;
2016-08-09 12:17:18 +00:00
}
2016-09-03 19:42:58 +00:00
void MenuMan : : setActionList ( ActionSet * actionSet ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
2016-08-25 19:59:02 +00:00
_actionList . _actionIndices [ 0 ] = ( ChampionAction ) actionSet - > _actionIndices [ 0 ] ;
_actionList . _minimumSkillLevel [ 0 ] = 1 ;
2016-09-04 13:44:40 +00:00
uint16 nextAvailableActionListIndex = 1 ;
for ( uint16 idx = 1 ; idx < 3 ; idx + + ) {
uint16 actionIndex = actionSet - > _actionIndices [ idx ] ;
2016-09-10 12:31:49 +00:00
if ( actionIndex = = kDMActionNone )
2016-08-09 12:17:18 +00:00
continue ;
2016-09-04 13:44:40 +00:00
uint16 minimumSkillLevel = actionSet - > _actionProperties [ idx - 1 ] ;
2016-09-18 20:15:51 +00:00
if ( getFlag ( minimumSkillLevel , kDMActionMaskRequiresCharge ) & & ! getActionObjectChargeCount ( ) )
2016-08-09 12:17:18 +00:00
continue ;
2016-09-04 13:44:40 +00:00
2016-09-18 20:15:51 +00:00
clearFlag ( minimumSkillLevel , kDMActionMaskRequiresCharge ) ;
2016-09-26 19:12:51 +00:00
if ( championMan . getSkillLevel ( _vm - > ordinalToIndex ( championMan . _actingChampionOrdinal ) , _actionSkillIndex [ actionIndex ] ) > = minimumSkillLevel ) {
2016-09-04 13:44:40 +00:00
_actionList . _actionIndices [ nextAvailableActionListIndex ] = ( ChampionAction ) actionIndex ;
_actionList . _minimumSkillLevel [ nextAvailableActionListIndex ] = minimumSkillLevel ;
nextAvailableActionListIndex + + ;
2016-08-09 12:17:18 +00:00
}
}
2016-09-04 13:44:40 +00:00
_actionCount = nextAvailableActionListIndex ;
for ( uint16 idx = nextAvailableActionListIndex ; idx < 3 ; idx + + )
2016-09-10 12:31:49 +00:00
_actionList . _actionIndices [ idx ] = kDMActionNone ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 19:59:02 +00:00
int16 MenuMan : : getActionObjectChargeCount ( ) {
2016-09-26 19:12:51 +00:00
ChampionMan & championMan = * _vm - > _championMan ;
Thing slotActionThing = championMan . _champions [ _vm - > ordinalToIndex ( championMan . _actingChampionOrdinal ) ] . _slots [ kDMSlotActionHand ] ;
2016-09-04 13:44:40 +00:00
Junk * junkData = ( Junk * ) _vm - > _dungeonMan - > getThingData ( slotActionThing ) ;
switch ( slotActionThing . getType ( ) ) {
2016-09-10 22:33:54 +00:00
case kDMThingTypeWeapon :
2016-09-04 13:44:40 +00:00
return ( ( Weapon * ) junkData ) - > getChargeCount ( ) ;
2016-09-10 22:33:54 +00:00
case kDMThingTypeArmour :
2016-09-04 13:44:40 +00:00
return ( ( Armour * ) junkData ) - > getChargeCount ( ) ;
2016-09-10 22:33:54 +00:00
case kDMThingTypeJunk :
2016-09-04 13:44:40 +00:00
return junkData - > getChargeCount ( ) ;
2016-08-09 12:17:18 +00:00
default :
return 1 ;
}
}
2016-08-25 19:59:02 +00:00
void MenuMan : : drawActionDamage ( int16 damage ) {
2016-09-04 16:29:16 +00:00
static const Box actionAreaMediumDamage ( 242 , 305 , 81 , 117 ) ;
static const Box actionAreaSmallDamage ( 251 , 292 , 81 , 117 ) ;
2016-08-09 12:17:18 +00:00
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > showMouse ( ) ;
2016-08-25 16:32:03 +00:00
_vm - > _displayMan - > _useByteBoxCoordinates = false ;
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > fillScreenBox ( _boxActionArea , kDMColorBlack ) ;
2016-08-09 12:17:18 +00:00
if ( damage < 0 ) {
2016-09-04 16:29:16 +00:00
static const char * messagesEN [ 2 ] = { " CAN'T REACH " , " NEED AMMO " } ;
static const char * messagesDE [ 2 ] = { " ZU WEIT WEG " , " MEHR MUNITION " } ;
static const char * messagesFR [ 2 ] = { " TROP LOIN " , " SANS MUNITION " } ;
static int16 posEN [ 2 ] = { 242 , 248 } ;
static int16 posDE [ 2 ] = { 242 , 236 } ;
static int16 posFR [ 2 ] = { 248 , 236 } ;
2016-08-22 22:08:10 +00:00
const char * * message ;
2016-08-15 18:25:40 +00:00
int16 * pos ;
switch ( _vm - > getGameLanguage ( ) ) { // localized
2016-09-04 16:29:16 +00:00
case Common : : DE_DEU :
message = messagesDE ;
pos = posDE ;
break ;
case Common : : FR_FRA :
message = messagesFR ;
pos = posFR ;
break ;
2016-08-15 18:25:40 +00:00
default :
2016-09-04 16:29:16 +00:00
message = messagesEN ;
pos = posEN ;
break ;
2016-08-15 18:25:40 +00:00
}
2016-09-04 16:29:16 +00:00
const char * displayString ;
int16 textPosX ;
2016-09-18 20:15:51 +00:00
if ( damage = = kDMDamageCantReach ) {
2016-09-04 16:29:16 +00:00
textPosX = pos [ 0 ] ;
displayString = message [ 0 ] ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 16:29:16 +00:00
textPosX = pos [ 1 ] ;
displayString = message [ 1 ] ;
2016-08-09 12:17:18 +00:00
}
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( textPosX , 100 , kDMColorCyan , kDMColorBlack , displayString ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 16:29:16 +00:00
int16 byteWidth ;
byte * blitBitmap ;
const Box * blitBox ;
int16 displayHeight ;
2016-08-09 12:17:18 +00:00
if ( damage > 40 ) {
2016-09-04 16:29:16 +00:00
blitBox = & _boxActionArea3ActionMenu ;
2016-09-21 05:53:54 +00:00
blitBitmap = _vm - > _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxDamageToCreature ) ;
2016-09-04 16:29:16 +00:00
byteWidth = k48_byteWidth ;
displayHeight = 45 ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 16:29:16 +00:00
uint16 derivedBitmapIndex ;
int16 destPixelWidth ;
2016-08-09 12:17:18 +00:00
if ( damage > 15 ) {
2016-09-16 05:46:10 +00:00
derivedBitmapIndex = kDMDerivedBitmapDamageToCreatureMedium ;
2016-09-04 16:29:16 +00:00
destPixelWidth = 64 ;
byteWidth = k32_byteWidth ;
blitBox = & actionAreaMediumDamage ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-16 05:46:10 +00:00
derivedBitmapIndex = kDMDerivedBitmapDamageToCreatureSmall ;
2016-09-04 16:29:16 +00:00
destPixelWidth = 42 ;
byteWidth = k24_byteWidth ;
blitBox = & actionAreaSmallDamage ;
2016-08-09 12:17:18 +00:00
}
2016-09-04 16:29:16 +00:00
displayHeight = 37 ;
if ( ! _vm - > _displayMan - > isDerivedBitmapInCache ( derivedBitmapIndex ) ) {
2016-09-21 05:53:54 +00:00
byte * nativeBitmap = _vm - > _displayMan - > getNativeBitmapOrGraphic ( kDMGraphicIdxDamageToCreature ) ;
2016-09-04 16:29:16 +00:00
blitBitmap = _vm - > _displayMan - > getDerivedBitmap ( derivedBitmapIndex ) ;
_vm - > _displayMan - > blitToBitmapShrinkWithPalChange ( nativeBitmap , blitBitmap , 96 , 45 , destPixelWidth , 37 , _vm - > _displayMan - > _palChangesNoChanges ) ;
_vm - > _displayMan - > addDerivedBitmap ( derivedBitmapIndex ) ;
2016-08-09 12:17:18 +00:00
} else {
2016-09-04 16:29:16 +00:00
blitBitmap = _vm - > _displayMan - > getDerivedBitmap ( derivedBitmapIndex ) ;
2016-08-09 12:17:18 +00:00
}
}
2016-09-16 05:46:10 +00:00
_vm - > _displayMan - > blitToScreen ( blitBitmap , blitBox , byteWidth , kDMColorNoTransparency , displayHeight ) ;
2016-08-09 12:17:18 +00:00
/* Convert damage value to string */
2016-09-04 16:29:16 +00:00
uint16 charIndex = 5 ;
int16 textPosX = 274 ;
char scoreString [ 6 ] ;
scoreString [ 5 ] = ' \0 ' ;
2016-08-09 12:17:18 +00:00
do {
2016-09-04 16:29:16 +00:00
scoreString [ - - charIndex ] = ' 0 ' + ( damage % 10 ) ;
textPosX - = 3 ;
2016-08-09 12:17:18 +00:00
} while ( damage / = 10 ) ;
2016-09-16 05:46:10 +00:00
_vm - > _textMan - > printToLogicalScreen ( textPosX , 100 , kDMColorCyan , kDMColorBlack , & scoreString [ charIndex ] ) ;
2016-08-09 12:17:18 +00:00
}
2016-08-25 06:12:23 +00:00
_vm - > _eventMan - > hideMouse ( ) ;
2016-08-09 12:17:18 +00:00
}
}