diff options
-rw-r--r-- | saga/actor.cpp | 9 | ||||
-rw-r--r-- | saga/actor.h | 1 | ||||
-rw-r--r-- | saga/isomap.cpp | 81 | ||||
-rw-r--r-- | saga/isomap.h | 2 | ||||
-rw-r--r-- | saga/script.h | 4 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 50 |
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) |