mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-18 07:53:12 +00:00
parent
a7e6397fa4
commit
b968a69468
@ -215,6 +215,12 @@ void ScummEngine::walkActors() {
|
||||
void Actor::stopActorMoving() {
|
||||
if (_walkScript)
|
||||
_vm->stopScript(_walkScript);
|
||||
|
||||
// V0 Games will walk on the spot if the actor is stopped mid-walk
|
||||
// So we must set the stand still frame
|
||||
if (_vm->_game.version == 0)
|
||||
startWalkAnim(3, -1);
|
||||
|
||||
_moving = 0;
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,13 @@ static const int v1MMNESLookup[25] = {
|
||||
0x17, 0x00, 0x01, 0x05, 0x16
|
||||
};
|
||||
|
||||
const byte v0ActorTalkArray[0x19] = {
|
||||
0x00, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x06, 0x00, 0x46, 0x06,
|
||||
0x06, 0x06, 0x06, 0xFF, 0xFF,
|
||||
0x06, 0xC0, 0x06, 0x06, 0x00,
|
||||
0xC0, 0xC0, 0x00, 0x06, 0x06
|
||||
};
|
||||
|
||||
byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
|
||||
int i, skip = 0;
|
||||
@ -1341,6 +1348,10 @@ int C64CostumeLoader::dirToDirStop(int oldDir) {
|
||||
}
|
||||
|
||||
void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
|
||||
|
||||
if ((v0ActorTalkArray[ a->_number ] & 0x80))
|
||||
return;
|
||||
|
||||
if ((a->_speaking & 0x80))
|
||||
cmd += 0x0C;
|
||||
else
|
||||
@ -1356,6 +1367,9 @@ void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
|
||||
|
||||
// Enable/Disable speaking flag
|
||||
if (frame == a->_talkStartFrame) {
|
||||
if ((v0ActorTalkArray[ a->_number ] & 0x40))
|
||||
return;
|
||||
|
||||
A->_speaking = 1;
|
||||
return;
|
||||
}
|
||||
@ -1393,15 +1407,7 @@ byte C64CostumeLoader::increaseAnims(Actor *a) {
|
||||
int cmd = A->_costCommand;
|
||||
A->_speakingPrev = A->_speaking;
|
||||
|
||||
// Update to use speak frame
|
||||
if (A->_speaking & 0x80) {
|
||||
actorSpeak(A, cmd);
|
||||
|
||||
} else {
|
||||
// Update to use stand frame
|
||||
if (A->_costFrame == A->_standFrame)
|
||||
cmd = dirToDirStop(cmd);
|
||||
}
|
||||
actorSpeak(A, cmd);
|
||||
|
||||
// Update the limb frames
|
||||
frameUpdate(A, cmd);
|
||||
@ -1410,7 +1416,11 @@ byte C64CostumeLoader::increaseAnims(Actor *a) {
|
||||
if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
|
||||
if (a->_cost.soundPos == 0)
|
||||
a->_cost.soundCounter++;
|
||||
a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
|
||||
|
||||
// Is this the correct location?
|
||||
// 0x073C
|
||||
if ((v0ActorTalkArray[ a->_number ] & 0x3F))
|
||||
a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
|
||||
}
|
||||
|
||||
// increase each frame pos
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "scumm/base-costume.h"
|
||||
|
||||
namespace Scumm {
|
||||
|
||||
class ClassicCostumeLoader : public BaseCostumeLoader {
|
||||
public:
|
||||
int _id;
|
||||
|
@ -635,7 +635,19 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
|
||||
|
||||
a = derefActor(VAR(VAR_EGO), "o_loadRoomWithEgo");
|
||||
|
||||
a->putActor(0, 0, room);
|
||||
//0x634F
|
||||
if ((((ActorC64*) a)->_miscflags & 0x40)) {
|
||||
|
||||
// TODO: Check if this is the correct function
|
||||
// to be calling here
|
||||
stopObjectCode();
|
||||
return;
|
||||
}
|
||||
|
||||
// The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
|
||||
// This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
|
||||
// This scripts runs before the actor position is set to the correct location
|
||||
a->putActor(a->getPos().x, a->getPos().y, room);
|
||||
_egoPositioned = false;
|
||||
|
||||
startScene(a->_room, a, obj);
|
||||
@ -815,6 +827,10 @@ void ScummEngine_v0::o_setActorBitVar() {
|
||||
else
|
||||
a->_miscflags &= ~mask;
|
||||
|
||||
// This flag causes the actor to stop moving (used by script #158, Green Tentacle 'Oomph!')
|
||||
if (a->_miscflags & 0x40)
|
||||
a->stopActorMoving();
|
||||
|
||||
debug(0, "o_setActorBitVar(%d, %d, %d)", act, mask, mod);
|
||||
}
|
||||
|
||||
|
@ -878,8 +878,9 @@ protected:
|
||||
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
|
||||
public:
|
||||
int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
|
||||
int getDist(int x, int y, int x2, int y2); // Also used in actor.cpp
|
||||
protected:
|
||||
int getDist(int x, int y, int x2, int y2);
|
||||
|
||||
int getObjActToObjActDist(int a, int b); // Not sure how to handle
|
||||
const byte *getObjOrActorName(int obj); // these three..
|
||||
void setObjectName(int obj);
|
||||
|
@ -154,10 +154,27 @@ void ScummEngine_v0::setNewKidVerbs() {
|
||||
}
|
||||
|
||||
void ScummEngine_v0::switchActor(int slot) {
|
||||
VAR(VAR_EGO) = VAR(97 + slot);
|
||||
actorFollowCamera(VAR(VAR_EGO));
|
||||
resetVerbs();
|
||||
resetSentence(false);
|
||||
|
||||
if (_currentRoom == 45)
|
||||
return;
|
||||
|
||||
// radiation suit? don't let the player switch
|
||||
if (VAR(VAR_EGO) == 8)
|
||||
return;
|
||||
|
||||
// verbs disabled? or just new kid button?
|
||||
if (_currentMode == 0 || _currentMode == 1 || _currentMode == 2)
|
||||
return;
|
||||
|
||||
// verbs disabled for the current actor
|
||||
ActorC64 *a = (ActorC64 *)derefActor(VAR(VAR_EGO), "switchActor");
|
||||
if (a->_miscflags & 0x40)
|
||||
return;
|
||||
|
||||
VAR(VAR_EGO) = VAR(97 + slot);
|
||||
resetVerbs();
|
||||
actorFollowCamera(VAR(VAR_EGO));
|
||||
setUserState(247);
|
||||
}
|
||||
|
||||
@ -668,6 +685,18 @@ void ScummEngine_v2::checkExecVerbs() {
|
||||
void ScummEngine_v0::runObject(int obj, int entry) {
|
||||
int prev = _v0ObjectInInventory;
|
||||
|
||||
if (getVerbEntrypoint(obj, entry) == 0) {
|
||||
// If nothing was found, attempt to find the 'WHAT-IS' verb script
|
||||
// (which is not really the what-is script, as this verb never actually executes
|
||||
// it merely seems to be some type of fallback)
|
||||
if (getVerbEntrypoint(obj, 0x0F) != 0) {
|
||||
|
||||
entry = 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
_v0ObjectInInventory = prev;
|
||||
|
||||
if (getVerbEntrypoint(obj, entry) != 0) {
|
||||
_v0ObjectInInventory = prev;
|
||||
runObjectScript(obj, entry, false, false, NULL);
|
||||
@ -698,17 +727,17 @@ void ScummEngine_v2::runObject(int obj, int entry) {
|
||||
}
|
||||
|
||||
bool ScummEngine_v0::verbMoveToActor(int actor) {
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
|
||||
Actor *a2 =derefActor(actor, "checkExecVerbs");
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "verbMoveToActor");
|
||||
Actor *a2 =derefActor(actor, "verbMoveToActor");
|
||||
int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
|
||||
|
||||
if (!a->_moving) {
|
||||
int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
|
||||
if (dist > 8)
|
||||
a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, 1);
|
||||
else
|
||||
if (!a->_moving && dist > 4) {
|
||||
a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, -1);
|
||||
} else {
|
||||
if (dist <= 4) {
|
||||
a->stopActorMoving();
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -716,21 +745,22 @@ bool ScummEngine_v0::verbMoveToActor(int actor) {
|
||||
|
||||
bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
|
||||
int x, y, dir;
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "verbMove");
|
||||
|
||||
if (_currentMode != 3 && _currentMode != 2)
|
||||
return false;
|
||||
|
||||
if (a->_moving)
|
||||
return true;
|
||||
|
||||
_v0ObjectIndex = true;
|
||||
getObjectXYPos(objectIndex, x, y, dir);
|
||||
_v0ObjectIndex = false;
|
||||
|
||||
// Detect distance from target object
|
||||
int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y);
|
||||
|
||||
if (dist > 8) {
|
||||
if (a->_moving)
|
||||
return true;
|
||||
|
||||
if (dist > 5) {
|
||||
a->startWalkActor(x, y, dir);
|
||||
VAR(6) = x;
|
||||
VAR(7) = y;
|
||||
@ -766,6 +796,7 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
|
||||
if (objIndex == 0)
|
||||
return false;
|
||||
|
||||
// Object in inventory ?
|
||||
if (where != WIO_INVENTORY) {
|
||||
_v0ObjectIndex = true;
|
||||
prep = verbPrep(objIndex);
|
||||
@ -778,13 +809,29 @@ bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
|
||||
} else {
|
||||
_verbPickup = false;
|
||||
}
|
||||
|
||||
// Ignore verbs?
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "verbObtain");
|
||||
if ((((ActorC64*) a)->_miscflags & 0x40)) {
|
||||
resetSentence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//attempt move to object
|
||||
if (verbMove(obj, objIndex, false))
|
||||
return true;
|
||||
|
||||
if (didPickup && (prep == 1 || prep == 4))
|
||||
if (_activeVerb != 13 && _activeVerb != 14)
|
||||
_activeInventory = obj;
|
||||
if (_activeVerb != 13 && _activeVerb != 14) {
|
||||
_v0ObjectInInventory = true;
|
||||
|
||||
if (whereIsObject( obj ) == WIO_INVENTORY)
|
||||
_activeInventory = obj;
|
||||
else
|
||||
resetSentence();
|
||||
|
||||
_v0ObjectInInventory = false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -795,6 +842,7 @@ int ScummEngine_v0::verbPrep(int object) {
|
||||
_v0ObjectIndex = true;
|
||||
else
|
||||
_v0ObjectIndex = false;
|
||||
|
||||
byte *ptr = getOBCDFromObject(object);
|
||||
_v0ObjectIndex = false;
|
||||
assert(ptr);
|
||||
@ -831,6 +879,7 @@ bool ScummEngine_v0::verbExec() {
|
||||
_activeObjectObtained = true;
|
||||
}
|
||||
|
||||
// Attempt to obtain/reach object2
|
||||
if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
|
||||
prep = verbPrep(_activeObject2Index);
|
||||
|
||||
@ -852,10 +901,16 @@ bool ScummEngine_v0::verbExec() {
|
||||
// Give-To
|
||||
if (_activeVerb == 3 && _activeInventory && _activeActor) {
|
||||
// FIXME: Actors need to turn and face each other
|
||||
// And walk to each other
|
||||
if (verbMoveToActor(_activeActor))
|
||||
return true;
|
||||
if (verbMoveToActor(_activeActor)) {
|
||||
// Ignore verbs?
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "verbExec");
|
||||
if ((((ActorC64*) a)->_miscflags & 0x40)) {
|
||||
resetSentence(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
_v0ObjectInInventory = true;
|
||||
VAR(5) = _activeActor;
|
||||
runObject(_activeInventory , 3);
|
||||
@ -865,6 +920,7 @@ bool ScummEngine_v0::verbExec() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Where we performing an action on an actor?
|
||||
if (_activeActor) {
|
||||
_v0ObjectIndex = true;
|
||||
runObject(_activeActor, entry);
|
||||
@ -905,13 +961,16 @@ bool ScummEngine_v0::verbExec() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Item not in inventory is executed
|
||||
if (_activeObject) {
|
||||
_v0ObjectIndex = true;
|
||||
runObject(_activeObjectIndex, entry);
|
||||
_v0ObjectIndex = false;
|
||||
} else if (_activeInventory) {
|
||||
// Not sure this is the correct way to do this,
|
||||
// however its working for most situations - segra
|
||||
if (verbExecutes(_activeInventory, true) == false) {
|
||||
if (_activeObject2 && verbExecutes(_activeObject2, true)) {
|
||||
if (_activeObject2 && _activeObject2Inv && verbExecutes(_activeObject2, true)) {
|
||||
_v0ObjectInInventory = true;
|
||||
|
||||
_activeObject = _activeInventory;
|
||||
@ -920,11 +979,17 @@ bool ScummEngine_v0::verbExec() {
|
||||
runObject(_activeObject, _activeVerb);
|
||||
} else {
|
||||
_v0ObjectInInventory = true;
|
||||
runObject(_activeInventory, _activeVerb);
|
||||
|
||||
if (_activeObject2) {
|
||||
_activeObject = _activeObject2;
|
||||
|
||||
runObject(_activeObject, _activeVerb);
|
||||
} else
|
||||
runObject(_activeInventory, _activeVerb);
|
||||
}
|
||||
} else {
|
||||
runObject(_activeInventory, _activeVerb);
|
||||
_v0ObjectInInventory = true;
|
||||
runObject(_activeInventory, _activeVerb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -941,7 +1006,7 @@ bool ScummEngine_v0::verbExec() {
|
||||
}
|
||||
|
||||
void ScummEngine_v0::checkExecVerbs() {
|
||||
Actor *a;
|
||||
Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
|
||||
VirtScreen *zone = findVirtScreen(_mouse.y);
|
||||
|
||||
// Is a verb currently executing
|
||||
@ -961,10 +1026,10 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
if (!obj && !act && !over) {
|
||||
resetSentence(false);
|
||||
} else {
|
||||
a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
|
||||
a->stopActorMoving();
|
||||
}
|
||||
} else {
|
||||
|
||||
if (_verbExecuting && !verbExec())
|
||||
return;
|
||||
}
|
||||
@ -994,14 +1059,37 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
// TODO
|
||||
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
|
||||
int prevInventory = _activeInventory;
|
||||
int invOff = _inventoryOffset;
|
||||
|
||||
// Click into V2 inventory
|
||||
checkV2Inventory(_mouse.x, _mouse.y);
|
||||
|
||||
// Did the Inventory position changed (arrows pressed, do nothing)
|
||||
if (invOff != _inventoryOffset)
|
||||
return;
|
||||
|
||||
// No inventory selected?
|
||||
if (!_activeInventory)
|
||||
return;
|
||||
|
||||
// Did we just change the selected inventory item?
|
||||
if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
|
||||
_v0ObjectInInventory = true;
|
||||
int prep = verbPrep( _activeInventory );
|
||||
_v0ObjectInInventory = true;
|
||||
int prep2 = verbPrep( prevInventory );
|
||||
|
||||
// Should the new inventory object remain as the secondary selected object
|
||||
// Or should the new inventory object become primary?
|
||||
if (prep != prep2 || prep != 1) {
|
||||
if (prep == 1 || prep == 3) {
|
||||
int tmp = _activeInventory;
|
||||
_activeInventory = prevInventory;
|
||||
prevInventory = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// Setup object2
|
||||
_activeObject = 0;
|
||||
_activeInvExecute = true;
|
||||
_activeObject2Inv = true;
|
||||
@ -1019,7 +1107,7 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
if (!_activeObject2 || prevInventory != _activeObject2)
|
||||
return;
|
||||
|
||||
if (_activeVerb == 11 && !((!(_activeObject || _activeInventory)) || !_activeObject2))
|
||||
if (_activeVerb == 11 && !(((_activeObject || _activeInventory)) || !_activeObject2))
|
||||
return;
|
||||
} else {
|
||||
int over = findVerbAtPos(_mouse.x, _mouse.y);
|
||||
@ -1027,6 +1115,8 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
int obj = findObject(_virtualMouse.x, _virtualMouse.y);
|
||||
int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
|
||||
|
||||
// If we already have an object selected, and we just clicked an actor
|
||||
// Clear any object we may of also clicked on
|
||||
if ((_activeObject || _activeInventory) && act) {
|
||||
obj = 0;
|
||||
objIdx = 0;
|
||||
@ -1037,10 +1127,12 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
// Disable New-Kid (in the secret lab)
|
||||
if (_currentMode == 2 || _currentMode == 0)
|
||||
return;
|
||||
|
||||
if (_activeVerb != 7) {
|
||||
_activeVerb = over;
|
||||
over = 0;
|
||||
|
||||
if (!(((ActorC64*) a)->_miscflags & 0x80)) {
|
||||
if (_activeVerb != 7) {
|
||||
_activeVerb = over;
|
||||
over = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (over) {
|
||||
@ -1064,9 +1156,14 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
|
||||
|
||||
if (zone->number == kMainVirtScreen) {
|
||||
a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
|
||||
// Ignore verbs?
|
||||
if ((((ActorC64*) a)->_miscflags & 0x40)) {
|
||||
resetSentence(false);
|
||||
return;
|
||||
}
|
||||
a->stopActorMoving();
|
||||
a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
|
||||
a->startWalkActor(VAR(6), VAR(7), -1);
|
||||
_verbExecuting = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1120,6 +1217,8 @@ void ScummEngine_v0::checkExecVerbs() {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a->stopActorMoving();
|
||||
|
||||
_activeObject = obj;
|
||||
_activeObjectIndex = objIdx;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user