aboutsummaryrefslogtreecommitdiff
path: root/saga
diff options
context:
space:
mode:
Diffstat (limited to 'saga')
-rw-r--r--saga/actionmap.h7
-rw-r--r--saga/actor.cpp135
-rw-r--r--saga/actor.h32
-rw-r--r--saga/input.cpp3
-rw-r--r--saga/interface.cpp9
-rw-r--r--saga/interface.h6
-rw-r--r--saga/objectmap.h13
-rw-r--r--saga/saga.h12
-rw-r--r--saga/scene.cpp20
-rw-r--r--saga/scene.h6
-rw-r--r--saga/script.cpp147
-rw-r--r--saga/script.h14
12 files changed, 344 insertions, 60 deletions
diff --git a/saga/actionmap.h b/saga/actionmap.h
index 9684a68975..3329d47b59 100644
--- a/saga/actionmap.h
+++ b/saga/actionmap.h
@@ -47,7 +47,12 @@ class ActionMap {
int getExitSceneNumber(int index) const;
int hitTest(const Point &testPoint);
int draw(SURFACE *ds, int color);
-
+ const HitZone * getHitZone(int index) const {
+ if ((index < 0) || (index >= _stepZoneListCount)) {
+ error("ActionMap::getHitZone wrong index 0x%X", index);
+ }
+ return _stepZoneList[index];
+ }
void cmdInfo();
private:
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 8f4d450800..3d9b681bb9 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -39,6 +39,7 @@
#include "saga/actordata.h"
#include "saga/stream.h"
#include "saga/interface.h"
+#include "saga/events.h"
#include "common/config-manager.h"
namespace Saga {
@@ -149,8 +150,8 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
_pathNodeList = _newPathNodeList = NULL;
_pathList = NULL;
- _pathListAlloced = _pathNodeListAlloced = 0;
- _pathListIndex = _pathNodeListIndex = -1;
+ _pathListAlloced = _pathNodeListAlloced = _newPathNodeListAlloced = 0;
+ _pathListIndex = _pathNodeListIndex = _newPathNodeListIndex = -1;
_centerActor = _protagonist = NULL;
@@ -202,6 +203,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {
actor->frameNumber = 0;
actor->targetObject = ID_NOTHING;
actor->actorFlags = 0;
+ actor->lastZone = NULL;
actor->location.x = ITE_ActorTable[i].x;
actor->location.y = ITE_ActorTable[i].y;
@@ -310,6 +312,57 @@ bool Actor::loadActorResources(ActorData *actor) {
return true;
}
+void Actor::takeExit(uint16 actorId, const HitZone *hitZone) {
+ ActorData *actor;
+ actor = getActor(actorId);
+ actor->lastZone = NULL;
+
+ _vm->_scene->changeScene(hitZone->getSceneNumber(), hitZone->getActorsEntrance());
+ _vm->_script->setNoPendingVerb();
+}
+
+void Actor::stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped) {
+ EVENT event;
+
+ if (actor != _protagonist) {
+ return;
+ }
+ if (((hitZone->getFlags() & kHitZoneTerminus) && !stopped) || (!(hitZone->getFlags() & kHitZoneTerminus) && stopped)) {
+ return;
+ }
+
+ if (!exit) {
+ if (hitZone->getFlags() & kHitZoneAutoWalk) {
+ actor->currentAction = kActionWalkDir;
+ actor->actionDirection = actor->facingDirection = hitZone->getDirection();
+ actor->walkFrameSequence = kFrameWalk;
+ return;
+ }
+ } else {
+ if (!(hitZone->getFlags() & kHitZoneAutoWalk)) {
+ return;
+ }
+ }
+ if (hitZone->getFlags() & kHitZoneExit) {
+ takeExit(actor->actorId, hitZone);
+ } else {
+ if (hitZone->getScriptNumber() > 0) {
+ event.type = ONESHOT_EVENT;
+ event.code = SCRIPT_EVENT;
+ event.op = EVENT_EXEC_NONBLOCKING;
+ event.time = 0;
+ event.param = hitZone->getScriptNumber();
+ event.param2 = kVerbEnter; // Action
+ event.param3 = ID_NOTHING; // Object
+ event.param4 = ID_NOTHING; // With Object
+ event.param5 = ID_PROTAG; // Actor
+
+ _vm->_events->queue(&event);
+ }
+ }
+
+}
+
void Actor::realLocation(Location &location, uint16 objectId, uint16 walkFlags) {
int angle;
int distance;
@@ -408,7 +461,7 @@ bool Actor::validFollowerLocation(const Location &location) {
return (_vm->_scene->canWalk(point));
}
-void Actor::updateActorsScene() {
+void Actor::updateActorsScene(int actorsEntrance) {
int i, j;
int followerDirection;
ActorData *actor;
@@ -638,6 +691,9 @@ void Actor::handleActions(int msec, bool setup) {
int speed;
Location delta;
Location addDelta;
+ int hitZoneIndex;
+ const HitZone *hitZone;
+ Point hitPoint;
for (i = 0; i < _actorsCount; i++) {
actor = _actors[i];
@@ -873,6 +929,28 @@ void Actor::handleActions(int msec, bool setup) {
//todo: do it
break;
}
+
+ if ((actor->currentAction >= kActionWalkToPoint) && (actor->currentAction <= kActionWalkDir)) {
+ hitZone = NULL;
+ // tiled stuff
+ if (_vm->_scene->getFlags() & kSceneFlagISO) {
+ //todo: it
+ } else {
+ actor->location.toScreenPointXY(hitPoint);
+ hitZoneIndex = _vm->_scene->_actionMap->hitTest(hitPoint);
+ if (hitZoneIndex != -1) {
+ hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex);
+ }
+ }
+
+ if (hitZone != actor->lastZone) {
+ if (actor->lastZone)
+ stepZoneAction( actor, actor->lastZone, true, false);
+ actor->lastZone = hitZone;
+ if (hitZone)
+ stepZoneAction( actor, hitZone, false, false);
+ }
+ }
}
}
@@ -1106,6 +1184,8 @@ bool Actor::followProtagonist(ActorData *actor) {
bool Actor::actorEndWalk(uint16 actorId, bool recurse) {
bool walkMore = false;
ActorData *actor;
+ const HitZone *hitZone;
+ int hitZoneIndex;
actor = getActor(actorId);
actor->actorFlags &= ~kActorBackwards;
@@ -1127,7 +1207,19 @@ bool Actor::actorEndWalk(uint16 actorId, bool recurse) {
if (actor == _protagonist) {
_vm->_script->wakeUpActorThread(kWaitTypeWalk, actor);
- //todo: it
+ if (_vm->_script->_pendingVerb == kVerbWalkTo) {
+ hitZoneIndex = _vm->_scene->_actionMap->hitTest(actor->screenPosition);
+ if (hitZoneIndex != -1) {
+ hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex);
+ stepZoneAction(actor, hitZone, false, true);
+ } else {
+ _vm->_script->setNoPendingVerb();
+ }
+ } else {
+ if (_vm->_script->_pendingVerb != kVerbNone) {
+ _vm->_script->doVerb();
+ }
+ }
} else {
if (recurse && (actor->flags & kFollower))
@@ -1826,7 +1918,6 @@ void Actor::condenseNodeList() {
void Actor::removePathPoints() {
int i, j, k, l;
PathNode *node;
- int newPathNodeIndex;
int start;
int end;
Point point1, point2;
@@ -1835,13 +1926,12 @@ void Actor::removePathPoints() {
if (_pathNodeListIndex < 2)
return;
- _newPathNodeList = (PathNode*)realloc(_newPathNodeList, _pathNodeListAlloced);
- _newPathNodeList[0] = _pathNodeList[0];
- newPathNodeIndex = 0;
-
+
+ _newPathNodeListIndex = -1;
+ addNewPathNodeListPoint(_pathNodeList[0].point, _pathNodeList[0].link);
+
for (i = 1, node = _pathNodeList + 1; i < _pathNodeListIndex; i++, node++) {
- newPathNodeIndex++;
- _newPathNodeList[newPathNodeIndex] = *node;
+ addNewPathNodeListPoint(node->point, node->link);
for (j = 5; j > 0; j--) {
start = node->link - j;
@@ -1859,17 +1949,17 @@ void Actor::removePathPoints() {
if (scanPathLine(point1, point2)) {
- for (l = 1; l <= newPathNodeIndex; l++) {
+ for (l = 1; l <= _newPathNodeListIndex; l++) {
if (start <= _newPathNodeList[l].link) {
- newPathNodeIndex = l;
- _newPathNodeList[newPathNodeIndex].point = point1;
- _newPathNodeList[newPathNodeIndex].link = start;
- newPathNodeIndex++;
+ _newPathNodeListIndex = l;
+ _newPathNodeList[_newPathNodeListIndex].point = point1;
+ _newPathNodeList[_newPathNodeListIndex].link = start;
+ incrementNewPathNodeListIndex();
break;
}
}
- _newPathNodeList[newPathNodeIndex].point = point2;
- _newPathNodeList[newPathNodeIndex].link = end;
+ _newPathNodeList[_newPathNodeListIndex].point = point2;
+ _newPathNodeList[_newPathNodeListIndex].link = end;
for (k = start + 1; k < end; k++) {
_pathList[k].x = PATH_NODE_EMPTY;
@@ -1878,12 +1968,11 @@ void Actor::removePathPoints() {
}
}
}
+
+ addNewPathNodeListPoint(_pathNodeList[_pathNodeListIndex].point, _pathNodeList[_pathNodeListIndex].link);
- newPathNodeIndex++;
- _newPathNodeList[newPathNodeIndex] = _pathNodeList[_pathNodeListIndex];
-
- for (i = 0, j = 0; i <= newPathNodeIndex; i++) {
- if (newPathNodeIndex == i || (_newPathNodeList[i].point != _newPathNodeList[i+1].point)) {
+ for (i = 0, j = 0; i <= _newPathNodeListIndex; i++) {
+ if (_newPathNodeListIndex == i || (_newPathNodeList[i].point != _newPathNodeList[i+1].point)) {
_pathNodeList[j++] = _newPathNodeList[i];
}
}
diff --git a/saga/actor.h b/saga/actor.h
index 8430c45643..07009bedfd 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -33,6 +33,8 @@
namespace Saga {
+class HitZone;
+
#define ACTOR_DEBUG
#define ACTOR_BARRIERS_MAX 16
@@ -191,7 +193,8 @@ struct ActorData {
int actionDirection;
int actionCycle;
int frameNumber; // current actor frame number
- uint16 targetObject;
+ uint16 targetObject;
+ const HitZone *lastZone;
int cycleFrameSequence;
uint8 cycleDelay;
@@ -263,6 +266,8 @@ struct SpeechData {
}
};
+
+
class Actor {
public:
ActorData *_centerActor;
@@ -279,11 +284,12 @@ public:
int direct(int msec);
int drawActors();
- void updateActorsScene(); // calls from scene loading to update Actors info
+ void updateActorsScene(int actorsEntrance); // calls from scene loading to update Actors info
void drawPathTest();
uint16 testHit(const Point& mousePointer){ return ID_NOTHING;}; //TODO: do it
+ void takeExit(uint16 actorId, const HitZone *hitZone);
const char * getActorName(uint16 actorId);
bool actorEndWalk(uint16 actorId, bool recurse);
bool actorWalkTo(uint16 actorId, const Location &toLocation);
@@ -309,7 +315,8 @@ public:
private:
bool loadActorResources(ActorData *actor);
-
+ void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
+
void createDrawOrderList();
void calcActorScreenPosition(ActorData *actor);
bool followProtagonist(ActorData *actor);
@@ -376,7 +383,6 @@ private:
int _pathNodeListIndex;
int _pathNodeListAlloced;
PathNode *_pathNodeList;
- PathNode *_newPathNodeList;
void addPathNodeListPoint(const Point &point) {
++_pathNodeListIndex;
if (_pathNodeListIndex >= _pathNodeListAlloced) {
@@ -386,6 +392,24 @@ private:
}
_pathNodeList[_pathNodeListIndex].point = point;
}
+
+ int _newPathNodeListIndex;
+ int _newPathNodeListAlloced;
+ PathNode *_newPathNodeList;
+ void incrementNewPathNodeListIndex() {
+ ++_newPathNodeListIndex;
+ if (_newPathNodeListIndex >= _newPathNodeListAlloced) {
+ _newPathNodeListAlloced += 100;
+ _newPathNodeList = (PathNode*) realloc(_newPathNodeList, _newPathNodeListAlloced * sizeof(*_newPathNodeList));
+
+ }
+ }
+ void addNewPathNodeListPoint(const Point &point, int link) {
+ incrementNewPathNodeListIndex();
+ _newPathNodeList[_newPathNodeListIndex].point = point;
+ _newPathNodeList[_newPathNodeListIndex].link = link;
+ }
+
public:
#ifdef ACTOR_DEBUG
//path debug - use with care
diff --git a/saga/input.cpp b/saga/input.cpp
index cfc3d48363..39f952b919 100644
--- a/saga/input.cpp
+++ b/saga/input.cpp
@@ -88,10 +88,11 @@ int SagaEngine::processInput() {
}
break;
case OSystem::EVENT_LBUTTONDOWN:
+ case OSystem::EVENT_RBUTTONDOWN:
_mousePos.x = event.mouse.x;
_mousePos.y = event.mouse.y;
imousePt = _mousePos;
- _interface->update(imousePt, UPDATE_MOUSECLICK);
+ _interface->update(imousePt, (event.type == OSystem::EVENT_LBUTTONDOWN) ? UPDATE_LEFTBUTTONCLICK : UPDATE_RIGHTBUTTONCLICK);
break;
case OSystem::EVENT_MOUSEMOVE:
_mousePos.x = event.mouse.x;
diff --git a/saga/interface.cpp b/saga/interface.cpp
index d64c1a2aa4..8012b2d9f3 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -350,7 +350,6 @@ int Interface::draw() {
int Interface::update(const Point& mousePoint, int updateFlag) {
SURFACE *backBuffer;
-
if (_vm->_scene->isInDemo() || _panelMode == kPanelFade)
return SUCCESS;
@@ -359,7 +358,7 @@ int Interface::update(const Point& mousePoint, int updateFlag) {
if (_panelMode == kPanelMain) {
- if (updateFlag == UPDATE_MOUSEMOVE) {
+ if (updateFlag & UPDATE_MOUSEMOVE) {
if (mousePoint.y < _vm->getSceneHeight()) {
//handlePlayfieldUpdate(backBuffer, imousePointer);
@@ -373,9 +372,11 @@ int Interface::update(const Point& mousePoint, int updateFlag) {
} else {
- if (updateFlag == UPDATE_MOUSECLICK) {
+ if (updateFlag & UPDATE_MOUSECLICK) {
if (mousePoint.y < _vm->getSceneHeight()) {
- handlePlayfieldClick(backBuffer, mousePoint);
+ //handlePlayfieldClick(backBuffer, mousePoint);
+ _vm->_script->playfieldClick(mousePoint, (updateFlag & UPDATE_LEFTBUTTONCLICK) != 0);
+
} else {
handleCommandClick(backBuffer, mousePoint);
}
diff --git a/saga/interface.h b/saga/interface.h
index d9030c3bd7..fa0558e134 100644
--- a/saga/interface.h
+++ b/saga/interface.h
@@ -31,9 +31,11 @@
namespace Saga {
-enum INTERFACE_UPDATE_FLAGS {
+enum InterfaceUpdateFlags {
UPDATE_MOUSEMOVE = 1,
- UPDATE_MOUSECLICK
+ UPDATE_LEFTBUTTONCLICK = 2,
+ UPDATE_RIGHTBUTTONCLICK = 4,
+ UPDATE_MOUSECLICK = UPDATE_LEFTBUTTONCLICK | UPDATE_RIGHTBUTTONCLICK
};
#define ITE_INVENTORY_SIZE 24
diff --git a/saga/objectmap.h b/saga/objectmap.h
index ffe3cbbf9a..3a856161c4 100644
--- a/saga/objectmap.h
+++ b/saga/objectmap.h
@@ -45,14 +45,21 @@ public:
int getSceneNumber() const {
return _nameNumber;
}
-
- int getEntranceNumber() const {
+ int getActorsEntrance() const {
+ return _scriptNumber;
+ }
+ int getScriptNumber() const {
return _scriptNumber;
}
int getRightButtonVerb() const {
return _rightButtonVerb;
}
-
+ int getFlags() const {
+ return _flags;
+ }
+ int getDirection() const {
+ return ((_flags >> 4) & 0xF);
+ }
void draw(SURFACE *ds, int color);
bool hitTest(const Point &testPoint);
private:
diff --git a/saga/saga.h b/saga/saga.h
index 02922eb709..bde42bc1d7 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -122,11 +122,21 @@ enum HitZoneFlags {
// in the specified direction, and the actual specified effect of
// the zone will be delayed until the actor leaves the zone.
kHitZoneAutoWalk = (1 << 2),
+
+ // When set on a hit zone, this causes the character not to walk
+ // to the object (but they will look at it).
+ kHitZoneNoWalk = (1 << 2),
// zone activates only when character stops walking
- kHitZoneTerminus = (1 << 3)
+ kHitZoneTerminus = (1 << 3),
+
+ // Hit zones only - when the zone is clicked on it projects the
+ // click point downwards from the middle of the zone until it
+ // reaches the lowest point in the zone.
+ kHitZoneProject = (1 << 3)
};
+
enum PanelButtonType {
kPanelButtonVerb = 0,
kPanelButtonArrow = 1
diff --git a/saga/scene.cpp b/saga/scene.cpp
index c5ff11199b..44598cfeb8 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -191,7 +191,7 @@ int Scene::startScene() {
scene_qdat = queueIterator.operator->();
assert(scene_qdat != NULL);
- loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType);
+ loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType, 0);
return SUCCESS;
}
@@ -230,7 +230,7 @@ int Scene::nextScene() {
scene_qdat = queueIterator.operator->();
assert(scene_qdat != NULL);
- loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType);
+ loadScene(scene_qdat->scene_n, scene_qdat->load_flag, scene_qdat->scene_proc, scene_qdat->sceneDescription, scene_qdat->fadeType, 0);
return SUCCESS;
}
@@ -277,14 +277,14 @@ int Scene::skipScene() {
_sceneQueue.erase(_sceneQueue.begin(), queueIterator);
endScene();
- loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->sceneDescription, skip_qdat->fadeType);
+ loadScene(skip_qdat->scene_n, skip_qdat->load_flag, skip_qdat->scene_proc, skip_qdat->sceneDescription, skip_qdat->fadeType, 0);
}
// Search for a scene to skip to
return SUCCESS;
}
-int Scene::changeScene(int scene_num) {
+int Scene::changeScene(int sceneNumber, int actorsEntrance) {
assert(_initialized);
if (!_sceneLoaded) {
@@ -292,18 +292,18 @@ int Scene::changeScene(int scene_num) {
return FAILURE;
}
- if ((scene_num < 0) || (scene_num > _sceneMax)) {
+ if ((sceneNumber < 0) || (sceneNumber > _sceneMax)) {
warning("Scene::changeScene(): Error: Can't change scene. Invalid scene number");
return FAILURE;
}
- if (_sceneLUT[scene_num] == 0) {
+ if (_sceneLUT[sceneNumber] == 0) {
warning("Scene::changeScene(): Error: Can't change scene; invalid scene descriptor resource number (0)");
return FAILURE;
}
endScene();
- loadScene(scene_num, BY_SCENE, SC_defaultScene, NULL, false);
+ loadScene(sceneNumber, BY_SCENE, SC_defaultScene, NULL, SCENE_NOFADE, actorsEntrance);
return SUCCESS;
}
@@ -504,7 +504,7 @@ int Scene::getSceneLUT(int scene_num) {
return _sceneLUT[scene_num];
}
-int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneDescription *scene_desc_param, int fadeType) {
+int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneDescription *scene_desc_param, int fadeType, int actorsEntrance) {
SCENE_INFO scene_info;
uint32 res_number = 0;
int result;
@@ -670,7 +670,7 @@ int Scene::loadScene(int scene_num, int load_flag, SCENE_PROC scene_proc, SceneD
_sceneProc(SCENE_BEGIN, &scene_info, this);
- _vm->_actor->updateActorsScene();
+ _vm->_actor->updateActorsScene(actorsEntrance);
if (_desc.flags & kSceneFlagShowCursor)
_vm->_interface->activate();
@@ -985,7 +985,7 @@ void Scene::cmdSceneChange(int argc, const char **argv) {
clearSceneQueue();
- if (changeScene(scene_num) == SUCCESS) {
+ if (changeScene(scene_num, 0) == SUCCESS) {
_vm->_console->DebugPrintf("Scene changed.\n");
} else {
_vm->_console->DebugPrintf("Couldn't change scene!\n");
diff --git a/saga/scene.h b/saga/scene.h
index 4f95a1082d..95889c73bc 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -131,7 +131,7 @@ struct SCENE_ANIMINFO {
typedef SortedList<SCENE_ANIMINFO> SceneAnimInfoList;
-enum SCENE_FADE_TYPES {
+enum SceneTransitionType {
SCENE_NOFADE = 0,
SCENE_FADE = 1,
SCENE_FADE_NO_INTERFACE = 2
@@ -224,7 +224,7 @@ class Scene {
void getSlopes(int &beginSlope, int &endSlope);
int clearSceneQueue(void);
- int changeScene(int scene_num);
+ int changeScene(int sceneNumber, int actorsEntrance);
bool initialized() { return _initialized; }
@@ -233,7 +233,7 @@ class Scene {
int currentSceneNumber() { return _sceneNumber; }
private:
- int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SceneDescription *, int fadeIn);
+ int loadScene(int scene, int load_flag, SCENE_PROC scene_proc, SceneDescription *, int fadeIn, int actorsEntrance);
int loadSceneDescriptor(uint32 res_number);
int loadSceneResourceList(uint32 res_number);
int processSceneResources();
diff --git a/saga/script.cpp b/saga/script.cpp
index 3fa26f5128..f404c3abe3 100644
--- a/saga/script.cpp
+++ b/saga/script.cpp
@@ -731,7 +731,144 @@ void Script::setPointerVerb() {
}
}
-void Script::whichObject(const Point& mousePointer) {
+void Script::hitObject(bool leftButton) {
+ int verb;
+ verb = leftButton ? _leftButtonVerb : _rightButtonVerb;
+
+ if (verb > kVerbNone) {
+ if (_firstObjectSet) {
+ if (_secondObjectNeeded) {
+ _pendingObject[0] = _currentObject[0];
+ _pendingObject[1] = _currentObject[1];
+ _pendingVerb = verb;
+
+ _leftButtonVerb = verb;
+ if (_pendingVerb > kVerbNone) {
+ // statusColor = BRIGHT_WHITE;
+ }
+ showVerb();
+ /*statusColor = GREEN_BA;*/
+
+ _secondObjectNeeded = false;
+ _firstObjectSet = false;
+ return;
+ }
+ } else {
+ if (verb == kVerbGive) {
+ _secondObjectNeeded = true;
+ } else {
+ if (verb == kVerbUse) {
+
+ if (_currentObjectFlags[0] & kObjUseWith) {
+ _secondObjectNeeded = true;
+ }
+ }
+ }
+
+ if (!_secondObjectNeeded) {
+ _pendingObject[0] = _currentObject[0];
+ _pendingObject[1] = ID_NOTHING;
+ _pendingVerb = verb;
+
+ _secondObjectNeeded = false;
+ _firstObjectSet = false;
+ } else {
+ _firstObjectSet = true;
+ }
+ }
+
+ _leftButtonVerb = verb;
+ if (_pendingVerb > kVerbNone) {
+ // statusColor = BRIGHT_WHITE;
+ }
+ showVerb();
+ //statusColor = GREEN_BA;
+ }
+
+}
+
+void Script::playfieldClick(const Point& mousePoint, bool leftButton) {
+ Location pickLocation;
+ const HitZone *hitZone;
+
+ _vm->_actor->abortSpeech();
+
+ if ((_vm->_actor->_protagonist->currentAction != kActionWait) &&
+ (_vm->_actor->_protagonist->currentAction != kActionFreeze) &&
+ (_vm->_actor->_protagonist->currentAction != kActionWalkToLink) &&
+ (_vm->_actor->_protagonist->currentAction != kActionWalkToPoint)) {
+ return;
+ }
+ if (_pendingVerb > kVerbNone) {
+ setLeftButtonVerb(kVerbWalkTo);
+ }
+
+ if (_pointerObject != ID_NOTHING) {
+ hitObject( leftButton );
+ } else {
+ _pendingObject[0] = ID_NOTHING;
+ _pendingObject[1] = ID_NOTHING;
+ _pendingVerb = kVerbWalkTo;
+ }
+
+
+ // tiled stuff
+ if (_vm->_scene->getFlags() & kSceneFlagISO) {
+ //todo: it
+ } else {
+ pickLocation.fromScreenPoint(mousePoint);
+ }
+
+
+ hitZone = NULL;
+
+ if (objectIdType(_pendingObject[0]) == kGameObjectHitZone) {
+ // hitZone = _vm->_scene->_objectMap _pendingObject[0]; //TODO:
+ } else {
+ if ((_pendingVerb == kVerbUse) && (objectIdType(_pendingObject[1]) == kGameObjectHitZone)) {
+ // hitZone = _vm->_scene->_objectMap _pendingObject[1]; //TODO:
+ }
+ }
+
+ if (hitZone != NULL) {
+ if (hitZone->getFlags() & kHitZoneNoWalk) {
+ _vm->_actor->actorFaceTowardsPoint(ID_PROTAG, pickLocation);
+ doVerb();
+ return;
+ }
+
+ if (hitZone->getFlags() & kHitZoneProject) {
+ //TODO: do it
+ }
+ }
+
+ switch (_pendingVerb) {
+ case kVerbWalkTo:
+ case kVerbPickUp:
+ case kVerbOpen:
+ case kVerbClose:
+ case kVerbUse:
+ _vm->_actor->actorWalkTo(ID_PROTAG, pickLocation);
+ break;
+
+ case kVerbLookAt:
+ if (objectIdType(_pendingObject[0]) != kGameObjectActor ) {
+ _vm->_actor->actorWalkTo(ID_PROTAG, pickLocation);
+ } else {
+ doVerb();
+ }
+ break;
+
+ case kVerbTalkTo:
+ case kVerbGive:
+ doVerb();
+ break;
+ }
+
+
+}
+
+void Script::whichObject(const Point& mousePoint) {
uint16 objectId;
int16 objectFlags;
int newRightButtonVerb;
@@ -748,7 +885,7 @@ void Script::whichObject(const Point& mousePointer) {
if (_vm->_actor->_protagonist->currentAction == kActionWalkDir) {
} else {
- newObjectId = _vm->_actor->testHit(mousePointer);
+ newObjectId = _vm->_actor->testHit(mousePoint);
if (newObjectId != ID_NOTHING) {
if (objectIdType(newObjectId) == kGameObjectObject) {
@@ -785,12 +922,12 @@ void Script::whichObject(const Point& mousePointer) {
if (_vm->_scene->getFlags() & kSceneFlagISO) {
//todo: it
} else {
- pickLocation.x = mousePointer.x;
- pickLocation.y = mousePointer.y;
+ pickLocation.x = mousePoint.x;
+ pickLocation.y = mousePoint.y;
pickLocation.z = 0;
}
- hitZoneId = _vm->_scene->_objectMap->hitTest(mousePointer);
+ hitZoneId = _vm->_scene->_objectMap->hitTest(mousePoint);
if ((hitZoneId != -1) && 0) { //TODO: do it
//hitZone = _vm->_scene->_objectMap->getZone(hitZoneId);
diff --git a/saga/script.h b/saga/script.h
index 9236a7e131..3f195f6df7 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -255,7 +255,9 @@ public:
void setVerb(int verb);
int getCurrentVerb() const { return _currentVerb; }
void setPointerVerb();
- void whichObject(const Point& mousePointer);
+ void whichObject(const Point& mousePoint);
+ void hitObject(bool leftButton);
+ void playfieldClick(const Point& mousePoint, bool leftButton);
void setLeftButtonVerb(int verb);
int getLeftButtonVerb() const { return _leftButtonVerb; }
@@ -266,6 +268,11 @@ public:
_pointerObject = ID_NOTHING;
_currentObject[_firstObjectSet ? 1 : 0] = ID_NOTHING;
}
+ void setNoPendingVerb() {
+ _pendingVerb = kVerbNone;
+ _currentObject[0] = _currentObject[0] = ID_NOTHING;
+ setPointerVerb();
+ }
void scriptInfo();
void scriptExec(int argc, const char **argv);
@@ -287,13 +294,14 @@ protected:
bool _secondObjectNeeded;
uint16 _currentObject[2];
int16 _currentObjectFlags[2];
- uint16 _pendingObject[2];
int _currentVerb;
int _stickyVerb;
int _leftButtonVerb;
int _rightButtonVerb;
- int _pendingVerb;
+public:
+ uint16 _pendingObject[2];
+ int _pendingVerb;
uint16 _pointerObject;
public: