aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--saga/actor.cpp9
-rw-r--r--saga/actor.h1
-rw-r--r--saga/isomap.cpp81
-rw-r--r--saga/isomap.h2
-rw-r--r--saga/script.h4
-rw-r--r--saga/sfuncs.cpp50
6 files changed, 128 insertions, 19 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 64ad312b4a..44994e6d87 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -847,7 +847,10 @@ void Actor::handleActions(int msec, bool setup) {
if (!actor->inScene)
continue;
- //todo: dragon stuff
+ if ((_vm->getGameType() == GType_ITE) && (i == ACTOR_DRAGON_INDEX)) {
+ moveDragon(actor);
+ continue;
+ }
/* if (actor->index == 2)
debug(9, "Action: %d Flags: %x", actor->currentAction, actor->flags);*/
@@ -1619,7 +1622,9 @@ bool Actor::actorWalkTo(uint16 actorId, const Location &toLocation) {
if (_vm->_scene->getFlags() & kSceneFlagISO) {
- //todo: dragon stuff
+ if ((_vm->getGameType() == GType_ITE) && (actor->index == ACTOR_DRAGON_INDEX)) {
+ return false;
+ }
actor->finalTarget = toLocation;
actor->walkStepsCount = 0;
diff --git a/saga/actor.h b/saga/actor.h
index 8a58431e33..bbc6965501 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -64,6 +64,7 @@ class HitZone;
#define ACTOR_SPEECH_ACTORS_MAX 8
#define ACTOR_DRAGON_TURN_MOVES 4
+#define ACTOR_DRAGON_INDEX 133
#define ACTOR_NO_ENTRANCE -1
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index dba57939b3..ab543981cb 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -997,14 +997,13 @@ void IsoMap::pushPoint(int16 u, int16 v, uint16 cost, uint16 direction) {
pathCell->cost = cost;
}
-IsoTileData *IsoMap::getTile(int16 u, int16 v, int16 z) {
+int16 IsoMap::getTileIndex(int16 u, int16 v, int16 z) {
int16 mtileU;
int16 mtileV;
int16 uc;
int16 vc;
int16 u0;
int16 v0;
- int16 tileIndex;
int16 platformIndex;
int16 metaTileIndex;
@@ -1044,14 +1043,20 @@ IsoTileData *IsoMap::getTile(int16 u, int16 v, int16 z) {
platformIndex = _metaTileList[metaTileIndex].stack[z];
if (platformIndex < 0) {
- return NULL;
+ return 0;
}
if (_tilePlatformsCount <= platformIndex) {
error("IsoMap::getTile wrong platformIndex");
}
- tileIndex = _tilePlatformList[platformIndex].tiles[u0][v0];
+ return _tilePlatformList[platformIndex].tiles[u0][v0];
+}
+
+IsoTileData *IsoMap::getTile(int16 u, int16 v, int16 z) {
+ int16 tileIndex;
+
+ tileIndex = getTileIndex(u, v, z);
if (tileIndex == 0) {
return NULL;
@@ -1255,6 +1260,74 @@ void IsoMap::placeOnTileMap(const Location &start, Location &result, int16 dista
result.v() = ((vBase + bestV) << 4) + 8;
}
+bool IsoMap::findNearestChasm(int16 &u0, int16 &v0, uint16 &direction) {
+ int16 u, v;
+ uint16 i;
+ u = u0;
+ v = v0;
+
+ for (i = 1; i < 5; i++) {
+ if (getTile( u - i, v, 6) == NULL) {
+ u0 = u - i - 1;
+ v0 = v;
+ direction = kDirDownLeft;
+ return true;
+ }
+
+ if (getTile( u, v - i, 6) == NULL) {
+ u0 = u;
+ v0 = v - i - 1;
+ direction = kDirDownRight;
+ return true;
+ }
+
+ if (getTile( u - i, v - i, 6) == NULL) {
+ u0 = u - i - 1;
+ v0 = v - i - 1;
+ direction = kDirDown;
+ return true;
+ }
+
+ if (getTile( u + i, v - i, 6) == NULL) {
+ u0 = u + i + 1;
+ v0 = v - i - 1;
+ direction = kDirDownRight;
+ return true;
+ }
+
+ if (getTile( u - i, v + i, 6) == NULL) {
+ u0 = u + i + 1;
+ v0 = v - i - 1;
+ direction = kDirLeft;
+ return true;
+ }
+ }
+
+ for (i = 1; i < 5; i++) {
+ if (getTile( u + i, v, 6) == NULL) {
+ u0 = u + i + 1;
+ v0 = v;
+ direction = kDirUpRight;
+ return true;
+ }
+
+ if (getTile( u, v + i, 6) == NULL) {
+ u0 = u;
+ v0 = v + i + 1;
+ direction = kDirUpLeft;
+ return true;
+ }
+
+ if (getTile( u + i, v + i, 6) == NULL) {
+ u0 = u + i + 1;
+ v0 = v + i + 1;
+ direction = kDirUp;
+ return true;
+ }
+ }
+ return false;
+}
+
void IsoMap::findDragonTilePath(ActorData* actor,const Location &start, const Location &end, uint16 initialDirection) {
byte *res;
int i;
diff --git a/saga/isomap.h b/saga/isomap.h
index 0fe11f7861..96802e560e 100644
--- a/saga/isomap.h
+++ b/saga/isomap.h
@@ -168,11 +168,13 @@ public:
void screenPointToTileCoords(const Point &position, Location &location);
void placeOnTileMap(const Location &start, Location &result, int16 distance, uint16 direction);
void findDragonTilePath(ActorData* actor, const Location &start, const Location &end, uint16 initialDirection);
+ bool findNearestChasm(int16 &u0, int16 &v0, uint16 &direction);
void findTilePath(ActorData* actor, const Location &start, const Location &end);
bool nextTileTarget(ActorData* actor);
void setTileDoorState(int doorNumber, int doorState);
Point getMapPosition() { return _mapPosition; }
void setMapPosition(int x, int y);
+ int16 getTileIndex(int16 u, int16 v, int16 z);
private:
void drawTiles(SURFACE *ds, const Location *location);
diff --git a/saga/script.h b/saga/script.h
index 8393b653f3..006bf7312d 100644
--- a/saga/script.h
+++ b/saga/script.h
@@ -527,8 +527,8 @@ private:
void sfGetActorY(SCRIPTFUNC_PARAMS);
void sfEraseDelta(SCRIPTFUNC_PARAMS);
void sfPlayMusic(SCRIPTFUNC_PARAMS);
- void SF_pickClimbOutPos(SCRIPTFUNC_PARAMS);
- void SF_tossRif(SCRIPTFUNC_PARAMS);
+ void sfPickClimbOutPos(SCRIPTFUNC_PARAMS);
+ void sfTossRif(SCRIPTFUNC_PARAMS);
void sfShowControls(SCRIPTFUNC_PARAMS);
void SF_showMap(SCRIPTFUNC_PARAMS);
void sfPuzzleWon(SCRIPTFUNC_PARAMS);
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index f0ef31c8ac..42c5a4282d 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -117,8 +117,8 @@ void Script::setupScriptFuncList(void) {
OPCODE(sfGetActorY),
OPCODE(sfEraseDelta),
OPCODE(sfPlayMusic),
- OPCODE(SF_pickClimbOutPos),
- OPCODE(SF_tossRif),
+ OPCODE(sfPickClimbOutPos),
+ OPCODE(sfTossRif),
OPCODE(sfShowControls),
OPCODE(SF_showMap),
OPCODE(sfPuzzleWon),
@@ -1593,19 +1593,47 @@ void Script::sfPlayMusic(SCRIPTFUNC_PARAMS) {
}
// Script function #64 (0x40)
-void Script::SF_pickClimbOutPos(SCRIPTFUNC_PARAMS) {
- for (int i = 0; i < nArgs; i++)
- thread->pop();
+void Script::sfPickClimbOutPos(SCRIPTFUNC_PARAMS) {
+ int16 u, v, t;
+ ActorData *protagonist = _vm->_actor->_protagonist;
+ while (true) {
+
+ u = (_vm->_rnd.getRandomNumber(63) & 63) + 40;
+ v = (_vm->_rnd.getRandomNumber(63) & 63) + 40;
+ t = _vm->_isoMap->getTileIndex(u, v, 6);
+ if (t == 65) {
+ protagonist->location.u() = (u << 4) + 4;
+ protagonist->location.v() = (v << 4) + 4;
+ protagonist->location.z = 48;
+ break;
+ }
- error("STUB: SF_pickClimbOutPos(), %d args", nArgs);
+ }
}
// Script function #65 (0x41)
-void Script::SF_tossRif(SCRIPTFUNC_PARAMS) {
- for (int i = 0; i < nArgs; i++)
- thread->pop();
-
- error("STUB: SF_tossRif(), %d args", nArgs);
+void Script::sfTossRif(SCRIPTFUNC_PARAMS) {
+ int16 uc , vc;
+ uint16 direction;
+ ActorData *protagonist = _vm->_actor->_protagonist;
+
+ uc = protagonist->location.u() >> 4;
+ vc = protagonist->location.v() >> 4;
+ if (_vm->_isoMap->findNearestChasm(uc, vc, direction)) {
+ uc <<= 4;
+ vc <<= 4;
+ protagonist->facingDirection = direction;
+
+ protagonist->finalTarget.u() = uc;
+ protagonist->finalTarget.v() = vc;
+ protagonist->finalTarget.z = -40;
+ protagonist->currentAction = kActionFall;
+ protagonist->actionCycle = 24;
+ protagonist->fallAcceleration = - 20;
+ protagonist->fallVelocity = - (protagonist->fallAcceleration * 16) / 2 - (44 / 12);
+ protagonist->fallPosition = protagonist->location.z << 4;
+ protagonist->actionCycle--;
+ }
}
// Script function #66 (0x42)