SHERLOCK: Refactor gotoStand into Person classes

This commit is contained in:
Paul Gilbert 2015-06-11 22:55:36 -04:00
parent a3e75c2a49
commit a97715f9dc
14 changed files with 184 additions and 105 deletions

View File

@ -301,7 +301,7 @@ void Sprite::checkSprite() {
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
} else {
people.gotoStand(*this);
gotoStand();
}
break;
@ -311,7 +311,7 @@ void Sprite::checkSprite() {
obj.setFlagsAndToggles();
talk.talkTo(obj._use[0]._target);
} else {
people.gotoStand(*this);
gotoStand();
}
break;
@ -323,7 +323,7 @@ void Sprite::checkSprite() {
case WALK_AROUND:
if (objBounds.contains(people._walkTo.front())) {
// Reached zone
people.gotoStand(*this);
gotoStand();
} else {
// Destination not within box, walk to best corner
Common::Point walkPos;

View File

@ -304,6 +304,11 @@ public:
* This adjusts the sprites position, as well as it's animation sequence:
*/
virtual void adjustSprite() = 0;
/**
* Bring a moving character using the sprite to a standing position
*/
virtual void gotoStand() = 0;
};
enum { OBJ_BEHIND = 1, OBJ_FLIPPED = 2, OBJ_FORWARD = 4, TURNON_OBJ = 0x20, TURNOFF_OBJ = 0x40 };

View File

@ -423,7 +423,7 @@ assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/
_oldWalkSequence = _data[PLAYER]->_sequenceNumber;
if (!_data[PLAYER]->_walkCount)
gotoStand(*_data[PLAYER]);
_data[PLAYER]->gotoStand();
// If the sequence is the same as when we started, then Holmes was
// standing still and we're trying to re-stand him, so reset Holmes'
@ -456,7 +456,7 @@ void People::walkToCoords(const Point32 &destPos, int destDir) {
assert(_data[PLAYER]->_position.y >= 10000);/***DEBUG****/
_data[PLAYER]->_sequenceNumber = destDir;
gotoStand(*_data[PLAYER]);
_data[PLAYER]->gotoStand();
// Draw Holmes facing the new direction
scene.doBgAnim();

View File

@ -58,6 +58,7 @@ struct PersonData {
class Person : public Sprite {
public:
Common::Queue<Common::Point> _walkTo;
bool _walkLoaded;
Common::String _portrait;
@ -183,12 +184,6 @@ public:
* Change the sequence of the scene background object associated with the current speaker.
*/
virtual void setTalkSequence(int speaker, int sequenceNum = 1) = 0;
/**
* Bring a moving character to a standing position. If the Scalpel chessboard
* is being displayed, then the chraracter will always face down.
*/
virtual void gotoStand(Sprite &sprite) = 0;
};
} // End of namespace Sherlock

View File

@ -49,7 +49,7 @@ void ScalpelPerson::adjustSprite() {
people._walkDest = people._walkTo.pop();
people.setWalking();
} else {
people.gotoStand(*this);
gotoStand();
}
}
}
@ -57,22 +57,22 @@ void ScalpelPerson::adjustSprite() {
if (_type == CHARACTER && !map._active) {
if ((_position.y / FIXED_INT_MULTIPLIER) > LOWER_LIMIT) {
_position.y = LOWER_LIMIT * FIXED_INT_MULTIPLIER;
people.gotoStand(*this);
gotoStand();
}
if ((_position.y / FIXED_INT_MULTIPLIER) < UPPER_LIMIT) {
_position.y = UPPER_LIMIT * FIXED_INT_MULTIPLIER;
people.gotoStand(*this);
gotoStand();
}
if ((_position.x / FIXED_INT_MULTIPLIER) < LEFT_LIMIT) {
_position.x = LEFT_LIMIT * FIXED_INT_MULTIPLIER;
people.gotoStand(*this);
gotoStand();
}
if ((_position.x / FIXED_INT_MULTIPLIER) > RIGHT_LIMIT) {
_position.x = RIGHT_LIMIT * FIXED_INT_MULTIPLIER;
people.gotoStand(*this);
gotoStand();
}
} else if (!map._active) {
_position.y = CLIP((int)_position.y, (int)UPPER_LIMIT, (int)LOWER_LIMIT);
@ -118,9 +118,9 @@ void ScalpelPerson::adjustSprite() {
if (exit) {
scene._goToScene = exit->_scene;
if (exit->_people.x != 0) {
people._hSavedPos = exit->_people;
people._hSavedFacing = exit->_peopleDir;
if (exit->_newPosition.x != 0) {
people._hSavedPos = exit->_newPosition;
people._hSavedFacing = exit->_newFacing;
if (people._hSavedFacing > 100 && people._hSavedPos.x < 1)
people._hSavedPos.x = 100;
@ -129,6 +129,58 @@ void ScalpelPerson::adjustSprite() {
}
}
void ScalpelPerson::gotoStand() {
ScalpelMap &map = *(ScalpelMap *)_vm->_map;
People &people = *_vm->_people;
_walkTo.clear();
_walkCount = 0;
switch (_sequenceNumber) {
case Scalpel::WALK_UP:
_sequenceNumber = STOP_UP;
break;
case WALK_DOWN:
_sequenceNumber = STOP_DOWN;
break;
case TALK_LEFT:
case WALK_LEFT:
_sequenceNumber = STOP_LEFT;
break;
case TALK_RIGHT:
case WALK_RIGHT:
_sequenceNumber = STOP_RIGHT;
break;
case WALK_UPRIGHT:
_sequenceNumber = STOP_UPRIGHT;
break;
case WALK_UPLEFT:
_sequenceNumber = STOP_UPLEFT;
break;
case WALK_DOWNRIGHT:
_sequenceNumber = STOP_DOWNRIGHT;
break;
case WALK_DOWNLEFT:
_sequenceNumber = STOP_DOWNLEFT;
break;
default:
break;
}
// Only restart frame at 0 if the sequence number has changed
if (_oldWalkSequence != -1 || _sequenceNumber == Scalpel::STOP_UP)
_frameNumber = 0;
if (map._active) {
_sequenceNumber = 0;
people[PLAYER]._position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER;
people[PLAYER]._position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER;
}
_oldWalkSequence = -1;
people._allowWalkAbort = true;
}
/*----------------------------------------------------------------*/
ScalpelPeople::ScalpelPeople(SherlockEngine *vm) : People(vm) {
@ -237,57 +289,6 @@ void ScalpelPeople::setTalkSequence(int speaker, int sequenceNum) {
}
}
void ScalpelPeople::gotoStand(Sprite &sprite) {
ScalpelMap &map = *(ScalpelMap *)_vm->_map;
_walkTo.clear();
sprite._walkCount = 0;
switch (sprite._sequenceNumber) {
case Scalpel::WALK_UP:
sprite._sequenceNumber = STOP_UP;
break;
case WALK_DOWN:
sprite._sequenceNumber = STOP_DOWN;
break;
case TALK_LEFT:
case WALK_LEFT:
sprite._sequenceNumber = STOP_LEFT;
break;
case TALK_RIGHT:
case WALK_RIGHT:
sprite._sequenceNumber = STOP_RIGHT;
break;
case WALK_UPRIGHT:
sprite._sequenceNumber = STOP_UPRIGHT;
break;
case WALK_UPLEFT:
sprite._sequenceNumber = STOP_UPLEFT;
break;
case WALK_DOWNRIGHT:
sprite._sequenceNumber = STOP_DOWNRIGHT;
break;
case WALK_DOWNLEFT:
sprite._sequenceNumber = STOP_DOWNLEFT;
break;
default:
break;
}
// Only restart frame at 0 if the sequence number has changed
if (_oldWalkSequence != -1 || sprite._sequenceNumber == Scalpel::STOP_UP)
sprite._frameNumber = 0;
if (map._active) {
sprite._sequenceNumber = 0;
_data[PLAYER]->_position.x = (map[map._charPoint].x - 6) * FIXED_INT_MULTIPLIER;
_data[PLAYER]->_position.y = (map[map._charPoint].y + 10) * FIXED_INT_MULTIPLIER;
}
_oldWalkSequence = -1;
_allowWalkAbort = true;
}
} // End of namespace Scalpel
} // End of namespace Sherlock

View File

@ -50,6 +50,11 @@ public:
* This adjusts the sprites position, as well as it's animation sequence:
*/
virtual void adjustSprite();
/**
* Bring a moving character to a standing position
*/
virtual void gotoStand();
};
class ScalpelPeople : public People {
@ -71,12 +76,6 @@ public:
* Change the sequence of the scene background object associated with the specified speaker.
*/
virtual void setTalkSequence(int speaker, int sequenceNum = 1);
/**
* Bring a moving character to a standing position. If the Scalpel chessboard
* is being displayed, then the chraracter will always face down.
*/
virtual void gotoStand(Sprite &sprite);
};
} // End of namespace Scalpel

View File

@ -660,7 +660,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
if (tpPos.x != -1) {
people[PLAYER]._position = tpPos; // Place the player
people[PLAYER]._sequenceNumber = tpDir;
people.gotoStand(people[PLAYER]);
people[PLAYER].gotoStand();
}
if (playRate < 0)
@ -689,7 +689,7 @@ int ScalpelScene::startCAnim(int cAnimNum, int playRate) {
people[PLAYER]._position = tpPos;
people[PLAYER]._sequenceNumber = tpDir;
people.gotoStand(people[PLAYER]);
people[PLAYER].gotoStand();
}
events.setCursor(oldCursor);

View File

@ -2232,7 +2232,7 @@ void ScalpelUserInterface::checkAction(ActionType &action, const char *const mes
// Ensure Holmes is on the exact intended location
people[PLAYER]._position = pt;
people[PLAYER]._sequenceNumber = dir;
people.gotoStand(people[PLAYER]);
people[PLAYER].gotoStand();
talk.talkTo(action._names[nameIdx].c_str() + 2);
if (ch == 'T')

View File

@ -114,9 +114,9 @@ void Exit::load(Common::SeekableReadStream &s, bool isRoseTattoo) {
if (!isRoseTattoo)
_allow = s.readSint16LE();
_people.x = s.readSint16LE();
_people.y = s.readSint16LE();
_peopleDir = s.readUint16LE();
_newPosition.x = s.readSint16LE();
_newPosition.y = s.readSint16LE();
_newFacing = s.readUint16LE();
if (isRoseTattoo)
_allow = s.readSint16LE();

View File

@ -79,8 +79,8 @@ class Exit: public Common::Rect {
public:
int _scene;
int _allow;
Common::Point _people;
int _peopleDir;
Common::Point _newPosition;
int _newFacing;
Common::String _dest;
int _image; // Arrow image to use

View File

@ -173,7 +173,7 @@ void Talk::talkTo(const Common::String &filename) {
if (people._allowWalkAbort)
abortFlag = true;
people.gotoStand(people[PLAYER]);
people[PLAYER].gotoStand();
}
if (_talkToAbort)
@ -965,7 +965,7 @@ void Talk::doScript(const Common::String &script) {
_yp = (_talkTo == -1) ? 5 : screen.fontHeight() + 11;
if (IS_ROSE_TATTOO) {
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
Person &p = people[idx];
p._savedNpcSequence = p._sequenceNumber;
p._savedNpcFrame = p._frameNumber;

View File

@ -21,6 +21,7 @@
*/
#include "sherlock/tattoo/tattoo_people.h"
#include "sherlock/tattoo/tattoo_scene.h"
#include "sherlock/tattoo/tattoo_talk.h"
#include "sherlock/sherlock.h"
@ -29,8 +30,83 @@ namespace Sherlock {
namespace Tattoo {
void TattooPerson::adjustSprite() {
// TODO
warning("TODO: TattooPerson::adjustSprite");
People &people = *_vm->_people;
TattooScene &scene = *(TattooScene *)_vm->_scene;
if (_type == INVALID)
return;
if (_type == CHARACTER && _status) {
// Sprite waiting to move, so restart walk
_walkCount = _status;
_status = 0;
people._walkDest = _walkTo.front();
setWalking();
} else if (_type == CHARACTER && _walkCount) {
if (_walkCount > 10) {
people._walkDest = _walkTo.front();
setWalking();
}
_position += _delta;
if (_walkCount)
--_walkCount;
if (!_walkCount) {
// If there are remaining points to walk, move to the next one
people._walkDest = _walkTo.pop();
setWalking();
} else {
gotoStand();
}
}
if (_type != CHARACTER) {
if (_position.y > SHERLOCK_SCREEN_HEIGHT)
_position.y = SHERLOCK_SCREEN_HEIGHT;
if (_position.y < UPPER_LIMIT)
_position.y = UPPER_LIMIT;
if (_position.x < LEFT_LIMIT)
_position.x = LEFT_LIMIT;
if (_position.x > RIGHT_LIMIT)
_position.x = RIGHT_LIMIT;
}
int frameNum = _frameNumber;
if (frameNum == -1)
frameNum = 0;
int idx = _walkSequences[_sequenceNumber][frameNum];
if (idx > _maxFrames)
idx = 1;
// Set the image frame
if (_altSeq)
_imageFrame = &(*_altImages)[idx - 1];
else
_imageFrame = &(*_images)[idx - 1];
// See if the player has come to a stop after clicking on an Arrow zone to leave the scene.
// If so, this will set up the exit information for the scene transition
if (!_walkCount && scene._exitZone != -1 && scene._walkedInScene && scene._goToScene != -1 &&
!_description.compareToIgnoreCase(people[PLAYER]._description)) {
people._hSavedPos = scene._exits[scene._exitZone]._newPosition;
people._hSavedFacing = scene._exits[scene._exitZone]._newFacing;
if (people._hSavedFacing > 100 && people._hSavedPos.x < 1)
people._hSavedPos.x = 100;
}
}
void TattooPerson::gotoStand() {
error("TODO: gotoStand");
}
void TattooPerson::setWalking() {
error("TODO: setWalking");
}
/*----------------------------------------------------------------*/
@ -236,10 +312,6 @@ void TattooPeople::synchronize(Serializer &s) {
}
}
void TattooPeople::gotoStand(Sprite &sprite) {
error("TODO: gotoStand");
}
} // End of namespace Tattoo
} // End of namespace Sherlock

View File

@ -72,6 +72,8 @@ enum TattooSequences {
};
class TattooPerson: public Person {
private:
bool checkCollision() const;
public:
TattooPerson() : Person() {}
virtual ~TattooPerson() {}
@ -80,6 +82,17 @@ public:
* This adjusts the sprites position, as well as it's animation sequence:
*/
virtual void adjustSprite();
/**
* Bring a moving character to a standing position
*/
virtual void gotoStand();
/**
* Set the variables for moving a character from one poisition to another
* in a straight line
*/
void setWalking();
};
class TattooPeople : public People {
@ -107,12 +120,6 @@ public:
* Change the sequence of the scene background object associated with the specified speaker.
*/
virtual void setTalkSequence(int speaker, int sequenceNum = 1);
/**
* Bring a moving character to a standing position. If the Scalpel chessboard
* is being displayed, then the chraracter will always face down.
*/
virtual void gotoStand(Sprite &sprite);
};
} // End of namespace Scalpel

View File

@ -157,7 +157,7 @@ void TattooScene::drawAllShapes() {
}
// Queue all active characters for drawing
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._type == CHARACTER && people[idx]._walkLoaded)
shapeList.push_back(ShapeEntry(&people[idx], people[idx]._position.y / FIXED_INT_MULTIPLIER));
}
@ -364,7 +364,7 @@ void TattooScene::doBgAnimEraseBackground() {
ui.doBgAnimRestoreUI();
// Restore background for any areas covered by characters and shapes
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx)
for (int idx = 0; idx < MAX_CHARACTERS; ++idx)
screen.restoreBackground(Common::Rect(people[idx]._oldPosition.x, people[idx]._oldPosition.y,
people[idx]._oldPosition.x + people[idx]._oldSize.x, people[idx]._oldPosition.y + people[idx]._oldSize.y));
@ -428,7 +428,7 @@ void TattooScene::doBgAnim() {
talk._talkToAbort = false;
// Check the characters and sprites for updates
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._type == CHARACTER)
people[idx].checkSprite();
}
@ -461,7 +461,7 @@ void TattooScene::doBgAnim() {
_doBgAnimDone = false;
ui._drawMenu = false;
for (uint idx = 1; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 1; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._updateNPCPath)
people[idx].updateNPC();
}
@ -478,7 +478,7 @@ void TattooScene::doBgAnimUpdateBgObjectsAndAnim() {
obj.adjustObject();
}
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
if (people[idx]._type == CHARACTER)
people[idx].adjustSprite();
}
@ -572,7 +572,7 @@ void TattooScene::updateBackground() {
screen._flushScreen = true;
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
Person &p = people[idx];
if (p._type != INVALID) {
@ -640,7 +640,7 @@ void TattooScene::doBgAnimDrawSprites() {
Screen &screen = *_vm->_screen;
TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui;
for (uint idx = 0; idx < MAX_CHARACTERS; ++idx) {
for (int idx = 0; idx < MAX_CHARACTERS; ++idx) {
Person &person = people[idx];
if (person._type != INVALID) {