2007-05-30 21:56:52 +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 .
2001-10-09 14:30:12 +00:00
*
* 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 .
2014-02-18 02:34:24 +01:00
*
2001-10-09 14:30:12 +00:00
* 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 .
2014-02-18 02:34:24 +01:00
*
2001-10-09 14:30:12 +00:00
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
2005-10-18 01:30:26 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
2001-10-09 14:30:12 +00:00
*
*/
2006-07-09 09:40:44 +00:00
# include "common/system.h" // for setFocusRectangle/clearFocusRectangle
2003-10-03 18:33:57 +00:00
# include "scumm/scumm.h"
# include "scumm/actor.h"
2011-04-05 11:36:38 +02:00
# include "scumm/actor_he.h"
2005-05-14 23:28:22 +00:00
# include "scumm/akos.h"
2003-10-03 18:33:57 +00:00
# include "scumm/boxes.h"
# include "scumm/charset.h"
# include "scumm/costume.h"
2006-02-15 00:57:50 +00:00
# include "scumm/he/intern_he.h"
2005-03-28 22:37:30 +00:00
# include "scumm/object.h"
2003-10-03 18:33:57 +00:00
# include "scumm/resource.h"
2009-03-20 16:33:58 +00:00
# include "scumm/scumm_v7.h"
2014-11-29 07:12:57 +11:00
# include "scumm/scumm_v0.h"
2006-04-23 18:52:39 +00:00
# include "scumm/he/sound_he.h"
2006-02-15 00:57:50 +00:00
# include "scumm/he/sprite_he.h"
2003-10-03 18:33:57 +00:00
# include "scumm/usage_bits.h"
2005-04-10 12:59:17 +00:00
# include "scumm/util.h"
2003-10-03 18:33:57 +00:00
namespace Scumm {
2002-05-14 23:35:28 +00:00
2003-05-20 20:42:28 +00:00
byte Actor : : kInvalidBox = 0 ;
2003-05-18 19:44:22 +00:00
2014-12-07 19:53:27 +11:00
static const byte v0ActorDemoTalk [ 25 ] = {
0x00 ,
0x06 , // Syd
0x06 , // Razor
0x06 , // Dave
0x06 , // Michael
0x06 , // Bernard
0x06 , // Wendy
0x00 , // Jeff
0x46 , // Radiation Suit
0x06 , // Dr Fred
0x06 , // Nurse Edna
0x06 , // Weird Ed
0x06 , // Dead Cousin Ted
0xE2 , // Purple Tentacle
0xE2 , // Green Tentacle
0x06 , // Meteor police
0xC0 , // Meteor
0x06 , // Mark Eteer
0x06 , // Talkshow Host
0x00 , // Plant
0xC0 , // Meteor Radiation
0xC0 , // Edsel (small, outro)
0x00 , // Meteor (small, intro)
0x06 , // Sandy (Lab)
0x06 , // Sandy (Cut-Scene)
} ;
static const byte v0ActorTalk [ 25 ] = {
0x00 ,
0x06 , // Syd
0x06 , // Razor
0x06 , // Dave
0x06 , // Michael
0x06 , // Bernard
0x06 , // Wendy
0x00 , // Jeff
0x46 , // Radiation Suit
0x06 , // Dr Fred
0x06 , // Nurse Edna
0x06 , // Weird Ed
0x06 , // Dead Cousin Ted
0xFF , // Purple Tentacle
0xFF , // Green Tentacle
0x06 , // Meteor police
0xC0 , // Meteor
0x06 , // Mark Eteer
0x06 , // Talkshow Host
0x00 , // Plant
0xC0 , // Meteor Radiation
0xC0 , // Edsel (small, outro)
0x00 , // Meteor (small, intro)
0x06 , // Sandy (Lab)
0x06 , // Sandy (Cut-Scene)
2012-01-24 23:23:19 +11:00
} ;
2016-10-09 14:59:58 +02:00
static const byte v0WalkboxSlantedModifier [ 0x16 ] = {
2014-11-30 22:01:23 +11:00
0x00 , 0x01 , 0x02 , 0x03 , 0x03 , 0x04 , 0x05 , 0x06 ,
0x06 , 0x07 , 0x08 , 0x09 , 0x09 , 0x0A , 0x0B ,
0x0C , 0x0C , 0x0D , 0x0E , 0x0F , 0x10 , 0x10
} ;
2007-03-12 12:11:59 +00:00
Actor : : Actor ( ScummEngine * scumm , int id ) :
_vm ( scumm ) , _number ( id ) {
2003-07-27 23:45:43 +00:00
assert ( _vm ! = 0 ) ;
}
2008-09-25 08:06:18 +00:00
void ActorHE : : initActor ( int mode ) {
Actor : : initActor ( mode ) ;
2006-12-25 15:37:20 +00:00
if ( mode = = - 1 ) {
2008-09-25 08:06:18 +00:00
_heOffsX = _heOffsY = 0 ;
2006-12-25 15:37:20 +00:00
_heSkipLimbs = false ;
memset ( _heTalkQueue , 0 , sizeof ( _heTalkQueue ) ) ;
}
if ( mode = = 1 | | mode = = - 1 ) {
_heCondMask = 1 ;
_heNoTalkAnimation = 0 ;
_heSkipLimbs = false ;
} else if ( mode = = 2 ) {
_heCondMask = 1 ;
_heSkipLimbs = false ;
}
_heXmapNum = 0 ;
_hePaletteNum = 0 ;
_heFlags = 0 ;
_heTalking = false ;
2007-09-19 08:40:12 +00:00
2008-09-25 08:06:18 +00:00
if ( _vm - > _game . heversion > = 61 )
_flip = 0 ;
2011-04-05 11:36:38 +02:00
_clipOverride = ( ( ScummEngine_v60he * ) _vm ) - > _actorClipOverride ;
2008-09-25 08:06:18 +00:00
_auxBlock . reset ( ) ;
}
void Actor : : initActor ( int mode ) {
2006-12-25 15:37:20 +00:00
2004-10-07 21:23:29 +00:00
if ( mode = = - 1 ) {
2005-03-11 01:10:06 +00:00
_top = _bottom = 0 ;
2006-12-25 15:37:20 +00:00
_needRedraw = false ;
_needBgReset = false ;
_costumeNeedsInit = false ;
_visible = false ;
2005-03-11 01:10:06 +00:00
_flip = false ;
2007-03-10 13:53:11 +00:00
_speedx = 8 ;
_speedy = 2 ;
2005-03-11 01:10:06 +00:00
_frame = 0 ;
2004-10-07 21:23:29 +00:00
_walkbox = 0 ;
2005-03-11 01:10:06 +00:00
_animProgress = 0 ;
_drawToBackBuf = false ;
memset ( _animVariable , 0 , sizeof ( _animVariable ) ) ;
memset ( _palette , 0 , sizeof ( _palette ) ) ;
memset ( _sound , 0 , sizeof ( _sound ) ) ;
memset ( & _cost , 0 , sizeof ( CostumeData ) ) ;
memset ( & _walkdata , 0 , sizeof ( ActorWalkData ) ) ;
_walkdata . point3 . x = 32000 ;
_walkScript = 0 ;
2004-10-07 21:23:29 +00:00
}
2006-12-25 15:37:20 +00:00
if ( mode = = 1 | | mode = = - 1 ) {
2005-03-11 01:10:06 +00:00
_costume = 0 ;
_room = 0 ;
2003-09-14 18:16:45 +00:00
_pos . x = 0 ;
_pos . y = 0 ;
2005-03-11 01:10:06 +00:00
_facing = 180 ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . version > = 7 )
2005-03-11 01:10:06 +00:00
_visible = false ;
2002-04-11 17:19:16 +00:00
} else if ( mode = = 2 ) {
2005-03-11 01:10:06 +00:00
_facing = 180 ;
2001-10-09 14:30:12 +00:00
}
2004-09-28 19:28:59 +00:00
_elevation = 0 ;
2005-03-11 01:10:06 +00:00
_width = 24 ;
_talkColor = 15 ;
_talkPosX = 0 ;
_talkPosY = - 80 ;
_boxscale = _scaley = _scalex = 0xFF ;
_charset = 0 ;
memset ( _sound , 0 , sizeof ( _sound ) ) ;
_targetFacing = _facing ;
2002-05-14 19:11:20 +00:00
2004-09-28 19:28:59 +00:00
_shadowMode = 0 ;
_layer = 0 ;
2002-05-14 19:11:20 +00:00
2006-12-25 15:37:20 +00:00
stopActorMoving ( ) ;
2007-03-10 13:53:11 +00:00
setActorWalkSpeed ( 8 , 2 ) ;
2007-02-04 01:24:43 +00:00
2005-03-11 01:10:06 +00:00
_animSpeed = 0 ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . version > = 6 )
2005-03-11 01:10:06 +00:00
_animProgress = 0 ;
2002-05-14 19:11:20 +00:00
2005-03-11 01:10:06 +00:00
_ignoreBoxes = false ;
2006-02-20 16:51:30 +00:00
_forceClip = ( _vm - > _game . version > = 7 ) ? 100 : 0 ;
2005-03-11 01:10:06 +00:00
_ignoreTurns = false ;
2004-07-04 03:12:02 +00:00
2005-03-11 01:10:06 +00:00
_talkFrequency = 256 ;
_talkPan = 64 ;
_talkVolume = 127 ;
2004-02-09 08:05:23 +00:00
2007-03-10 13:53:11 +00:00
_initFrame = 1 ;
_walkFrame = 2 ;
_standFrame = 3 ;
_talkStartFrame = 4 ;
_talkStopFrame = 5 ;
2002-05-14 19:11:20 +00:00
2005-03-11 01:10:06 +00:00
_walkScript = 0 ;
_talkScript = 0 ;
2002-05-14 19:11:20 +00:00
2006-02-20 16:51:30 +00:00
_vm - > _classData [ _number ] = ( _vm - > _game . version > = 7 ) ? _vm - > _classData [ 0 ] : 0 ;
2001-12-27 17:51:58 +00:00
}
2007-03-10 13:53:11 +00:00
void Actor_v2 : : initActor ( int mode ) {
Actor : : initActor ( mode ) ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
_speedx = 1 ;
_speedy = 1 ;
2007-03-10 13:53:11 +00:00
_initFrame = 2 ;
_walkFrame = 0 ;
_standFrame = 1 ;
_talkStartFrame = 5 ;
_talkStopFrame = 4 ;
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : initActor ( int mode ) {
2012-02-04 17:35:59 +01:00
Actor_v2 : : initActor ( mode ) ;
_costCommandNew = 0xFF ;
_costCommand = 0xFF ;
_miscflags = 0 ;
_speaking = 0 ;
2016-10-09 14:59:58 +02:00
2014-11-30 22:01:23 +11:00
_walkCountModulo = 0 ;
_newWalkBoxEntered = false ;
_walkDirX = 0 ;
_walkDirY = 0 ;
_walkYCountGreaterThanXCount = 0 ;
_walkXCount = 0 ;
_walkXCountInc = 0 ;
_walkYCount = 0 ;
_walkYCountInc = 0 ;
_walkMaxXYCountInc = 0 ;
_tmp_WalkBox = 0 ;
_tmp_NewWalkBoxEntered = 0 ;
2012-02-04 17:35:59 +01:00
_animFrameRepeat = 0 ;
2012-02-06 08:06:48 +01:00
for ( int i = 0 ; i < 8 ; + + i ) {
2012-02-04 17:35:59 +01:00
_limbFrameRepeatNew [ i ] = 0 ;
_limbFrameRepeat [ i ] = 0 ;
_limb_flipped [ i ] = false ;
}
2014-12-07 19:53:27 +11:00
2016-07-16 17:18:11 +10:00
walkBoxQueueReset ( ) ;
2014-12-07 19:53:27 +11:00
if ( _vm - > _game . features & GF_DEMO ) {
_sound [ 0 ] = v0ActorDemoTalk [ _number ] ;
} else {
_sound [ 0 ] = v0ActorTalk [ _number ] ;
}
2012-02-04 17:35:59 +01:00
}
2007-03-10 13:53:11 +00:00
2016-07-16 17:18:11 +10:00
void Actor_v0 : : walkBoxQueueReset ( ) {
_walkboxHistory . clear ( ) ;
_walkboxQueueIndex = 0 ;
2016-07-19 18:55:27 +10:00
for ( uint i = 0 ; i < ARRAYSIZE ( _walkboxQueue ) ; + + i ) {
2016-07-16 17:18:11 +10:00
_walkboxQueue [ i ] = kInvalidBox ;
}
}
bool Actor_v0 : : walkBoxQueueAdd ( int box ) {
2016-07-19 18:55:27 +10:00
if ( _walkboxQueueIndex = = ARRAYSIZE ( _walkboxQueue ) )
2016-07-16 17:18:11 +10:00
return false ;
2016-07-19 18:55:27 +10:00
_walkboxQueue [ _walkboxQueueIndex + + ] = box ;
_walkboxHistory . push_back ( box ) ;
2016-07-16 17:18:11 +10:00
return true ;
}
void Actor_v0 : : walkboxQueueReverse ( ) {
2016-07-19 18:55:27 +10:00
int j = ARRAYSIZE ( _walkboxQueue ) - 1 ;
2016-07-16 17:18:11 +10:00
while ( _walkboxQueue [ j ] = = kInvalidBox & & j > = 1 )
- - j ;
if ( j < = 1 )
return ;
for ( int i = 1 ; i < j & & j > = 1 ; + + i , - - j ) {
2016-10-09 14:59:58 +02:00
2016-07-16 17:18:11 +10:00
byte tmp = _walkboxQueue [ i ] ;
_walkboxQueue [ i ] = _walkboxQueue [ j ] ;
_walkboxQueue [ j ] = tmp ;
}
}
bool Actor_v0 : : walkBoxQueueFind ( int box ) {
for ( uint i = 0 ; i < _walkboxHistory . size ( ) ; + + i ) {
if ( box = = _walkboxHistory [ i ] )
return true ;
}
return false ;
}
bool Actor_v0 : : walkBoxQueuePrepare ( ) {
walkBoxQueueReset ( ) ;
int BoxFound = _walkbox ;
if ( BoxFound = = _walkdata . destbox ) {
_newWalkBoxEntered = true ;
return true ;
}
// Build a series of walkboxes from our current position, to the target
do {
// Add the current box to the queue
2016-07-19 18:55:27 +10:00
if ( ! walkBoxQueueAdd ( BoxFound ) )
2016-07-16 17:18:11 +10:00
return false ;
// Loop until we find a walkbox which hasn't been tested
while ( _walkboxQueueIndex > 0 ) {
// Check if the dest box is a direct neighbour
2016-07-19 18:55:27 +10:00
if ( ( BoxFound = _vm - > getNextBox ( BoxFound , _walkdata . destbox ) ) = = kInvalidBox ) {
2016-07-16 17:18:11 +10:00
// Its not, start hunting through this boxes immediate connections
2016-07-19 18:55:27 +10:00
byte * boxm = _vm - > getBoxConnectionBase ( _walkboxQueue [ _walkboxQueueIndex - 1 ] ) ;
2016-07-16 17:18:11 +10:00
// Attempt to find one, which we havn't already used
for ( ; * boxm ! = kInvalidBox ; + + boxm ) {
2016-07-19 18:55:27 +10:00
if ( walkBoxQueueFind ( * boxm ) ! = true )
2016-07-16 17:18:11 +10:00
break ;
}
BoxFound = * boxm ;
}
// Found one?
if ( BoxFound ! = kInvalidBox ) {
// Did we find a connection to the final walkbox
if ( BoxFound = = _walkdata . destbox ) {
_newWalkBoxEntered = true ;
2016-07-19 18:55:27 +10:00
walkBoxQueueAdd ( BoxFound ) ;
2016-07-16 17:18:11 +10:00
walkboxQueueReverse ( ) ;
return true ;
}
// Nope, check the next box
break ;
}
// Drop this box, its useless to us
_walkboxQueue [ - - _walkboxQueueIndex ] = kInvalidBox ;
BoxFound = _walkboxQueue [ _walkboxQueueIndex - 1 ] ;
2016-10-09 14:59:58 +02:00
}
2016-07-16 17:18:11 +10:00
} while ( _walkboxQueueIndex > 0 ) ;
return false ;
}
2006-10-18 14:01:28 +00:00
void Actor : : setBox ( int box ) {
_walkbox = box ;
setupActorScale ( ) ;
}
2007-03-10 13:53:11 +00:00
void Actor_v3 : : setupActorScale ( ) {
2011-05-14 16:29:28 +02:00
// WORKAROUND bug #1463598: Under certain circumstances, it is possible
// for Henry Sr. to reach the front side of Castle Brunwald (following
// Indy there). But it seems the game has no small costume for Henry,
// hence he is shown as a giant, triple in size compared to Indy.
// To workaround this, we override the scale of Henry. Since V3 games
// like Indy3 don't use the costume scale otherwise, this works fine.
// The scale factor 0x50 was determined by some guess work.
if ( _number = = 2 & & _costume = = 7 & & _vm - > _game . id = = GID_INDY3 & & _vm - > _currentRoom = = 12 ) {
_scalex = 0x50 ;
_scaley = 0x50 ;
} else {
// TODO: The following could probably be removed
_scalex = 0xFF ;
_scaley = 0xFF ;
}
2007-02-04 01:24:43 +00:00
}
2006-10-18 14:01:28 +00:00
2007-02-04 01:24:43 +00:00
void Actor : : setupActorScale ( ) {
2006-10-18 14:01:28 +00:00
if ( _ignoreBoxes )
return ;
// For some boxes, we ignore the scaling and use whatever values the
// scripts set. This is used e.g. in the Mystery Vortex in Sam&Max.
// Older games used the flag 0x20 differently, though.
if ( _vm - > _game . id = = GID_SAMNMAX & & ( _vm - > getBoxFlags ( _walkbox ) & kBoxIgnoreScale ) )
return ;
_boxscale = _vm - > getBoxScale ( _walkbox ) ;
uint16 scale = _vm - > getScale ( _walkbox , _pos . x , _pos . y ) ;
assert ( scale < = 0xFF ) ;
_scalex = _scaley = ( byte ) scale ;
}
# pragma mark -
# pragma mark --- Actor walking ---
# pragma mark -
void ScummEngine : : walkActors ( ) {
2006-12-25 17:21:54 +00:00
for ( int i = 1 ; i < _numActors ; + + i ) {
2006-12-25 15:03:36 +00:00
if ( _actors [ i ] - > isInCurrentRoom ( ) )
2006-12-25 17:21:54 +00:00
_actors [ i ] - > walkActor ( ) ;
2006-10-18 14:01:28 +00:00
}
}
2003-03-06 17:58:13 +00:00
void Actor : : stopActorMoving ( ) {
2005-03-11 01:10:06 +00:00
if ( _walkScript )
_vm - > stopScript ( _walkScript ) ;
2010-03-16 08:59:48 +00:00
2014-11-28 22:24:45 +11:00
if ( _vm - > _game . version = = 0 ) {
_moving = 2 ;
2012-02-10 23:46:32 +01:00
setDirection ( _facing ) ;
2014-11-30 22:01:23 +11:00
} else {
_moving = 0 ;
2014-11-28 22:24:45 +11:00
}
2001-10-09 14:30:12 +00:00
}
2003-03-06 17:58:13 +00:00
void Actor : : setActorWalkSpeed ( uint newSpeedX , uint newSpeedY ) {
2005-03-11 01:10:06 +00:00
if ( newSpeedX = = _speedx & & newSpeedY = = _speedy )
2001-10-09 14:30:12 +00:00
return ;
2005-03-11 01:10:06 +00:00
_speedx = newSpeedX ;
_speedy = newSpeedY ;
2001-10-09 14:30:12 +00:00
2005-03-11 01:10:06 +00:00
if ( _moving ) {
2007-12-02 02:33:50 +00:00
if ( _vm - > _game . version = = 8 & & ( _moving & MF_IN_LEG ) = = 0 )
return ;
2005-03-11 01:10:06 +00:00
calcMovementFactor ( _walkdata . next ) ;
2001-10-09 14:30:12 +00:00
}
}
2006-10-18 14:01:28 +00:00
int getAngleFromPos ( int x , int y , bool useATAN ) {
if ( useATAN ) {
2002-07-08 01:04:29 +00:00
double temp = atan2 ( ( double ) x , ( double ) - y ) ;
2011-03-19 02:33:09 +02:00
return normalizeAngle ( ( int ) ( temp * 180 / M_PI ) ) ;
2001-11-26 19:57:57 +00:00
} else {
2005-05-25 09:17:35 +00:00
if ( ABS ( y ) * 2 < ABS ( x ) ) {
2002-04-11 17:19:16 +00:00
if ( x > 0 )
2002-04-11 14:13:53 +00:00
return 90 ;
return 270 ;
} else {
2002-04-11 17:19:16 +00:00
if ( y > 0 )
2002-04-11 14:13:53 +00:00
return 180 ;
return 0 ;
}
2001-11-26 19:57:57 +00:00
}
}
2004-09-30 23:49:46 +00:00
int Actor : : calcMovementFactor ( const Common : : Point & next ) {
2004-08-22 08:53:53 +00:00
int diffX , diffY ;
int32 deltaXFactor , deltaYFactor ;
2001-10-09 14:30:12 +00:00
2007-02-03 01:21:49 +00:00
if ( _pos = = next )
2001-10-09 14:30:12 +00:00
return 0 ;
2007-02-03 01:21:49 +00:00
diffX = next . x - _pos . x ;
diffY = next . y - _pos . y ;
2005-03-11 01:10:06 +00:00
deltaYFactor = _speedy < < 16 ;
2004-08-22 08:53:53 +00:00
2001-10-09 14:30:12 +00:00
if ( diffY < 0 )
2003-05-05 12:09:22 +00:00
deltaYFactor = - deltaYFactor ;
2001-10-09 14:30:12 +00:00
2003-05-05 12:09:22 +00:00
deltaXFactor = deltaYFactor * diffX ;
2001-10-09 14:30:12 +00:00
if ( diffY ! = 0 ) {
2003-05-05 12:09:22 +00:00
deltaXFactor / = diffY ;
2001-10-09 14:30:12 +00:00
} else {
2003-05-05 12:09:22 +00:00
deltaYFactor = 0 ;
2001-10-09 14:30:12 +00:00
}
2012-01-29 04:42:02 +01:00
if ( ( uint ) ABS ( deltaXFactor ) > ( _speedx < < 16 ) ) {
2005-03-11 01:10:06 +00:00
deltaXFactor = _speedx < < 16 ;
2001-10-09 14:30:12 +00:00
if ( diffX < 0 )
2003-05-05 12:09:22 +00:00
deltaXFactor = - deltaXFactor ;
2001-10-09 14:30:12 +00:00
2003-05-05 12:09:22 +00:00
deltaYFactor = deltaXFactor * diffY ;
2001-10-09 14:30:12 +00:00
if ( diffX ! = 0 ) {
2003-05-05 12:09:22 +00:00
deltaYFactor / = diffX ;
2001-10-09 14:30:12 +00:00
} else {
2003-05-05 12:09:22 +00:00
deltaXFactor = 0 ;
2001-10-09 14:30:12 +00:00
}
}
2007-02-03 01:21:49 +00:00
_walkdata . cur = _pos ;
2005-03-11 01:10:06 +00:00
_walkdata . next = next ;
_walkdata . deltaXFactor = deltaXFactor ;
_walkdata . deltaYFactor = deltaYFactor ;
_walkdata . xfrac = 0 ;
_walkdata . yfrac = 0 ;
2002-03-06 09:40:21 +00:00
2007-02-18 21:07:00 +00:00
if ( _vm - > _game . version < = 2 )
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * deltaXFactor , V12_Y_MULTIPLIER * deltaYFactor , false ) ;
else
_targetFacing = getAngleFromPos ( deltaXFactor , deltaYFactor , ( _vm - > _game . id = = GID_DIG | | _vm - > _game . id = = GID_CMI ) ) ;
2001-10-09 14:30:12 +00:00
2002-05-14 19:11:20 +00:00
return actorWalkStep ( ) ;
2001-10-09 14:30:12 +00:00
}
2003-03-06 17:58:13 +00:00
int Actor : : actorWalkStep ( ) {
2001-11-26 19:57:57 +00:00
int tmpX , tmpY ;
int distX , distY ;
2003-07-24 17:44:00 +00:00
int nextFacing ;
2002-04-11 17:19:16 +00:00
2005-03-11 01:10:06 +00:00
_needRedraw = true ;
2001-11-26 19:57:57 +00:00
2012-01-25 16:18:33 +11:00
nextFacing = updateActorDirection ( true ) ;
2005-03-11 01:10:06 +00:00
if ( ! ( _moving & MF_IN_LEG ) | | _facing ! = nextFacing ) {
if ( _walkFrame ! = _frame | | _facing ! = nextFacing ) {
2006-07-07 12:47:44 +00:00
startWalkAnim ( 1 , nextFacing ) ;
2001-11-26 19:57:57 +00:00
}
2005-03-11 01:10:06 +00:00
_moving | = MF_IN_LEG ;
2001-10-09 14:30:12 +00:00
}
2007-02-03 01:21:49 +00:00
if ( _walkbox ! = _walkdata . curbox & & _vm - > checkXYInBoxBounds ( _walkdata . curbox , _pos . x , _pos . y ) ) {
2005-03-11 01:10:06 +00:00
setBox ( _walkdata . curbox ) ;
2001-10-09 14:30:12 +00:00
}
2005-05-25 09:17:35 +00:00
distX = ABS ( _walkdata . next . x - _walkdata . cur . x ) ;
distY = ABS ( _walkdata . next . y - _walkdata . cur . y ) ;
2001-10-09 14:30:12 +00:00
2007-02-03 01:21:49 +00:00
if ( ABS ( _pos . x - _walkdata . cur . x ) > = distX & & ABS ( _pos . y - _walkdata . cur . y ) > = distY ) {
2005-03-11 01:10:06 +00:00
_moving & = ~ MF_IN_LEG ;
2001-10-09 14:30:12 +00:00
return 0 ;
}
2014-12-08 10:29:23 +11:00
if ( _vm - > _game . version < = 2 ) {
if ( _walkdata . deltaXFactor ! = 0 ) {
if ( _walkdata . deltaXFactor > 0 )
_pos . x + = 1 ;
else
_pos . x - = 1 ;
}
if ( _walkdata . deltaYFactor ! = 0 ) {
if ( _walkdata . deltaYFactor > 0 )
_pos . y + = 1 ;
else
_pos . y - = 1 ;
}
} else {
2017-11-29 19:36:28 -06:00
tmpX = ( _pos . x * ( 1 < < 16 ) ) + _walkdata . xfrac + ( _walkdata . deltaXFactor / 256 ) * _scalex ;
2014-12-08 10:29:23 +11:00
_walkdata . xfrac = ( uint16 ) tmpX ;
2017-11-29 19:36:28 -06:00
_pos . x = ( tmpX / ( 1 < < 16 ) ) ;
2001-11-26 19:57:57 +00:00
2017-11-29 19:36:28 -06:00
tmpY = ( _pos . y * ( 1 < < 16 ) ) + _walkdata . yfrac + ( _walkdata . deltaYFactor / 256 ) * _scaley ;
2014-12-08 10:29:23 +11:00
_walkdata . yfrac = ( uint16 ) tmpY ;
2017-11-29 19:36:28 -06:00
_pos . y = ( tmpY / ( 1 < < 16 ) ) ;
2014-12-08 10:29:23 +11:00
}
2002-04-11 17:19:16 +00:00
2007-02-03 01:21:49 +00:00
if ( ABS ( _pos . x - _walkdata . cur . x ) > distX ) {
_pos . x = _walkdata . next . x ;
2001-11-26 19:57:57 +00:00
}
2007-02-03 01:21:49 +00:00
if ( ABS ( _pos . y - _walkdata . cur . y ) > distY ) {
_pos . y = _walkdata . next . y ;
2001-11-26 19:57:57 +00:00
}
2014-12-08 10:29:23 +11:00
if ( ( _vm - > _game . version < = 2 | | ( _vm - > _game . version > = 4 & & _vm - > _game . version < = 6 ) ) & & _pos = = _walkdata . next ) {
2006-06-24 01:46:54 +00:00
_moving & = ~ MF_IN_LEG ;
return 0 ;
}
2012-02-05 16:35:44 +11:00
2001-10-09 14:30:12 +00:00
return 1 ;
}
2014-11-30 22:01:23 +11:00
bool Actor_v0 : : calcWalkDistances ( ) {
_walkDirX = 0 ;
_walkDirY = 0 ;
_walkYCountGreaterThanXCount = 0 ;
uint16 A = 0 ;
2018-02-13 21:08:07 +11:00
if ( _CurrentWalkTo . x > = _tmp_NewPos . x ) {
A = _CurrentWalkTo . x - _tmp_NewPos . x ;
2014-11-30 22:01:23 +11:00
_walkDirX = 1 ;
} else {
2018-02-13 21:08:07 +11:00
A = _tmp_NewPos . x - _CurrentWalkTo . x ;
2014-11-30 22:01:23 +11:00
}
_walkXCountInc = A ;
2018-02-13 21:08:07 +11:00
if ( _CurrentWalkTo . y > = _tmp_NewPos . y ) {
A = _CurrentWalkTo . y - _tmp_NewPos . y ;
2014-11-30 22:01:23 +11:00
_walkDirY = 1 ;
} else {
2018-02-13 21:08:07 +11:00
A = _tmp_NewPos . y - _CurrentWalkTo . y ;
2014-11-30 22:01:23 +11:00
}
_walkYCountInc = A ;
2014-12-07 15:24:21 +11:00
if ( ! _walkXCountInc & & ! _walkYCountInc )
2014-11-30 22:01:23 +11:00
return true ;
2016-10-09 14:59:58 +02:00
if ( _walkXCountInc < = _walkYCountInc )
2014-11-30 22:01:23 +11:00
_walkYCountGreaterThanXCount = 1 ;
// 2FCC
A = _walkXCountInc ;
2014-12-07 15:24:21 +11:00
if ( A < = _walkYCountInc )
2014-11-30 22:01:23 +11:00
A = _walkYCountInc ;
_walkMaxXYCountInc = A ;
_walkXCount = _walkXCountInc ;
_walkYCount = _walkYCountInc ;
_walkCountModulo = _walkMaxXYCountInc ;
return false ;
}
2018-02-13 21:08:07 +11:00
/* Calculate the result of moving X+1 or X-1 */
byte Actor_v0 : : actorWalkXCalculate ( ) {
2014-11-30 22:01:23 +11:00
byte A = _walkXCount ;
A + = _walkXCountInc ;
if ( A > = _walkCountModulo ) {
2014-12-07 15:24:21 +11:00
if ( ! _walkDirX ) {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . x - - ;
2014-11-30 22:01:23 +11:00
} else {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . x + + ;
2014-11-30 22:01:23 +11:00
}
A - = _walkCountModulo ;
}
// 2EAC
_walkXCount = A ;
2018-02-13 21:08:07 +11:00
setActorToTempPosition ( ) ;
2014-11-30 22:01:23 +11:00
if ( updateWalkbox ( ) = = kInvalidBox ) {
// 2EB9
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
2014-11-30 22:01:23 +11:00
return 3 ;
2016-10-09 14:59:58 +02:00
}
2014-11-30 22:01:23 +11:00
// 2EBF
2018-02-13 21:08:07 +11:00
if ( _tmp_NewPos . x = = _CurrentWalkTo . x )
2014-11-30 22:01:23 +11:00
return 1 ;
return 0 ;
}
2018-02-13 21:08:07 +11:00
/* Calculate the result of moving Y+1 or Y-1 */
byte Actor_v0 : : actorWalkYCalculate ( ) {
2014-11-30 22:01:23 +11:00
byte A = _walkYCount ;
A + = _walkYCountInc ;
if ( A > = _walkCountModulo ) {
2014-12-07 15:24:21 +11:00
if ( ! _walkDirY ) {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . y - - ;
2014-11-30 22:01:23 +11:00
} else {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . y + + ;
2014-11-30 22:01:23 +11:00
}
A - = _walkCountModulo ;
}
// 2EEB
_walkYCount = A ;
2018-02-13 21:08:07 +11:00
setActorToTempPosition ( ) ;
2014-11-30 22:01:23 +11:00
if ( updateWalkbox ( ) = = kInvalidBox ) {
// 2EF8
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
2014-11-30 22:01:23 +11:00
return 4 ;
2016-10-09 14:59:58 +02:00
}
2014-11-30 22:01:23 +11:00
// 2EFE
if ( _walkYCountInc ! = 0 ) {
if ( _walkYCountInc = = 0xFF ) {
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
2014-11-30 22:01:23 +11:00
return 4 ;
}
}
// 2F0D
2018-02-13 21:08:07 +11:00
if ( _CurrentWalkTo . y = = _tmp_NewPos . y )
2014-11-30 22:01:23 +11:00
return 1 ;
2016-10-09 14:59:58 +02:00
2014-11-30 22:01:23 +11:00
return 0 ;
}
2006-10-18 14:01:28 +00:00
void Actor : : startWalkActor ( int destX , int destY , int dir ) {
AdjustBoxResult abr ;
2001-11-26 19:57:57 +00:00
2006-10-18 14:01:28 +00:00
if ( ! isInCurrentRoom ( ) & & _vm - > _game . version > = 7 ) {
debugC ( DEBUG_ACTORS , " startWalkActor: attempting to walk actor %d who is not in this room " , _number ) ;
2002-02-15 13:11:51 +00:00
return ;
}
2002-04-11 17:19:16 +00:00
2006-10-18 14:01:28 +00:00
if ( _vm - > _game . version < = 4 ) {
abr . x = destX ;
abr . y = destY ;
} else {
abr = adjustXYToBeInBox ( destX , destY ) ;
}
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( ! isInCurrentRoom ( ) & & _vm - > _game . version < = 6 ) {
_pos . x = abr . x ;
_pos . y = abr . y ;
if ( ! _ignoreTurns & & dir ! = - 1 )
_facing = dir ;
2003-11-01 01:17:15 +00:00
return ;
2006-10-18 14:01:28 +00:00
}
2003-11-01 01:17:15 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( _vm - > _game . version < = 2 ) {
abr = adjustXYToBeInBox ( abr . x , abr . y ) ;
if ( _pos . x = = abr . x & & _pos . y = = abr . y & & ( dir = = - 1 | | _facing = = dir ) )
return ;
2006-10-18 14:01:28 +00:00
} else {
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( _ignoreBoxes ) {
abr . box = kInvalidBox ;
_walkbox = kInvalidBox ;
2006-10-18 14:01:28 +00:00
} else {
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( _vm - > checkXYInBoxBounds ( _walkdata . destbox , abr . x , abr . y ) ) {
abr . box = _walkdata . destbox ;
} else {
abr = adjustXYToBeInBox ( abr . x , abr . y ) ;
}
if ( _moving & & _walkdata . destdir = = dir & & _walkdata . dest . x = = abr . x & & _walkdata . dest . y = = abr . y )
return ;
2006-10-18 14:01:28 +00:00
}
2007-09-19 08:40:12 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( _pos . x = = abr . x & & _pos . y = = abr . y ) {
if ( dir ! = _facing )
turnToDirection ( dir ) ;
2006-10-18 14:01:28 +00:00
return ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
}
2006-10-18 14:01:28 +00:00
}
2003-09-09 17:29:22 +00:00
2006-10-18 14:01:28 +00:00
_walkdata . dest . x = abr . x ;
_walkdata . dest . y = abr . y ;
_walkdata . destbox = abr . box ;
_walkdata . destdir = dir ;
2016-07-16 17:18:11 +10:00
_walkdata . point3 . x = 32000 ;
_walkdata . curbox = _walkbox ;
2014-12-07 15:24:21 +11:00
if ( _vm - > _game . version = = 0 ) {
2016-07-19 18:55:27 +10:00
( ( Actor_v0 * ) this ) - > walkBoxQueuePrepare ( ) ;
2016-07-16 17:18:11 +10:00
2014-12-08 10:29:23 +11:00
} else if ( _vm - > _game . version < = 2 ) {
_moving = ( _moving & ~ ( MF_LAST_LEG | MF_IN_LEG ) ) | MF_NEW_LEG ;
} else {
_moving = ( _moving & MF_IN_LEG ) | MF_NEW_LEG ;
}
2006-10-18 14:01:28 +00:00
}
2004-01-15 02:59:51 +00:00
2006-10-18 14:01:28 +00:00
void Actor : : startWalkAnim ( int cmd , int angle ) {
if ( angle = = - 1 )
angle = _facing ;
/* Note: walk scripts aren't required to make the Dig
* work as usual
*/
if ( _walkScript ) {
2017-11-29 23:40:33 -06:00
int args [ NUM_SCRIPT_LOCAL ] ;
2006-10-18 14:01:28 +00:00
memset ( args , 0 , sizeof ( args ) ) ;
args [ 0 ] = _number ;
args [ 1 ] = cmd ;
args [ 2 ] = angle ;
_vm - > runScript ( _walkScript , 1 , 0 , args ) ;
2001-12-27 17:51:58 +00:00
} else {
2006-10-18 14:01:28 +00:00
switch ( cmd ) {
case 1 : /* start walk */
setDirection ( angle ) ;
startAnimActor ( _walkFrame ) ;
2002-05-14 19:11:20 +00:00
break ;
2006-10-18 14:01:28 +00:00
case 2 : /* change dir only */
setDirection ( angle ) ;
2002-05-14 19:11:20 +00:00
break ;
2006-10-18 14:01:28 +00:00
case 3 : /* stop walk */
turnToDirection ( angle ) ;
startAnimActor ( _standFrame ) ;
2002-05-14 19:11:20 +00:00
break ;
}
2006-10-18 14:01:28 +00:00
}
}
2003-12-28 12:51:18 +00:00
2006-10-18 14:01:28 +00:00
void Actor : : walkActor ( ) {
int new_dir , next_box ;
Common : : Point foundPath ;
2002-11-10 12:59:36 +00:00
2006-10-18 14:01:28 +00:00
if ( _vm - > _game . version > = 7 ) {
if ( _moving & MF_FROZEN ) {
if ( _moving & MF_TURN ) {
new_dir = updateActorDirection ( false ) ;
if ( _facing ! = new_dir )
setDirection ( new_dir ) ;
else
_moving & = ~ MF_TURN ;
2004-09-19 03:26:47 +00:00
}
2006-10-18 14:01:28 +00:00
return ;
2001-10-09 14:30:12 +00:00
}
2001-12-27 17:51:58 +00:00
}
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
if ( ! _moving )
return ;
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
if ( ! ( _moving & MF_NEW_LEG ) ) {
if ( _moving & MF_IN_LEG & & actorWalkStep ( ) )
return ;
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_LAST_LEG ) {
_moving = 0 ;
setBox ( _walkdata . destbox ) ;
if ( _vm - > _game . version < = 6 ) {
startAnimActor ( _standFrame ) ;
if ( _targetFacing ! = _walkdata . destdir )
turnToDirection ( _walkdata . destdir ) ;
} else {
startWalkAnim ( 3 , _walkdata . destdir ) ;
}
return ;
}
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_TURN ) {
new_dir = updateActorDirection ( false ) ;
if ( _facing ! = new_dir )
setDirection ( new_dir ) ;
else
_moving = 0 ;
return ;
}
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
setBox ( _walkdata . curbox ) ;
_moving & = MF_IN_LEG ;
}
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
_moving & = ~ MF_NEW_LEG ;
do {
if ( _walkbox = = kInvalidBox ) {
setBox ( _walkdata . destbox ) ;
_walkdata . curbox = _walkdata . destbox ;
break ;
}
2002-06-04 23:32:53 +00:00
2006-10-18 14:01:28 +00:00
if ( _walkbox = = _walkdata . destbox )
break ;
2002-06-04 23:32:53 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
next_box = _vm - > getNextBox ( _walkbox , _walkdata . destbox ) ;
2006-10-18 14:01:28 +00:00
if ( next_box < 0 ) {
_walkdata . destbox = _walkbox ;
_moving | = MF_LAST_LEG ;
return ;
}
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
_walkdata . curbox = next_box ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( findPathTowards ( _walkbox , next_box , _walkdata . destbox , foundPath ) )
break ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( calcMovementFactor ( foundPath ) )
return ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
setBox ( _walkdata . curbox ) ;
} while ( 1 ) ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
_moving | = MF_LAST_LEG ;
calcMovementFactor ( _walkdata . dest ) ;
2001-10-09 14:30:12 +00:00
}
2014-11-28 22:24:45 +11:00
void Actor_v0 : : walkActor ( ) {
actorSetWalkTo ( ) ;
_needRedraw = true ;
if ( _NewWalkTo ! = _CurrentWalkTo ) {
_CurrentWalkTo = _NewWalkTo ;
2018-02-13 21:08:07 +11:00
UpdateActorDirection : ;
_tmp_NewPos = _pos ;
2014-11-28 22:24:45 +11:00
2014-11-29 07:12:57 +11:00
byte tmp = calcWalkDistances ( ) ;
2014-11-28 22:24:45 +11:00
_moving & = 0xF0 ;
_moving | = tmp ;
if ( ! _walkYCountGreaterThanXCount ) {
if ( _walkDirX ) {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 1 , V12_Y_MULTIPLIER * 0 , false ) ;
} else {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * - 1 , V12_Y_MULTIPLIER * 0 , false ) ;
}
} else {
if ( _walkDirY ) {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 0 , V12_Y_MULTIPLIER * 1 , false ) ;
} else {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 0 , V12_Y_MULTIPLIER * - 1 , false ) ;
}
}
directionUpdate ( ) ;
2016-10-09 14:59:58 +02:00
2018-02-13 21:08:07 +11:00
// Need to turn again?
2016-10-09 14:59:58 +02:00
if ( _moving & 0x80 )
2014-11-28 22:24:45 +11:00
return ;
animateActor ( newDirToOldDir ( _facing ) ) ;
} else {
// 2A0A
if ( ( _moving & 0x7F ) ! = 1 ) {
2016-10-09 14:59:58 +02:00
2014-11-30 22:01:23 +11:00
if ( _NewWalkTo = = _pos )
2014-11-28 22:24:45 +11:00
return ;
}
}
2018-02-13 21:08:07 +11:00
// 2A9A: Nothing to do
2014-11-29 07:12:57 +11:00
if ( _moving = = 2 )
2014-11-28 22:24:45 +11:00
return ;
2018-02-13 21:08:07 +11:00
// Reached Target
2014-11-29 07:12:57 +11:00
if ( ( _moving & 0x0F ) = = 1 )
2014-11-28 22:24:45 +11:00
return stopActorMoving ( ) ;
2018-02-13 21:08:07 +11:00
// 2AAD: Turn actor?
2014-11-28 22:24:45 +11:00
if ( _moving & 0x80 ) {
directionUpdate ( ) ;
2018-02-13 21:08:07 +11:00
// Turn again?
2014-11-29 07:12:57 +11:00
if ( _moving & 0x80 )
2014-11-28 22:24:45 +11:00
return ;
2018-02-13 21:08:07 +11:00
// Start Walk animation
2014-11-28 22:24:45 +11:00
animateActor ( newDirToOldDir ( _facing ) ) ;
}
2018-02-13 21:08:07 +11:00
// Walk X
2014-12-07 15:24:21 +11:00
if ( ( _moving & 0x0F ) = = 3 ) {
2018-02-13 21:08:07 +11:00
WalkX : ;
setActorToTempPosition ( ) ;
2014-11-28 22:24:45 +11:00
2014-11-29 07:12:57 +11:00
if ( ! _walkDirX ) {
2014-11-28 22:24:45 +11:00
_pos . x - - ;
} else {
_pos . x + + ;
}
// 2C51
2018-02-13 21:08:07 +11:00
// Does this move us into the walkbox?
2014-11-30 22:01:23 +11:00
if ( updateWalkbox ( ) ! = kInvalidBox ) {
2018-02-13 21:08:07 +11:00
// Yes, Lets update our direction
setActorToOriginalPosition ( ) ;
goto UpdateActorDirection ;
2014-11-28 22:24:45 +11:00
}
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
2014-11-28 22:24:45 +11:00
2018-02-13 21:08:07 +11:00
// Have we reached Y Target?
if ( _CurrentWalkTo . y = = _tmp_NewPos . y ) {
2014-11-28 22:24:45 +11:00
stopActorMoving ( ) ;
return ;
}
2018-02-13 21:08:07 +11:00
// Lets check one more pixel up or down
2014-11-28 22:24:45 +11:00
if ( ! _walkDirY ) {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . y - - ;
2014-11-28 22:24:45 +11:00
} else {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . y + + ;
2014-11-28 22:24:45 +11:00
}
2014-11-30 22:01:23 +11:00
2018-02-13 21:08:07 +11:00
setActorToTempPosition ( ) ;
2014-11-30 22:01:23 +11:00
2018-02-13 21:08:07 +11:00
// Are we still inside an invalid walkbox?
if ( updateWalkbox ( ) = = kInvalidBox ) {
setActorToOriginalPosition ( ) ;
2014-11-28 22:24:45 +11:00
stopActorMoving ( ) ;
return ;
}
2016-07-16 17:18:11 +10:00
2018-02-13 21:08:07 +11:00
// Found a valid walkbox
2014-11-28 22:24:45 +11:00
return ;
}
2018-02-13 21:08:07 +11:00
// 2ADA: Walk Y
2014-11-29 07:12:57 +11:00
if ( ( _moving & 0x0F ) = = 4 ) {
2018-02-13 21:08:07 +11:00
setActorToTempPosition ( ) ;
2014-11-28 22:24:45 +11:00
if ( ! _walkDirY ) {
_pos . y - - ;
} else {
_pos . y + + ;
}
2018-02-13 21:08:07 +11:00
// Moved out of walkbox?
2014-11-30 22:01:23 +11:00
if ( updateWalkbox ( ) = = kInvalidBox ) {
2014-11-28 22:24:45 +11:00
// 2CC7
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
// Reached X?
if ( _CurrentWalkTo . x = = _tmp_NewPos . x ) {
2014-11-28 22:24:45 +11:00
stopActorMoving ( ) ;
return ;
}
2014-11-30 22:01:23 +11:00
2018-02-13 21:08:07 +11:00
// Lets check one more pixel to left or right
2014-11-29 07:12:57 +11:00
if ( ! _walkDirX ) {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . x - - ;
2014-11-28 22:24:45 +11:00
} else {
2018-02-13 21:08:07 +11:00
_tmp_NewPos . x + + ;
2014-11-28 22:24:45 +11:00
}
2018-02-13 21:08:07 +11:00
setActorToTempPosition ( ) ;
// Still in an invalid walkbox?
2014-11-30 22:01:23 +11:00
if ( updateWalkbox ( ) = = kInvalidBox ) {
2018-02-13 21:08:07 +11:00
setActorToOriginalPosition ( ) ;
2014-11-28 22:24:45 +11:00
stopActorMoving ( ) ;
}
return ;
} else {
2018-02-13 21:08:07 +11:00
// Lets update our direction
setActorToOriginalPosition ( ) ;
goto UpdateActorDirection ;
2014-11-28 22:24:45 +11:00
}
}
2014-11-29 07:12:57 +11:00
if ( ( _moving & 0x0F ) = = 0 ) {
2014-11-30 22:01:23 +11:00
// 2AE8
2018-02-13 21:08:07 +11:00
byte A = actorWalkXCalculate ( ) ;
2014-11-28 22:24:45 +11:00
2018-02-13 21:08:07 +11:00
// Will X movement reach destination
2014-11-29 07:12:57 +11:00
if ( A = = 1 ) {
2018-02-13 21:08:07 +11:00
A = actorWalkYCalculate ( ) ;
// Will Y movement also reach destination?
2014-11-30 22:01:23 +11:00
if ( A = = 1 ) {
2014-11-28 22:24:45 +11:00
_moving & = 0xF0 ;
_moving | = A ;
} else {
2016-10-09 14:59:58 +02:00
if ( A = = 4 )
2014-11-28 22:24:45 +11:00
stopActorMoving ( ) ;
}
return ;
} else {
2018-02-13 21:08:07 +11:00
// 2B0C: Moving X will put us in an invalid walkbox
2014-11-28 22:24:45 +11:00
if ( A = = 3 ) {
_moving & = 0xF0 ;
_moving | = A ;
if ( _walkDirY ) {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 0 , V12_Y_MULTIPLIER * 1 , false ) ;
} else {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 0 , V12_Y_MULTIPLIER * - 1 , false ) ;
}
directionUpdate ( ) ;
animateActor ( newDirToOldDir ( _facing ) ) ;
2018-02-13 21:08:07 +11:00
// FIXME: During the hands-free-demo in the library (room 5), Purple Tentacle gets stuck following Sandy due to the corner of the stairs,
// This is due to distance, and walkbox gap/layout. This works fine with the original engine, because it 'brute forces'
// another pixel move in the walk direction before giving up, allowing us to move enough pixels to hit the next walkbox.
// Why this fails with the return is because script-10 is executing a 'walkActorToActor' every cycle, which restarts the movement process
// As a work around, we implement the original engine behaviour only for Purple Tentacle in the Demo. Doing this for other actors
// causes a skipping effect while transitioning walkboxes (the original has another bug in this situation, in which the actor just changes direction for 1 frame during this moment)
if ( ( _vm - > _game . features & GF_DEMO ) & & _number = = 13 )
goto WalkX ;
2017-02-21 06:17:32 +11:00
return ;
2014-11-28 22:24:45 +11:00
} else {
2018-02-13 21:08:07 +11:00
// 2B39: Moving X was ok, do we also move Y
A = actorWalkYCalculate ( ) ;
// Are we in a valid walkbox?
2014-11-29 07:12:57 +11:00
if ( A ! = 4 )
2014-11-28 22:24:45 +11:00
return ;
2018-02-13 21:08:07 +11:00
// No, we need to change direction
2014-11-28 22:24:45 +11:00
_moving & = 0xF0 ;
_moving | = A ;
if ( _walkDirX ) {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * 1 , V12_Y_MULTIPLIER * 0 , false ) ;
} else {
_targetFacing = getAngleFromPos ( V12_X_MULTIPLIER * - 1 , V12_Y_MULTIPLIER * 0 , false ) ;
}
2016-10-09 14:59:58 +02:00
2014-11-28 22:24:45 +11:00
directionUpdate ( ) ;
animateActor ( newDirToOldDir ( _facing ) ) ;
2018-02-13 21:08:07 +11:00
2017-02-21 06:17:32 +11:00
return ;
2014-11-28 22:24:45 +11:00
}
}
}
}
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
void Actor_v2 : : walkActor ( ) {
2006-10-18 14:01:28 +00:00
Common : : Point foundPath , tmp ;
int new_dir , next_box ;
2005-04-12 02:29:50 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_TURN ) {
new_dir = updateActorDirection ( false ) ;
2009-07-25 05:39:57 +00:00
if ( _facing ! = new_dir ) {
2012-01-27 22:05:10 +11:00
setDirection ( new_dir ) ;
2012-01-24 23:23:19 +11:00
} else {
2006-10-18 14:01:28 +00:00
_moving = 0 ;
2012-01-24 23:23:19 +11:00
}
2006-10-18 14:01:28 +00:00
return ;
}
2005-04-12 02:29:50 +00:00
2006-10-18 14:01:28 +00:00
if ( ! _moving )
return ;
2005-04-12 02:29:50 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_IN_LEG ) {
actorWalkStep ( ) ;
} else {
if ( _moving & MF_LAST_LEG ) {
_moving = 0 ;
startAnimActor ( _standFrame ) ;
if ( _targetFacing ! = _walkdata . destdir )
turnToDirection ( _walkdata . destdir ) ;
} else {
setBox ( _walkdata . curbox ) ;
if ( _walkbox = = _walkdata . destbox ) {
foundPath = _walkdata . dest ;
_moving | = MF_LAST_LEG ;
} else {
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
next_box = _vm - > getNextBox ( _walkbox , _walkdata . destbox ) ;
2006-10-18 14:01:28 +00:00
if ( next_box < 0 ) {
_moving | = MF_LAST_LEG ;
return ;
}
2005-04-12 02:29:50 +00:00
2006-10-18 14:01:28 +00:00
// Can't walk through locked boxes
int flags = _vm - > getBoxFlags ( next_box ) ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( ( flags & kBoxLocked ) & & ! ( ( flags & kBoxPlayerOnly ) & & ! isPlayer ( ) ) ) {
2006-10-18 14:01:28 +00:00
_moving | = MF_LAST_LEG ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
//_walkdata.destdir = -1;
2006-10-18 14:01:28 +00:00
}
2005-04-12 02:29:50 +00:00
2006-10-18 14:01:28 +00:00
_walkdata . curbox = next_box ;
2005-04-12 02:29:50 +00:00
2014-11-29 07:12:57 +11:00
getClosestPtOnBox ( _vm - > getBoxCoordinates ( _walkdata . curbox ) , _pos . x , _pos . y , tmp . x , tmp . y ) ;
getClosestPtOnBox ( _vm - > getBoxCoordinates ( _walkbox ) , tmp . x , tmp . y , foundPath . x , foundPath . y ) ;
2006-10-18 14:01:28 +00:00
}
calcMovementFactor ( foundPath ) ;
}
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
}
2001-10-09 14:30:12 +00:00
2007-03-10 13:53:11 +00:00
void Actor_v3 : : walkActor ( ) {
2006-10-18 14:01:28 +00:00
Common : : Point p2 , p3 ; // Gate locations
int new_dir , next_box ;
2003-06-06 10:01:26 +00:00
2006-10-18 14:01:28 +00:00
if ( ! _moving )
return ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( ! ( _moving & MF_NEW_LEG ) ) {
if ( _moving & MF_IN_LEG & & actorWalkStep ( ) )
return ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_LAST_LEG ) {
_moving = 0 ;
startAnimActor ( _standFrame ) ;
if ( _targetFacing ! = _walkdata . destdir )
turnToDirection ( _walkdata . destdir ) ;
return ;
2001-10-09 14:30:12 +00:00
}
2002-04-11 20:10:47 +00:00
2006-10-18 14:01:28 +00:00
if ( _moving & MF_TURN ) {
new_dir = updateActorDirection ( false ) ;
if ( _facing ! = new_dir )
setDirection ( new_dir ) ;
else
_moving = 0 ;
return ;
}
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( _walkdata . point3 . x ! = 32000 ) {
if ( calcMovementFactor ( _walkdata . point3 ) ) {
_walkdata . point3 . x = 32000 ;
return ;
}
_walkdata . point3 . x = 32000 ;
}
2002-03-11 08:34:12 +00:00
2006-10-18 14:01:28 +00:00
setBox ( _walkdata . curbox ) ;
_moving & = MF_IN_LEG ;
}
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
_moving & = ~ MF_NEW_LEG ;
do {
if ( _walkbox = = kInvalidBox ) {
setBox ( _walkdata . destbox ) ;
_walkdata . curbox = _walkdata . destbox ;
break ;
}
2002-02-12 18:20:37 +00:00
2006-10-18 14:01:28 +00:00
if ( _walkbox = = _walkdata . destbox )
break ;
2002-03-26 05:23:06 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
next_box = _vm - > getNextBox ( _walkbox , _walkdata . destbox ) ;
2006-10-18 14:01:28 +00:00
if ( next_box < 0 ) {
_moving | = MF_LAST_LEG ;
return ;
}
2002-08-15 16:46:29 +00:00
2006-10-18 14:01:28 +00:00
// Can't walk through locked boxes
int flags = _vm - > getBoxFlags ( next_box ) ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( ( flags & kBoxLocked ) & & ! ( ( flags & kBoxPlayerOnly ) & & ! isPlayer ( ) ) ) {
2006-10-18 14:01:28 +00:00
_moving | = MF_LAST_LEG ;
return ;
}
2005-07-30 21:11:48 +00:00
2006-10-18 14:01:28 +00:00
_walkdata . curbox = next_box ;
2003-05-18 19:44:22 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
findPathTowardsOld ( _walkbox , next_box , _walkdata . destbox , p2 , p3 ) ;
if ( p2 . x = = 32000 & & p3 . x = = 32000 ) {
break ;
}
2001-10-09 14:30:12 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( p2 . x ! = 32000 ) {
if ( calcMovementFactor ( p2 ) ) {
_walkdata . point3 = p3 ;
return ;
2002-07-27 20:11:02 +00:00
}
2003-05-18 19:44:22 +00:00
}
2006-10-18 14:01:28 +00:00
if ( calcMovementFactor ( p3 ) )
return ;
2002-04-11 17:19:16 +00:00
2007-03-12 12:16:41 +00:00
setBox ( _walkdata . curbox ) ;
2006-10-18 14:01:28 +00:00
} while ( 1 ) ;
2002-07-15 18:11:30 +00:00
2006-10-18 14:01:28 +00:00
_moving | = MF_LAST_LEG ;
calcMovementFactor ( _walkdata . dest ) ;
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
# pragma mark -
# pragma mark --- Actor direction ---
# pragma mark -
2001-11-26 19:57:57 +00:00
2006-10-18 14:01:28 +00:00
int Actor : : remapDirection ( int dir , bool is_walking ) {
int specdir ;
byte flags ;
2010-10-25 07:07:23 +00:00
byte mask ;
2006-10-18 14:01:28 +00:00
bool flipX ;
bool flipY ;
2001-10-09 14:30:12 +00:00
2007-09-11 09:20:39 +00:00
// FIXME: It seems that at least in The Dig the original code does
2006-10-18 14:01:28 +00:00
// check _ignoreBoxes here. However, it breaks some animations in Loom,
// causing Bobbin to face towards the camera instead of away from it
// in some places: After the tree has been destroyed by lightning, and
// when entering the dark tunnels beyond the dragon's lair at the very
// least. Possibly other places as well.
//
// The Dig also checks if the actor is in the current room, but that's
// not necessary here because we never call the function unless the
// actor is in the current room anyway.
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( ! _ignoreBoxes | | _vm - > _game . id = = GID_LOOM ) {
specdir = _vm - > _extraBoxFlags [ _walkbox ] ;
if ( specdir ) {
if ( specdir & 0x8000 ) {
dir = specdir & 0x3FFF ;
} else {
specdir = specdir & 0x3FFF ;
if ( specdir - 90 < dir & & dir < specdir + 90 )
dir = specdir ;
else
dir = specdir + 180 ;
}
2003-05-18 19:44:22 +00:00
}
2003-01-01 18:22:41 +00:00
2006-10-18 14:01:28 +00:00
flags = _vm - > getBoxFlags ( _walkbox ) ;
2003-01-01 18:22:41 +00:00
2006-10-18 14:01:28 +00:00
flipX = ( _walkdata . deltaXFactor > 0 ) ;
flipY = ( _walkdata . deltaYFactor > 0 ) ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
// Check for X-Flip
if ( ( flags & kBoxXFlip ) | | isInClass ( kObjectClassXFlip ) ) {
dir = 360 - dir ;
flipX = ! flipX ;
}
// Check for Y-Flip
if ( ( flags & kBoxYFlip ) | | isInClass ( kObjectClassYFlip ) ) {
dir = 180 - dir ;
flipY = ! flipY ;
2006-06-24 01:46:54 +00:00
}
2001-11-26 19:57:57 +00:00
2006-10-18 14:01:28 +00:00
switch ( flags & 7 ) {
case 1 :
if ( _vm - > _game . version > = 7 ) {
if ( dir < 180 )
return 90 ;
else
return 270 ;
} else {
if ( is_walking ) // Actor is walking
return flipX ? 90 : 270 ;
else // Actor is standing/turning
return ( dir = = 90 ) ? 90 : 270 ;
}
case 2 :
if ( _vm - > _game . version > = 7 ) {
if ( dir > 90 & & dir < 270 )
return 180 ;
else
return 0 ;
} else {
if ( is_walking ) // Actor is walking
return flipY ? 180 : 0 ;
else // Actor is standing/turning
return ( dir = = 0 ) ? 0 : 180 ;
}
case 3 :
return 270 ;
case 4 :
return 90 ;
case 5 :
return 0 ;
case 6 :
return 180 ;
}
2010-10-25 07:07:23 +00:00
2012-02-04 18:34:08 +01:00
// MM v0 stores flags as a part of the mask
2010-10-25 07:07:23 +00:00
if ( _vm - > _game . version = = 0 ) {
mask = _vm - > getMaskFromBox ( _walkbox ) ;
// face the wall if climbing/descending a ladder
if ( ( mask & 0x8C ) = = 0x84 )
return 0 ;
}
2006-10-18 14:01:28 +00:00
}
// OR 1024 in to signal direction interpolation should be done
return normalizeAngle ( dir ) | 1024 ;
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
int Actor : : updateActorDirection ( bool is_walking ) {
int from ;
bool dirType = false ;
int dir ;
bool shouldInterpolate ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
if ( ( _vm - > _game . version = = 6 ) & & _ignoreTurns )
return _facing ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
dirType = ( _vm - > _game . version > = 7 ) ? _vm - > _costumeLoader - > hasManyDirections ( _costume ) : false ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
from = toSimpleDir ( dirType , _facing ) ;
dir = remapDirection ( _targetFacing , is_walking ) ;
if ( _vm - > _game . version > = 7 )
// Direction interpolation interfers with walk scripts in Dig; they perform
// (much better) interpolation themselves.
shouldInterpolate = false ;
else
shouldInterpolate = ( dir & 1024 ) ? true : false ;
dir & = 1023 ;
if ( shouldInterpolate ) {
int to = toSimpleDir ( dirType , dir ) ;
int num = dirType ? 8 : 4 ;
// Turn left or right, depending on which is shorter.
int diff = to - from ;
if ( ABS ( diff ) > ( num > > 1 ) )
diff = - diff ;
if ( diff > 0 ) {
to = from + 1 ;
} else if ( diff < 0 ) {
to = from - 1 ;
2003-05-22 09:52:21 +00:00
}
2006-10-18 14:01:28 +00:00
dir = fromSimpleDir ( dirType , ( to + num ) % num ) ;
}
return dir ;
}
void Actor : : setDirection ( int direction ) {
uint aMask ;
int i ;
uint16 vald ;
2007-05-29 21:50:32 +00:00
// HACK to fix bug #774783
// If Hitler's direction is being set to anything other than 90, set it to 90
if ( ( _vm - > _game . id = = GID_INDY3 ) & & _vm - > _roomResource = = 46 & & _number = = 9 & & direction ! = 90 )
direction = 90 ;
2006-10-18 14:01:28 +00:00
// Do nothing if actor is already facing in the given direction
2012-01-24 23:23:19 +11:00
if ( _facing = = direction )
2006-10-18 14:01:28 +00:00
return ;
// Normalize the angle
_facing = normalizeAngle ( direction ) ;
// If there is no costume set for this actor, we are finished
if ( _costume = = 0 )
return ;
// Update the costume for the new direction (and mark the actor for redraw)
aMask = 0x8000 ;
for ( i = 0 ; i < 16 ; i + + , aMask > > = 1 ) {
vald = _cost . frame [ i ] ;
if ( vald = = 0xFFFF )
continue ;
_vm - > _costumeLoader - > costumeDecodeData ( this , vald , ( _vm - > _game . version < = 2 ) ? 0xFFFF : aMask ) ;
2001-10-09 14:30:12 +00:00
}
2003-09-12 00:42:36 +00:00
2005-03-11 01:10:06 +00:00
_needRedraw = true ;
2001-10-09 14:30:12 +00:00
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : setDirection ( int direction ) {
2014-12-07 15:24:21 +11:00
int dir = newDirToOldDir ( direction ) ;
2012-02-04 14:49:44 +01:00
int res = 0 ;
2012-01-21 17:50:55 +11:00
2012-01-26 18:38:38 +11:00
switch ( dir ) {
2012-01-24 23:23:19 +11:00
case 0 :
res = 4 ; // Left
2012-02-04 14:49:44 +01:00
break ;
2012-01-24 23:23:19 +11:00
case 1 :
res = 5 ; // Right
2012-02-04 14:49:44 +01:00
break ;
2012-01-24 23:23:19 +11:00
case 2 :
2014-11-28 22:24:45 +11:00
res = 6 ; // Face Camera
2012-02-04 14:49:44 +01:00
break ;
2012-01-24 23:23:19 +11:00
2012-02-04 14:49:44 +01:00
default :
2014-11-28 22:24:45 +11:00
res = 7 ; // Face Away
2012-02-04 14:49:44 +01:00
break ;
2012-01-24 23:23:19 +11:00
}
2012-09-26 04:17:31 +02:00
2012-01-25 16:18:33 +11:00
_animFrameRepeat = - 1 ;
2012-01-24 23:23:19 +11:00
animateActor ( res ) ;
2012-01-21 17:50:55 +11:00
}
2006-10-18 14:01:28 +00:00
void Actor : : faceToObject ( int obj ) {
int x2 , y2 , dir ;
if ( ! isInCurrentRoom ( ) )
return ;
if ( _vm - > getObjectOrActorXY ( obj , x2 , y2 ) = = - 1 )
return ;
dir = ( x2 > _pos . x ) ? 90 : 270 ;
turnToDirection ( dir ) ;
2004-03-16 23:51:41 +00:00
}
2004-01-16 10:45:56 +00:00
2006-10-18 14:01:28 +00:00
void Actor : : turnToDirection ( int newdir ) {
if ( newdir = = - 1 | | _ignoreTurns )
return ;
2006-07-09 09:40:44 +00:00
2006-10-18 14:01:28 +00:00
if ( _vm - > _game . version < = 6 ) {
_targetFacing = newdir ;
2016-10-09 14:59:58 +02:00
2014-12-07 15:24:21 +11:00
if ( _vm - > _game . version = = 0 ) {
setDirection ( newdir ) ;
2014-11-28 22:24:45 +11:00
return ;
}
_moving = MF_TURN ;
2016-10-09 14:59:58 +02:00
2006-07-09 09:40:44 +00:00
} else {
2006-10-18 14:01:28 +00:00
_moving & = ~ MF_TURN ;
if ( newdir ! = _facing ) {
_moving | = MF_TURN ;
_targetFacing = newdir ;
}
2006-07-09 09:40:44 +00:00
}
2004-03-16 23:51:41 +00:00
}
2004-01-16 10:45:56 +00:00
2006-10-18 14:01:28 +00:00
# pragma mark -
# pragma mark --- Actor position ---
# pragma mark -
2004-07-05 06:25:01 +00:00
void ScummEngine : : putActors ( ) {
Actor * a ;
int i ;
for ( i = 1 ; i < _numActors ; i + + ) {
2006-12-25 15:03:36 +00:00
a = _actors [ i ] ;
2004-07-05 06:25:01 +00:00
if ( a & & a - > isInCurrentRoom ( ) )
2006-11-19 00:39:48 +00:00
a - > putActor ( ) ;
2004-07-05 06:25:01 +00:00
}
}
2006-11-19 00:39:48 +00:00
void Actor : : putActor ( int dstX , int dstY , int newRoom ) {
2006-10-18 14:01:28 +00:00
if ( _visible & & _vm - > _currentRoom ! = newRoom & & _vm - > getTalkingActor ( ) = = _number ) {
_vm - > stopTalk ( ) ;
2005-05-19 01:54:37 +00:00
}
2002-04-11 17:19:16 +00:00
2008-09-25 10:11:06 +00:00
// WORKAROUND: The green transparency of the tank in the Hall of Oddities
// is positioned one pixel too far to the left. This appears to be a bug
// in the original game as well.
2006-10-18 14:01:28 +00:00
if ( _vm - > _game . id = = GID_SAMNMAX & & newRoom = = 16 & & _number = = 5 & & dstX = = 235 & & dstY = = 236 )
dstX + + ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
_pos . x = dstX ;
_pos . y = dstY ;
_room = newRoom ;
_needRedraw = true ;
2002-02-22 16:06:09 +00:00
2006-10-18 14:01:28 +00:00
if ( _vm - > VAR ( _vm - > VAR_EGO ) = = _number ) {
_vm - > _egoPositioned = true ;
2001-10-09 14:30:12 +00:00
}
2002-04-11 17:19:16 +00:00
2006-10-18 14:01:28 +00:00
if ( _visible ) {
if ( isInCurrentRoom ( ) ) {
if ( _moving ) {
stopActorMoving ( ) ;
startAnimActor ( _standFrame ) ;
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
adjustActorPos ( ) ;
} else {
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_HE
2006-10-18 14:01:28 +00:00
if ( _vm - > _game . heversion > = 71 )
2008-09-25 10:11:06 +00:00
( ( ScummEngine_v71he * ) _vm ) - > queueAuxBlock ( ( ActorHE * ) this ) ;
2006-10-18 14:01:28 +00:00
# endif
hideActor ( ) ;
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
} else {
if ( isInCurrentRoom ( ) )
showActor ( ) ;
2001-10-09 14:30:12 +00:00
}
2012-01-28 00:38:19 +11:00
2014-11-28 22:24:45 +11:00
if ( _vm - > _game . version = = 0 ) {
2016-07-19 18:55:27 +10:00
( ( Actor_v0 * ) this ) - > _newWalkBoxEntered = false ;
( ( Actor_v0 * ) this ) - > _CurrentWalkTo = _pos ;
( ( Actor_v0 * ) this ) - > _NewWalkTo = _pos ;
2016-12-27 10:21:09 +11:00
}
2014-11-28 22:24:45 +11:00
2016-12-27 10:21:09 +11:00
// V0-V1 Maniac always sets the actor to face the camera upon entering a room
if ( _vm - > _game . id = = GID_MANIAC & & _vm - > _game . version < = 1 & & _vm - > _game . platform ! = Common : : kPlatformNES )
2012-02-04 14:49:44 +01:00
setDirection ( oldDirToNewDir ( 2 ) ) ;
2001-10-09 14:30:12 +00:00
}
2006-10-29 13:30:20 +00:00
static bool inBoxQuickReject ( const BoxCoords & box , int x , int y , int threshold ) {
int t ;
t = x - threshold ;
if ( t > box . ul . x & & t > box . ur . x & & t > box . lr . x & & t > box . ll . x )
return true ;
t = x + threshold ;
if ( t < box . ul . x & & t < box . ur . x & & t < box . lr . x & & t < box . ll . x )
return true ;
t = y - threshold ;
if ( t > box . ul . y & & t > box . ur . y & & t > box . lr . y & & t > box . ll . y )
return true ;
t = y + threshold ;
if ( t < box . ul . y & & t < box . ur . y & & t < box . lr . y & & t < box . ll . y )
return true ;
return false ;
}
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
static int checkXYInBoxBounds ( int boxnum , int x , int y , int & destX , int & destY ) {
BoxCoords box = g_scumm - > getBoxCoordinates ( boxnum ) ;
int xmin , xmax ;
2007-09-19 08:40:12 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
// We are supposed to determine the point (destX,destY) contained in
// the given box which is closest to the point (x,y), and then return
// some kind of "distance" between the two points.
// First, we determine destY and a range (xmin to xmax) in which destX
// is contained.
if ( y < box . ul . y ) {
// Point is above the box
destY = box . ul . y ;
xmin = box . ul . x ;
xmax = box . ur . x ;
} else if ( y > = box . ll . y ) {
// Point is below the box
destY = box . ll . y ;
xmin = box . ll . x ;
xmax = box . lr . x ;
} else if ( ( x > = box . ul . x ) & & ( x > = box . ll . x ) & & ( x < box . ur . x ) & & ( x < box . lr . x ) ) {
// Point is strictly inside the box
destX = x ;
destY = y ;
xmin = xmax = x ;
} else {
// Point is to the left or right of the box,
// so the y coordinate remains unchanged
destY = y ;
int ul = box . ul . x ;
int ll = box . ll . x ;
int ur = box . ur . x ;
int lr = box . lr . x ;
int top = box . ul . y ;
int bottom = box . ll . y ;
int cury ;
// Perform a binary search to determine the x coordinate.
// Note: It would be possible to compute this value in a
// single step simply by calculating the slope of the left
// resp. right side and using that to find the correct
// result. However, the original engine did use the search
// approach, so we do that, too.
do {
xmin = ( ul + ll ) / 2 ;
xmax = ( ur + lr ) / 2 ;
cury = ( top + bottom ) / 2 ;
2007-09-19 08:40:12 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( cury < y ) {
top = cury ;
ul = xmin ;
ur = xmax ;
} else if ( cury > y ) {
bottom = cury ;
ll = xmin ;
lr = xmax ;
}
} while ( cury ! = y ) ;
}
2007-09-19 08:40:12 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
// Now that we have limited the value of destX to a fixed
// interval, it's a trivial matter to finally determine it.
if ( x < xmin ) {
destX = xmin ;
} else if ( x > xmax ) {
destX = xmax ;
} else {
destX = x ;
}
// Compute the distance of the points. We measure the
// distance with a granularity of 8x8 blocks only (hence
// yDist must be divided by 4, as we are using 8x2 pixels
// blocks for actor coordinates).
int xDist = ABS ( x - destX ) ;
2012-01-26 22:39:34 +01:00
int yDist = ABS ( y - destY ) / 4 ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
int dist ;
2012-02-06 08:06:48 +01:00
if ( g_scumm - > _game . version = = 0 )
2012-01-26 22:39:34 +01:00
xDist * = 2 ;
2010-10-25 08:03:55 +00:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( xDist < yDist )
dist = ( xDist > > 1 ) + yDist ;
else
dist = ( yDist > > 1 ) + xDist ;
return dist ;
}
2014-11-30 22:01:23 +11:00
AdjustBoxResult Actor_v0 : : adjustPosInBorderWalkbox ( AdjustBoxResult box ) {
AdjustBoxResult Result = box ;
BoxCoords BoxCoord = _vm - > getBoxCoordinates ( box . box ) ;
byte boxMask = _vm - > getMaskFromBox ( box . box ) ;
if ( ! ( boxMask & 0x80 ) )
return Result ;
2014-12-08 23:31:59 +11:00
int16 A ;
2014-11-30 22:01:23 +11:00
boxMask & = 0x7C ;
2016-10-09 14:59:58 +02:00
if ( boxMask = = 0x0C )
2014-11-30 22:01:23 +11:00
A = 2 ;
else {
if ( boxMask ! = 0x08 )
return Result ;
A = 1 ;
}
// 1BC6
byte Modifier = box . y - BoxCoord . ul . y ;
assert ( Modifier < 0x16 ) ;
if ( A = = 1 ) {
// 1BCF
A = BoxCoord . ur . x - v0WalkboxSlantedModifier [ Modifier ] ;
if ( A < box . x )
return box ;
2016-07-16 17:18:11 +10:00
if ( A < = 0xA0 )
2014-11-30 22:01:23 +11:00
A = 0 ;
Result . x = A ;
} else {
// 1BED
A = BoxCoord . ul . x + v0WalkboxSlantedModifier [ Modifier ] ;
if ( A < box . x | | A = = box . x )
Result . x = A ;
}
return Result ;
}
AdjustBoxResult Actor_v0 : : adjustXYToBeInBox ( int dstX , int dstY ) {
AdjustBoxResult Result = Actor_v2 : : adjustXYToBeInBox ( dstX , dstY ) ;
2014-12-07 15:24:21 +11:00
if ( Result . box = = kInvalidBox )
2014-11-30 22:01:23 +11:00
return Result ;
return adjustPosInBorderWalkbox ( Result ) ;
}
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
AdjustBoxResult Actor_v2 : : adjustXYToBeInBox ( const int dstX , const int dstY ) {
AdjustBoxResult abr ;
abr . x = dstX ;
abr . y = dstY ;
abr . box = kInvalidBox ;
int numBoxes = _vm - > getNumBoxes ( ) - 1 ;
int bestDist = 0xFF ;
2012-01-26 22:39:34 +01:00
for ( int i = 0 ; i < = numBoxes ; i + + ) {
// MM v0 prioritizes lower boxes, other engines higher boxes
int box = ( _vm - > _game . version = = 0 ? i : numBoxes - i ) ;
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
int foundX , foundY ;
int flags = _vm - > getBoxFlags ( box ) ;
if ( ( flags & kBoxInvisible ) & & ! ( ( flags & kBoxPlayerOnly ) & & ! isPlayer ( ) ) )
continue ;
int dist = checkXYInBoxBounds ( box , dstX , dstY , foundX , foundY ) ; // also merged with getClosestPtOnBox
if ( dist = = 0 ) {
abr . x = foundX ;
abr . y = foundY ;
abr . box = box ;
2012-02-04 14:49:44 +01:00
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
break ;
}
if ( dist < bestDist ) {
bestDist = dist ;
abr . x = foundX ;
abr . y = foundY ;
abr . box = box ;
}
}
return abr ;
}
2006-10-18 14:01:28 +00:00
AdjustBoxResult Actor : : adjustXYToBeInBox ( int dstX , int dstY ) {
const uint thresholdTable [ ] = { 30 , 80 , 0 } ;
AdjustBoxResult abr ;
int16 tmpX , tmpY ;
int tmpDist , bestDist , threshold , numBoxes ;
byte flags , bestBox ;
int box ;
const int firstValidBox = ( _vm - > _game . features & GF_SMALL_HEADER ) ? 0 : 1 ;
abr . x = dstX ;
abr . y = dstY ;
abr . box = kInvalidBox ;
if ( _ignoreBoxes )
return abr ;
for ( int tIdx = 0 ; tIdx < ARRAYSIZE ( thresholdTable ) ; tIdx + + ) {
threshold = thresholdTable [ tIdx ] ;
numBoxes = _vm - > getNumBoxes ( ) - 1 ;
if ( numBoxes < firstValidBox )
return abr ;
bestDist = ( _vm - > _game . version > = 7 ) ? 0x7FFFFFFF : 0xFFFF ;
bestBox = kInvalidBox ;
// We iterate (backwards) over all boxes, searching the one closest
// to the desired coordinates.
for ( box = numBoxes ; box > = firstValidBox ; box - - ) {
flags = _vm - > getBoxFlags ( box ) ;
// Skip over invisible boxes
A long time ago, in a virtual machine far, far away...
It is a period of bug fixing. Rebel
developers, coding from a public
project, have won their umpteenth victory
against the evil Actor Walk Bugs.
During the debugging, programmers
used secret plans to the LucasArts'
ultimate tool, the SCUMM engine, an
extensible scripting system with enough
power to create an entire adventure.
Pursued by ensuing sinister regressions,
High King Fingolfin gleefully jumps up
and down, making use of the hotkey
that can save his games and restore
them back again later....
[With apologies to George Lucas. Good
riddance to bugs #751662, #771483, #959001,
#1329457, #1329498, #1329529, #1527672,
#1538260, #1571701, #1571705, #1571740,
and a warm welcome to the regressions
this change will cause. :-) ]
svn-id: r26090
2007-03-11 15:23:50 +00:00
if ( ( flags & kBoxInvisible ) & & ! ( ( flags & kBoxPlayerOnly ) & & ! isPlayer ( ) ) )
2006-10-18 14:01:28 +00:00
continue ;
// For increased performance, we perform a quick test if
// the coordinates can even be within a distance of 'threshold'
// pixels of the box.
if ( threshold > 0 & & inBoxQuickReject ( _vm - > getBoxCoordinates ( box ) , dstX , dstY , threshold ) )
continue ;
// Check if the point is contained in the box. If it is,
// we don't have to search anymore.
if ( _vm - > checkXYInBoxBounds ( box , dstX , dstY ) ) {
abr . x = dstX ;
abr . y = dstY ;
abr . box = box ;
return abr ;
}
// Find the point in the box which is closest to our point.
tmpDist = getClosestPtOnBox ( _vm - > getBoxCoordinates ( box ) , dstX , dstY , tmpX , tmpY ) ;
// Check if the box is closer than the previous boxes.
if ( tmpDist < bestDist ) {
abr . x = tmpX ;
abr . y = tmpY ;
if ( tmpDist = = 0 ) {
abr . box = box ;
return abr ;
}
bestDist = tmpDist ;
bestBox = box ;
}
}
// If the closest ('best') box we found is within the threshold, or if
// we are on the last run (i.e. threshold == 0), return that box.
if ( threshold = = 0 | | threshold * threshold > = bestDist ) {
abr . box = bestBox ;
return abr ;
}
}
return abr ;
}
void Actor : : adjustActorPos ( ) {
AdjustBoxResult abr ;
abr = adjustXYToBeInBox ( _pos . x , _pos . y ) ;
_pos . x = abr . x ;
_pos . y = abr . y ;
_walkdata . destbox = abr . box ;
setBox ( abr . box ) ;
_walkdata . dest . x = - 1 ;
stopActorMoving ( ) ;
_cost . soundCounter = 0 ;
2009-11-26 00:45:06 +00:00
_cost . soundPos = 0 ;
2006-10-18 14:01:28 +00:00
if ( _walkbox ! = kInvalidBox ) {
byte flags = _vm - > getBoxFlags ( _walkbox ) ;
if ( flags & 7 ) {
turnToDirection ( _facing ) ;
}
}
}
int ScummEngine : : getActorFromPos ( int x , int y ) {
int i ;
if ( ! testGfxAnyUsageBits ( x / 8 ) )
return 0 ;
for ( i = 1 ; i < _numActors ; i + + ) {
if ( testGfxUsageBit ( x / 8 , i ) & & ! getClass ( i , kObjectClassUntouchable )
2006-12-25 15:03:36 +00:00
& & y > = _actors [ i ] - > _top & & y < = _actors [ i ] - > _bottom ) {
2006-10-18 14:01:28 +00:00
if ( _game . version > 2 | | i ! = VAR ( VAR_EGO ) )
return i ;
}
}
return 0 ;
}
int ScummEngine_v70he : : getActorFromPos ( int x , int y ) {
int curActor , i ;
if ( ! testGfxAnyUsageBits ( x / 8 ) )
return 0 ;
curActor = 0 ;
for ( i = 1 ; i < _numActors ; i + + ) {
if ( testGfxUsageBit ( x / 8 , i ) & & ! getClass ( i , kObjectClassUntouchable )
2006-12-25 15:03:36 +00:00
& & y > = _actors [ i ] - > _top & & y < = _actors [ i ] - > _bottom
& & ( _actors [ i ] - > getPos ( ) . y > _actors [ curActor ] - > getPos ( ) . y | | curActor = = 0 ) )
2006-10-18 14:01:28 +00:00
curActor = i ;
}
return curActor ;
}
# pragma mark -
# pragma mark --- TODO ---
# pragma mark -
void Actor : : hideActor ( ) {
if ( ! _visible )
return ;
if ( _moving ) {
stopActorMoving ( ) ;
startAnimActor ( _standFrame ) ;
}
_visible = false ;
_cost . soundCounter = 0 ;
2009-11-26 00:45:06 +00:00
_cost . soundPos = 0 ;
2006-10-18 14:01:28 +00:00
_needRedraw = false ;
_needBgReset = true ;
2008-09-25 10:11:06 +00:00
}
void ActorHE : : hideActor ( ) {
Actor : : hideActor ( ) ;
2006-10-18 14:01:28 +00:00
_auxBlock . reset ( ) ;
}
void Actor : : showActor ( ) {
if ( _vm - > _currentRoom = = 0 | | _visible )
return ;
adjustActorPos ( ) ;
_vm - > ensureResourceLoaded ( rtCostume , _costume ) ;
2009-07-25 05:39:57 +00:00
if ( _vm - > _game . version = = 0 ) {
2012-02-04 18:34:08 +01:00
Actor_v0 * a = ( ( Actor_v0 * ) this ) ;
2012-09-26 04:17:31 +02:00
2012-01-24 23:23:19 +11:00
a - > _costCommand = a - > _costCommandNew = 0xFF ;
2014-11-30 22:01:23 +11:00
_walkdata . dest = a - > _CurrentWalkTo ;
2012-01-24 23:23:19 +11:00
2012-02-06 08:06:48 +01:00
for ( int i = 0 ; i < 8 ; + + i ) {
2012-01-25 16:18:33 +11:00
a - > _limbFrameRepeat [ i ] = 0 ;
2012-01-24 23:23:19 +11:00
a - > _limbFrameRepeatNew [ i ] = 0 ;
}
2012-01-19 17:59:56 +11:00
2012-01-25 16:18:33 +11:00
_cost . reset ( ) ;
2012-02-04 14:49:44 +01:00
a - > _animFrameRepeat = 1 ;
2012-01-25 16:18:33 +11:00
a - > _speaking = 0 ;
2012-01-19 17:59:56 +11:00
2012-01-26 21:37:04 +11:00
startAnimActor ( _standFrame ) ;
2012-01-25 16:18:33 +11:00
_visible = true ;
return ;
2012-01-24 23:23:19 +11:00
2009-07-25 05:39:57 +00:00
} else if ( _vm - > _game . version < = 2 ) {
2006-10-18 14:01:28 +00:00
_cost . reset ( ) ;
startAnimActor ( _standFrame ) ;
startAnimActor ( _initFrame ) ;
startAnimActor ( _talkStopFrame ) ;
} else {
if ( _costumeNeedsInit ) {
startAnimActor ( _initFrame ) ;
_costumeNeedsInit = false ;
}
}
stopActorMoving ( ) ;
_visible = true ;
_needRedraw = true ;
}
void ScummEngine : : showActors ( ) {
int i ;
for ( i = 1 ; i < _numActors ; i + + ) {
2006-12-25 15:03:36 +00:00
if ( _actors [ i ] - > isInCurrentRoom ( ) )
_actors [ i ] - > showActor ( ) ;
2006-10-18 14:01:28 +00:00
}
}
/* Used in Scumm v5 only. Play sounds associated with actors */
void ScummEngine : : playActorSounds ( ) {
2009-11-26 00:45:06 +00:00
int i , j ;
int sound ;
2006-10-18 14:01:28 +00:00
for ( i = 1 ; i < _numActors ; i + + ) {
2013-08-18 09:07:49 +02:00
if ( _actors [ i ] - > _cost . soundCounter & & _actors [ i ] - > isInCurrentRoom ( ) ) {
2006-10-18 14:01:28 +00:00
_currentScript = 0xFF ;
2009-11-26 00:45:06 +00:00
if ( _game . version = = 0 ) {
2014-12-07 19:53:27 +11:00
sound = _actors [ i ] - > _sound [ 0 ] & 0x3F ;
2009-11-26 00:45:06 +00:00
} else {
sound = _actors [ i ] - > _sound [ 0 ] ;
}
2011-12-26 13:54:53 +01:00
// fast mode will flood the queue with walk sounds
if ( ! _fastMode ) {
_sound - > addSoundToQueue ( sound ) ;
}
2009-11-26 00:45:06 +00:00
for ( j = 1 ; j < _numActors ; j + + ) {
_actors [ j ] - > _cost . soundCounter = 0 ;
2006-10-18 14:01:28 +00:00
}
return ;
}
}
}
bool ScummEngine : : isValidActor ( int id ) const {
2006-12-25 15:03:36 +00:00
return id > = 0 & & id < _numActors & & _actors [ id ] - > _number = = id ;
2006-10-18 14:01:28 +00:00
}
Actor * ScummEngine : : derefActor ( int id , const char * errmsg ) const {
if ( id = = 0 )
debugC ( DEBUG_ACTORS , " derefActor(0, \" %s \" ) in script %d, opcode 0x%x " ,
errmsg , vm . slot [ _currentScript ] . number , _opcode ) ;
if ( ! isValidActor ( id ) ) {
2003-07-19 18:18:01 +00:00
if ( errmsg )
error ( " Invalid actor %d in %s " , id , errmsg ) ;
else
error ( " Invalid actor %d " , id ) ;
}
2006-12-25 15:03:36 +00:00
return _actors [ id ] ;
2003-07-19 18:18:01 +00:00
}
2003-10-02 22:42:03 +00:00
Actor * ScummEngine : : derefActorSafe ( int id , const char * errmsg ) const {
2003-08-12 16:43:43 +00:00
if ( id = = 0 )
2005-07-30 21:11:48 +00:00
debugC ( DEBUG_ACTORS , " derefActorSafe(0, \" %s \" ) in script %d, opcode 0x%x " ,
2006-01-10 21:39:14 +00:00
errmsg , vm . slot [ _currentScript ] . number , _opcode ) ;
2004-01-10 11:01:47 +00:00
2006-01-18 11:53:07 +00:00
if ( ! isValidActor ( id ) ) {
2004-01-10 11:01:47 +00:00
debugC ( DEBUG_ACTORS , " Invalid actor %d in %s (script %d, opcode 0x%x) " ,
2006-01-10 21:39:14 +00:00
id , errmsg , vm . slot [ _currentScript ] . number , _opcode ) ;
2003-07-19 18:18:01 +00:00
return NULL ;
}
2006-12-25 15:03:36 +00:00
return _actors [ id ] ;
2003-07-19 18:18:01 +00:00
}
2006-10-18 14:01:28 +00:00
# pragma mark -
# pragma mark --- Actor drawing ---
# pragma mark -
2003-10-02 22:42:03 +00:00
void ScummEngine : : processActors ( ) {
2002-06-07 16:54:11 +00:00
int numactors = 0 ;
2001-10-09 14:30:12 +00:00
2002-06-01 21:45:15 +00:00
// Make a list of all actors in this room
2003-06-05 03:19:07 +00:00
for ( int i = 1 ; i < _numActors ; i + + ) {
2006-12-25 15:03:36 +00:00
if ( _game . version = = 8 & & _actors [ i ] - > _layer < 0 )
2003-02-27 10:17:29 +00:00
continue ;
2006-12-25 15:03:36 +00:00
if ( _actors [ i ] - > isInCurrentRoom ( ) ) {
_sortedActors [ numactors + + ] = _actors [ i ] ;
2005-05-23 22:48:36 +00:00
}
2001-10-09 14:30:12 +00:00
}
2002-12-25 00:31:39 +00:00
if ( ! numactors ) {
2001-10-09 14:30:12 +00:00
return ;
2002-12-25 00:31:39 +00:00
}
2002-07-07 19:31:51 +00:00
2005-06-15 06:58:27 +00:00
// Sort actors by position before drawing them (to ensure that actors
// in front are drawn after those "behind" them).
//
2005-05-23 22:48:36 +00:00
// Note: This algorithm works exactly the way the original engine did.
2005-06-15 06:58:27 +00:00
// Please resist any urge to 'optimize' this. Many of the games rely on
// the quirks of this particular sorting algorithm, and since we are
// dealing with far less than 100 objects being sorted here, any
// 'optimization' wouldn't yield a useful gain anyway.
//
// In particular, changing this loop caused a number of bugs in the
// past, including bugs #758167, #775097, and #1093867.
//
// Note that Sam & Max uses a stable sorting method. Older games don't
// and, according to cyx, neither do newer ones. At least not FT and
// COMI. See bug #1220168 for more details.
2006-02-20 16:51:30 +00:00
if ( _game . id = = GID_SAMNMAX ) {
2005-06-15 06:58:27 +00:00
for ( int j = 0 ; j < numactors ; + + j ) {
for ( int i = 0 ; i < numactors ; + + i ) {
2006-11-19 00:39:48 +00:00
int sc_actor1 = _sortedActors [ j ] - > getPos ( ) . y ;
int sc_actor2 = _sortedActors [ i ] - > getPos ( ) . y ;
2005-06-15 06:58:27 +00:00
if ( sc_actor1 = = sc_actor2 ) {
sc_actor1 + = _sortedActors [ j ] - > _number ;
sc_actor2 + = _sortedActors [ i ] - > _number ;
}
if ( sc_actor1 < sc_actor2 ) {
SWAP ( _sortedActors [ i ] , _sortedActors [ j ] ) ;
}
}
}
2009-06-18 07:12:53 +00:00
} else if ( _game . heversion > = 90 ) {
for ( int j = 0 ; j < numactors ; + + j ) {
for ( int i = 0 ; i < numactors ; + + i ) {
int sc_actor1 = _sortedActors [ j ] - > _layer ;
int sc_actor2 = _sortedActors [ i ] - > _layer ;
if ( sc_actor1 < sc_actor2 ) {
SWAP ( _sortedActors [ i ] , _sortedActors [ j ] ) ;
} else if ( sc_actor1 = = sc_actor2 ) {
sc_actor1 = _sortedActors [ j ] - > getPos ( ) . y ;
sc_actor2 = _sortedActors [ i ] - > getPos ( ) . y ;
if ( sc_actor1 < sc_actor2 ) {
SWAP ( _sortedActors [ i ] , _sortedActors [ j ] ) ;
}
}
}
}
2012-01-15 19:26:02 +01:00
} else if ( _game . version = = 0 ) {
for ( int j = 0 ; j < numactors ; + + j ) {
for ( int i = 0 ; i < numactors ; + + i ) {
// Note: the plant is handled different in v0, the y value is not used.
// In v1/2 this is done by the actor's elevation instead.
int sc_actor1 = ( _sortedActors [ j ] - > _number = = 19 ? 0 : _sortedActors [ j ] - > getPos ( ) . y ) ;
int sc_actor2 = ( _sortedActors [ i ] - > _number = = 19 ? 0 : _sortedActors [ i ] - > getPos ( ) . y ) ;
if ( sc_actor1 < sc_actor2 ) {
SWAP ( _sortedActors [ i ] , _sortedActors [ j ] ) ;
}
}
}
2005-06-15 06:58:27 +00:00
} else {
for ( int j = 0 ; j < numactors ; + + j ) {
for ( int i = 0 ; i < numactors ; + + i ) {
2006-11-19 00:39:48 +00:00
int sc_actor1 = _sortedActors [ j ] - > getPos ( ) . y - _sortedActors [ j ] - > _layer * 2000 ;
int sc_actor2 = _sortedActors [ i ] - > getPos ( ) . y - _sortedActors [ i ] - > _layer * 2000 ;
2005-06-15 06:58:27 +00:00
if ( sc_actor1 < sc_actor2 ) {
SWAP ( _sortedActors [ i ] , _sortedActors [ j ] ) ;
}
2005-05-23 22:48:36 +00:00
}
}
}
2001-10-09 14:30:12 +00:00
2002-06-07 16:54:11 +00:00
// Finally draw the now sorted actors
2005-05-23 22:48:36 +00:00
Actor * * end = _sortedActors + numactors ;
2005-04-30 22:01:16 +00:00
for ( Actor * * ac = _sortedActors ; ac ! = end ; + + ac ) {
2003-06-05 03:19:07 +00:00
Actor * a = * ac ;
2010-01-25 01:39:44 +00:00
2009-07-25 05:39:57 +00:00
if ( _game . version = = 0 ) {
2012-01-21 23:05:16 +01:00
// 0x057B
2012-02-10 23:39:07 +01:00
Actor_v0 * a0 = ( Actor_v0 * ) a ;
2016-07-16 17:18:11 +10:00
if ( a0 - > _speaking & 1 ) {
2012-02-10 23:39:07 +01:00
a0 - > _speaking ^ = 0xFE ;
2016-07-16 17:18:11 +10:00
+ + _V0Delay . _actorRedrawCount ;
}
2012-01-21 23:05:16 +01:00
// 0x22B5
2012-02-10 23:39:07 +01:00
if ( a0 - > _miscflags & kActorMiscFlagHide )
2012-01-21 23:05:16 +01:00
continue ;
2012-01-28 01:25:13 +11:00
// Sound
2014-11-30 22:01:23 +11:00
if ( a0 - > _moving ! = 2 & & _currentRoom ! = 1 & & _currentRoom ! = 44 ) {
2012-02-10 23:39:07 +01:00
if ( a0 - > _cost . soundPos = = 0 )
a0 - > _cost . soundCounter + + ;
2012-01-28 01:25:13 +11:00
// Is this the correct location?
// 0x073C
2014-12-07 19:53:27 +11:00
if ( a0 - > _sound [ 0 ] & 0x3F )
2012-02-10 23:39:07 +01:00
a0 - > _cost . soundPos = ( a0 - > _cost . soundPos + 1 ) % 3 ;
2012-01-28 01:25:13 +11:00
}
}
2005-05-23 22:48:36 +00:00
// Draw and animate the actors, except those w/o a costume.
2005-06-15 06:58:27 +00:00
// Note: We could 'optimize' this a little bit by only putting
// actors with a costume into the _sortedActors array in the
// first place. However, that would mess up the sorting, and
// would hence cause regressions. See also the other big
// comment further up in this method for some details.
2005-05-23 22:48:36 +00:00
if ( a - > _costume ) {
2014-11-28 22:24:45 +11:00
2016-10-09 14:59:58 +02:00
// Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor' (which is before drawing the actor)...
2014-11-30 22:01:23 +11:00
// doing it the other way with V0, causes animation glitches (when beginnning to walk, as the costume hasnt been updated).
// Updating the costume directly after 'walkActor' and again, after drawing... causes frame skipping
2014-11-29 07:12:57 +11:00
if ( _game . version = = 0 ) {
2014-11-28 22:24:45 +11:00
a - > animateCostume ( ) ;
2014-11-29 07:12:57 +11:00
a - > drawActorCostume ( ) ;
} else {
a - > drawActorCostume ( ) ;
2014-11-28 22:24:45 +11:00
a - > animateCostume ( ) ;
2014-11-29 07:12:57 +11:00
}
2005-05-23 22:48:36 +00:00
}
2002-06-07 16:54:11 +00:00
}
2006-04-29 16:51:29 +00:00
}
void ScummEngine_v6 : : processActors ( ) {
ScummEngine : : processActors ( ) ;
2005-07-30 21:11:48 +00:00
2006-02-20 16:51:30 +00:00
if ( _game . features & GF_NEW_COSTUMES )
2004-08-28 03:18:52 +00:00
akos_processQueue ( ) ;
2001-10-09 14:30:12 +00:00
}
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_HE
2005-04-29 01:36:30 +00:00
void ScummEngine_v71he : : processActors ( ) {
preProcessAuxQueue ( ) ;
2005-04-28 00:45:06 +00:00
if ( ! _skipProcessActors )
2006-04-29 16:51:29 +00:00
ScummEngine_v6 : : processActors ( ) ;
2005-04-28 00:45:06 +00:00
2005-05-10 15:43:40 +00:00
_fullRedraw = false ;
2005-04-29 01:36:30 +00:00
postProcessAuxQueue ( ) ;
2005-04-28 00:45:06 +00:00
}
2005-04-29 01:36:30 +00:00
void ScummEngine_v90he : : processActors ( ) {
preProcessAuxQueue ( ) ;
2005-05-23 11:50:36 +00:00
_sprite - > setRedrawFlags ( false ) ;
_sprite - > processImages ( true ) ;
2005-04-29 01:36:30 +00:00
if ( ! _skipProcessActors )
2006-04-29 16:51:29 +00:00
ScummEngine_v6 : : processActors ( ) ;
2005-04-29 01:36:30 +00:00
2005-05-10 15:43:40 +00:00
_fullRedraw = false ;
2005-04-29 01:36:30 +00:00
postProcessAuxQueue ( ) ;
2005-05-23 11:50:36 +00:00
_sprite - > setRedrawFlags ( true ) ;
_sprite - > processImages ( false ) ;
2005-04-29 01:36:30 +00:00
}
2005-05-14 14:06:37 +00:00
# endif
2005-04-29 01:36:30 +00:00
2003-02-27 10:17:29 +00:00
// Used in Scumm v8, to allow the verb coin to be drawn over the inventory
// chest. I'm assuming that draw order won't matter here.
2003-10-02 22:42:03 +00:00
void ScummEngine : : processUpperActors ( ) {
2003-02-27 10:17:29 +00:00
int i ;
2003-05-13 23:42:41 +00:00
for ( i = 1 ; i < _numActors ; i + + ) {
2006-12-25 15:03:36 +00:00
if ( _actors [ i ] - > isInCurrentRoom ( ) & & _actors [ i ] - > _costume & & _actors [ i ] - > _layer < 0 ) {
_actors [ i ] - > drawActorCostume ( ) ;
_actors [ i ] - > animateCostume ( ) ;
2003-02-27 10:17:29 +00:00
}
}
}
2004-09-03 19:54:58 +00:00
void Actor : : drawActorCostume ( bool hitTestMode ) {
2005-04-14 11:33:12 +00:00
if ( _costume = = 0 )
return ;
2004-09-03 19:54:58 +00:00
if ( ! hitTestMode ) {
2005-03-11 01:10:06 +00:00
if ( ! _needRedraw )
2004-09-03 19:54:58 +00:00
return ;
2005-07-30 21:11:48 +00:00
2005-03-11 01:10:06 +00:00
_needRedraw = false ;
2004-09-03 19:54:58 +00:00
}
2001-11-26 19:57:57 +00:00
2002-07-15 22:56:24 +00:00
setupActorScale ( ) ;
2009-01-01 15:06:43 +00:00
2008-09-25 08:06:18 +00:00
BaseCostumeRenderer * bcr = _vm - > _costumeRenderer ;
prepareDrawActorCostume ( bcr ) ;
2001-12-27 17:51:58 +00:00
2008-09-25 08:06:18 +00:00
// If the actor is partially hidden, redraw it next frame.
if ( bcr - > drawCostume ( _vm - > _virtscr [ kMainVirtScreen ] , _vm - > _gdi - > _numStrips , this , _drawToBackBuf ) & 1 ) {
_needRedraw = ( _vm - > _game . version < = 6 ) ;
2007-02-04 01:24:43 +00:00
}
2007-09-19 08:40:12 +00:00
2008-09-25 08:06:18 +00:00
if ( ! hitTestMode ) {
// Record the vertical extent of the drawn actor
_top = bcr - > _draw_top ;
_bottom = bcr - > _draw_bottom ;
2003-07-02 14:23:45 +00:00
}
2008-09-25 08:06:18 +00:00
}
2003-07-12 17:53:22 +00:00
2009-01-01 15:06:43 +00:00
2008-09-25 08:06:18 +00:00
void Actor : : prepareDrawActorCostume ( BaseCostumeRenderer * bcr ) {
bcr - > _actorID = _number ;
bcr - > _actorX = _pos . x - _vm - > _virtscr [ kMainVirtScreen ] . xstart ;
bcr - > _actorY = _pos . y - _elevation ;
2004-09-04 00:18:55 +00:00
2007-03-12 12:16:41 +00:00
if ( _vm - > _game . version = = 4 & & ( _boxscale & 0x8000 ) ) {
2005-03-11 01:10:06 +00:00
bcr - > _scaleX = bcr - > _scaleY = _vm - > getScaleFromSlot ( ( _boxscale & 0x7fff ) + 1 , _pos . x , _pos . y ) ;
2004-07-28 11:56:14 +00:00
} else {
2005-03-11 01:10:06 +00:00
bcr - > _scaleX = _scalex ;
bcr - > _scaleY = _scaley ;
2004-07-28 11:56:14 +00:00
}
2001-12-27 17:51:58 +00:00
2004-09-28 19:28:59 +00:00
bcr - > _shadow_mode = _shadowMode ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . version > = 5 & & _vm - > _game . heversion = = 0 ) {
2005-10-29 01:59:18 +00:00
bcr - > _shadow_table = _vm - > _shadowPalette ;
2005-10-21 02:26:24 +00:00
}
2003-05-20 12:25:47 +00:00
2008-09-29 20:08:26 +00:00
bcr - > setCostume ( _costume , ( _vm - > _game . heversion = = 0 ) ? 0 : _heXmapNum ) ;
2005-03-11 01:10:06 +00:00
bcr - > setPalette ( _palette ) ;
2003-05-20 12:25:47 +00:00
bcr - > setFacing ( this ) ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . version > = 7 ) {
2001-12-27 17:51:58 +00:00
2005-03-11 01:10:06 +00:00
bcr - > _zbuf = _forceClip ;
2004-01-11 08:59:51 +00:00
if ( bcr - > _zbuf = = 100 ) {
2004-09-28 19:28:59 +00:00
bcr - > _zbuf = _vm - > getMaskFromBox ( _walkbox ) ;
2006-09-17 20:22:47 +00:00
if ( bcr - > _zbuf > _vm - > _gdi - > _numZBuffer - 1 )
bcr - > _zbuf = _vm - > _gdi - > _numZBuffer - 1 ;
2003-05-18 19:44:22 +00:00
}
2002-04-11 17:19:16 +00:00
2004-01-11 08:39:39 +00:00
} else {
2005-03-11 01:10:06 +00:00
if ( _forceClip )
bcr - > _zbuf = _forceClip ;
2004-01-11 08:39:39 +00:00
else if ( isInClass ( kObjectClassNeverClip ) )
bcr - > _zbuf = 0 ;
else {
2004-09-28 19:28:59 +00:00
bcr - > _zbuf = _vm - > getMaskFromBox ( _walkbox ) ;
2009-10-27 12:08:19 +00:00
if ( _vm - > _game . version = = 0 )
bcr - > _zbuf & = 0x03 ;
2006-09-17 20:22:47 +00:00
if ( bcr - > _zbuf > _vm - > _gdi - > _numZBuffer - 1 )
bcr - > _zbuf = _vm - > _gdi - > _numZBuffer - 1 ;
2002-03-05 23:05:55 +00:00
}
2002-04-11 17:19:16 +00:00
2003-05-28 21:43:34 +00:00
}
2003-01-05 23:53:16 +00:00
2004-09-03 19:54:58 +00:00
bcr - > _draw_top = 0x7fffffff ;
bcr - > _draw_bottom = 0 ;
2008-09-25 08:06:18 +00:00
}
void ActorHE : : prepareDrawActorCostume ( BaseCostumeRenderer * bcr ) {
2009-06-02 06:03:49 +00:00
// HE palette number must be set, before setting the costume palette
bcr - > _paletteNum = _hePaletteNum ;
2008-09-25 08:06:18 +00:00
Actor : : prepareDrawActorCostume ( bcr ) ;
2009-01-01 15:06:43 +00:00
2008-09-25 08:06:18 +00:00
bcr - > _actorX + = _heOffsX ;
bcr - > _actorY + = _heOffsY ;
bcr - > _clipOverride = _clipOverride ;
if ( _vm - > _game . heversion = = 70 ) {
bcr - > _shadow_table = _vm - > _HEV7ActorPalette ;
}
2004-09-03 15:39:14 +00:00
2005-03-11 01:10:06 +00:00
bcr - > _skipLimbs = ( _heSkipLimbs ! = 0 ) ;
2005-07-30 21:11:48 +00:00
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . heversion > = 80 & & _heNoTalkAnimation = = 0 & & _animProgress = = 0 ) {
2005-10-29 04:48:47 +00:00
if ( _vm - > getTalkingActor ( ) = = _number & & ! _vm - > _string [ 0 ] . no_talk_anim ) {
2006-01-05 07:06:47 +00:00
int talkState = 0 ;
2006-04-23 18:52:39 +00:00
if ( ( ( SoundHE * ) _vm - > _sound ) - > isSoundCodeUsed ( 1 ) )
talkState = ( ( SoundHE * ) _vm - > _sound ) - > getSoundVar ( 1 , 19 ) ;
2006-01-05 07:06:47 +00:00
if ( talkState = = 0 )
talkState = _vm - > _rnd . getRandomNumberRng ( 1 , 10 ) ;
2006-09-16 13:38:43 +00:00
assertRange ( 1 , talkState , 13 , " Talk state " ) ;
2006-01-05 07:06:47 +00:00
setTalkCondition ( talkState ) ;
2005-10-29 04:48:47 +00:00
} else {
setTalkCondition ( 1 ) ;
2005-07-30 21:11:48 +00:00
}
2004-09-11 12:22:06 +00:00
}
2005-03-11 01:10:06 +00:00
_heNoTalkAnimation = 0 ;
2008-09-25 08:06:18 +00:00
}
2004-09-11 12:22:06 +00:00
2008-09-25 08:06:18 +00:00
void Actor_v2 : : prepareDrawActorCostume ( BaseCostumeRenderer * bcr ) {
Actor : : prepareDrawActorCostume ( bcr ) ;
bcr - > _actorX = _pos . x ;
bcr - > _actorY = _pos . y - _elevation ;
if ( _vm - > _game . version < = 2 ) {
bcr - > _actorX * = V12_X_MULTIPLIER ;
bcr - > _actorY * = V12_Y_MULTIPLIER ;
2002-03-05 23:05:55 +00:00
}
2008-09-25 08:06:18 +00:00
bcr - > _actorX - = _vm - > _virtscr [ kMainVirtScreen ] . xstart ;
2003-05-20 12:25:47 +00:00
2008-09-25 08:06:18 +00:00
if ( _vm - > _game . platform = = Common : : kPlatformNES ) {
// In the NES version, when the actor is facing right,
// we need to shift it 8 pixels to the left
if ( _facing = = 90 )
bcr - > _actorX - = 8 ;
2009-07-25 05:39:57 +00:00
} else if ( _vm - > _game . version = = 0 ) {
bcr - > _actorX + = 12 ;
2008-09-25 08:06:18 +00:00
} else if ( _vm - > _game . version < = 2 ) {
// HACK: We have to adjust the x position by one strip (8 pixels) in
// V2 games. However, it is not quite clear to me why. And to fully
// match the original, it seems we have to offset by 2 strips if the
// actor is facing left (270 degree).
// V1 games are once again slightly different, here we only have
// to adjust the 270 degree case...
if ( _facing = = 270 )
bcr - > _actorX + = 16 ;
else if ( _vm - > _game . version = = 2 )
bcr - > _actorX + = 8 ;
2004-09-03 19:54:58 +00:00
}
}
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_SCUMM_7_8
2004-09-03 19:54:58 +00:00
bool Actor : : actorHitTest ( int x , int y ) {
AkosRenderer * ar = ( AkosRenderer * ) _vm - > _costumeRenderer ;
ar - > _actorHitX = x ;
ar - > _actorHitY = y ;
ar - > _actorHitMode = true ;
ar - > _actorHitResult = false ;
drawActorCostume ( true ) ;
ar - > _actorHitMode = false ;
2005-07-30 21:11:48 +00:00
2004-09-03 19:54:58 +00:00
return ar - > _actorHitResult ;
2001-10-09 14:30:12 +00:00
}
2005-05-14 22:56:41 +00:00
# endif
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
void Actor : : startAnimActor ( int f ) {
2013-05-02 18:26:58 -04:00
if ( _vm - > _game . version > = 7 & & ! ( ( _vm - > _game . id = = GID_FT ) & & ( _vm - > _game . features & GF_DEMO ) & & ( _vm - > _game . platform = = Common : : kPlatformDOS ) ) ) {
2006-10-18 14:01:28 +00:00
switch ( f ) {
case 1001 :
f = _initFrame ;
break ;
case 1002 :
f = _walkFrame ;
break ;
case 1003 :
f = _standFrame ;
break ;
case 1004 :
f = _talkStartFrame ;
break ;
case 1005 :
f = _talkStopFrame ;
break ;
}
2005-07-30 21:11:48 +00:00
2006-10-18 14:01:28 +00:00
if ( _costume ! = 0 ) {
_animProgress = 0 ;
2005-03-27 01:07:22 +00:00
_needRedraw = true ;
2006-10-18 14:01:28 +00:00
if ( f = = _initFrame )
_cost . reset ( ) ;
_vm - > _costumeLoader - > costumeDecodeData ( this , f , ( uint ) - 1 ) ;
_frame = f ;
2001-10-09 14:30:12 +00:00
}
2006-10-18 14:01:28 +00:00
} else {
switch ( f ) {
case 0x38 :
f = _initFrame ;
break ;
case 0x39 :
f = _walkFrame ;
break ;
case 0x3A :
f = _standFrame ;
break ;
case 0x3B :
f = _talkStartFrame ;
break ;
case 0x3C :
f = _talkStopFrame ;
break ;
}
assert ( f ! = 0x3E ) ;
if ( isInCurrentRoom ( ) & & _costume ! = 0 ) {
_animProgress = 0 ;
_needRedraw = true ;
2008-09-25 10:11:06 +00:00
_cost . animCounter = 0 ;
2006-10-18 14:01:28 +00:00
// V1 - V2 games don't seem to need a _cost.reset() at this point.
// Causes Zak to lose his body in several scenes, see bug #771508
if ( _vm - > _game . version > = 3 & & f = = _initFrame ) {
_cost . reset ( ) ;
2008-09-25 10:11:06 +00:00
if ( _vm - > _game . heversion ! = 0 ) {
( ( ActorHE * ) this ) - > _auxBlock . reset ( ) ;
}
2006-10-18 14:01:28 +00:00
}
_vm - > _costumeLoader - > costumeDecodeData ( this , f , ( uint ) - 1 ) ;
_frame = f ;
}
}
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : startAnimActor ( int f ) {
2012-01-24 23:23:19 +11:00
if ( f = = _talkStartFrame ) {
2014-12-07 19:53:27 +11:00
if ( _sound [ 0 ] & 0x40 )
2012-01-24 23:23:19 +11:00
return ;
_speaking = 1 ;
2017-02-15 17:03:54 +11:00
speakCheck ( ) ;
2012-01-24 23:23:19 +11:00
return ;
}
if ( f = = _talkStopFrame ) {
_speaking = 0 ;
return ;
}
2012-02-06 08:06:48 +01:00
if ( f = = _standFrame )
2012-02-04 14:49:44 +01:00
setDirection ( _facing ) ;
2012-01-24 23:23:19 +11:00
}
2006-10-18 14:01:28 +00:00
void Actor : : animateActor ( int anim ) {
int cmd , dir ;
2013-05-02 18:26:58 -04:00
if ( _vm - > _game . version > = 7 & & ! ( ( _vm - > _game . id = = GID_FT ) & & ( _vm - > _game . features & GF_DEMO ) & & ( _vm - > _game . platform = = Common : : kPlatformDOS ) ) ) {
2006-10-18 14:01:28 +00:00
if ( anim = = 0xFF )
anim = 2000 ;
cmd = anim / 1000 ;
dir = anim % 1000 ;
} else {
2012-02-04 14:49:44 +01:00
2006-10-18 14:01:28 +00:00
cmd = anim / 4 ;
dir = oldDirToNewDir ( anim % 4 ) ;
// Convert into old cmd code
cmd = 0x3F - cmd + 2 ;
}
switch ( cmd ) {
case 2 : // stop walking
startAnimActor ( _standFrame ) ;
stopActorMoving ( ) ;
break ;
case 3 : // change direction immediatly
_moving & = ~ MF_TURN ;
setDirection ( dir ) ;
break ;
case 4 : // turn to new direction
turnToDirection ( dir ) ;
break ;
2009-07-25 05:39:57 +00:00
case 64 :
if ( _vm - > _game . version = = 0 ) {
_moving & = ~ MF_TURN ;
setDirection ( dir ) ;
break ;
}
2017-08-06 11:51:57 +02:00
// fall through
2006-10-18 14:01:28 +00:00
default :
if ( _vm - > _game . version < = 2 )
startAnimActor ( anim / 4 ) ;
else
startAnimActor ( anim ) ;
}
}
void Actor : : animateCostume ( ) {
if ( _costume = = 0 )
return ;
_animProgress + + ;
if ( _animProgress > = _animSpeed ) {
_animProgress = 0 ;
_vm - > _costumeLoader - > loadCostume ( _costume ) ;
if ( _vm - > _costumeLoader - > increaseAnims ( this ) ) {
_needRedraw = true ;
}
}
2001-10-09 14:30:12 +00:00
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : limbFrameCheck ( int limb ) {
2012-02-04 17:32:26 +01:00
if ( _cost . frame [ limb ] = = 0xFFFF )
2012-01-24 23:23:19 +11:00
return ;
2012-02-04 17:32:26 +01:00
if ( _cost . start [ limb ] = = _cost . frame [ limb ] )
2012-01-24 23:23:19 +11:00
return ;
// 0x25A4
2012-02-04 17:32:26 +01:00
_cost . start [ limb ] = _cost . frame [ limb ] ;
2012-01-24 23:23:19 +11:00
2012-02-04 17:32:26 +01:00
_limbFrameRepeat [ limb ] = _limbFrameRepeatNew [ limb ] ;
2012-01-24 23:23:19 +11:00
2012-01-27 22:05:10 +11:00
// 0x25C3
2012-02-15 09:53:31 -06:00
_cost . active [ limb ] = ( ( V0CostumeLoader * ) _vm - > _costumeLoader ) - > getFrame ( this , limb ) ;
2012-02-04 17:32:26 +01:00
_cost . curpos [ limb ] = 0 ;
2012-01-24 23:23:19 +11:00
_needRedraw = true ;
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : animateCostume ( ) {
2012-01-24 23:23:19 +11:00
speakCheck ( ) ;
2016-07-19 18:55:27 +10:00
byte count = _vm - > _costumeLoader - > increaseAnims ( this ) ;
2016-07-16 17:18:11 +10:00
if ( count ) {
_vm - > _V0Delay . _actorLimbRedrawDrawCount + = count ;
2012-02-04 17:32:26 +01:00
_needRedraw = true ;
2016-07-16 17:18:11 +10:00
}
2012-01-24 23:23:19 +11:00
}
2012-02-04 18:34:08 +01:00
void Actor_v0 : : speakCheck ( ) {
2014-12-07 19:53:27 +11:00
if ( _sound [ 0 ] & 0x80 )
2012-01-24 23:23:19 +11:00
return ;
2012-09-26 04:17:31 +02:00
2012-02-04 14:49:44 +01:00
int cmd = newDirToOldDir ( _facing ) ;
2012-01-24 23:23:19 +11:00
if ( _speaking & 0x80 )
cmd + = 0x0C ;
else
cmd + = 0x10 ;
2012-02-04 14:49:44 +01:00
_animFrameRepeat = - 1 ;
animateActor ( cmd ) ;
2012-01-24 23:23:19 +11:00
}
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_SCUMM_7_8
2003-03-06 17:58:13 +00:00
void Actor : : animateLimb ( int limb , int f ) {
2005-07-30 21:11:48 +00:00
// This methods is very similiar to animateCostume().
2003-01-06 16:04:01 +00:00
// However, instead of animating *all* the limbs, it only animates
2005-07-30 21:11:48 +00:00
// the specified limb to be at the frame specified by "f".
2003-01-06 16:04:01 +00:00
if ( ! f )
return ;
2005-03-11 01:10:06 +00:00
_animProgress + + ;
if ( _animProgress > = _animSpeed ) {
_animProgress = 0 ;
2003-01-06 16:04:01 +00:00
2005-03-11 01:10:06 +00:00
if ( _costume = = 0 )
2003-01-06 16:04:01 +00:00
return ;
2003-05-28 20:01:47 +00:00
const byte * aksq , * akfo ;
2003-01-06 16:04:01 +00:00
uint size ;
2005-03-11 01:10:06 +00:00
byte * akos = _vm - > getResourceAddress ( rtCostume , _costume ) ;
2003-01-06 16:04:01 +00:00
assert ( akos ) ;
2011-04-12 16:53:15 +02:00
aksq = _vm - > findResourceData ( MKTAG ( ' A ' , ' K ' , ' S ' , ' Q ' ) , akos ) ;
akfo = _vm - > findResourceData ( MKTAG ( ' A ' , ' K ' , ' F ' , ' O ' ) , akos ) ;
2005-07-30 21:11:48 +00:00
2003-11-16 20:52:57 +00:00
size = _vm - > getResourceDataSize ( akfo ) / 2 ;
2005-07-30 21:11:48 +00:00
2003-01-06 16:04:01 +00:00
while ( f - - ) {
2005-03-11 01:10:06 +00:00
if ( _cost . active [ limb ] ! = 0 )
2006-04-29 16:51:29 +00:00
( ( ScummEngine_v6 * ) _vm ) - > akos_increaseAnim ( this , limb , aksq , ( const uint16 * ) akfo , size ) ;
2003-01-06 16:04:01 +00:00
}
2005-03-11 01:10:06 +00:00
// _needRedraw = true;
// _needBgReset = true;
2003-01-06 16:04:01 +00:00
}
}
2005-05-14 22:56:41 +00:00
# endif
2003-01-06 16:04:01 +00:00
2005-04-02 14:24:43 +00:00
void ScummEngine : : redrawAllActors ( ) {
2006-12-25 15:03:36 +00:00
int i ;
2005-04-02 14:24:43 +00:00
2006-12-25 15:03:36 +00:00
for ( i = 1 ; i < _numActors ; + + i ) {
_actors [ i ] - > _needRedraw = true ;
_actors [ i ] - > _needBgReset = true ;
2005-04-02 14:24:43 +00:00
}
}
2003-10-02 22:42:03 +00:00
void ScummEngine : : setActorRedrawFlags ( ) {
2002-04-11 17:19:16 +00:00
int i , j ;
2001-10-09 14:30:12 +00:00
2005-06-04 15:47:42 +00:00
// Redraw all actors if a full redraw was requested.
// Also redraw all actors in COMI (see bug #1066329 for details).
2006-02-20 16:51:30 +00:00
if ( _fullRedraw | | _game . version = = 8 | | ( VAR_REDRAW_ALL_ACTORS ! = 0xFF & & VAR ( VAR_REDRAW_ALL_ACTORS ) ! = 0 ) ) {
2003-05-13 23:42:41 +00:00
for ( j = 1 ; j < _numActors ; j + + ) {
2006-12-25 15:03:36 +00:00
_actors [ j ] - > _needRedraw = true ;
2002-06-07 16:54:11 +00:00
}
} else {
2016-05-24 20:19:18 +10:00
if ( _game . heversion > = 72 ) {
for ( j = 1 ; j < _numActors ; j + + ) {
if ( _actors [ j ] - > _costume & & _actors [ j ] - > _heXmapNum )
_actors [ j ] - > _needRedraw = true ;
}
}
2006-09-17 20:22:47 +00:00
for ( i = 0 ; i < _gdi - > _numStrips ; i + + ) {
2003-01-14 10:06:56 +00:00
int strip = _screenStartStrip + i ;
if ( testGfxAnyUsageBits ( strip ) ) {
2003-05-13 23:42:41 +00:00
for ( j = 1 ; j < _numActors ; j + + ) {
2003-01-14 10:06:56 +00:00
if ( testGfxUsageBit ( strip , j ) & & testGfxOtherUsageBits ( strip , j ) ) {
2006-12-25 15:03:36 +00:00
_actors [ j ] - > _needRedraw = true ;
2002-06-07 16:54:11 +00:00
}
2001-10-09 14:30:12 +00:00
}
}
}
}
}
2003-10-02 22:42:03 +00:00
void ScummEngine : : resetActorBgs ( ) {
2003-09-08 21:03:31 +00:00
int i , j ;
2006-09-17 20:22:47 +00:00
for ( i = 0 ; i < _gdi - > _numStrips ; i + + ) {
2003-09-08 21:03:31 +00:00
int strip = _screenStartStrip + i ;
clearGfxUsageBit ( strip , USAGE_BIT_DIRTY ) ;
clearGfxUsageBit ( strip , USAGE_BIT_RESTORED ) ;
for ( j = 1 ; j < _numActors ; j + + ) {
2008-09-25 10:11:06 +00:00
if ( _game . heversion ! = 0 & & ( ( ActorHE * ) _actors [ j ] ) - > _heFlags & 1 )
2006-07-10 10:14:10 +00:00
continue ;
2003-09-08 21:03:31 +00:00
if ( testGfxUsageBit ( strip , j ) & &
2006-12-25 15:03:36 +00:00
( ( _actors [ j ] - > _top ! = 0x7fffffff & & _actors [ j ] - > _needRedraw ) | | _actors [ j ] - > _needBgReset ) ) {
2003-09-08 21:03:31 +00:00
clearGfxUsageBit ( strip , j ) ;
2006-12-25 15:03:36 +00:00
if ( ( _actors [ j ] - > _bottom - _actors [ j ] - > _top ) > = 0 )
_gdi - > resetBackground ( _actors [ j ] - > _top , _actors [ j ] - > _bottom , i ) ;
2003-09-08 21:03:31 +00:00
}
}
}
for ( i = 1 ; i < _numActors ; i + + ) {
2006-12-25 15:03:36 +00:00
_actors [ i ] - > _needBgReset = false ;
2003-09-08 21:03:31 +00:00
}
}
2006-10-18 14:01:28 +00:00
// HE specific
2008-09-25 08:19:51 +00:00
void ActorHE : : drawActorToBackBuf ( int x , int y ) {
2006-10-18 14:01:28 +00:00
int curTop = _top ;
int curBottom = _bottom ;
2001-10-09 14:30:12 +00:00
2006-10-18 14:01:28 +00:00
_pos . x = x ;
_pos . y = y ;
2005-07-30 05:51:28 +00:00
2006-10-18 14:01:28 +00:00
_drawToBackBuf = true ;
_needRedraw = true ;
drawActorCostume ( ) ;
_drawToBackBuf = false ;
_needRedraw = true ;
drawActorCostume ( ) ;
_needRedraw = false ;
if ( _top > curTop )
_top = curTop ;
if ( _bottom < curBottom )
_bottom = curBottom ;
}
# pragma mark -
# pragma mark --- Actor talking ---
# pragma mark -
// V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses
// an internal variable. Emulate this to prevent overwriting script vars...
// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR
int ScummEngine : : getTalkingActor ( ) {
if ( _game . id = = GID_MANIAC & & _game . version < = 1 & & ! ( _game . platform = = Common : : kPlatformNES ) )
return _V1TalkingActor ;
else
return VAR ( VAR_TALK_ACTOR ) ;
}
2006-12-25 15:03:36 +00:00
void ScummEngine : : setTalkingActor ( int i ) {
2006-10-18 14:01:28 +00:00
2006-12-25 15:03:36 +00:00
if ( i = = 255 ) {
2006-10-18 14:01:28 +00:00
_system - > clearFocusRectangle ( ) ;
} else {
// Work out the screen co-ordinates of the actor
2006-12-25 15:03:36 +00:00
int x = _actors [ i ] - > getPos ( ) . x - ( camera . _cur . x - ( _screenWidth > > 1 ) ) ;
int y = _actors [ i ] - > _top - ( camera . _cur . y - ( _screenHeight > > 1 ) ) ;
2006-12-21 15:09:13 +00:00
2006-10-18 14:01:28 +00:00
// Set the focus area to the calculated position
// TODO: Make the size adjust depending on what it's focusing on.
2007-12-07 20:53:06 +00:00
_system - > setFocusRectangle ( Common : : Rect : : center ( x , y , 192 , 128 ) ) ;
2005-07-30 05:58:48 +00:00
}
2006-10-18 14:01:28 +00:00
if ( _game . id = = GID_MANIAC & & _game . version < = 1 & & ! ( _game . platform = = Common : : kPlatformNES ) )
2006-12-25 15:03:36 +00:00
_V1TalkingActor = i ;
2006-10-18 14:01:28 +00:00
else
2006-12-25 15:03:36 +00:00
VAR ( VAR_TALK_ACTOR ) = i ;
2005-07-30 05:58:48 +00:00
}
2012-02-04 18:34:08 +01:00
static const int v0MMActorTalkColor [ 25 ] = {
2006-10-18 14:01:28 +00:00
1 , 7 , 2 , 14 , 8 , 15 , 3 , 7 , 7 , 15 , 1 , 13 , 1 , 4 , 5 , 5 , 4 , 3 , 1 , 5 , 1 , 1 , 1 , 1 , 7
} ;
static const int v1MMActorTalkColor [ 25 ] = {
1 , 7 , 2 , 14 , 8 , 1 , 3 , 7 , 7 , 12 , 1 , 13 , 1 , 4 , 5 , 5 , 4 , 3 , 1 , 5 , 1 , 1 , 1 , 7 , 7
} ;
2005-07-30 05:58:48 +00:00
2006-10-18 14:01:28 +00:00
void ScummEngine : : resetV1ActorTalkColor ( ) {
int i ;
2005-07-30 05:58:48 +00:00
for ( i = 1 ; i < _numActors ; i + + ) {
2007-02-25 07:23:52 +00:00
if ( _game . version = = 0 ) {
2012-02-04 18:34:08 +01:00
_actors [ i ] - > _talkColor = v0MMActorTalkColor [ i ] ;
2006-10-18 14:01:28 +00:00
} else {
2006-12-25 15:03:36 +00:00
_actors [ i ] - > _talkColor = v1MMActorTalkColor [ i ] ;
2006-10-18 14:01:28 +00:00
}
2001-10-09 14:30:12 +00:00
}
}
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_SCUMM_7_8
2005-04-28 22:17:23 +00:00
void ScummEngine_v7 : : actorTalk ( const byte * msg ) {
2005-06-04 06:18:28 +00:00
Actor * a ;
2007-04-15 22:14:06 +00:00
bool stringWrap = false ;
2005-04-28 22:17:23 +00:00
2005-06-04 06:18:28 +00:00
convertMessageToString ( msg , _charsetBuffer , sizeof ( _charsetBuffer ) ) ;
2005-07-30 21:11:48 +00:00
2005-04-28 22:17:23 +00:00
// Play associated speech, if any
playSpeech ( ( byte * ) _lastStringTag ) ;
2005-06-04 06:18:28 +00:00
2008-04-30 12:54:07 +00:00
if ( _game . id = = GID_DIG | | _game . id = = GID_CMI ) {
if ( VAR ( VAR_HAVE_MSG ) )
stopTalk ( ) ;
} else {
if ( ! _keepText )
stopTalk ( ) ;
2005-10-31 19:48:48 +00:00
}
2005-06-04 06:18:28 +00:00
if ( _actorToPrintStrFor = = 0xFF ) {
setTalkingActor ( 0xFF ) ;
2007-04-15 20:45:55 +00:00
_charsetColor = ( byte ) _string [ 0 ] . color ;
2005-06-04 06:18:28 +00:00
} else {
a = derefActor ( _actorToPrintStrFor , " actorTalk " ) ;
setTalkingActor ( a - > _number ) ;
if ( ! _string [ 0 ] . no_talk_anim ) {
a - > runActorTalkScript ( a - > _talkStartFrame ) ;
}
_charsetColor = a - > _talkColor ;
}
2007-04-15 20:45:55 +00:00
2005-06-04 06:18:28 +00:00
_charsetBufPos = 0 ;
_talkDelay = 0 ;
2005-11-02 21:47:44 +00:00
_haveMsg = 1 ;
2008-04-30 04:42:53 +00:00
if ( _game . id = = GID_FT )
2005-06-04 06:18:28 +00:00
VAR ( VAR_HAVE_MSG ) = 0xFF ;
2010-12-28 06:05:57 +00:00
_haveActorSpeechMsg = ( _game . id = = GID_FT ) ? true : ( ! _sound - > isSoundRunning ( kTalkSoundID ) ) ;
2008-04-30 04:38:29 +00:00
if ( _game . id = = GID_DIG | | _game . id = = GID_CMI ) {
2007-04-15 20:36:44 +00:00
stringWrap = _string [ 0 ] . wrapping ;
_string [ 0 ] . wrapping = true ;
}
2005-06-04 06:18:28 +00:00
CHARSET_1 ( ) ;
2008-04-30 04:38:29 +00:00
if ( _game . id = = GID_DIG | | _game . id = = GID_CMI ) {
if ( _game . version = = 8 )
VAR ( VAR_HAVE_MSG ) = ( _string [ 0 ] . no_talk_anim ) ? 2 : 1 ;
else
VAR ( VAR_HAVE_MSG ) = 1 ;
2007-04-15 20:36:44 +00:00
_string [ 0 ] . wrapping = stringWrap ;
}
2005-04-28 22:17:23 +00:00
}
2005-05-14 22:56:41 +00:00
# endif
2005-04-28 22:17:23 +00:00
2004-03-15 03:09:48 +00:00
void ScummEngine : : actorTalk ( const byte * msg ) {
2001-10-09 14:30:12 +00:00
Actor * a ;
2005-05-26 14:14:32 +00:00
convertMessageToString ( msg , _charsetBuffer , sizeof ( _charsetBuffer ) ) ;
2005-07-30 21:11:48 +00:00
2007-09-11 09:20:39 +00:00
// WORKAROUND for bugs #770039 and #770049
2006-02-20 16:51:30 +00:00
if ( _game . id = = GID_LOOM ) {
2004-01-08 14:41:14 +00:00
if ( ! * _charsetBuffer )
return ;
}
2002-04-11 17:19:16 +00:00
if ( _actorToPrintStrFor = = 0xFF ) {
2005-10-31 19:48:48 +00:00
if ( ! _keepText ) {
2001-10-09 14:30:12 +00:00
stopTalk ( ) ;
2004-07-16 03:39:23 +00:00
}
2004-03-15 03:33:08 +00:00
setTalkingActor ( 0xFF ) ;
2001-10-09 14:30:12 +00:00
} else {
2003-05-13 23:03:18 +00:00
int oldact ;
2005-07-30 21:11:48 +00:00
2006-01-22 20:46:51 +00:00
// WORKAROUND bug #770724
2006-02-20 16:51:30 +00:00
if ( _game . id = = GID_LOOM & & _roomResource = = 23 & &
2003-07-15 19:09:11 +00:00
vm . slot [ _currentScript ] . number = = 232 & & _actorToPrintStrFor = = 0 ) {
_actorToPrintStrFor = 2 ; // Could be anything from 2 to 5. Maybe compare to original?
}
2005-07-30 21:11:48 +00:00
2003-05-23 12:48:50 +00:00
a = derefActor ( _actorToPrintStrFor , " actorTalk " ) ;
2005-10-31 19:48:48 +00:00
if ( ! a - > isInCurrentRoom ( ) ) {
2001-10-09 14:30:12 +00:00
oldact = 0xFF ;
} else {
2005-10-31 19:48:48 +00:00
if ( ! _keepText ) {
2001-10-09 14:30:12 +00:00
stopTalk ( ) ;
2005-10-31 19:48:48 +00:00
}
2005-03-11 01:10:06 +00:00
setTalkingActor ( a - > _number ) ;
2008-09-25 10:11:06 +00:00
if ( _game . heversion ! = 0 )
( ( ActorHE * ) a ) - > _heTalking = true ;
2004-08-05 20:14:43 +00:00
if ( ! _string [ 0 ] . no_talk_anim ) {
2004-09-28 19:28:59 +00:00
a - > runActorTalkScript ( a - > _talkStartFrame ) ;
2001-11-05 19:21:49 +00:00
_useTalkAnims = true ;
}
2004-03-15 03:33:08 +00:00
oldact = getTalkingActor ( ) ;
2001-10-09 14:30:12 +00:00
}
2003-05-13 23:03:18 +00:00
if ( oldact > = 0x80 )
return ;
2001-10-09 14:30:12 +00:00
}
2002-04-11 17:19:16 +00:00
2006-02-20 16:51:30 +00:00
if ( _game . heversion > = 72 | | getTalkingActor ( ) > 0x7F ) {
2002-09-22 01:17:53 +00:00
_charsetColor = ( byte ) _string [ 0 ] . color ;
2006-02-20 16:51:30 +00:00
} else if ( _game . platform = = Common : : kPlatformNES ) {
2005-03-25 00:37:14 +00:00
if ( _NES_lastTalkingActor ! = getTalkingActor ( ) )
_NES_talkColor ^ = 1 ;
_NES_lastTalkingActor = getTalkingActor ( ) ;
_charsetColor = _NES_talkColor ;
2001-10-09 14:30:12 +00:00
} else {
2004-03-15 03:33:08 +00:00
a = derefActor ( getTalkingActor ( ) , " actorTalk(2) " ) ;
2005-03-11 01:10:06 +00:00
_charsetColor = a - > _talkColor ;
2001-10-09 14:30:12 +00:00
}
2002-12-26 00:21:19 +00:00
_charsetBufPos = 0 ;
2001-10-09 14:30:12 +00:00
_talkDelay = 0 ;
_haveMsg = 0xFF ;
2005-10-31 19:48:48 +00:00
VAR ( VAR_HAVE_MSG ) = 0xFF ;
2003-05-14 13:30:52 +00:00
if ( VAR_CHARCOUNT ! = 0xFF )
VAR ( VAR_CHARCOUNT ) = 0 ;
2005-11-02 21:47:44 +00:00
_haveActorSpeechMsg = true ;
2001-10-09 14:30:12 +00:00
CHARSET_1 ( ) ;
}
2004-07-15 12:26:10 +00:00
void Actor : : runActorTalkScript ( int f ) {
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . version = = 8 & & _vm - > VAR ( _vm - > VAR_HAVE_MSG ) = = 2 )
2004-07-16 03:39:23 +00:00
return ;
2008-04-30 12:54:07 +00:00
if ( _vm - > _game . id = = GID_FT & & _vm - > _string [ 0 ] . no_talk_anim )
return ;
if ( ! _vm - > getTalkingActor ( ) | | _room ! = _vm - > _currentRoom | | _frame = = f )
return ;
2005-03-11 01:10:06 +00:00
if ( _talkScript ) {
int script = _talkScript ;
2017-11-29 18:41:42 -06:00
int args [ NUM_SCRIPT_LOCAL ] ;
2004-07-15 12:26:10 +00:00
memset ( args , 0 , sizeof ( args ) ) ;
args [ 1 ] = f ;
2005-03-11 01:10:06 +00:00
args [ 0 ] = _number ;
2004-07-15 12:26:10 +00:00
_vm - > runScript ( script , 1 , 0 , args ) ;
2004-07-16 03:39:23 +00:00
} else {
2008-04-30 12:54:07 +00:00
startAnimActor ( f ) ;
2004-07-16 03:39:23 +00:00
}
2004-07-15 12:26:10 +00:00
}
2003-10-02 22:42:03 +00:00
void ScummEngine : : stopTalk ( ) {
2003-05-13 23:03:18 +00:00
int act ;
_sound - > stopTalkSound ( ) ;
_haveMsg = 0 ;
_talkDelay = 0 ;
2004-03-15 03:33:08 +00:00
act = getTalkingActor ( ) ;
2003-05-13 23:03:18 +00:00
if ( act & & act < 0x80 ) {
2003-05-23 12:48:50 +00:00
Actor * a = derefActor ( act , " stopTalk " ) ;
2006-02-20 16:51:30 +00:00
if ( ( _game . version > = 7 & & ! _string [ 0 ] . no_talk_anim ) | |
( _game . version < = 6 & & a - > isInCurrentRoom ( ) & & _useTalkAnims ) ) {
2004-09-28 19:28:59 +00:00
a - > runActorTalkScript ( a - > _talkStopFrame ) ;
_useTalkAnims = false ;
2003-05-13 23:03:18 +00:00
}
2006-02-20 16:51:30 +00:00
if ( _game . version < = 7 & & _game . heversion = = 0 )
2004-03-15 03:33:08 +00:00
setTalkingActor ( 0xFF ) ;
2008-09-25 10:11:06 +00:00
if ( _game . heversion ! = 0 )
( ( ActorHE * ) a ) - > _heTalking = false ;
2003-05-13 23:03:18 +00:00
}
2008-04-30 12:54:07 +00:00
if ( _game . id = = GID_DIG | | _game . id = = GID_CMI ) {
2004-03-15 03:33:08 +00:00
setTalkingActor ( 0 ) ;
2004-07-16 03:39:23 +00:00
VAR ( VAR_HAVE_MSG ) = 0 ;
2008-04-30 12:54:07 +00:00
} else if ( _game . heversion > = 60 ) {
setTalkingActor ( 0 ) ;
}
2003-05-13 23:03:18 +00:00
_keepText = false ;
2006-02-20 16:51:30 +00:00
if ( _game . version > = 7 ) {
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_SCUMM_7_8
2005-11-02 21:47:44 +00:00
( ( ScummEngine_v7 * ) this ) - > clearSubtitleQueue ( ) ;
# endif
} else {
2010-10-05 19:04:52 +00:00
# ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
SCUMM/FM-TOWNS: fix palette and other graphics issues
This commit should fix at least the following bugs/feature requests: #1032859, #1252088, #1055391, #1315968, #1315938, #1742106, #812891.
The FM-Towns version of Scumm games use a mixed graphics mode with 2 layers (one with 32767 colors and one with 16 colors). Among other things I have added a screen output class which emulates this dual layer approach which allows specific hardware effects like enabling and disabling layers (e.g. in the voodoo priestess scene in MI1).
Old savegames (saved before this update) will load, but you’ll encounter palette glitches in the verb/inventory screen, since the 16 color palette for layer 2 is not contained in your savegame. This will be true at least for version 5 games. Certain scene change actions (which require the verb/inventory part to be redrawn) might correct this (e.g. try looking at the treasure map in MI1 and closing it). Version 3 games should be okay, since they use a static text palette which is never changed and which will be reset after loading a savegame.
This update requires a USE_RGB_COLORS setting for proper operation. 8 bit users will get a warning that they’ll have to expect palette glitches . Apart from that the engine in 8 bit mode should not only still work okay, but also benefit from some of the other (non palette related) improvements (e.g. bug #1032859 should be fixed even in 8 bit mode).
Japanese font drawing hasn’t been improved much yet. This will be a separate task.
svn-id: r52966
2010-10-01 19:24:52 +00:00
if ( _game . platform = = Common : : kPlatformFMTowns )
towns_restoreCharsetBg ( ) ;
else
2010-10-05 19:04:52 +00:00
# endif
SCUMM/FM-TOWNS: fix palette and other graphics issues
This commit should fix at least the following bugs/feature requests: #1032859, #1252088, #1055391, #1315968, #1315938, #1742106, #812891.
The FM-Towns version of Scumm games use a mixed graphics mode with 2 layers (one with 32767 colors and one with 16 colors). Among other things I have added a screen output class which emulates this dual layer approach which allows specific hardware effects like enabling and disabling layers (e.g. in the voodoo priestess scene in MI1).
Old savegames (saved before this update) will load, but you’ll encounter palette glitches in the verb/inventory screen, since the 16 color palette for layer 2 is not contained in your savegame. This will be true at least for version 5 games. Certain scene change actions (which require the verb/inventory part to be redrawn) might correct this (e.g. try looking at the treasure map in MI1 and closing it). Version 3 games should be okay, since they use a static text palette which is never changed and which will be reset after loading a savegame.
This update requires a USE_RGB_COLORS setting for proper operation. 8 bit users will get a warning that they’ll have to expect palette glitches . Apart from that the engine in 8 bit mode should not only still work okay, but also benefit from some of the other (non palette related) improvements (e.g. bug #1032859 should be fixed even in 8 bit mode).
Japanese font drawing hasn’t been improved much yet. This will be a separate task.
svn-id: r52966
2010-10-01 19:24:52 +00:00
restoreCharsetBg ( ) ;
2005-11-02 21:47:44 +00:00
}
2003-05-13 23:03:18 +00:00
}
2006-10-18 14:01:28 +00:00
# pragma mark -
# pragma mark --- TODO ---
# pragma mark -
2008-09-25 10:11:06 +00:00
void ActorHE : : setActorCostume ( int c ) {
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . heversion > = 61 & & ( c = = - 1 | | c = = - 2 ) ) {
2005-03-11 01:10:06 +00:00
_heSkipLimbs = ( c = = - 1 ) ;
_needRedraw = true ;
2004-01-12 14:09:39 +00:00
return ;
}
2004-07-03 03:06:15 +00:00
// Based on disassembly. It seems that high byte is not used at all, though
// it is attached to all horizontally flipped object, like left eye.
2010-04-04 09:36:10 +00:00
if ( _vm - > _game . heversion > = 61 & & _vm - > _game . heversion < = 62 )
2004-07-03 03:06:15 +00:00
c & = 0xff ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . features & GF_NEW_COSTUMES ) {
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_HE
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . heversion > = 71 )
2005-05-15 09:46:34 +00:00
( ( ScummEngine_v71he * ) _vm ) - > queueAuxBlock ( this ) ;
2005-05-15 19:27:46 +00:00
# endif
2008-09-25 10:11:06 +00:00
_auxBlock . reset ( ) ;
if ( _visible ) {
if ( _vm - > _game . heversion > = 60 )
_needRedraw = true ;
}
}
Actor : : setActorCostume ( c ) ;
if ( _vm - > _game . heversion > = 71 & & _vm - > getTalkingActor ( ) = = _number ) {
if ( _vm - > _game . heversion < = 95 | | ( _vm - > _game . heversion > = 98 & & _vm - > VAR ( _vm - > VAR_SKIP_RESET_TALK_ACTOR ) = = 0 ) ) {
_vm - > setTalkingActor ( 0 ) ;
}
}
}
void Actor : : setActorCostume ( int c ) {
int i ;
_costumeNeedsInit = true ;
if ( _vm - > _game . features & GF_NEW_COSTUMES ) {
memset ( _animVariable , 0 , sizeof ( _animVariable ) ) ;
2005-07-30 21:11:48 +00:00
2005-04-27 13:55:55 +00:00
_costume = c ;
_cost . reset ( ) ;
2005-03-11 01:10:06 +00:00
if ( _visible ) {
if ( _costume ) {
_vm - > ensureResourceLoaded ( rtCostume , _costume ) ;
2003-07-25 18:07:42 +00:00
}
2004-09-28 19:28:59 +00:00
startAnimActor ( _initFrame ) ;
2003-07-25 18:07:42 +00:00
}
2001-10-09 14:30:12 +00:00
} else {
2005-03-11 01:10:06 +00:00
if ( _visible ) {
2003-07-25 18:07:42 +00:00
hideActor ( ) ;
2005-03-11 01:10:06 +00:00
_cost . reset ( ) ;
_costume = c ;
2003-07-25 18:07:42 +00:00
showActor ( ) ;
} else {
2005-03-11 01:10:06 +00:00
_costume = c ;
_cost . reset ( ) ;
2003-07-25 18:07:42 +00:00
}
2001-10-09 14:30:12 +00:00
}
2003-07-25 18:07:42 +00:00
2003-08-23 15:16:07 +00:00
// V1 zak uses palette[] as a dynamic costume color array.
2006-05-29 12:45:11 +00:00
if ( _vm - > _game . version < = 1 )
2003-08-20 12:04:25 +00:00
return ;
2006-02-20 16:51:30 +00:00
if ( _vm - > _game . features & GF_NEW_COSTUMES ) {
2002-11-10 17:17:11 +00:00
for ( i = 0 ; i < 256 ; i + + )
2005-03-11 01:10:06 +00:00
_palette [ i ] = 0xFF ;
2006-02-20 16:51:30 +00:00
} else if ( _vm - > _game . features & GF_OLD_BUNDLE ) {
2003-04-16 07:11:04 +00:00
for ( i = 0 ; i < 16 ; i + + )
2005-03-11 01:10:06 +00:00
_palette [ i ] = i ;
2005-02-20 00:17:22 +00:00
// Make stuff more visible on CGA. Based on disassembly
2006-02-20 16:51:30 +00:00
if ( _vm - > _renderMode = = Common : : kRenderCGA & & _vm - > _game . version > 2 ) {
2005-03-11 01:10:06 +00:00
_palette [ 6 ] = 5 ;
_palette [ 7 ] = 15 ;
2005-02-20 00:17:22 +00:00
}
2002-11-10 17:17:11 +00:00
} else {
for ( i = 0 ; i < 32 ; i + + )
2005-03-11 01:10:06 +00:00
_palette [ i ] = 0xFF ;
2002-11-10 17:17:11 +00:00
}
2001-10-09 14:30:12 +00:00
}
2011-09-08 20:13:13 +02:00
static const char * const v0ActorNames_English [ 25 ] = {
2007-03-06 07:09:18 +00:00
" Syd " ,
" Razor " ,
" Dave " ,
" Michael " ,
" Bernard " ,
" Wendy " ,
2009-07-25 05:39:57 +00:00
" Jeff " ,
2011-12-26 20:58:03 +01:00
" " , // Radiation Suit
2009-07-25 05:39:57 +00:00
" Dr Fred " ,
" Nurse Edna " ,
" Weird Ed " ,
" Dead Cousin Ted " ,
" Purple Tentacle " ,
" Green Tentacle " ,
2011-12-26 20:58:03 +01:00
" " , // Meteor Police
2009-07-25 05:39:57 +00:00
" Meteor " ,
2011-12-26 20:58:03 +01:00
" " , // Mark Eteer
" " , // Talkshow Host
2010-10-25 10:35:52 +00:00
" Plant " ,
2011-12-26 20:58:03 +01:00
" " , // Meteor Radiation
" " , // Edsel (small, outro)
" " , // Meteor (small, intro)
" Sandy " , // (Lab)
" " , // Sandy (Cut-Scene)
2007-03-06 07:09:18 +00:00
} ;
2011-09-08 20:13:13 +02:00
static const char * const v0ActorNames_German [ 25 ] = {
2010-10-25 05:26:16 +00:00
" Syd " ,
" Razor " ,
" Dave " ,
" Michael " ,
" Bernard " ,
" Wendy " ,
" Jeff " ,
" " ,
" Dr.Fred " ,
" Schwester Edna " ,
" Weird Ed " ,
" Ted " ,
" Lila Tentakel " ,
" Gr<nes Tentakel " ,
" " ,
2011-12-26 20:58:03 +01:00
" Meteor " ,
2010-10-25 05:26:16 +00:00
" " ,
" " ,
2010-10-25 10:35:52 +00:00
" Pflanze " ,
2010-10-25 05:26:16 +00:00
" " ,
" " ,
" " ,
2011-12-26 20:58:03 +01:00
" Sandy " ,
" " ,
2010-10-25 05:26:16 +00:00
} ;
2007-03-06 07:09:18 +00:00
const byte * Actor : : getActorName ( ) {
2009-07-25 05:39:57 +00:00
const byte * ptr = NULL ;
2007-03-06 07:09:18 +00:00
if ( _vm - > _game . version = = 0 ) {
2010-10-25 05:26:16 +00:00
if ( _number ) {
switch ( _vm - > _language ) {
case Common : : DE_DEU :
ptr = ( const byte * ) v0ActorNames_German [ _number - 1 ] ;
break ;
default :
ptr = ( const byte * ) v0ActorNames_English [ _number - 1 ] ;
}
}
2007-03-06 07:09:18 +00:00
} else {
2008-01-28 00:14:17 +00:00
ptr = _vm - > getResourceAddress ( rtActorName , _number ) ;
2007-03-06 07:09:18 +00:00
}
2003-05-21 18:09:49 +00:00
if ( ptr = = NULL ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Failed to find name of actor %d " , _number ) ;
2003-05-21 18:09:49 +00:00
}
2002-07-15 21:50:51 +00:00
return ptr ;
}
2005-04-10 12:59:17 +00:00
int Actor : : getAnimVar ( byte var ) const {
2006-09-16 13:38:43 +00:00
assertRange ( 0 , var , 26 , " getAnimVar: " ) ;
2005-04-10 12:59:17 +00:00
return _animVariable [ var ] ;
}
void Actor : : setAnimVar ( byte var , int value ) {
2006-09-16 13:38:43 +00:00
assertRange ( 0 , var , 26 , " setAnimVar: " ) ;
2005-04-10 12:59:17 +00:00
_animVariable [ var ] = value ;
}
2004-01-16 01:52:49 +00:00
void Actor : : remapActorPaletteColor ( int color , int new_color ) {
const byte * akos , * akpl ;
int akpl_size , i ;
byte akpl_color ;
2005-03-11 01:10:06 +00:00
akos = _vm - > getResourceAddress ( rtCostume , _costume ) ;
2004-01-16 01:52:49 +00:00
if ( ! akos ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPaletteColor: Can't remap actor %d, costume %d not found " , _number , _costume ) ;
2004-01-16 01:52:49 +00:00
return ;
}
2011-04-12 16:53:15 +02:00
akpl = _vm - > findResourceData ( MKTAG ( ' A ' , ' K ' , ' P ' , ' L ' ) , akos ) ;
2004-01-16 01:52:49 +00:00
if ( ! akpl ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPaletteColor: Can't remap actor %d, costume %d doesn't contain an AKPL block " , _number , _costume ) ;
2004-01-16 01:52:49 +00:00
return ;
}
2004-09-21 12:57:38 +00:00
// Get the number palette entries
akpl_size = _vm - > getResourceDataSize ( akpl ) ;
2004-01-16 01:52:49 +00:00
for ( i = 0 ; i < akpl_size ; i + + ) {
akpl_color = * akpl + + ;
if ( akpl_color = = color ) {
2005-03-11 01:10:06 +00:00
_palette [ i ] = new_color ;
2004-01-16 01:52:49 +00:00
return ;
}
}
}
2003-03-06 17:58:13 +00:00
void Actor : : remapActorPalette ( int r_fact , int g_fact , int b_fact , int threshold ) {
2003-05-28 20:01:47 +00:00
const byte * akos , * rgbs , * akpl ;
2002-07-15 21:50:51 +00:00
int akpl_size , i ;
int r , g , b ;
byte akpl_color ;
2004-07-04 03:25:24 +00:00
if ( ! isInCurrentRoom ( ) ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPalette: Actor %d not in current room " , _number ) ;
2002-07-15 21:50:51 +00:00
return ;
2004-07-04 03:25:24 +00:00
}
2002-07-15 21:50:51 +00:00
2005-03-11 01:10:06 +00:00
akos = _vm - > getResourceAddress ( rtCostume , _costume ) ;
2002-10-02 09:14:59 +00:00
if ( ! akos ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPalette: Can't remap actor %d, costume %d not found " , _number , _costume ) ;
2002-10-02 09:14:59 +00:00
return ;
}
2011-04-12 16:53:15 +02:00
akpl = _vm - > findResourceData ( MKTAG ( ' A ' , ' K ' , ' P ' , ' L ' ) , akos ) ;
2002-10-02 09:14:59 +00:00
if ( ! akpl ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPalette: Can't remap actor %d, costume %d doesn't contain an AKPL block " , _number , _costume ) ;
2002-10-02 09:14:59 +00:00
return ;
}
2002-07-15 21:50:51 +00:00
2004-09-21 12:57:38 +00:00
// Get the number palette entries
akpl_size = _vm - > getResourceDataSize ( akpl ) ;
2002-07-15 21:50:51 +00:00
2011-04-12 16:53:15 +02:00
rgbs = _vm - > findResourceData ( MKTAG ( ' R ' , ' G ' , ' B ' , ' S ' ) , akos ) ;
2002-07-15 21:50:51 +00:00
if ( ! rgbs ) {
2006-09-16 12:43:18 +00:00
debugC ( DEBUG_ACTORS , " Actor::remapActorPalette: Can't remap actor %d costume %d doesn't contain an RGB block " , _number , _costume ) ;
2002-07-15 21:50:51 +00:00
return ;
}
for ( i = 0 ; i < akpl_size ; i + + ) {
r = * rgbs + + ;
g = * rgbs + + ;
b = * rgbs + + ;
akpl_color = * akpl + + ;
// allow remap of generic palette entry?
2004-09-28 19:28:59 +00:00
if ( ! _shadowMode | | akpl_color > = 16 ) {
2004-09-21 13:54:30 +00:00
r = ( r * r_fact ) > > 8 ;
g = ( g * g_fact ) > > 8 ;
b = ( b * b_fact ) > > 8 ;
2005-03-11 01:10:06 +00:00
_palette [ i ] = _vm - > remapPaletteColor ( r , g , b , threshold ) ;
2002-07-15 21:50:51 +00:00
}
}
}
2003-03-06 17:58:13 +00:00
void Actor : : classChanged ( int cls , bool value ) {
2003-05-20 20:42:28 +00:00
if ( cls = = kObjectClassAlwaysClip )
2005-03-11 01:10:06 +00:00
_forceClip = value ;
2003-05-20 20:42:28 +00:00
if ( cls = = kObjectClassIgnoreBoxes )
2005-03-11 01:10:06 +00:00
_ignoreBoxes = value ;
2002-07-26 16:13:04 +00:00
}
2003-03-06 17:58:13 +00:00
bool Actor : : isInClass ( int cls ) {
2005-03-11 01:10:06 +00:00
return _vm - > getClass ( _number , cls ) ;
2002-07-15 22:56:24 +00:00
}
2003-05-22 00:51:42 +00:00
bool Actor : : isPlayer ( ) {
2007-03-10 13:53:11 +00:00
return isInClass ( kObjectClassPlayer ) ;
}
bool Actor_v2 : : isPlayer ( ) {
2012-02-04 14:49:44 +01:00
// isPlayer() is not supported by v0
2012-01-29 06:35:57 +01:00
assert ( _vm - > _game . version ! = 0 ) ;
2007-03-10 13:53:11 +00:00
return _vm - > VAR ( 42 ) < = _number & & _number < = _vm - > VAR ( 43 ) ;
2003-05-22 00:51:42 +00:00
}
2008-09-25 10:11:06 +00:00
void ActorHE : : setHEFlag ( int bit , int set ) {
2006-07-10 10:14:10 +00:00
// Note that condition is inverted
if ( ! set ) {
_heFlags | = bit ;
} else {
_heFlags & = ~ bit ;
}
}
2008-09-25 10:11:06 +00:00
void ActorHE : : setUserCondition ( int slot , int set ) {
2006-07-06 11:17:14 +00:00
const int condMaskCode = ( _vm - > _game . heversion > = 85 ) ? 0x1FFF : 0x3FF ;
2006-09-16 13:38:43 +00:00
assertRange ( 1 , slot , 32 , " setUserCondition: Condition " ) ;
2004-09-08 21:14:12 +00:00
if ( set = = 0 ) {
2005-03-11 01:10:06 +00:00
_heCondMask & = ~ ( 1 < < ( slot + 0xF ) ) ;
2004-09-08 21:14:12 +00:00
} else {
2005-03-11 01:10:06 +00:00
_heCondMask | = 1 < < ( slot + 0xF ) ;
2004-09-08 21:14:12 +00:00
}
2006-01-06 10:14:59 +00:00
if ( _heCondMask & condMaskCode ) {
2005-03-11 01:10:06 +00:00
_heCondMask & = ~ 1 ;
2004-09-08 21:14:12 +00:00
} else {
2005-03-11 01:10:06 +00:00
_heCondMask | = 1 ;
2004-09-08 21:14:12 +00:00
}
}
2008-09-25 10:11:06 +00:00
bool ActorHE : : isUserConditionSet ( int slot ) const {
2006-09-16 13:38:43 +00:00
assertRange ( 1 , slot , 32 , " isUserConditionSet: Condition " ) ;
2005-03-11 01:10:06 +00:00
return ( _heCondMask & ( 1 < < ( slot + 0xF ) ) ) ! = 0 ;
2004-09-08 21:14:12 +00:00
}
2008-09-25 10:11:06 +00:00
void ActorHE : : setTalkCondition ( int slot ) {
2006-07-06 11:17:14 +00:00
const int condMaskCode = ( _vm - > _game . heversion > = 85 ) ? 0x1FFF : 0x3FF ;
2006-09-16 13:38:43 +00:00
assertRange ( 1 , slot , 32 , " setTalkCondition: Condition " ) ;
2006-01-06 10:14:59 +00:00
_heCondMask = ( _heCondMask & ~ condMaskCode ) | 1 ;
2004-09-08 21:14:12 +00:00
if ( slot ! = 1 ) {
2005-03-11 01:10:06 +00:00
_heCondMask | = 1 < < ( slot - 1 ) ;
2006-01-06 10:14:59 +00:00
if ( _heCondMask & condMaskCode ) {
2005-03-11 01:10:06 +00:00
_heCondMask & = ~ 1 ;
2004-09-08 21:14:12 +00:00
} else {
2005-03-11 01:10:06 +00:00
_heCondMask | = 1 ;
2004-09-08 21:14:12 +00:00
}
2005-07-30 21:11:48 +00:00
}
2004-09-08 21:14:12 +00:00
}
2008-09-25 10:11:06 +00:00
bool ActorHE : : isTalkConditionSet ( int slot ) const {
2006-09-16 13:38:43 +00:00
assertRange ( 1 , slot , 32 , " isTalkConditionSet: Condition " ) ;
2005-03-11 01:10:06 +00:00
return ( _heCondMask & ( 1 < < ( slot - 1 ) ) ) ! = 0 ;
2004-09-08 21:14:12 +00:00
}
2008-05-06 03:00:26 +00:00
# ifdef ENABLE_HE
2005-04-29 01:36:30 +00:00
void ScummEngine_v71he : : preProcessAuxQueue ( ) {
2004-09-18 00:36:17 +00:00
if ( ! _skipProcessActors ) {
for ( int i = 0 ; i < _auxBlocksNum ; + + i ) {
AuxBlock * ab = & _auxBlocks [ i ] ;
2005-11-05 00:11:49 +00:00
if ( ab - > r . top < = ab - > r . bottom ) {
2006-09-17 23:35:09 +00:00
restoreBackgroundHE ( ab - > r ) ;
2004-09-18 00:36:17 +00:00
}
}
}
_auxBlocksNum = 0 ;
}
2005-04-29 01:36:30 +00:00
void ScummEngine_v71he : : postProcessAuxQueue ( ) {
2004-09-18 00:36:17 +00:00
if ( ! _skipProcessActors ) {
for ( int i = 0 ; i < _auxEntriesNum ; + + i ) {
AuxEntry * ae = & _auxEntries [ i ] ;
if ( ae - > actorNum ! = - 1 ) {
2008-09-25 08:06:18 +00:00
ActorHE * a = ( ActorHE * ) derefActor ( ae - > actorNum , " postProcessAuxQueue " ) ;
2005-03-11 01:10:06 +00:00
const uint8 * cost = getResourceAddress ( rtCostume , a - > _costume ) ;
2008-09-25 08:06:18 +00:00
int dy = a - > _heOffsY + a - > getPos ( ) . y ;
int dx = a - > _heOffsX + a - > getPos ( ) . x ;
2004-09-18 00:36:17 +00:00
2007-05-21 13:45:38 +00:00
if ( _game . heversion > = 72 )
dy - = a - > getElevation ( ) ;
2011-04-12 16:53:15 +02:00
const uint8 * akax = findResource ( MKTAG ( ' A ' , ' K ' , ' A ' , ' X ' ) , cost ) ;
2004-09-21 20:21:31 +00:00
assert ( akax ) ;
2004-09-18 00:36:17 +00:00
const uint8 * auxd = findPalInPals ( akax , ae - > subIndex ) - _resourceHeaderSize ;
2004-09-21 20:21:31 +00:00
assert ( auxd ) ;
2011-04-12 16:53:15 +02:00
const uint8 * frel = findResourceData ( MKTAG ( ' F ' , ' R ' , ' E ' , ' L ' ) , auxd ) ;
2004-09-21 21:10:23 +00:00
if ( frel ) {
2005-03-30 03:36:31 +00:00
error ( " unhandled FREL block " ) ;
2004-09-21 21:10:23 +00:00
}
2011-04-12 16:53:15 +02:00
const uint8 * disp = findResourceData ( MKTAG ( ' D ' , ' I ' , ' S ' , ' P ' ) , auxd ) ;
2004-09-21 21:10:23 +00:00
if ( disp ) {
2005-03-30 03:36:31 +00:00
error ( " unhandled DISP block " ) ;
2004-09-21 21:10:23 +00:00
}
2011-04-12 16:53:15 +02:00
const uint8 * axfd = findResourceData ( MKTAG ( ' A ' , ' X ' , ' F ' , ' D ' ) , auxd ) ;
2004-09-21 20:21:31 +00:00
assert ( axfd ) ;
uint16 comp = READ_LE_UINT16 ( axfd ) ;
if ( comp ! = 0 ) {
int x = ( int16 ) READ_LE_UINT16 ( axfd + 2 ) + dx ;
int y = ( int16 ) READ_LE_UINT16 ( axfd + 4 ) + dy ;
int w = ( int16 ) READ_LE_UINT16 ( axfd + 6 ) ;
int h = ( int16 ) READ_LE_UINT16 ( axfd + 8 ) ;
2007-09-08 11:15:27 +00:00
VirtScreen * pvs = & _virtscr [ kMainVirtScreen ] ;
2004-09-21 20:21:31 +00:00
uint8 * dst1 = pvs - > getPixels ( 0 , pvs - > topline ) ;
uint8 * dst2 = pvs - > getBackPixels ( 0 , pvs - > topline ) ;
switch ( comp ) {
case 1 :
2009-09-25 09:13:33 +00:00
Wiz : : copyAuxImage ( dst1 , dst2 , axfd + 10 , pvs - > pitch , pvs - > h , x , y , w , h , _bytesPerPixel ) ;
2004-09-21 20:21:31 +00:00
break ;
default :
2005-03-30 03:36:31 +00:00
error ( " unimplemented compression type %d " , comp ) ;
2004-09-18 00:36:17 +00:00
}
}
2011-04-12 16:53:15 +02:00
const uint8 * axur = findResourceData ( MKTAG ( ' A ' , ' X ' , ' U ' , ' R ' ) , auxd ) ;
2004-09-18 00:36:17 +00:00
if ( axur ) {
uint16 n = READ_LE_UINT16 ( axur ) ; axur + = 2 ;
while ( n - - ) {
2004-09-20 18:27:13 +00:00
int x1 = ( int16 ) READ_LE_UINT16 ( axur + 0 ) + dx ;
int y1 = ( int16 ) READ_LE_UINT16 ( axur + 2 ) + dy ;
int x2 = ( int16 ) READ_LE_UINT16 ( axur + 4 ) + dx ;
2005-07-30 21:11:48 +00:00
int y2 = ( int16 ) READ_LE_UINT16 ( axur + 6 ) + dy ;
2005-04-27 13:55:55 +00:00
markRectAsDirty ( kMainVirtScreen , x1 , x2 , y1 , y2 + 1 ) ;
2004-09-18 00:36:17 +00:00
axur + = 8 ;
}
}
2011-04-12 16:53:15 +02:00
const uint8 * axer = findResourceData ( MKTAG ( ' A ' , ' X ' , ' E ' , ' R ' ) , auxd ) ;
2004-09-18 00:36:17 +00:00
if ( axer ) {
2005-03-11 01:10:06 +00:00
a - > _auxBlock . visible = true ;
a - > _auxBlock . r . left = ( int16 ) READ_LE_UINT16 ( axer + 0 ) + dx ;
a - > _auxBlock . r . top = ( int16 ) READ_LE_UINT16 ( axer + 2 ) + dy ;
a - > _auxBlock . r . right = ( int16 ) READ_LE_UINT16 ( axer + 4 ) + dx ;
a - > _auxBlock . r . bottom = ( int16 ) READ_LE_UINT16 ( axer + 6 ) + dy ;
2007-05-27 23:28:24 +00:00
adjustRect ( a - > _auxBlock . r ) ;
2004-09-18 00:36:17 +00:00
}
}
}
}
_auxEntriesNum = 0 ;
}
2008-09-25 10:11:06 +00:00
void ScummEngine_v71he : : queueAuxBlock ( ActorHE * a ) {
2005-03-11 01:10:06 +00:00
if ( ! a - > _auxBlock . visible )
2004-09-19 02:00:33 +00:00
return ;
2004-09-18 00:36:17 +00:00
assert ( _auxBlocksNum < ARRAYSIZE ( _auxBlocks ) ) ;
2005-03-11 01:10:06 +00:00
_auxBlocks [ _auxBlocksNum ] = a - > _auxBlock ;
2004-09-18 00:36:17 +00:00
+ + _auxBlocksNum ;
}
2005-05-15 09:46:34 +00:00
void ScummEngine_v71he : : queueAuxEntry ( int actorNum , int subIndex ) {
2004-09-18 00:36:17 +00:00
assert ( _auxEntriesNum < ARRAYSIZE ( _auxEntries ) ) ;
AuxEntry * ae = & _auxEntries [ _auxEntriesNum ] ;
ae - > actorNum = actorNum ;
ae - > subIndex = subIndex ;
+ + _auxEntriesNum ;
}
2005-05-15 19:27:46 +00:00
# endif
2004-09-18 00:36:17 +00:00
2012-02-04 18:34:08 +01:00
void Actor_v0 : : animateActor ( int anim ) {
2012-01-24 23:23:19 +11:00
int dir = - 1 ;
2012-01-27 22:05:10 +11:00
2012-02-04 14:49:44 +01:00
switch ( anim ) {
2012-01-25 16:18:33 +11:00
case 0x00 :
2012-01-24 23:23:19 +11:00
case 0x04 :
dir = 0 ;
break ;
2012-01-25 16:18:33 +11:00
case 0x01 :
2012-01-24 23:23:19 +11:00
case 0x05 :
dir = 1 ;
break ;
2012-01-25 16:18:33 +11:00
case 0x02 :
2012-01-24 23:23:19 +11:00
case 0x06 :
dir = 2 ;
break ;
2012-01-25 16:18:33 +11:00
case 0x03 :
2012-01-24 23:23:19 +11:00
case 0x07 :
dir = 3 ;
break ;
default :
break ;
}
2012-02-06 08:06:48 +01:00
if ( isInCurrentRoom ( ) ) {
2012-01-24 23:23:19 +11:00
_costCommandNew = anim ;
_vm - > _costumeLoader - > costumeDecodeData ( this , 0 , 0 ) ;
2012-09-26 04:17:31 +02:00
2012-02-06 08:06:48 +01:00
if ( dir = = - 1 )
2012-01-24 23:23:19 +11:00
return ;
2012-02-04 14:49:44 +01:00
_facing = normalizeAngle ( oldDirToNewDir ( dir ) ) ;
2012-01-24 23:23:19 +11:00
} else {
2016-07-16 17:18:11 +10:00
if ( anim > = 4 & & anim < = 7 )
2012-02-04 14:49:44 +01:00
_facing = normalizeAngle ( oldDirToNewDir ( dir ) ) ;
}
2012-01-15 23:23:11 +11:00
}
2003-05-22 00:51:42 +00:00
2014-11-30 22:01:23 +11:00
byte Actor_v0 : : updateWalkbox ( ) {
2014-12-07 15:24:21 +11:00
if ( _vm - > checkXYInBoxBounds ( _walkbox , _pos . x , _pos . y ) )
2014-11-30 22:01:23 +11:00
return 0 ;
int numBoxes = _vm - > getNumBoxes ( ) - 1 ;
for ( int i = 0 ; i < = numBoxes ; i + + ) {
2014-12-07 15:24:21 +11:00
if ( _vm - > checkXYInBoxBounds ( i , _pos . x , _pos . y ) = = true ) {
2014-11-30 22:01:23 +11:00
if ( _walkdata . curbox = = i ) {
setBox ( i ) ;
directionUpdate ( ) ;
_newWalkBoxEntered = true ;
return i ;
}
}
}
return kInvalidBox ;
}
void Actor_v0 : : directionUpdate ( ) {
int nextFacing = updateActorDirection ( true ) ;
if ( _facing ! = nextFacing ) {
// 2A89
setDirection ( nextFacing ) ;
// Still need to turn?
if ( _facing ! = _targetFacing ) {
_moving | = 0x80 ;
return ;
}
}
_moving & = ~ 0x80 ;
}
2018-02-13 21:08:07 +11:00
void Actor_v0 : : setActorToTempPosition ( ) {
2014-11-30 22:01:23 +11:00
_tmp_Pos = _pos ;
2018-02-13 21:08:07 +11:00
_pos = _tmp_NewPos ;
2014-11-30 22:01:23 +11:00
_tmp_WalkBox = _walkbox ;
_tmp_NewWalkBoxEntered = _newWalkBoxEntered ;
}
2018-02-13 21:08:07 +11:00
void Actor_v0 : : setActorToOriginalPosition ( ) {
2014-11-30 22:01:23 +11:00
_pos = _tmp_Pos ;
2018-02-13 21:08:07 +11:00
_tmp_NewPos = _tmp_Pos ;
2014-11-30 22:01:23 +11:00
_walkbox = _tmp_WalkBox ;
_newWalkBoxEntered = _tmp_NewWalkBoxEntered ;
}
void Actor_v0 : : actorSetWalkTo ( ) {
2016-07-16 17:18:11 +10:00
2014-11-30 22:01:23 +11:00
if ( _newWalkBoxEntered = = false )
return ;
_newWalkBoxEntered = false ;
2016-07-19 18:55:27 +10:00
int nextBox = ( ( ScummEngine_v0 * ) _vm ) - > walkboxFindTarget ( this , _walkdata . destbox , _walkdata . dest ) ;
2014-11-30 22:01:23 +11:00
if ( nextBox ! = kInvalidBox ) {
_walkdata . curbox = nextBox ;
}
}
2017-11-29 00:06:12 -06:00
void Actor_v0 : : saveLoadWithSerializer ( Common : : Serializer & s ) {
Actor : : saveLoadWithSerializer ( s ) ;
s . syncAsByte ( _costCommand , VER ( 84 ) ) ;
s . skip ( 1 , VER ( 84 ) , VER ( 89 ) ) ; // _costFrame
s . syncAsByte ( _miscflags , VER ( 84 ) ) ;
s . syncAsByte ( _speaking , VER ( 84 ) ) ;
s . skip ( 1 , VER ( 84 ) , VER ( 89 ) ) ; // _speakingPrev
s . skip ( 1 , VER ( 89 ) , VER ( 89 ) ) ; // _limbTemp
s . syncAsByte ( _animFrameRepeat , VER ( 89 ) ) ;
s . syncArray ( _limbFrameRepeatNew , 8 , Common : : Serializer : : SByte , VER ( 89 ) ) ;
s . syncArray ( _limbFrameRepeat , 8 , Common : : Serializer : : SByte , VER ( 90 ) ) ;
s . syncAsSint16LE ( _CurrentWalkTo . x , VER ( 97 ) ) ;
s . syncAsSint16LE ( _CurrentWalkTo . y , VER ( 97 ) ) ;
s . syncAsSint16LE ( _NewWalkTo . x , VER ( 97 ) ) ;
s . syncAsSint16LE ( _NewWalkTo . y , VER ( 97 ) ) ;
s . syncAsSByte ( _walkCountModulo , VER ( 97 ) ) ;
s . syncAsByte ( _newWalkBoxEntered , VER ( 97 ) ) ;
s . syncAsByte ( _walkDirX , VER ( 97 ) ) ;
s . syncAsByte ( _walkDirY , VER ( 97 ) ) ;
s . syncAsByte ( _walkYCountGreaterThanXCount , VER ( 97 ) ) ;
s . syncAsByte ( _walkXCount , VER ( 97 ) ) ;
s . syncAsByte ( _walkXCountInc , VER ( 97 ) ) ;
s . syncAsByte ( _walkYCount , VER ( 97 ) ) ;
s . syncAsByte ( _walkYCountInc , VER ( 97 ) ) ;
s . syncAsByte ( _walkMaxXYCountInc , VER ( 97 ) ) ;
s . syncBytes ( _walkboxQueue , 16 , VER ( 98 ) ) ;
s . syncAsByte ( _walkboxQueueIndex , VER ( 98 ) ) ;
2016-07-16 17:18:11 +10:00
2016-07-19 18:55:27 +10:00
// When loading, we need to ensure the limbs are restarted
2017-11-29 00:06:12 -06:00
if ( s . isLoading ( ) ) {
2016-07-19 18:55:27 +10:00
// valid costume command?
if ( _costCommand ! = 0xFF ) {
2016-10-09 14:59:58 +02:00
2016-07-19 18:55:27 +10:00
// Do we have a walkbox queue?
2016-07-16 17:18:11 +10:00
if ( _walkboxQueueIndex < 1 ) {
_costCommand = 0xFF ;
2016-07-19 18:55:27 +10:00
// Standing Still
setDirection ( _facing ) ;
2016-07-16 17:18:11 +10:00
speakCheck ( ) ;
2016-07-19 18:55:27 +10:00
} else {
// Force limb direction update
2016-07-16 17:18:11 +10:00
_facing = 0 ;
directionUpdate ( ) ;
2016-07-19 18:55:27 +10:00
// Begin walking
animateActor ( newDirToOldDir ( _facing ) ) ;
2016-07-16 17:18:11 +10:00
}
}
}
2010-10-26 04:20:20 +00:00
}
2017-11-29 00:06:12 -06:00
void Actor : : saveLoadWithSerializer ( Common : : Serializer & s ) {
if ( s . isLoading ( ) ) {
2005-10-21 23:01:13 +00:00
// Not all actor data is saved; so when loading, we first reset
2011-05-25 10:31:37 -04:00
// the actor, to ensure completely reproducible behavior (else,
2005-10-21 23:01:13 +00:00
// some not saved value in the actor class can cause odd things)
initActor ( - 1 ) ;
}
2017-11-29 00:06:12 -06:00
s . syncAsSint16LE ( _pos . x , VER ( 8 ) ) ;
s . syncAsSint16LE ( _pos . y , VER ( 8 ) ) ;
s . syncAsSint16LE ( _heOffsX , VER ( 32 ) ) ;
s . syncAsSint16LE ( _heOffsY , VER ( 32 ) ) ;
s . syncAsSint16LE ( _top , VER ( 8 ) ) ;
s . syncAsSint16LE ( _bottom , VER ( 8 ) ) ;
s . syncAsSint16LE ( _elevation , VER ( 8 ) ) ;
s . syncAsUint16LE ( _width , VER ( 8 ) ) ;
s . syncAsUint16LE ( _facing , VER ( 8 ) ) ;
s . syncAsUint16LE ( _costume , VER ( 8 ) ) ;
s . syncAsByte ( _room , VER ( 8 ) ) ;
s . syncAsByte ( _talkColor , VER ( 8 ) ) ;
s . syncAsSint16LE ( _talkFrequency , VER ( 16 ) ) ;
s . syncAsSint16LE ( _talkPan , VER ( 24 ) ) ;
s . syncAsSint16LE ( _talkVolume , VER ( 29 ) ) ;
s . syncAsUint16LE ( _boxscale , VER ( 34 ) ) ;
s . syncAsByte ( _scalex , VER ( 8 ) ) ;
s . syncAsByte ( _scaley , VER ( 8 ) ) ;
s . syncAsByte ( _charset , VER ( 8 ) ) ;
// Actor sound grew from 8 to 32 bytes and switched to uint16 in HE games
s . syncArray ( _sound , 8 , Common : : Serializer : : Byte , VER ( 8 ) , VER ( 36 ) ) ;
s . syncArray ( _sound , 32 , Common : : Serializer : : Byte , VER ( 37 ) , VER ( 61 ) ) ;
s . syncArray ( _sound , 32 , Common : : Serializer : : Uint16LE , VER ( 62 ) ) ;
// Actor animVariable grew from 8 to 27
s . syncArray ( _animVariable , 8 , Common : : Serializer : : Uint16LE , VER ( 8 ) , VER ( 40 ) ) ;
s . syncArray ( _animVariable , 27 , Common : : Serializer : : Uint16LE , VER ( 41 ) ) ;
s . syncAsUint16LE ( _targetFacing , VER ( 8 ) ) ;
s . syncAsByte ( _moving , VER ( 8 ) ) ;
s . syncAsByte ( _ignoreBoxes , VER ( 8 ) ) ;
s . syncAsByte ( _forceClip , VER ( 8 ) ) ;
s . syncAsByte ( _initFrame , VER ( 8 ) ) ;
s . syncAsByte ( _walkFrame , VER ( 8 ) ) ;
s . syncAsByte ( _standFrame , VER ( 8 ) ) ;
s . syncAsByte ( _talkStartFrame , VER ( 8 ) ) ;
s . syncAsByte ( _talkStopFrame , VER ( 8 ) ) ;
s . syncAsUint16LE ( _speedx , VER ( 8 ) ) ;
s . syncAsUint16LE ( _speedy , VER ( 8 ) ) ;
s . syncAsUint16LE ( _cost . animCounter , VER ( 8 ) ) ;
s . syncAsByte ( _cost . soundCounter , VER ( 8 ) ) ;
s . syncAsByte ( _drawToBackBuf , VER ( 32 ) ) ;
s . syncAsByte ( _flip , VER ( 32 ) ) ;
s . syncAsByte ( _heSkipLimbs , VER ( 32 ) ) ;
// Actor palette grew from 64 to 256 bytes and switched to uint16 in HE games
s . syncArray ( _palette , 64 , Common : : Serializer : : Byte , VER ( 8 ) , VER ( 9 ) ) ;
s . syncArray ( _palette , 256 , Common : : Serializer : : Byte , VER ( 10 ) , VER ( 79 ) ) ;
s . syncArray ( _palette , 256 , Common : : Serializer : : Uint16LE , VER ( 80 ) ) ;
s . skip ( 1 , VER ( 8 ) , VER ( 9 ) ) ; // _mask
s . syncAsByte ( _shadowMode , VER ( 8 ) ) ;
s . syncAsByte ( _visible , VER ( 8 ) ) ;
s . syncAsByte ( _frame , VER ( 8 ) ) ;
s . syncAsByte ( _animSpeed , VER ( 8 ) ) ;
s . syncAsByte ( _animProgress , VER ( 8 ) ) ;
s . syncAsByte ( _walkbox , VER ( 8 ) ) ;
s . syncAsByte ( _needRedraw , VER ( 8 ) ) ;
s . syncAsByte ( _needBgReset , VER ( 8 ) ) ;
s . syncAsByte ( _costumeNeedsInit , VER ( 8 ) ) ;
s . syncAsUint32LE ( _heCondMask , VER ( 38 ) ) ;
s . syncAsUint32LE ( _hePaletteNum , VER ( 59 ) ) ;
s . syncAsUint32LE ( _heXmapNum , VER ( 59 ) ) ;
s . syncAsSint16LE ( _talkPosY , VER ( 8 ) ) ;
s . syncAsSint16LE ( _talkPosX , VER ( 8 ) ) ;
s . syncAsByte ( _ignoreTurns , VER ( 8 ) ) ;
// Actor layer switched to int32 in HE games
s . syncAsByte ( _layer , VER ( 8 ) , VER ( 57 ) ) ;
s . syncAsSint32LE ( _layer , VER ( 58 ) ) ;
s . syncAsUint16LE ( _talkScript , VER ( 8 ) ) ;
s . syncAsUint16LE ( _walkScript , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . dest . x , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . dest . y , VER ( 8 ) ) ;
s . syncAsByte ( _walkdata . destbox , VER ( 8 ) ) ;
s . syncAsUint16LE ( _walkdata . destdir , VER ( 8 ) ) ;
s . syncAsByte ( _walkdata . curbox , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . cur . x , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . cur . y , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . next . x , VER ( 8 ) ) ;
s . syncAsSint16LE ( _walkdata . next . y , VER ( 8 ) ) ;
s . syncAsSint32LE ( _walkdata . deltaXFactor , VER ( 8 ) ) ;
s . syncAsSint32LE ( _walkdata . deltaYFactor , VER ( 8 ) ) ;
s . syncAsUint16LE ( _walkdata . xfrac , VER ( 8 ) ) ;
s . syncAsUint16LE ( _walkdata . yfrac , VER ( 8 ) ) ;
s . syncAsUint16LE ( _walkdata . point3 . x , VER ( 42 ) ) ;
s . syncAsUint16LE ( _walkdata . point3 . y , VER ( 42 ) ) ;
s . syncBytes ( _cost . active , 16 , VER ( 8 ) ) ;
s . syncAsUint16LE ( _cost . stopped , VER ( 8 ) ) ;
s . syncArray ( _cost . curpos , 16 , Common : : Serializer : : Uint16LE , VER ( 8 ) ) ;
s . syncArray ( _cost . start , 16 , Common : : Serializer : : Uint16LE , VER ( 8 ) ) ;
s . syncArray ( _cost . end , 16 , Common : : Serializer : : Uint16LE , VER ( 8 ) ) ;
s . syncArray ( _cost . frame , 16 , Common : : Serializer : : Uint16LE , VER ( 8 ) ) ;
s . syncArray ( _cost . heJumpOffsetTable , 16 , Common : : Serializer : : Uint16LE , VER ( 65 ) ) ;
s . syncArray ( _cost . heJumpCountTable , 16 , Common : : Serializer : : Uint16LE , VER ( 65 ) ) ;
s . syncArray ( _cost . heCondMaskTable , 16 , Common : : Serializer : : Uint32LE , VER ( 65 ) ) ;
if ( s . isLoading ( ) & & _vm - > _game . version < = 2 & & s . getVersion ( ) < VER ( 70 ) ) {
2007-02-15 18:12:29 +00:00
_pos . x > > = V12_X_SHIFT ;
_pos . y > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
2007-02-15 18:12:29 +00:00
_speedx > > = V12_X_SHIFT ;
_speedy > > = V12_Y_SHIFT ;
_elevation > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
if ( _walkdata . dest . x ! = - 1 ) {
2007-02-15 18:12:29 +00:00
_walkdata . dest . x > > = V12_X_SHIFT ;
_walkdata . dest . y > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
}
2007-02-15 18:12:29 +00:00
_walkdata . cur . x > > = V12_X_SHIFT ;
_walkdata . cur . y > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
2007-02-15 18:12:29 +00:00
_walkdata . next . x > > = V12_X_SHIFT ;
_walkdata . next . y > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
if ( _walkdata . point3 . x ! = 32000 ) {
2007-02-15 18:12:29 +00:00
_walkdata . point3 . x > > = V12_X_SHIFT ;
_walkdata . point3 . y > > = V12_Y_SHIFT ;
2007-02-04 01:24:43 +00:00
}
2016-07-16 17:18:11 +10:00
2016-07-19 18:55:27 +10:00
setDirection ( _facing ) ;
2007-02-04 01:24:43 +00:00
}
2003-05-26 02:26:13 +00:00
}
2003-10-03 18:33:57 +00:00
} // End of namespace Scumm