aboutsummaryrefslogtreecommitdiff
path: root/sword1/router.cpp
diff options
context:
space:
mode:
authorRobert Göffringmann2003-12-16 18:23:15 +0000
committerRobert Göffringmann2003-12-16 18:23:15 +0000
commit0cf52df6510cbb06b6b8489beac829d58687542d (patch)
treeeb129b32b5bdb4860daf5fae74bd2a1f7153d667 /sword1/router.cpp
parentde51f631be939a9da9ef0dd2e5f33fc605bdd01b (diff)
downloadscummvm-rg350-0cf52df6510cbb06b6b8489beac829d58687542d.tar.gz
scummvm-rg350-0cf52df6510cbb06b6b8489beac829d58687542d.tar.bz2
scummvm-rg350-0cf52df6510cbb06b6b8489beac829d58687542d.zip
copied the SwordRouter from the original BS1 sources.
It doesn't fit to our coding guidelines but at least it's working, so please bear with it for now. :) svn-id: r11687
Diffstat (limited to 'sword1/router.cpp')
-rw-r--r--sword1/router.cpp3331
1 files changed, 2011 insertions, 1320 deletions
diff --git a/sword1/router.cpp b/sword1/router.cpp
index 7ae4296140..a4d2ed7006 100644
--- a/sword1/router.cpp
+++ b/sword1/router.cpp
@@ -1,5 +1,5 @@
/* ScummVM - Scumm Interpreter
- * Copyright (C) Revolution Software Ltd.
+ * Copyright (C) 2003 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,625 +21,298 @@
#include "stdafx.h"
#include "router.h"
-#include "util.h"
+#include "common/util.h"
+#include "scummsys.h"
+#include "swordres.h"
+#include "sworddefs.h"
#include "objectman.h"
#include "resman.h"
-#include "sworddefs.h"
-#define SLOW_IN 3
-#define SLOW_OUT 7
+/****************************************************************************
+ * JROUTER.C polygon router with modular walks
+ * using a tree of modules
+ * 21 july 94
+ * 3 november 94
+ * System currently works by scanning grid data and coming up with a ROUTE
+ * as a series of way points(nodes), the smoothest eight directional PATH
+ * through these nodes is then found, and a WALK created to fit the PATH.
+ *
+ * Two funtions are called by the user, RouteFinder creates a route as a
+ * module list, HardWalk creates an animation list from the module list.
+ * The split is only provided to allow the possibility of turning the
+ * autorouter over two game cycles.
+ ****************************************************************************
+ *
+ * Routine timings on osborne 486
+ *
+ * Read floor resource (file already loaded) 112 pixels
+ *
+ * Read mega resource (file already loaded) 112 pixels
+ *
+ *
+ *
+ ****************************************************************************
+ *
+ * Modified 12 Oct 95
+ *
+ * Target Points within 1 pixel of a line are ignored ???
+ *
+ * Modules split into Points within 1 pixel of a line are ignored ???
+ *
+ ****************************************************************************/
+
+
+
+
+/*
+ * Include Files
+ */
+
+/*#include <stdio.h>
+#include <conio.h>
+#include <stdlib.h>
+#include <io.h>
+#include <dos.h>
+#include <string.h>
+
+#include "coredata.h"
+#include "utypes.h"
+#include "header.h"
+#include "object.h"
+#include "varnames.h"
+#include "jrouter.h"
+#include "svga.h"
+#include "protocol.h"
+#include "memman.h"
+#include "resman.h"
+#include "tdebug.h"
+#include "blit.h"
+#include "line.h"
+#include "pc.h"
+#include "vblank.h"*/
+
+//#define MAX_FRAMES_PER_CHAR 128
+#define NO_DIRECTIONS 8
+#define SLOW_IN 3
+#define SLOW_OUT 7
+#define ROUTE_END_FLAG 255
+//#define PLOT_PATHS 1
+#undef PLOT_PATHS
SwordRouter::SwordRouter(ObjectMan *pObjMan, ResMan *pResMan) {
_objMan = pObjMan;
_resMan = pResMan;
_numExtraBars = _numExtraNodes = 0;
- _nNodes = _nBars = 0;
+ nnodes = nbars = 0;
_playerTargetX = _playerTargetY = _playerTargetDir = _playerTargetStance = 0;
+ diagonalx = diagonaly = 0;
}
-int SwordRouter::routeFinder(int32 id, BsObject *mega, int32 x, int32 y, int32 targetDir) {
- loadWalkResources(id, mega, x, y, targetDir); // init vars for subs
- // init offset pointers
- FrameInfos frameInfo;
-
- frameInfo.framesPerStep = _nWalkFrames / 2;
- frameInfo.framesPerChar = _nWalkFrames * NO_DIRECTIONS;
- frameInfo.standFrames = frameInfo.framesPerChar;
- frameInfo.turnFramesLeft = frameInfo.framesPerChar;
- frameInfo.turnFramesRight = frameInfo.framesPerChar;
- frameInfo.walkFramesLeft = 0;
- frameInfo.walkFramesRight = 0;
- frameInfo.slowInFrames = 0;
- frameInfo.slowOutFrames = 0;
- frameInfo.startX = mega->o_xcoord;
- frameInfo.startY = mega->o_ycoord;
- frameInfo.targetX = x;
- frameInfo.targetY = y;
- frameInfo.targetDir = targetDir;
- frameInfo.scaleA = mega->o_scale_a;
- frameInfo.scaleB = mega->o_scale_b;
-
- if (id == GEORGE) {
- frameInfo.turnFramesLeft = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT;
- frameInfo.turnFramesRight = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT + NO_DIRECTIONS;
- frameInfo.walkFramesLeft = frameInfo.framesPerChar + NO_DIRECTIONS;
- frameInfo.walkFramesRight = 2 * frameInfo.framesPerChar + NO_DIRECTIONS;
- frameInfo.slowInFrames = 3 * frameInfo.framesPerChar + NO_DIRECTIONS;
- frameInfo.slowOutFrames = 3 * frameInfo.framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN;
- } else if (id == NICO) {
- frameInfo.turnFramesLeft = frameInfo.framesPerChar + NO_DIRECTIONS;
- frameInfo.turnFramesRight = frameInfo.framesPerChar + 2 * NO_DIRECTIONS;
- frameInfo.walkFramesLeft = 0;
- frameInfo.walkFramesRight = 0;
- frameInfo.slowInFrames = 0;
- frameInfo.slowOutFrames = 0;
- }
- int32 routeFlag = getRoute();
- int32 routeLength = 0;
- if (routeFlag == 1) {
- // extract the route as nodes and the directions to go between each node
- // route.X,route.Y and route.Dir now hold all the route infomation with
- // the target dir or route continuation
- routeLength = extractRoute(targetDir);
- }
- int32 solidFlag = 0;
- if (routeFlag == 2) //special case for zero length route
- {
- if (targetDir >7)// if target direction specified as any
- targetDir = mega->o_dir;
- // just a turn on the spot is required set an end module for the route let the animator deal with it
- // modularPath is normally set by ExtractRoute
- _modularPath[0].dir = mega->o_dir;
- _modularPath[0].num = 0;
- _modularPath[0].x = mega->o_xcoord;
- _modularPath[0].y = mega->o_ycoord;
- _modularPath[1].dir = targetDir;
- _modularPath[1].num = 0;
- _modularPath[1].x = mega->o_xcoord;
- _modularPath[1].y = mega->o_ycoord;
- _modularPath[2].dir = 9;
- _modularPath[2].num = ROUTE_END_FLAG;
-
- slidyWalkAnimator(mega->o_route, &frameInfo, id);
- routeFlag = 2;
- } else if (routeFlag == 1) { // a normal route
- smoothestPath(mega->o_xcoord, mega->o_ycoord, mega->o_dir, routeLength);//Converts the route to an exact path
- // The Route had waypoints and direction options
- // The Path is an exact set of lines in 8 directions that reach the target.
- // The path is in module format, but steps taken in each direction are not accurate
- // if target dir = 8 then the walk isn't linked to an anim so
- // we can create a route without sliding and miss the exact target
- if (targetDir == NO_DIRECTIONS) {
- solidPath(mega->o_scale_a, mega->o_scale_b);
- solidFlag = solidWalkAnimator(mega->o_route, &frameInfo, id);
- }
-
- if (!solidFlag) {
- slidyPath(mega->o_scale_a, mega->o_scale_b, targetDir);
- slidyWalkAnimator(mega->o_route, &frameInfo, id);
- }
- }
- return routeFlag;
-}
-
-void SwordRouter::slidyPath(int32 scaleA, int32 scaleB, uint16 targetDir) {
- /****************************************************************************
- * SlidyPath creates a path based on part steps with no sliding to get
- * as near as possible to the target without any sliding this routine is
- * currently unused, but is intended for use when just clicking about.
- *
- * produce a module list from the line data
- *
- ****************************************************************************/
- int32 smooth;
- int32 slidy;
- int32 scale;
- int32 stepX;
- int32 stepY;
- int32 deltaX;
- int32 deltaY;
+/*
+ *
+ */
- // strip out the short sections
- slidy = 1;
- smooth = 1;
- _modularPath[0].x = _smoothPath[0].x;
- _modularPath[0].y = _smoothPath[0].y;
- _modularPath[0].dir = _smoothPath[0].dir;
- _modularPath[0].num = 0;
+/*
+ * CODE
+ */
- while (_smoothPath[smooth].num < ROUTE_END_FLAG)
- {
- scale = scaleA * _smoothPath[smooth].y + scaleB;
- deltaX = _smoothPath[smooth].x - _modularPath[slidy-1].x;
- deltaY = _smoothPath[smooth].y - _modularPath[slidy-1].y;
- stepX = _modX[_smoothPath[smooth].dir];
- stepY = _modY[_smoothPath[smooth].dir];
- stepX = stepX * scale;
- stepY = stepY * scale;
- stepX = stepX >> 19;// quarter a step minimum
- stepY = stepY >> 19;
- if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY)))
- {
- _modularPath[slidy].x = _smoothPath[smooth].x;
- _modularPath[slidy].y = _smoothPath[smooth].y;
- _modularPath[slidy].dir = _smoothPath[smooth].dir;
- _modularPath[slidy].num = 1;
- slidy += 1;
- }
- smooth += 1;
- }
- // in case the last bit had no steps
- if (slidy > 1)
- {
- _modularPath[slidy-1].x = _smoothPath[smooth-1].x;
- _modularPath[slidy-1].y = _smoothPath[smooth-1].y;
- }
- // set up the end of the walk
- _modularPath[slidy].x = _smoothPath[smooth-1].x;
- _modularPath[slidy].y = _smoothPath[smooth-1].y;
- _modularPath[slidy].dir = targetDir;
- _modularPath[slidy].num = 0;
- slidy += 1;
- _modularPath[slidy].x = _smoothPath[smooth-1].x;
- _modularPath[slidy].y = _smoothPath[smooth-1].y;
- _modularPath[slidy].dir = 9;
- _modularPath[slidy].num = ROUTE_END_FLAG;
-}
+// **************************************************************************
+// **************************************************************************
+// **************************************************************************
+// **************************************************************************
+// **************************************************************************
-int32 SwordRouter::solidPath(int32 scaleA, int32 scaleB) {
+int32 SwordRouter::routeFinder(int32 id, BsObject *megaObject, int32 x, int32 y, int32 dir)
+{
/****************************************************************************
- * SolidPath creates a path based on whole steps with no sliding to get
- * as near as possible to the target without any sliding this routine is
- * currently unused, but is intended for use when just clicking about.
+ * RouteFinder.C polygon router with modular walks
+ * 21 august 94
+ * 3 november 94
+ * RouteFinder creates a list of modules that enables HardWalk to create
+ * an animation list.
*
- * produce a module list from the line data
+ * RouteFinder currently works by scanning grid data and coming up with a ROUTE
+ * as a series of way points(nodes), the smoothest eight directional PATH
+ * through these nodes is then found, this information is made available to
+ * HardWalk for a WALK to be created to fit the PATH.
+ *
+ * 30 november 94 return values modified
+ *
+ * return 0 = failed to find a route
+ *
+ * 1 = found a route
*
+ * 2 = mega already at target
+ *
****************************************************************************/
- int32 smooth;
- int32 solid;
- int32 scale;
- int32 stepX;
- int32 stepY;
- int32 deltaX;
- int32 deltaY;
-
- solid = 1;
- smooth = 1;
- _modularPath[0].x = _smoothPath[0].x;
- _modularPath[0].y = _smoothPath[0].y;
- _modularPath[0].dir = _smoothPath[0].dir;
- _modularPath[0].num = 0;
-
- do {
- scale = scaleA * _smoothPath[smooth].y + scaleB;
- deltaX = _smoothPath[smooth].x - _modularPath[solid-1].x;
- deltaY = _smoothPath[smooth].y - _modularPath[solid-1].y;
- stepX = _modX[_smoothPath[smooth].dir];
- stepY = _modY[_smoothPath[smooth].dir];
- stepX = stepX * scale;
- stepY = stepY * scale;
- stepX = stepX >> 16;
- stepY = stepY >> 16;
- if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY))) {
- _modularPath[solid].x = _smoothPath[smooth].x;
- _modularPath[solid].y = _smoothPath[smooth].y;
- _modularPath[solid].dir = _smoothPath[smooth].dir;
- _modularPath[solid].num = 1;
- solid += 1;
- }
- smooth += 1;
- } while (_smoothPath[smooth].num < ROUTE_END_FLAG);
- // in case the last bit had no steps
- if (solid == 1) { //there were no paths so put in a dummy end
- solid = 2;
- _modularPath[1].dir = _smoothPath[0].dir;
- _modularPath[1].num = 0;
- }
- _modularPath[solid-1].x = _smoothPath[smooth-1].x;
- _modularPath[solid-1].y = _smoothPath[smooth-1].y;
- // set up the end of the walk
- _modularPath[solid].x = _smoothPath[smooth-1].x;
- _modularPath[solid].y = _smoothPath[smooth-1].y;
- _modularPath[solid].dir = 9;
- _modularPath[solid].num = ROUTE_END_FLAG;
- return 1;
-}
-int32 SwordRouter::solidWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId) {
- int32 p;
- int32 i;
- int32 left;
- int32 lastDir;
- int32 currentDir;
- int32 turnDir;
- int32 scale;
- int32 step;
- int32 module;
- int32 moduleX;
- int32 moduleY;
- int32 module16X;
- int32 module16Y;
- int32 errorX;
- int32 errorY;
- int32 moduleEnd;
- int32 slowStart;
- int32 stepCount;
- int32 lastCount;
- int32 frame;
-// start at the begining for a change
- lastDir = _modularPath[0].dir;
- p = 1;
- currentDir = _modularPath[1].dir;
- module = frInfo->framesPerChar + lastDir;
- moduleX = frInfo->startX;
- moduleY = frInfo->startY;
- module16X = moduleX << 16;
- module16Y = moduleY << 16;
- slowStart = 0;
- stepCount = 0;
+ int32 routeFlag = 0;
+ int32 solidFlag = 0;
- //****************************************************************************
- // SOLID
- // START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY
- // BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED
- //****************************************************************************
- walkAnim[stepCount].frame = module;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = lastDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
+ megaId = id;
- //****************************************************************************
- // SOLID
- // TURN TO START THE WALK
- //****************************************************************************
- // rotate if we need to
- if (lastDir != currentDir)
- {
- // get the direction to turn
- turnDir = currentDir - lastDir;
- if ( turnDir < 0)
- turnDir += NO_DIRECTIONS;
+ LoadWalkResources(megaObject, x, y, dir);
- if (turnDir > 4)
- turnDir = -1;
- else if (turnDir > 0)
- turnDir = 1;
-
- // rotate to new walk direction
- // for george and nico put in a head turn at the start
- if ((megaId == GEORGE) || (megaId == NICO))
- {
- if ( turnDir < 0) // new frames for turn frames 29oct95jps
- {
- module = frInfo->turnFramesLeft + lastDir;
- }
- else
- {
- module = frInfo->turnFramesRight + lastDir;
- }
- walkAnim[stepCount].frame = module;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = lastDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
-
- // rotate till were facing new dir then go back 45 degrees
- while (lastDir != currentDir)
- {
- lastDir += turnDir;
- if ( turnDir < 0) // new frames for turn frames 29oct95jps
- {
- if ( lastDir < 0)
- lastDir += NO_DIRECTIONS;
- module = frInfo->turnFramesLeft + lastDir;
- }
- else
- {
- if ( lastDir > 7)
- lastDir -= NO_DIRECTIONS;
- module = frInfo->turnFramesRight + lastDir;
- }
- walkAnim[stepCount].frame = module;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = lastDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
- // the back 45 degrees bit
- stepCount -= 1;// step back one because new head turn for george takes us past the new dir
- }
+ framesPerStep = nWalkFrames/2;
+ framesPerChar = nWalkFrames * NO_DIRECTIONS;
- //****************************************************************************
- // SOLID
- // THE SLOW IN
- //****************************************************************************
+ // offset pointers added Oct 30 95 JPS
+ standFrames = framesPerChar;
+ turnFramesLeft = standFrames;
+ turnFramesRight = standFrames;
+ walkFramesLeft = 0;
+ walkFramesRight = 0;
+ slowInFrames = 0;
+ slowOutFrames = 0;
- // do start frames if its george and left or right
if (megaId == GEORGE)
{
- if (_modularPath[1].num > 0)
- {
- if (currentDir == 2) // only for george
- {
- slowStart = 1;
- walkAnim[stepCount].frame = 296;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- walkAnim[stepCount].frame = 297;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- walkAnim[stepCount].frame = 298;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
- else if (currentDir == 6) // only for george
- {
- slowStart = 1;
- walkAnim[stepCount].frame = 299;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- walkAnim[stepCount].frame = 300;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- walkAnim[stepCount].frame = 301;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
- }
+ turnFramesLeft = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT;
+ turnFramesRight = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN + 4 * SLOW_OUT + NO_DIRECTIONS;
+ walkFramesLeft = framesPerChar + NO_DIRECTIONS;
+ walkFramesRight = 2 * framesPerChar + NO_DIRECTIONS;
+ slowInFrames = 3 * framesPerChar + NO_DIRECTIONS;
+ slowOutFrames = 3 * framesPerChar + NO_DIRECTIONS + 2 * SLOW_IN;
+ }
+ else if (megaId == NICO)
+ {
+ turnFramesLeft = framesPerChar + NO_DIRECTIONS;
+ turnFramesRight = framesPerChar + 2 * NO_DIRECTIONS;
+ walkFramesLeft = 0;
+ walkFramesRight = 0;
+ slowInFrames = 0;
+ slowOutFrames = 0;
}
- //****************************************************************************
- // SOLID
- // THE WALK
- //****************************************************************************
- if (currentDir > 4)
- left = frInfo->framesPerStep;
- else
- left = 0;
+// **************************************************************************
+// All route data now loaded start finding a route
+// **************************************************************************
+// **************************************************************************
+// Check if we can get a route through the floor changed 12 Oct95 JPS
+// **************************************************************************
- lastCount = stepCount;
- lastDir = 99;// this ensures that we don't put in turn frames for the start
- currentDir = 99;// this ensures that we don't put in turn frames for the start
+ routeFlag = GetRoute();
- do
+ if (routeFlag == 2) //special case for zero length route
{
- while(_modularPath[p].num > 0)
+ if (targetDir >7)// if target direction specified as any
{
- currentDir = _modularPath[p].dir;
- if (currentDir< NO_DIRECTIONS)
- {
-
- module = currentDir * frInfo->framesPerStep * 2 + left;
- if (left == 0)
- left = frInfo->framesPerStep;
- else
- left = 0;
- moduleEnd = module + frInfo->framesPerStep;
- step = 0;
- scale = (frInfo->scaleA * moduleY + frInfo->scaleB);
- do
- {
- module16X += _dx[module]*scale;
- module16Y += _dy[module]*scale;
- moduleX = module16X >> 16;
- moduleY = module16Y >> 16;
- walkAnim[stepCount].frame = module;
- walkAnim[stepCount].step = step;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- module += 1;
- step += 1;
- }
- while( module < moduleEnd) ;
- errorX = _modularPath[p].x - moduleX;
- errorX = errorX * _modX[_modularPath[p].dir];
- errorY = _modularPath[p].y - moduleY;
- errorY = errorY * _modY[_modularPath[p].dir];
- if ((errorX < 0) || (errorY < 0))
- {
- _modularPath[p].num = 0;
- stepCount -= frInfo->framesPerStep;
- if (left == 0)
- left = frInfo->framesPerStep;
- else
- left = 0;
- // Okay this is the end of a section
- moduleX = walkAnim[stepCount-1].x;
- moduleY = walkAnim[stepCount-1].y;
- module16X = moduleX << 16;
- module16Y = moduleY << 16;
- _modularPath[p].x =moduleX;
- _modularPath[p].y =moduleY;
- // Now is the time to put in the turn frames for the last turn
- if ((stepCount - lastCount) < frInfo->framesPerStep)// no step taken
- {
- currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next
- if (slowStart == 1)// clean up if a slow in but no walk
- {
- stepCount -= 3;
- lastCount -= 3;
- slowStart = 0;
- }
- }
- // check each turn condition in turn
- if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) // only for george
- {
- lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left
- if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6)))
- {
- // turn at the end of the last walk
- frame = lastCount - frInfo->framesPerStep;
- do
- {
- walkAnim[frame].frame += 104;//turning left
- frame += 1;
- }
- while(frame < lastCount );
- }
- if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6)))
- {
- // turn at the end of the current walk
- frame = lastCount - frInfo->framesPerStep;
- do
- {
- walkAnim[frame].frame += 200; //was 60 now 116
- frame += 1;
- }
- while(frame < lastCount );
- }
- }
- // all turns checked
- lastCount = stepCount;
- }
- }
- }
- p = p + 1;
- lastDir = currentDir;
- slowStart = 0; //can only be valid first time round
+ targetDir = startDir;
+ }
+ // just a turn on the spot is required set an end module for the route let the animator deal with it
+ // modularPath is normally set by ExtractRoute
+ modularPath[0].dir = startDir;
+ modularPath[0].num = 0;
+ modularPath[0].x = startX;
+ modularPath[0].y = startY;
+ modularPath[1].dir = targetDir;
+ modularPath[1].num = 0;
+ modularPath[1].x = startX;
+ modularPath[1].y = startY;
+ modularPath[2].dir = 9;
+ modularPath[2].num = ROUTE_END_FLAG;
+
+ SlidyWalkAnimator(megaObject->o_route);
+ routeFlag = 2;
}
- while (_modularPath[p].dir < NO_DIRECTIONS);
-
- //****************************************************************************
- // SOLID
- // THE SLOW OUT
- //****************************************************************************
-
- if ((currentDir == 2) && (megaId == GEORGE)) // only for george
+ else if (routeFlag == 1) // a normal route
{
- // place stop frames here
- // slowdown at the end of the last walk
- frame = lastCount - frInfo->framesPerStep;
- if (walkAnim[frame].frame == 24)
+ SmoothestPath();//Converts the route to an exact path
+ // The Route had waypoints and direction options
+ // The Path is an exact set of lines in 8 directions that reach the target.
+ // The path is in module format, but steps taken in each direction are not accurate
+ // if target dir = 8 then the walk isn't linked to an anim so
+ // we can create a route without sliding and miss the exact target
+ if (targetDir == NO_DIRECTIONS)
{
- do
- {
- walkAnim[frame].frame += 278;//stopping right
- frame += 1;
- }
- while(frame < lastCount );
- walkAnim[stepCount].frame = 308;
- walkAnim[stepCount].step = 7;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
+ SolidPath();
+ solidFlag = SolidWalkAnimator(megaObject->o_route);
}
- else if (walkAnim[frame].frame == 30)
+
+ if(!solidFlag)
{
- do
- {
- walkAnim[frame].frame += 279;//stopping right
- frame += 1;
- }
- while(frame < lastCount );
- walkAnim[stepCount].frame = 315;
- walkAnim[stepCount].step = 7;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
+ SlidyPath();
+ SlidyWalkAnimator(megaObject->o_route);
}
}
- else if ((currentDir == 6) && (megaId == GEORGE)) // only for george
+ else // Route didn't reach target so assume point was off the floor
{
- // place stop frames here
- // slowdown at the end of the last walk
- frame = lastCount - frInfo->framesPerStep;
- if (walkAnim[frame].frame == 72)
- {
- do
- {
- walkAnim[frame].frame += 244;//stopping left
- frame += 1;
- }
- while(frame < lastCount );
- walkAnim[stepCount].frame = 322;
- walkAnim[stepCount].step = 7;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
- else if (walkAnim[frame].frame == 78)
- {
- do
- {
- walkAnim[frame].frame += 245;//stopping left
- frame += 1;
- }
- while(frame < lastCount );
- walkAnim[stepCount].frame = 329;
- walkAnim[stepCount].step = 7;
- walkAnim[stepCount].dir = currentDir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
- }
+// routeFlag = 0;
}
- module = frInfo->framesPerChar + _modularPath[p-1].dir;
- walkAnim[stepCount].frame = module;
- walkAnim[stepCount].step = 0;
- walkAnim[stepCount].dir = _modularPath[p-1].dir;
- walkAnim[stepCount].x = moduleX;
- walkAnim[stepCount].y = moduleY;
- stepCount += 1;
+ return routeFlag; // send back null route
+}
- walkAnim[stepCount].frame = 512;
- stepCount += 1;
- walkAnim[stepCount].frame = 512;
- stepCount += 1;
- walkAnim[stepCount].frame = 512;
+/*******************************************************************************
+ *******************************************************************************
+ * GET A ROUTE
+ *******************************************************************************
+ *******************************************************************************/
- //****************************************************************************
- // SOLID
- // NO END TURNS
- //****************************************************************************
-// Tdebug("RouteFinder RouteSize is %d", stepCount);
-// now check the route
- i = 0;
+int32 SwordRouter::GetRoute()
+{
+ /****************************************************************************
+ * GetRoute.C extract a path from walk grid
+ * 12 october 94
+ *
+ * GetRoute currently works by scanning grid data and coming up with a ROUTE
+ * as a series of way points(nodes).
+ * static _routeData route[O_ROUTE_SIZE];
+ *
+ * return 0 = failed to find a route
+ *
+ * 1 = found a route
+ *
+ * 2 = mega already at target
+ *
+ * 3 = failed to find a route because target was on a line
+ *
+ ****************************************************************************/
+ int32 routeGot = 0;
+ int32 level;
+ int32 changed;
+
+ if ((startX == targetX) && (startY == targetY))
+ routeGot = 2;
+
+ else // 'else' added by JEL (23jan96) otherwise 'routeGot' affected even when already set to '2' above - causing some 'turns' to walk downwards on the spot
+ routeGot = CheckTarget(targetX,targetY);// returns 3 if target on a line ( +- 1 pixel )
+
+
+ if (routeGot == 0) //still looking for a route check if target is within a pixel of a line
+ {
+ // scan through the nodes linking each node to its nearest neighbour until no more nodes change
+ // This is the routine that finds a route using Scan()
+ level = 1;
do
{
- if (!check(_modularPath[i].x, _modularPath[i].y, _modularPath[i+1].x, _modularPath[i+1].y))
- p=0;
- i += 1;
+ changed = Scan(level);
+ level =level + 1;
}
- while(i<p-1);
- if (p != 0) {
- frInfo->targetDir = _modularPath[p-1].dir;
- if (checkTarget(moduleX,moduleY) == 3)// new target on a line
- p = 0;
+ while(changed == 1);
+
+ // Check to see if the route reached the target
+ if (node[nnodes].dist < 9999)
+ {
+ routeGot = 1;
+ ExtractRoute(); // it did so extract the route as nodes and the directions to go between each node
+ // route.X,route.Y and route.Dir now hold all the route infomation with the target dir or route continuation
}
+ }
- return p;
+ return routeGot;
}
-int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir, int32 routeLength) {
+
+/*******************************************************************************
+ *******************************************************************************
+ * THE SLIDY PATH ROUTINES
+ *******************************************************************************
+ *******************************************************************************/
+
+
+int32 SwordRouter::SmoothestPath()
+{
/*
* This is the second big part of the route finder and the the only bit that tries to be clever
* (the other bits are clever).
@@ -653,6 +326,7 @@ int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir,
* steps taken between two points to the shrunken step size
*
*/
+ int32 p;
int32 dirS;
int32 dirD;
int32 dS;
@@ -665,29 +339,36 @@ int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir,
int32 SD;
int32 DS;
int32 DD;
+ int32 i;
+ int32 j;
int32 temp;
- int32 steps = 0;
+ int32 steps;
int32 option;
int32 options;
- int32 lastDir;
- int32 nextDirS;
- int32 nextDirD;
- int32 tempturns[4];
- int32 turns[4];
- int32 turntable[NO_DIRECTIONS] = {0,1,3,5,7,5,3,1};
+ int32 lastDir;
+ int32 nextDirS;
+ int32 nextDirD;
+ int32 tempturns[4];
+ int32 turns[4];
+ int32 turntable[NO_DIRECTIONS] = {0,1,3,5,7,5,3,1};
+
+ targetDir;// no warnings
// route.X route.Y and route.Dir start at far end
- _smoothPath[0].x = startX;
- _smoothPath[0].y = startY;
- _smoothPath[0].dir = startDir;
- _smoothPath[0].num = 0;
- lastDir = startDir;
- // for each section of the route
- for (int32 p = 0; p < routeLength; p++) {
- dirS = _route[p].dirS;
- dirD = _route[p].dirD;
- nextDirS = _route[p+1].dirS;
- nextDirD = _route[p+1].dirD;
+ smoothPath[0].x = startX;
+ smoothPath[0].y = startY;
+ smoothPath[0].dir = startDir;
+ smoothPath[0].num = 0;
+ p = 0;
+ lastDir = startDir;
+ // for each section of the route
+ do
+ {
+
+ dirS = route[p].dirS;
+ dirD = route[p].dirD;
+ nextDirS = route[p+1].dirS;
+ nextDirD = route[p+1].dirD;
// Check directions into and out of a pair of nodes
// going in
@@ -725,9 +406,13 @@ int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir,
dDS = turntable[dDS];
// get the best path out ie assume next section uses best direction
if (dSD < dSS)
+ {
dSS = dSD;
+ }
if (dDS < dDD)
+ {
dDD = dDS;
+ }
// rate each option
SS = dS + dSS + 3; // Split routes look crap so weight against them
SD = dS + dDD;
@@ -742,9 +427,14 @@ int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir,
turns[2] = 2;
tempturns[3] = DD;
turns[3] = 3;
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- if (tempturns[j] > tempturns[j + 1]) {
+ i = 0;
+ do
+ {
+ j = 0;
+ do
+ {
+ if (tempturns[j] > tempturns[j + 1])
+ {
temp = turns[j];
turns[j] = turns[j+1];
turns[j+1] = temp;
@@ -752,34 +442,81 @@ int32 SwordRouter::smoothestPath(uint16 startX, uint16 startY, uint16 startDir,
tempturns[j] = tempturns[j+1];
tempturns[j+1] = temp;
}
+ j = j + 1;
}
+ while (j < 3);
+ i = i + 1;
}
+ while (i < 3);
// best option matched in order of the priority we would like to see on the screen
// but each option must be checked to see if it can be walked
- options = newCheck(1, _route[p].x, _route[p].y, _route[p + 1].x, _route[p + 1].y);
+ options = NewCheck(1, route[p].x, route[p].y, route[p + 1].x, route[p + 1].y);
if (options == 0)
+ {
+ /*Tdebug("BestTurns fail %d %d %d %d",route[p].x, route[p].y, route[p + 1].x, route[p + 1].y);
+ Tdebug("BestTurns fail %d %d %d %d",turns[0],turns[1],turns[2],options);
+ Go_dos("BestTurns failed");*/
error("BestTurns failed");
- steps = 0;
- for (int i = 0; (i < 4) && (steps == 0); i++) {
+ }
+ i = 0;
+ steps = 0;
+ do
+ {
option = 1 << turns[i];
if (option & options)
- steps = smoothCheck(turns[i],p,dirS,dirD);
+ steps = SmoothCheck(turns[i],p,dirS,dirD);
+ i = i + 1;
}
+ while ((steps == 0) && (i < 4));
+
+#ifdef PLOT_PATHS // plot the best path
+ if (steps != 0)
+ {
+ i = 0;
+ do
+ {
+ RouteLine(smoothPath[i].x, smoothPath[i].y, smoothPath[i+1].x, smoothPath[i+1].y, 228);
+ i = i + 1;
+ }
+ while (i < steps);
+ }
+#endif
if (steps == 0)
+ {
+ /*Tdebug("BestTurns failed %d %d %d %d",route[p].x, route[p].y, route[p + 1].x, route[p + 1].y);
+ Tdebug("BestTurns failed %d %d %d %d",turns[0],turns[1],turns[2],options);
+ Go_dos("BestTurns failed");*/
error("BestTurns failed");
+ }
// route.X route.Y route.dir and bestTurns start at far end
+ p = p + 1;
+
+
}
- _smoothPath[steps].dir = 9;
- _smoothPath[steps].num = ROUTE_END_FLAG;
- return 1;
+ while (p < (routeLength));
+ // best turns will end heading as near as possible to target dir rest is down to anim for now
+ smoothPath[steps].dir = 9;
+ smoothPath[steps].num = ROUTE_END_FLAG;
+ return 1;
}
-int32 SwordRouter::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) {
- static int32 k;
+
+
+
+int32 SwordRouter::SmoothCheck(int32 best, int32 p, int32 dirS, int32 dirD)
+/****************************************************************************
+ * Slip sliding away
+ * This path checker checks to see if a walk that exactly follows the path
+ * would be valid. This should be inherently true for atleast one of the turn
+ * options.
+ * No longer checks the data it only creates the smoothPath array JPS
+ ****************************************************************************/
+{
+static int32 k;
int32 tempK;
int32 x;
int32 y;
@@ -787,136 +524,218 @@ int32 SwordRouter::smoothCheck(int32 best, int32 p, int32 dirS, int32 dirD) {
int32 y2;
int32 dx;
int32 dy;
- int32 dsx;
- int32 dsy;
- int32 ddx;
- int32 ddy;
- int32 dirX;
- int32 dirY;
- int32 ss0;
- int32 ss1;
- int32 ss2;
- int32 sd0;
- int32 sd1;
- int32 sd2;
+ int32 dsx;
+ int32 dsy;
+ int32 ddx;
+ int32 ddy;
+ int32 dirX;
+ int32 dirY;
+ int32 ss0;
+ int32 ss1;
+ int32 ss2;
+ int32 sd0;
+ int32 sd1;
+ int32 sd2;
if (p == 0)
+ {
k = 1;
+ }
tempK = 0;
- x = _route[p].x;
- y = _route[p].y;
- x2 = _route[p + 1].x;
- y2 = _route[p + 1].y;
+ x = route[p].x;
+ y = route[p].y;
+ x2 = route[p + 1].x;
+ y2 = route[p + 1].y;
dx = x2 - x;
dy = y2 - y;
dirX = 1;
dirY = 1;
- if (dx < 0) {
+ if (dx < 0)
+ {
dx = -dx;
dirX = -1;
}
- if (dy < 0) {
+ if (dy < 0)
+ {
dy = -dy;
dirY = -1;
}
// set up sd0-ss2 to reflect possible movement in each direction
- if ((dirS == 0) || (dirS == 4)) { // vert and diag
- ddx = dx;
- ddy = (dx*_diagonaly)/_diagonalx;
- dsy = dy - ddy;
- ddx = ddx * dirX;
- ddy = ddy * dirY;
- dsy = dsy * dirY;
- dsx = 0;
-
- sd0 = (ddx + _modX[dirD]/2) / _modX[dirD];
- ss0 = (dsy + _modY[dirS]/2) / _modY[dirS];
- sd1 = sd0/2;
- ss1 = ss0/2;
- sd2 = sd0 - sd1;
- ss2 = ss0 - ss1;
- } else {
- ddy = dy;
- ddx = (dy*_diagonalx)/_diagonaly;
- dsx = dx - ddx;
- ddy = ddy * dirY;
- ddx = ddx * dirX;
- dsx = dsx * dirX;
- dsy = 0;
-
- sd0 = (ddy + _modY[dirD]/2) / _modY[dirD];
- ss0 = (dsx + _modX[dirS]/2) / _modX[dirS];
- sd1 = sd0/2;
- ss1 = ss0/2;
- sd2 = sd0 - sd1;
- ss2 = ss0 - ss1;
- }
+ if ((dirS == 0) || (dirS == 4))// vert and diag
+ {
+ ddx = dx;
+ ddy = (dx*diagonaly)/diagonalx;
+ dsy = dy - ddy;
+ ddx = ddx * dirX;
+ ddy = ddy * dirY;
+ dsy = dsy * dirY;
+ dsx = 0;
+
+ sd0 = (ddx + modX[dirD]/2)/ modX[dirD];
+ ss0 = (dsy + modY[dirS]/2) / modY[dirS];
+ sd1 = sd0/2;
+ ss1 = ss0/2;
+ sd2 = sd0 - sd1;
+ ss2 = ss0 - ss1;
+ }
+ else
+ {
+ ddy = dy;
+ ddx = (dy*diagonalx)/diagonaly;
+ dsx = dx - ddx;
+ ddy = ddy * dirY;
+ ddx = ddx * dirX;
+ dsx = dsx * dirX;
+ dsy = 0;
+
+ sd0 = (ddy + modY[dirD]/2)/ modY[dirD];
+ ss0 = (dsx + modX[dirS]/2)/ modX[dirS];
+ sd1 = sd0/2;
+ ss1 = ss0/2;
+ sd2 = sd0 - sd1;
+ ss2 = ss0 - ss1;
+ }
+
+ if (best == 0) //halfsquare, diagonal, halfsquare
+ {
+ smoothPath[k].x = x+dsx/2;
+ smoothPath[k].y = y+dsy/2;
+ smoothPath[k].dir = dirS;
+ smoothPath[k].num = ss1;
+ k = k + 1;
+ smoothPath[k].x = x+dsx/2+ddx;
+ smoothPath[k].y = y+dsy/2+ddy;
+ smoothPath[k].dir = dirD;
+ smoothPath[k].num = sd0;
+ k = k + 1;
+ smoothPath[k].x = x+dsx+ddx;
+ smoothPath[k].y = y+dsy+ddy;
+ smoothPath[k].dir = dirS;
+ smoothPath[k].num = ss2;
+ k = k + 1;
+ tempK = k;
+ }
+ else if (best == 1) //square, diagonal
+ {
+ smoothPath[k].x = x+dsx;
+ smoothPath[k].y = y+dsy;
+ smoothPath[k].dir = dirS;
+ smoothPath[k].num = ss0;
+ k = k + 1;
+ smoothPath[k].x = x2;
+ smoothPath[k].y = y2;
+ smoothPath[k].dir = dirD;
+ smoothPath[k].num = sd0;
+ k = k + 1;
+ tempK = k;
+ }
+ else if (best == 2) //diagonal square
+ {
+ smoothPath[k].x = x+ddx;
+ smoothPath[k].y = y+ddy;
+ smoothPath[k].dir = dirD;
+ smoothPath[k].num = sd0;
+ k = k + 1;
+ smoothPath[k].x = x2;
+ smoothPath[k].y = y2;
+ smoothPath[k].dir = dirS;
+ smoothPath[k].num = ss0;
+ k = k + 1;
+ tempK = k;
+ }
+ else //halfdiagonal, square, halfdiagonal
+ {
+ smoothPath[k].x = x+ddx/2;
+ smoothPath[k].y = y+ddy/2;
+ smoothPath[k].dir = dirD;
+ smoothPath[k].num = sd1;
+ k = k + 1;
+ smoothPath[k].x = x+dsx+ddx/2;
+ smoothPath[k].y = y+dsy+ddy/2;
+ smoothPath[k].dir = dirS;
+ smoothPath[k].num = ss0;
+ k = k + 1;
+ smoothPath[k].x = x2;
+ smoothPath[k].y = y2;
+ smoothPath[k].dir = dirD;
+ smoothPath[k].num = sd2;
+ k = k + 1;
+ tempK = k;
+ }
+
+ return tempK;
+}
+
+int32 SwordRouter::SlidyPath()
+{
+/****************************************************************************
+ * SlidyPath creates a path based on part steps with no sliding to get
+ * as near as possible to the target without any sliding this routine is
+ * currently unused, but is intended for use when just clicking about.
+ *
+ * produce a module list from the line data
+ *
+ ****************************************************************************/
+int32 smooth;
+int32 slidy;
+int32 scale;
+int32 stepX;
+int32 stepY;
+int32 deltaX;
+int32 deltaY;
+
+ // strip out the short sections
+ slidy = 1;
+ smooth = 1;
+ modularPath[0].x = smoothPath[0].x;
+ modularPath[0].y = smoothPath[0].y;
+ modularPath[0].dir = smoothPath[0].dir;
+ modularPath[0].num = 0;
- if (best == 0) { //halfsquare, diagonal, halfsquare
- _smoothPath[k].x = x+dsx/2;
- _smoothPath[k].y = y+dsy/2;
- _smoothPath[k].dir = dirS;
- _smoothPath[k].num = ss1;
- k = k + 1;
- _smoothPath[k].x = x+dsx/2+ddx;
- _smoothPath[k].y = y+dsy/2+ddy;
- _smoothPath[k].dir = dirD;
- _smoothPath[k].num = sd0;
- k = k + 1;
- _smoothPath[k].x = x+dsx+ddx;
- _smoothPath[k].y = y+dsy+ddy;
- _smoothPath[k].dir = dirS;
- _smoothPath[k].num = ss2;
- k = k + 1;
- tempK = k;
- } else if (best == 1) { //square, diagonal
- _smoothPath[k].x = x+dsx;
- _smoothPath[k].y = y+dsy;
- _smoothPath[k].dir = dirS;
- _smoothPath[k].num = ss0;
- k = k + 1;
- _smoothPath[k].x = x2;
- _smoothPath[k].y = y2;
- _smoothPath[k].dir = dirD;
- _smoothPath[k].num = sd0;
- k = k + 1;
- tempK = k;
- } else if (best == 2) { //diagonal square
- _smoothPath[k].x = x+ddx;
- _smoothPath[k].y = y+ddy;
- _smoothPath[k].dir = dirD;
- _smoothPath[k].num = sd0;
- k = k + 1;
- _smoothPath[k].x = x2;
- _smoothPath[k].y = y2;
- _smoothPath[k].dir = dirS;
- _smoothPath[k].num = ss0;
- k = k + 1;
- tempK = k;
- } else { //halfdiagonal, square, halfdiagonal
- _smoothPath[k].x = x+ddx/2;
- _smoothPath[k].y = y+ddy/2;
- _smoothPath[k].dir = dirD;
- _smoothPath[k].num = sd1;
- k = k + 1;
- _smoothPath[k].x = x+dsx+ddx/2;
- _smoothPath[k].y = y+dsy+ddy/2;
- _smoothPath[k].dir = dirS;
- _smoothPath[k].num = ss0;
- k = k + 1;
- _smoothPath[k].x = x2;
- _smoothPath[k].y = y2;
- _smoothPath[k].dir = dirD;
- _smoothPath[k].num = sd2;
- k = k + 1;
- tempK = k;
+ while (smoothPath[smooth].num < ROUTE_END_FLAG)
+ {
+ scale = scaleA * smoothPath[smooth].y + scaleB;
+ deltaX = smoothPath[smooth].x - modularPath[slidy-1].x;
+ deltaY = smoothPath[smooth].y - modularPath[slidy-1].y;
+ stepX = modX[smoothPath[smooth].dir];
+ stepY = modY[smoothPath[smooth].dir];
+ stepX = stepX * scale;
+ stepY = stepY * scale;
+ stepX = stepX >> 19;// quarter a step minimum
+ stepY = stepY >> 19;
+ if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY)))
+ {
+ modularPath[slidy].x = smoothPath[smooth].x;
+ modularPath[slidy].y = smoothPath[smooth].y;
+ modularPath[slidy].dir = smoothPath[smooth].dir;
+ modularPath[slidy].num = 1;
+ slidy += 1;
+ }
+ smooth += 1;
+ }
+ // in case the last bit had no steps
+ if (slidy > 1)
+ {
+ modularPath[slidy-1].x = smoothPath[smooth-1].x;
+ modularPath[slidy-1].y = smoothPath[smooth-1].y;
}
- return tempK;
+ // set up the end of the walk
+ modularPath[slidy].x = smoothPath[smooth-1].x;
+ modularPath[slidy].y = smoothPath[smooth-1].y;
+ modularPath[slidy].dir = targetDir;
+ modularPath[slidy].num = 0;
+ slidy += 1;
+ modularPath[slidy].x = smoothPath[smooth-1].x;
+ modularPath[slidy].y = smoothPath[smooth-1].y;
+ modularPath[slidy].dir = 9;
+ modularPath[slidy].num = ROUTE_END_FLAG;
+ return 1;
+
}
-void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int32 megaId) {
+void SwordRouter::SlidyWalkAnimator(WalkData *walkAnim)
/****************************************************************************
* Skidding every where HardWalk creates an animation that exactly fits the
* smoothPath and uses foot slipping to fit whole steps into the route
@@ -926,47 +745,54 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
* produce a module list from the line data
*
****************************************************************************/
- static int32 left = 0;
- int32 p;
- int32 lastDir;
- int32 lastRealDir;
- int32 currentDir;
- int32 turnDir;
- int32 scale;
- int32 step;
- int32 module;
- int32 moduleEnd;
- int32 moduleX;
- int32 moduleY;
- int32 module16X = 0;
- int32 module16Y = 0;
- int32 stepX;
- int32 stepY;
- int32 errorX;
- int32 errorY;
- int32 lastErrorX;
- int32 lastErrorY;
- int32 lastCount;
- int32 stepCount;
- int32 frameCount;
- int32 frames;
- int32 frame;
-
- lastDir = _modularPath[0].dir;
- currentDir = _modularPath[1].dir;
+{
+
+static int32 left = 0;
+int32 p;
+int32 lastDir;
+int32 lastRealDir;
+int32 currentDir;
+int32 turnDir;
+int32 scale;
+int32 step;
+int32 module;
+int32 moduleEnd;
+int32 moduleX;
+int32 moduleY;
+int32 module16X = 0;
+int32 module16Y = 0;
+int32 stepX;
+int32 stepY;
+int32 errorX;
+int32 errorY;
+int32 lastErrorX;
+int32 lastErrorY;
+int32 lastCount;
+int32 stepCount;
+int32 frameCount;
+int32 frames;
+int32 frame;
+
+ // start at the begining for a change
+ p = 0;
+ lastDir = modularPath[0].dir;
+ currentDir = modularPath[1].dir;
if (currentDir == NO_DIRECTIONS)
+ {
currentDir = lastDir;
- moduleX = frInfo->startX;
- moduleY = frInfo->startY;
+ }
+ moduleX = startX;
+ moduleY = startY;
module16X = moduleX << 16;
module16Y = moduleY << 16;
stepCount = 0;
+
//****************************************************************************
// SLIDY
// START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY
// BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED
//****************************************************************************
- module = frInfo->framesPerChar + lastDir;
+ module = framesPerChar + lastDir;
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
walkAnim[stepCount].dir = lastDir;
@@ -984,7 +810,7 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
// get the direction to turn
turnDir = currentDir - lastDir;
if ( turnDir < 0)
- turnDir += NO_DIRECTIONS;
+ turnDir += NO_DIRECTIONS;
if (turnDir > 4)
turnDir = -1;
@@ -997,11 +823,11 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
{
if ( turnDir < 0) // new frames for turn frames 29oct95jps
{
- module = frInfo->turnFramesLeft + lastDir;
+ module = turnFramesLeft + lastDir;
}
else
{
- module = frInfo->turnFramesRight + lastDir;
+ module = turnFramesRight + lastDir;
}
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
@@ -1012,16 +838,20 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
}
// rotate till were facing new dir then go back 45 degrees
- while (lastDir != currentDir) {
+ while (lastDir != currentDir)
+ {
lastDir += turnDir;
- if ( turnDir < 0) { // new frames for turn frames
+ if ( turnDir < 0) // new frames for turn frames 29oct95jps
+ {
if ( lastDir < 0)
- lastDir += NO_DIRECTIONS;
- module = frInfo->turnFramesLeft + lastDir;
- } else {
+ lastDir += NO_DIRECTIONS;
+ module = turnFramesLeft + lastDir;
+ }
+ else
+ {
if ( lastDir > 7)
- lastDir -= NO_DIRECTIONS;
- module = frInfo->turnFramesRight + lastDir;
+ lastDir -= NO_DIRECTIONS;
+ module = turnFramesRight + lastDir;
}
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
@@ -1042,17 +872,16 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
//****************************************************************************
if (left == 0)
- left = frInfo->framesPerStep;
+ left = framesPerStep;
else
left = 0;
lastCount = stepCount;
- lastDir = 99;// this ensures that we don't put in turn frames for the start
- currentDir = 99;// this ensures that we don't put in turn frames for the start
- p = 0;
+ lastDir = 99;// this ensures that we don't put in turn frames for the start
+ currentDir = 99;// this ensures that we don't put in turn frames for the start
do
{
- while (_modularPath[p].num == 0)
+ while (modularPath[p].num == 0)
{
p = p + 1;
if (currentDir != 99)
@@ -1061,20 +890,21 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
lastCount = stepCount;
}
//calculate average amount to lose in each step on the way to the next node
- currentDir = _modularPath[p].dir;
+ currentDir = modularPath[p].dir;
if (currentDir < NO_DIRECTIONS)
{
- module = currentDir * frInfo->framesPerStep * 2 + left;
+ module = currentDir * framesPerStep * 2 + left;
if (left == 0)
- left = frInfo->framesPerStep;
+ left = framesPerStep;
else
- left = 0;
- moduleEnd = module + frInfo->framesPerStep;
+ left = 0;
+ moduleEnd = module + framesPerStep;
step = 0;
- scale = (frInfo->scaleA * moduleY + frInfo->scaleB);
- do {
- module16X += _dx[module]*scale;
- module16Y += _dy[module]*scale;
+ scale = (scaleA * moduleY + scaleB);
+ do
+ {
+ module16X += dx[module]*scale;
+ module16Y += dy[module]*scale;
moduleX = module16X >> 16;
moduleY = module16Y >> 16;
walkAnim[stepCount].frame = module;
@@ -1085,83 +915,104 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
stepCount += 1;
step += 1;
module += 1;
- } while( module < moduleEnd);
- stepX = _modX[_modularPath[p].dir];
- stepY = _modY[_modularPath[p].dir];
- errorX = _modularPath[p].x - moduleX;
+ }
+ while( module < moduleEnd) ;
+ stepX = modX[modularPath[p].dir];
+ stepY = modY[modularPath[p].dir];
+ errorX = modularPath[p].x - moduleX;
errorX = errorX * stepX;
- errorY = _modularPath[p].y - moduleY;
+ errorY = modularPath[p].y - moduleY;
errorY = errorY * stepY;
- if ((errorX < 0) || (errorY < 0)) {
- _modularPath[p].num = 0; // the end of the path
+ if ((errorX < 0) || (errorY < 0))
+ {
+ modularPath[p].num = 0; // the end of the path
// okay those last steps took us past our target but do we want to scoot or moonwalk
frames = stepCount - lastCount;
- errorX = _modularPath[p].x - walkAnim[stepCount-1].x;
- errorY = _modularPath[p].y - walkAnim[stepCount-1].y;
-
- if (frames > frInfo->framesPerStep) {
- lastErrorX = _modularPath[p].x - walkAnim[stepCount-7].x;
- lastErrorY = _modularPath[p].y - walkAnim[stepCount-7].y;
- if (stepX==0) {
- if (3*abs(lastErrorY) < abs(errorY)) { //the last stop was closest
- stepCount -= frInfo->framesPerStep;
+ errorX = modularPath[p].x - walkAnim[stepCount-1].x;
+ errorY = modularPath[p].y - walkAnim[stepCount-1].y;
+
+ if (frames > framesPerStep)
+ {
+ lastErrorX = modularPath[p].x - walkAnim[stepCount-7].x;
+ lastErrorY = modularPath[p].y - walkAnim[stepCount-7].y;
+ if (stepX==0)
+ {
+ if (3*abs(lastErrorY) < abs(errorY)) //the last stop was closest
+ {
+ stepCount -= framesPerStep;
if (left == 0)
- left = frInfo->framesPerStep;
+ left = framesPerStep;
else
left = 0;
}
- } else {
- if (3*abs(lastErrorX) < abs(errorX)) { //the last stop was closest
- stepCount -= frInfo->framesPerStep;
+ }
+ else
+ {
+ if (3*abs(lastErrorX) < abs(errorX)) //the last stop was closest
+ {
+ stepCount -= framesPerStep;
if (left == 0)
- left = frInfo->framesPerStep;
+ left = framesPerStep;
else
left = 0;
}
}
}
- errorX = _modularPath[p].x - walkAnim[stepCount-1].x;
- errorY = _modularPath[p].y - walkAnim[stepCount-1].y;
+ errorX = modularPath[p].x - walkAnim[stepCount-1].x;
+ errorY = modularPath[p].y - walkAnim[stepCount-1].y;
// okay we've reached the end but we still have an error
- if (errorX != 0) {
+ if (errorX != 0)
+ {
frameCount = 0;
frames = stepCount - lastCount;
- do {
+ do
+ {
frameCount += 1;
- walkAnim[lastCount + frameCount - 1].x += errorX*frameCount/frames;
- } while(frameCount<frames);
+ walkAnim[lastCount + frameCount - 1].x += errorX*frameCount/frames;
+ }
+ while(frameCount<frames);
}
- if (errorY != 0) {
+ if (errorY != 0)
+ {
frameCount = 0;
frames = stepCount - lastCount;
- do {
+ do
+ {
frameCount += 1;
walkAnim[lastCount + frameCount-1].y += errorY*frameCount/frames;
- } while(frameCount<frames);
+ }
+ while(frameCount<frames);
}
// Now is the time to put in the turn frames for the last turn
- if (frames < frInfo->framesPerStep)
+ if (frames < framesPerStep)
currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next
if (currentDir != 99)
lastRealDir = currentDir;
// check each turn condition in turn
- if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) { // only for george
- lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left
- if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6))) {
+ if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) // only for george
+ {
+ lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left
+ if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6)))
+ {
// turn at the end of the last walk
- frame = lastCount - frInfo->framesPerStep;
- do {
+ frame = lastCount - framesPerStep;
+ do
+ {
walkAnim[frame].frame += 104;//turning left
frame += 1;
- } while(frame < lastCount );
+ }
+ while(frame < lastCount );
}
- if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6))) {
+ if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6)))
+ {
// turn at the end of the current walk
- frame = lastCount - frInfo->framesPerStep;
- do {
+ frame = lastCount - framesPerStep;
+ do
+ {
walkAnim[frame].frame += 200; //was 60 now 116
frame += 1;
- } while(frame < lastCount );
+ }
+ while(frame < lastCount );
}
lastDir = currentDir;
}
@@ -1174,14 +1025,27 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
module16Y = moduleY << 16;
}
}
- } while (_modularPath[p].dir < NO_DIRECTIONS);
+ }
+ while (modularPath[p].dir < NO_DIRECTIONS);
+
+
if (lastRealDir == 99)
- error("SlidyWalkAnimator direction error");
+ {
+ error("SlidyWalkAnimatorlast direction error\n");
+ }
+ //****************************************************************************
+ // SLIDY
+ // TURNS TO END THE WALK ?
+ //****************************************************************************
+
+ // We've done the walk now put in any turns at the end
+
- if (frInfo->targetDir == NO_DIRECTIONS) { // stand in the last direction
- module = frInfo->standFrames + lastRealDir;
- frInfo->targetDir = lastRealDir;
+ if (targetDir == NO_DIRECTIONS) // stand in the last direction
+ {
+ module = standFrames + lastRealDir;
+ targetDir = lastRealDir;
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
walkAnim[stepCount].dir = lastRealDir;
@@ -1189,9 +1053,11 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
walkAnim[stepCount].y = moduleY;
stepCount += 1;
}
- if (frInfo->targetDir == 9) {
- if (stepCount == 0) {
- module = frInfo->framesPerChar + lastRealDir;
+ if (targetDir == 9)
+ {
+ if (stepCount == 0)
+ {
+ module = framesPerChar + lastRealDir;
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
walkAnim[stepCount].dir = lastRealDir;
@@ -1199,9 +1065,11 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
walkAnim[stepCount].y = moduleY;
stepCount += 1;
}
- } else if (frInfo->targetDir != lastRealDir) { // rotate to targetDir
+ }
+ else if (targetDir != lastRealDir) // rotate to targetDir
+ {
// rotate to target direction
- turnDir = frInfo->targetDir - lastRealDir;
+ turnDir = targetDir - lastRealDir;
if ( turnDir < 0)
turnDir += NO_DIRECTIONS;
@@ -1212,11 +1080,16 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
// rotate to target direction
// for george and nico put in a head turn at the start
- if ((megaId == GEORGE) || (megaId == NICO)) {
+ if ((megaId == GEORGE) || (megaId == NICO))
+ {
if ( turnDir < 0) // new frames for turn frames 29oct95jps
- module = frInfo->turnFramesLeft + lastDir;
+ {
+ module = turnFramesLeft + lastDir;
+ }
else
- module = frInfo->turnFramesRight + lastDir;
+ {
+ module = turnFramesRight + lastDir;
+ }
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
walkAnim[stepCount].dir = lastRealDir;
@@ -1226,16 +1099,20 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
}
// rotate if we need to
- while (lastRealDir != frInfo->targetDir) {
+ while (lastRealDir != targetDir)
+ {
lastRealDir += turnDir;
- if ( turnDir < 0) { // new frames for turn frames 29oct95jps
+ if ( turnDir < 0) // new frames for turn frames 29oct95jps
+ {
if ( lastRealDir < 0)
- lastRealDir += NO_DIRECTIONS;
- module = frInfo->turnFramesLeft + lastRealDir;
- } else {
+ lastRealDir += NO_DIRECTIONS;
+ module = turnFramesLeft + lastRealDir;
+ }
+ else
+ {
if ( lastRealDir > 7)
- lastRealDir -= NO_DIRECTIONS;
- module = frInfo->turnFramesRight + lastRealDir;
+ lastRealDir -= NO_DIRECTIONS;
+ module = turnFramesRight + lastRealDir;
}
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
@@ -1244,10 +1121,12 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
walkAnim[stepCount].y = moduleY;
stepCount += 1;
}
- module = frInfo->standFrames + lastRealDir;
+ module = standFrames + lastRealDir;
walkAnim[stepCount-1].frame = module;
- } else { // just stand at the end
- module = frInfo->standFrames + lastRealDir;
+ }
+ else // just stand at the end
+ {
+ module = standFrames + lastRealDir;
walkAnim[stepCount].frame = module;
walkAnim[stepCount].step = 0;
walkAnim[stepCount].dir = lastRealDir;
@@ -1261,149 +1140,576 @@ void SwordRouter::slidyWalkAnimator(WalkData *walkAnim, FrameInfos *frInfo, int3
walkAnim[stepCount].frame = 512;
stepCount += 1;
walkAnim[stepCount].frame = 512;
+// Tdebug("RouteFinder RouteSize is %d", stepCount);
+ return;
}
+
+/*******************************************************************************
+ *******************************************************************************
+ * THE SOLID PATH ROUTINES
+ *******************************************************************************
+ *******************************************************************************/
+
+int32 SwordRouter::SolidPath()
+{
/****************************************************************************
- * ExtractRoute gets route from the node data after a full scan, route is
- * written with just the basic way points and direction options for heading
- * to the next point.
+ * SolidPath creates a path based on whole steps with no sliding to get
+ * as near as possible to the target without any sliding this routine is
+ * currently unused, but is intended for use when just clicking about.
+ *
+ * produce a module list from the line data
+ *
****************************************************************************/
-int32 SwordRouter::extractRoute(int32 targetDir) {
- int32 prev;
- int32 prevx;
- int32 prevy;
- int32 last;
- int32 point;
- int32 dirx;
- int32 diry;
- int32 dir;
+int32 smooth;
+int32 solid;
+int32 scale;
+int32 stepX;
+int32 stepY;
+int32 deltaX;
+int32 deltaY;
- // extract the route from the node data
- prev = _nNodes;
- last = prev;
- point = O_ROUTE_SIZE - 1;
- _route[point].x = _node[last].x;
- _route[point].y = _node[last].y;
- while (prev > 0) {
- point = point - 1;
- prev = _node[last].prev;
- prevx = _node[prev].x;
- prevy = _node[prev].y;
- _route[point].x = prevx;
- _route[point].y = prevy;
- last = prev;
+ // strip out the short sections
+ solid = 1;
+ smooth = 1;
+ modularPath[0].x = smoothPath[0].x;
+ modularPath[0].y = smoothPath[0].y;
+ modularPath[0].dir = smoothPath[0].dir;
+ modularPath[0].num = 0;
+
+ do
+ {
+ scale = scaleA * smoothPath[smooth].y + scaleB;
+ deltaX = smoothPath[smooth].x - modularPath[solid-1].x;
+ deltaY = smoothPath[smooth].y - modularPath[solid-1].y;
+ stepX = modX[smoothPath[smooth].dir];
+ stepY = modY[smoothPath[smooth].dir];
+ stepX = stepX * scale;
+ stepY = stepY * scale;
+ stepX = stepX >> 16;
+ stepY = stepY >> 16;
+ if ((abs(deltaX)>=abs(stepX)) && (abs(deltaY)>=abs(stepY)))
+ {
+ modularPath[solid].x = smoothPath[smooth].x;
+ modularPath[solid].y = smoothPath[smooth].y;
+ modularPath[solid].dir = smoothPath[smooth].dir;
+ modularPath[solid].num = 1;
+ solid += 1;
+ }
+ smooth += 1;
}
+ while (smoothPath[smooth].num < ROUTE_END_FLAG);
+ // in case the last bit had no steps
+ if (solid == 1) //there were no paths so put in a dummy end
+ {
+ solid = 2;
+ modularPath[1].dir = smoothPath[0].dir;
+ modularPath[1].num = 0;
+ }
+ modularPath[solid-1].x = smoothPath[smooth-1].x;
+ modularPath[solid-1].y = smoothPath[smooth-1].y;
+ // set up the end of the walk
+ modularPath[solid].x = smoothPath[smooth-1].x;
+ modularPath[solid].y = smoothPath[smooth-1].y;
+ modularPath[solid].dir = 9;
+ modularPath[solid].num = ROUTE_END_FLAG;
+ return 1;
- int32 routeLength = 0;
- do {
- _route[routeLength].x = _route[point].x;
- _route[routeLength].y = _route[point].y;
- point = point + 1;
- routeLength = routeLength + 1;
- } while (point < O_ROUTE_SIZE);
+}
- for (int p = 0; p < routeLength; p++) {
- int32 dx = _route[p+1].x - _route[p].x;
- int32 dy = _route[p+1].y - _route[p].y;
- dirx = 1;
- diry = 1;
- if (dx < 0)
+int32 SwordRouter::SolidWalkAnimator(WalkData *walkAnim)
+{
+/****************************************************************************
+ * SolidWalk creates an animation based on whole steps with no sliding to get
+ * as near as possible to the target without any sliding this routine is
+ * is intended for use when just clicking about.
+ *
+ * produce a module list from the line data
+ *
+ * returns 0 if solid route not found
+ ****************************************************************************/
+int32 p;
+int32 i;
+int32 left;
+int32 lastDir;
+int32 currentDir;
+int32 turnDir;
+int32 scale;
+int32 step;
+int32 module;
+int32 moduleX;
+int32 moduleY;
+int32 module16X;
+int32 module16Y;
+int32 errorX;
+int32 errorY;
+int32 moduleEnd;
+int32 slowStart;
+int32 stepCount;
+int32 lastCount;
+int32 frame;
+
+ // start at the begining for a change
+ lastDir = modularPath[0].dir;
+ p = 1;
+ currentDir = modularPath[1].dir;
+ module = framesPerChar + lastDir;
+ moduleX = startX;
+ moduleY = startY;
+ module16X = moduleX << 16;
+ module16Y = moduleY << 16;
+ slowStart = 0;
+ stepCount = 0;
+
+ //****************************************************************************
+ // SOLID
+ // START THE WALK WITH THE FIRST STANDFRAME THIS MAY CAUSE A DELAY
+ // BUT IT STOPS THE PLAYER MOVING FOR COLLISIONS ARE DETECTED
+ //****************************************************************************
+ walkAnim[stepCount].frame = module;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = lastDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+
+ //****************************************************************************
+ // SOLID
+ // TURN TO START THE WALK
+ //****************************************************************************
+ // rotate if we need to
+ if (lastDir != currentDir)
+ {
+ // get the direction to turn
+ turnDir = currentDir - lastDir;
+ if ( turnDir < 0)
+ turnDir += NO_DIRECTIONS;
+
+ if (turnDir > 4)
+ turnDir = -1;
+ else if (turnDir > 0)
+ turnDir = 1;
+
+ // rotate to new walk direction
+ // for george and nico put in a head turn at the start
+ if ((megaId == GEORGE) || (megaId == NICO))
{
- dx = -dx;
- dirx = -1;
+ if ( turnDir < 0) // new frames for turn frames 29oct95jps
+ {
+ module = turnFramesLeft + lastDir;
+ }
+ else
+ {
+ module = turnFramesRight + lastDir;
+ }
+ walkAnim[stepCount].frame = module;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = lastDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
}
- if (dy < 0)
+
+ // rotate till were facing new dir then go back 45 degrees
+ while (lastDir != currentDir)
{
- dy = -dy;
- diry = -1;
+ lastDir += turnDir;
+ if ( turnDir < 0) // new frames for turn frames 29oct95jps
+ {
+ if ( lastDir < 0)
+ lastDir += NO_DIRECTIONS;
+ module = turnFramesLeft + lastDir;
+ }
+ else
+ {
+ if ( lastDir > 7)
+ lastDir -= NO_DIRECTIONS;
+ module = turnFramesRight + lastDir;
+ }
+ walkAnim[stepCount].frame = module;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = lastDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
}
+ // the back 45 degrees bit
+ stepCount -= 1;// step back one because new head turn for george takes us past the new dir
+ }
+
+ //****************************************************************************
+ // SOLID
+ // THE SLOW IN
+ //****************************************************************************
- if ((_diagonaly * dx) > (_diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7
+ // do start frames if its george and left or right
+ if (megaId == GEORGE)
+ {
+ if (modularPath[1].num > 0)
{
- dir = 4 - 2 * dirx; // 2 or 6
- _route[p].dirS = dir;
- dir = dir + diry * dirx; // 1,3,5 or 7
- _route[p].dirD = dir;
+ if (currentDir == 2) // only for george
+ {
+ slowStart = 1;
+ walkAnim[stepCount].frame = 296;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 297;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 298;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
+ else if (currentDir == 6) // only for george
+ {
+ slowStart = 1;
+ walkAnim[stepCount].frame = 299;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 300;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 301;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
}
- else // dir = 7,0 or 0,1 or 3,4 or 4,5
+ }
+ //****************************************************************************
+ // SOLID
+ // THE WALK
+ //****************************************************************************
+
+ if (currentDir > 4)
+ left = framesPerStep;
+ else
+ left = 0;
+
+ lastCount = stepCount;
+ lastDir = 99;// this ensures that we don't put in turn frames for the start
+ currentDir = 99;// this ensures that we don't put in turn frames for the start
+
+ do
+ {
+ while(modularPath[p].num > 0)
{
- dir = 2 + 2 * diry; // 0 or 4
- _route[p].dirS = dir;
- dir = 4 - 2 * dirx; // 2 or 6
- dir = dir + diry * dirx; // 1,3,5 or 7
- _route[p].dirD = dir;
+ currentDir = modularPath[p].dir;
+ if (currentDir< NO_DIRECTIONS)
+ {
+
+ module = currentDir * framesPerStep * 2 + left;
+ if (left == 0)
+ left = framesPerStep;
+ else
+ left = 0;
+ moduleEnd = module + framesPerStep;
+ step = 0;
+ scale = (scaleA * moduleY + scaleB);
+ do
+ {
+ module16X += dx[module]*scale;
+ module16Y += dy[module]*scale;
+ moduleX = module16X >> 16;
+ moduleY = module16Y >> 16;
+ walkAnim[stepCount].frame = module;
+ walkAnim[stepCount].step = step;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ module += 1;
+ step += 1;
+ }
+ while( module < moduleEnd) ;
+ errorX = modularPath[p].x - moduleX;
+ errorX = errorX * modX[modularPath[p].dir];
+ errorY = modularPath[p].y - moduleY;
+ errorY = errorY * modY[modularPath[p].dir];
+ if ((errorX < 0) || (errorY < 0))
+ {
+ modularPath[p].num = 0;
+ stepCount -= framesPerStep;
+ if (left == 0)
+ left = framesPerStep;
+ else
+ left = 0;
+ // Okay this is the end of a section
+ moduleX = walkAnim[stepCount-1].x;
+ moduleY = walkAnim[stepCount-1].y;
+ module16X = moduleX << 16;
+ module16Y = moduleY << 16;
+ modularPath[p].x =moduleX;
+ modularPath[p].y =moduleY;
+ // Now is the time to put in the turn frames for the last turn
+ if ((stepCount - lastCount) < framesPerStep)// no step taken
+ {
+ currentDir = 99;// this ensures that we don't put in turn frames for this walk or the next
+ if (slowStart == 1)// clean up if a slow in but no walk
+ {
+ stepCount -= 3;
+ lastCount -= 3;
+ slowStart = 0;
+ }
+ }
+ // check each turn condition in turn
+ if (((lastDir != 99) && (currentDir != 99)) && (megaId == GEORGE)) // only for george
+ {
+ lastDir = currentDir - lastDir;//1 and -7 going right -1 and 7 going left
+ if (((lastDir == -1) || (lastDir == 7)) || ((lastDir == -2) || (lastDir == 6)))
+ {
+ // turn at the end of the last walk
+ frame = lastCount - framesPerStep;
+ do
+ {
+ walkAnim[frame].frame += 104;//turning left
+ frame += 1;
+ }
+ while(frame < lastCount );
+ }
+ if (((lastDir == 1) || (lastDir == -7)) || ((lastDir == 2) || (lastDir == -6)))
+ {
+ // turn at the end of the current walk
+ frame = lastCount - framesPerStep;
+ do
+ {
+ walkAnim[frame].frame += 200; //was 60 now 116
+ frame += 1;
+ }
+ while(frame < lastCount );
+ }
+ }
+ // all turns checked
+ lastCount = stepCount;
+ }
+ }
}
+ p = p + 1;
+ lastDir = currentDir;
+ slowStart = 0; //can only be valid first time round
}
- if (targetDir == 8) // ANY direction
- {
- _route[routeLength].dirS = _route[routeLength-1].dirS;
- _route[routeLength].dirD = _route[routeLength-1].dirD;
+ while (modularPath[p].dir < NO_DIRECTIONS);
+
+ //****************************************************************************
+ // SOLID
+ // THE SLOW OUT
+ //****************************************************************************
+
+ if ((currentDir == 2) && (megaId == GEORGE)) // only for george
+ {
+ // place stop frames here
+ // slowdown at the end of the last walk
+ frame = lastCount - framesPerStep;
+ if (walkAnim[frame].frame == 24)
+ {
+ do
+ {
+ walkAnim[frame].frame += 278;//stopping right
+ frame += 1;
+ }
+ while(frame < lastCount );
+ walkAnim[stepCount].frame = 308;
+ walkAnim[stepCount].step = 7;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
+ else if (walkAnim[frame].frame == 30)
+ {
+ do
+ {
+ walkAnim[frame].frame += 279;//stopping right
+ frame += 1;
+ }
+ while(frame < lastCount );
+ walkAnim[stepCount].frame = 315;
+ walkAnim[stepCount].step = 7;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
}
- else
- {
- _route[routeLength].dirS = targetDir;
- _route[routeLength].dirD = targetDir;
+ else if ((currentDir == 6) && (megaId == GEORGE)) // only for george
+ {
+ // place stop frames here
+ // slowdown at the end of the last walk
+ frame = lastCount - framesPerStep;
+ if (walkAnim[frame].frame == 72)
+ {
+ do
+ {
+ walkAnim[frame].frame += 244;//stopping left
+ frame += 1;
+ }
+ while(frame < lastCount );
+ walkAnim[stepCount].frame = 322;
+ walkAnim[stepCount].step = 7;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
+ else if (walkAnim[frame].frame == 78)
+ {
+ do
+ {
+ walkAnim[frame].frame += 245;//stopping left
+ frame += 1;
+ }
+ while(frame < lastCount );
+ walkAnim[stepCount].frame = 329;
+ walkAnim[stepCount].step = 7;
+ walkAnim[stepCount].dir = currentDir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
+ }
}
- return routeLength;
-}
+ module = framesPerChar + modularPath[p-1].dir;
+ walkAnim[stepCount].frame = module;
+ walkAnim[stepCount].step = 0;
+ walkAnim[stepCount].dir = modularPath[p-1].dir;
+ walkAnim[stepCount].x = moduleX;
+ walkAnim[stepCount].y = moduleY;
+ stepCount += 1;
-int SwordRouter::getRoute() {
- int32 routeRes;
- if ((_node[0].x == _node[_nNodes].x) && (_node[0].y == _node[_nNodes].y))
- routeRes = 2; // start is the same as destination
- else
- routeRes = checkTarget(_node[_nNodes].x, _node[_nNodes].y);
+ walkAnim[stepCount].frame = 512;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 512;
+ stepCount += 1;
+ walkAnim[stepCount].frame = 512;
- if (routeRes == 0) { // still looking for a route check if target is within a pixel of a line
- int32 level = 1;
- int changed;
+ //****************************************************************************
+ // SOLID
+ // NO END TURNS
+ //****************************************************************************
+
+// Tdebug("RouteFinder RouteSize is %d", stepCount);
+// now check the route
+ i = 0;
do
{
- changed = scan(level);
- level++;
- } while(changed == 1);
- if (_node[_nNodes].dist < 9999) // did we reach the target?
- routeRes = 1;
- }
- return routeRes;
+ if (!Check(modularPath[i].x, modularPath[i].y, modularPath[i+1].x, modularPath[i+1].y))
+ p=0;
+ #ifdef PLOT_PATHS
+ RouteLine(modularPath[i].x, modularPath[i].y, modularPath[i+1].x, modularPath[i+1].y, 227);
+ #endif
+ i += 1;
+ }
+ while(i<p-1);
+ if (p != 0)
+ {
+ targetDir = modularPath[p-1].dir;
+ }
+ if (p != 0)
+ {
+ if (CheckTarget(moduleX,moduleY) == 3)// new target on a line
+ {
+ p = 0;
+ //Tdebug("Solid walk target was on a line %d %d", moduleX, moduleY);
+ }
+ }
+
+ return p;
}
-int SwordRouter::scan(int32 level) {
- int32 distance;
- int changed = 0;
- // For all the nodes that have new values and a distance less than enddist
+
+/*******************************************************************************
+ *******************************************************************************
+ * THE SCAN ROUTINES
+ *******************************************************************************
+ *******************************************************************************/
+
+int32 SwordRouter::Scan(int32 level)
+/*******************************************************************************
+ * Called successively from RouteFinder until no more changes take place in the
+ * grid array ie he best path has been found
+ *
+ * Scans through every point in the node array and checks if there is a route
+ * between each point and if this route gives a new route.
+ *
+ * This routine could probably halve its processing time if it doubled up on the
+ * checks after each route check
+ *
+ *******************************************************************************/
+{
+ int32 i;
+ int32 k;
+ int32 x1;
+ int32 y1;
+ int32 x2;
+ int32 y2;
+ int32 distance;
+ int32 changed = 0;
+ // For all the nodes that have new values and a distance less than enddist
// ie dont check for new routes from a point we checked before or from a point
// that is already further away than the best route so far.
- for (int32 i = 0; i < _nNodes; i++) {
- if ((_node[i].dist < _node[_nNodes].dist) && (_node[i].level == level)) {
- int16 x1 = _node[i].x;
- int16 y1 = _node[i].y;
-
- for (int32 k = _nNodes; k > 0; k--) {
- if (_node[k].dist > _node[i].dist) {
- int16 x2 = _node[k].x;
- int16 y2 = _node[k].y;
- if (abs(x2 - x1) > (4.5 * abs(y2 - y1)))
- distance = (8 * abs(x2 - x1) + 18 * abs(y2 - y1)) / (54 * 8) + 1;
+ i = 0;
+ do
+ {
+ if ((node[i].dist < node[nnodes].dist) && (node[i].level == level))
+ {
+ x1 = node[i].x;
+ y1 = node[i].y;
+ k=nnodes;
+ do
+ {
+ if (node[k].dist > node[i].dist)
+ {
+ x2 = node[k].x;
+ y2 = node[k].y;
+
+ if (abs(x2-x1)>(4.5*abs(y2-y1)))
+ {
+ distance = (8*abs(x2-x1)+18*abs(y2-y1))/(54*8)+1;
+ }
else
- distance = (6 * abs(x2 - x1) + 36 * abs(y2 - y1)) / (36 * 14) + 1;
-
- if ((distance + _node[i].dist < _node[_nNodes].dist) && (distance + _node[i].dist < _node[k].dist)) {
- //if (int temp = newCheck(0, x1, y1, x2, y2)) {
- if (newCheck(0, x1, y1, x2, y2)) {
- _node[k].level = level + 1;
- _node[k].dist = distance + _node[i].dist;
- _node[k].prev = i;
+ {
+ distance = (6*abs(x2-x1)+36*abs(y2-y1))/(36*14)+1;
+ }
+
+ if ((distance + node[i].dist < node[nnodes].dist) && (distance + node[i].dist < node[k].dist))
+ {
+ if (NewCheck(0, x1,y1,x2,y2))
+ {
+ node[k].level = level + 1;
+ node[k].dist = distance + node[i].dist;
+ node[k].prev = i;
changed = 1;
}
}
}
+ k-=1;
}
+ while(k > 0);
}
+ i=i+1;
}
+ while(i < nnodes);
return changed;
}
+
+int32 SwordRouter::NewCheck(int32 status, int32 x1 , int32 y1 , int32 x2 ,int32 y2)
/*******************************************************************************
* NewCheck routine checks if the route between two points can be achieved
* without crossing any of the bars in the Bars array.
@@ -1415,518 +1721,892 @@ int SwordRouter::scan(int32 level) {
*
* Note Bars array must be properly calculated ie min max dx dy co
*******************************************************************************/
-int SwordRouter::newCheck(int32 status, int16 x1, int16 x2, int16 y1, int16 y2) {
-
- int32 ldx;
- int32 ldy;
- int32 dlx;
- int32 dly;
- int32 dirX;
- int32 dirY;
- int32 step1;
- int32 step2;
- int32 step3;
- int32 steps;
- int32 options;
+{
+ int32 dx;
+ int32 dy;
+ int32 dlx;
+ int32 dly;
+ int32 dirX;
+ int32 dirY;
+ int32 step1;
+ int32 step2;
+ int32 step3;
+ int32 steps;
+ int32 options;
steps = 0;
options = 0;
- ldx = x2 - x1;
- ldy = y2 - y1;
+ dx = x2 - x1;
+ dy = y2 - y1;
dirX = 1;
dirY = 1;
-
- if (ldx < 0) {
- ldx = -ldx;
+ if (dx < 0)
+ {
+ dx = -dx;
dirX = -1;
}
- if (ldy < 0) {
- ldy = -ldy;
+ if (dy < 0)
+ {
+ dy = -dy;
dirY = -1;
}
- // make the route options
-
- if (_diagonaly * ldx > _diagonalx * ldy) {
- // dir = 1,2 or 2,3 or 5,6 or 6,7
-
- dly = ldy;
- dlx = (ldy * _diagonalx) / _diagonaly;
- ldx = ldx - dlx;
+ //make the route options
+ if ((diagonaly * dx) > (diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7
+ {
+ dly = dy;
+ dlx = (dy*diagonalx)/diagonaly;
+ dx = dx - dlx;
dlx = dlx * dirX;
dly = dly * dirY;
- ldx = ldx * dirX;
- ldy = 0;
+ dx = dx * dirX;
+ dy = 0;
//options are
//square, diagonal a code 1 route
-
- step1 = check(x1, y1, x1 + ldx, y1);
- if (step1 != 0) {
- step2 = check(x1 + ldx, y1, x2, y2);
- if (step2 != 0) {
- steps = step1 + step2;
+ step1 = Check(x1, y1, x1+dx, y1);
+ if (step1 != 0)
+ {
+ step2 = Check(x1+dx, y1, x2, y2);
+ if (step2 != 0)
+ {
+ steps = step1 + step2; // yes
options = options + 2;
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1+dx, y1, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dx, y1, x2, y2, 231);
+ #endif
}
}
-
//diagonal, square a code 2 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x1 + dlx, y1 + dly);
- if (step1 != 0) {
- step2 = check(x1 + dlx, y2, x2, y2);
- if (step2 != 0) {
- steps = step1 + step2;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x1+dlx,y1+dly);
+ if (step1 != 0)
+ {
+ step2 = Check(x1+dlx, y2, x2, y2);
+ if (step2 != 0)
+ {
+ steps = step1 + step2; // yes
options = options + 4;
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1+dlx,y1+dly, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dlx, y2, x2, y2, 231);
+ #endif
}
}
}
-
//halfsquare, diagonal, halfsquare a code 0 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x1 + ldx / 2, y1);
- if (step1 != 0) {
- step2 = check(x1 + ldx / 2, y1, x1 + ldx / 2 + dlx, y2);
- if (step2 != 0) {
- step3 = check(x1 + ldx / 2 + dlx, y2, x2, y2);
- if (step3 != 0) {
- steps = step1 + step2 + step3;
- options++;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x1+dx/2, y1);
+ if (step1 != 0)
+ {
+ step2 = Check(x1+dx/2, y1, x1+dx/2+dlx, y2);
+ if (step2 != 0)
+ {
+ step3 = Check(x1+dx/2+dlx, y2, x2, y2);
+ if (step3 != 0)
+ {
+ steps = step1 + step2 + step3; // yes
+ options = options + 1;
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1+dx/2, y1, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dx/2, y1, x1+dx/2+dlx, y2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dx/2+dlx, y2, x2, y2, 231);
+ #endif
}
}
}
}
-
//halfdiagonal, square, halfdiagonal a code 3 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2);
- if (step1 != 0) {
- step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + ldx + dlx / 2, y1 + dly / 2);
- if (step2 != 0) {
- step3 = check(x1 + ldx + dlx / 2, y1 + dly / 2, x2, y2);
- if (step3 != 0) {
- steps = step1 + step2 + step3;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x1+dlx/2, y1+dly/2);
+ if (step1 != 0)
+ {
+ step2 = Check(x1+dlx/2, y1+dly/2, x1+dx+dlx/2, y1+dly/2);
+ if (step2 != 0)
+ {
+ step3 = Check(x1+dx+dlx/2, y1+dly/2, x2, y2);
+ if (step3 != 0)
+ {
+ steps = step1 + step2 + step3; // yes
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1+dlx/2, y1+dly/2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dlx/2, y1+dly/2, x1+dx+dlx/2, y1+dly/2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dx+dlx/2, y1+dly/2, x2, y2, 231);
+ #endif
options = options + 8;
}
}
}
}
- } else {
- // dir = 7,0 or 0,1 or 3,4 or 4,5
-
- dlx = ldx;
- dly = (ldx * _diagonaly) / _diagonalx;
- ldy = ldy - dly;
+ }
+ else // dir = 7,0 or 0,1 or 3,4 or 4,5
+ {
+ dlx = dx;
+ dly = (dx*diagonaly)/diagonalx;
+ dy = dy - dly;
dlx = dlx * dirX;
dly = dly * dirY;
- ldy = ldy * dirY;
- ldx = 0;
+ dy = dy * dirY;
+ dx = 0;
//options are
//square, diagonal a code 1 route
-
- step1 = check(x1 ,y1, x1, y1 + ldy);
- if (step1 != 0) {
- step2 = check(x1, y1 + ldy, x2, y2);
- if (step2 != 0) {
- steps = step1 + step2;
+ step1 = Check(x1 ,y1 ,x1 ,y1+dy );
+ if (step1 != 0)
+ {
+ step2 = Check(x1 ,y1+dy ,x2,y2);
+ if (step2 != 0)
+ {
+ steps = step1 + step2; // yes
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1 ,y1 ,x1 ,y1+dy, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1 ,y1+dy ,x2, y2, 231);
+ #endif
options = options + 2;
}
}
-
//diagonal, square a code 2 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x2, y1 + dly);
- if (step1 != 0) {
- step2 = check(x2, y1 + dly, x2, y2);
- if (step2 != 0) {
- steps = step1 + step2;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x2, y1+dly);
+ if (step1 != 0)
+ {
+ step2 = Check(x2, y1+dly, x2, y2);
+ if (step2 != 0)
+ {
+ steps = step1 + step2; // yes
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x2, y1+dly, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x2, y1+dly, x2, y2, 231);
+ #endif
options = options + 4;
}
}
}
-
//halfsquare, diagonal, halfsquare a code 0 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x1, y1 + ldy / 2);
- if (step1 != 0) {
- step2 = check(x1, y1 + ldy / 2, x2, y1 + ldy / 2 + dly);
- if (step2 != 0) {
- step3 = check(x2, y1 + ldy / 2 + dly, x2, y2);
- if (step3 != 0) {
- steps = step1 + step2 + step3;
- options++;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x1, y1+dy/2);
+ if (step1 != 0)
+ {
+ step2 = Check(x1, y1+dy/2, x2, y1+dy/2+dly);
+ if (step2 != 0)
+ {
+ step3 = Check(x2, y1+dy/2+dly, x2, y2);
+ if (step3 != 0)
+ {
+ steps = step1 + step2 + step3; // yes
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1, y1+dy/2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1+dy/2, x2, y1+dy/2+dly, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x2, y1+dy/2+dly, x2, y2, 231);
+ #endif
+ options = options + 1;
}
}
}
}
-
//halfdiagonal, square, halfdiagonal a code 3 route
-
- if (steps == 0 || status == 1) {
- step1 = check(x1, y1, x1 + dlx / 2, y1 + dly / 2);
- if (step1 != 0) {
- step2 = check(x1 + dlx / 2, y1 + dly / 2, x1 + dlx / 2, y1 + ldy + dly / 2);
- if (step2 != 0) {
- step3 = check(x1 + dlx / 2, y1 + ldy + dly / 2, x2, y2);
- if (step3 != 0) {
- steps = step1 + step2 + step3;
+ if ((steps == 0) || (status == 1))
+ {
+ step1 = Check(x1, y1, x1+dlx/2, y1+dly/2);
+ if (step1 != 0)
+ {
+ step2 = Check(x1+dlx/2, y1+dly/2, x1+dlx/2, y1+dy+dly/2);
+ if (step2 != 0)
+ {
+ step3 = Check(x1+dlx/2, y1+dy+dly/2, x2, y2);
+ if (step3 != 0)
+ {
+ steps = step1 + step2 + step3; // yes
options = options + 8;
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1, y1, x1+dlx/2, y1+dly/2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dlx/2, y1+dly/2, x1+dlx/2, y1+dy+dly/2, 231);
+ #endif
+ #ifdef PLOT_PATHS
+ if (status == 1)
+ RouteLine(x1+dlx/2, y1+dy+dly/2, x2, y2, 231);
+ #endif
}
}
}
}
}
-
if (status == 0)
+ {
status = steps;
+ }
else
+ {
status = options;
-
+ }
return status;
}
-int SwordRouter::check(int16 x1, int16 y1, int16 x2, int16 y2) {
- //call the fastest line check for the given line
- //returns 1 if line didn't cross any bars
- int steps;
- if ((x1 == x2) && (y1 == y2))
+/*******************************************************************************
+ *******************************************************************************
+ * CHECK ROUTINES
+ *******************************************************************************
+ *******************************************************************************/
+
+
+int32 SwordRouter::Check(int32 x1 , int32 y1 , int32 x2 ,int32 y2)
+{
+//call the fastest line check for the given line
+//returns 1 if line didn't cross any bars
+ int32 steps;
+
+ if ((x1 == x2) && (y1 == y2))
+ {
steps = 1;
+ }
else if (x1 == x2)
- steps = vertCheck(x1, y1, y2);
+ {
+ steps = VertCheck(x1, y1, y2);
+ }
else if (y1 == y2)
- steps = horizCheck(x1, y1, x2);
+ {
+ steps = HorizCheck(x1, y1, x2);
+ }
else
- steps = lineCheck(x1, y1, x2, y2);
- return steps;
-}
-
-int SwordRouter::horizCheck(int16 x1, int16 y, int16 x2) {
- int32 ldy;
- int32 i;
- int32 xc;
- int32 xmin;
- int32 xmax;
- int32 linesCrossed = 1;
-
- if (x1 > x2) {
- xmin = x2;
- xmax = x1;
- } else {
- xmin = x1;
- xmax = x2;
+ {
+ steps = LineCheck(x1, y1, x2, y2);
}
+ return steps;
- // line set to go one step in chosen direction
- // so ignore if it hits anything
+}
- i = 0;
- do {
- // skip if not on module
- if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) {
- // skip if not on module
- if (y >= _bars[i].ymin && y <= _bars[i].ymax) {
- // okay its a valid line calculate an intercept
- // wow but all this arithmetic we must have
- // loads of time
-
- if (_bars[i].dy == 0)
- linesCrossed = 0;
- else {
- ldy = y - _bars[i].y1;
- xc = _bars[i].x1 + (_bars[i].dx * ldy) / _bars[i].dy;
- // skip if not on module
- if (xc >= xmin - 1 && xc <= xmax + 1)
- linesCrossed = 0;
+int32 SwordRouter::LineCheck(int32 x1 , int32 y1 , int32 x2 ,int32 y2)
+{
+ int32 dirx;
+ int32 diry;
+ int32 co;
+ int32 slope;
+ int32 i;
+ int32 xc;
+ int32 yc;
+ int32 xmin;
+ int32 ymin;
+ int32 xmax;
+ int32 ymax;
+ int32 linesCrossed = 1;
+
+
+ if (x1 > x2)
+ {
+ xmin = x2;
+ xmax = x1;
+ }
+ else
+ {
+ xmin = x1;
+ xmax = x2;
+ }
+ if (y1 > y2)
+ {
+ ymin = y2;
+ ymax = y1;
+ }
+ else
+ {
+ ymin = y1;
+ ymax = y2;
+ }
+ //line set to go one step in chosen direction
+ //so ignore if it hits anything
+ dirx = x2 - x1;
+ diry = y2 - y1;
+ co = (y1 *dirx)- (x1*diry); //new line equation
+
+ i = 0;
+ do
+ {
+ // this is the inner inner loop
+ if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //skip if not on module
+ {
+ if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //skip if not on module
+ {
+ // okay its a valid line calculate an intersept
+ // wow but all this arithmatic we must have loads of time
+ slope = (bars[i].dx * diry) - (bars[i].dy *dirx);// slope it he slope between the two lines
+ if (slope != 0)//assuming parallel lines don't cross
+ {
+ //calculate x intercept and check its on both lines
+ xc = ((bars[i].co * dirx) - (co * bars[i].dx)) / slope;
+
+ if ((xc >= xmin-1) && (xc <= xmax+1)) //skip if not on module
+ {
+ if ((xc >= bars[i].xmin-1) && (xc <= bars[i].xmax+1)) //skip if not on line
+ {
+
+ yc = ((bars[i].co * diry) - (co * bars[i].dy)) / slope;
+
+ if ((yc >= ymin-1) && (yc <= ymax+1)) //skip if not on module
+ {
+ if ((yc >= bars[i].ymin-1) && (yc <= bars[i].ymax+1)) //skip if not on line
+ {
+ linesCrossed = 0;
+ }
+ }
+ }
+ }
}
}
}
- i++;
- } while (i < _nBars && linesCrossed);
+ i = i + 1;
+ }
+ while((i < nbars) && linesCrossed);
- return linesCrossed;
+ return linesCrossed;
}
-int SwordRouter::vertCheck(int16 x, int16 y1, int16 y2) {
- int32 ldx;
- int32 i;
- int32 yc;
- int32 ymin;
- int32 ymax;
- int32 linesCrossed = 1;
-
- if (y1 > y2) {
- ymin = y2;
- ymax = y1;
- } else {
- ymin = y1;
- ymax = y2;
- }
-
- // line set to go one step in chosen direction
- // so ignore if it hits anything
- i = 0;
-
- do {
- if (x >= _bars[i].xmin && x <= _bars[i].xmax) {
- // overlapping
- // skip if not on module
- if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) {
- // okay its a valid line calculate an intercept
- // wow but all this arithmetic we must have
- // loads of time
-
- // both lines vertical and overlap in x and y
- // so they cross
-
- if (_bars[i].dx == 0)
- linesCrossed = 0;
- else {
- ldx = x - _bars[i].x1;
- yc = _bars[i].y1 + (_bars[i].dy * ldx) / _bars[i].dx;
- // the intercept overlaps
- if (yc >= ymin - 1 && yc <= ymax + 1)
- linesCrossed = 0;
+int32 SwordRouter::HorizCheck(int32 x1 , int32 y , int32 x2)
+{
+ int32 dy;
+ int32 i;
+ int32 xc;
+ int32 xmin;
+ int32 xmax;
+ int32 linesCrossed = 1;
+
+ if (x1 > x2)
+ {
+ xmin = x2;
+ xmax = x1;
+ }
+ else
+ {
+ xmin = x1;
+ xmax = x2;
+ }
+ //line set to go one step in chosen direction
+ //so ignore if it hits anything
+
+ i = 0;
+ do
+ {
+ // this is the inner inner loop
+ if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //skip if not on module
+ {
+ if ((y >= bars[i].ymin) && ( y <= bars[i].ymax)) //skip if not on module
+ {
+ // okay its a valid line calculate an intersept
+ // wow but all this arithmatic we must have loads of time
+ if (bars[i].dy == 0)
+ {
+ linesCrossed = 0;
+ }
+ else
+ {
+ dy = y-bars[i].y1;
+ xc = bars[i].x1 + (bars[i].dx * dy)/bars[i].dy;
+ if ((xc >= xmin-1) && (xc <= xmax+1)) //skip if not on module
+ {
+ linesCrossed = 0;
+ }
}
}
}
- i++;
- } while (i < _nBars && linesCrossed);
+ i = i + 1;
+ }
+ while((i < nbars) && linesCrossed);
- return linesCrossed;
+ return linesCrossed;
}
-int SwordRouter::lineCheck(int16 x1, int16 y1, int16 x2, int16 y2) {
- int32 dirx;
- int32 diry;
- int32 co;
- int32 slope;
- int32 i;
- int32 xc;
- int32 yc;
- int32 xmin;
- int32 ymin;
- int32 xmax;
- int32 ymax;
- int32 linesCrossed = 1;
-
- if (x1 > x2) {
- xmin = x2;
- xmax = x1;
- } else {
- xmin = x1;
- xmax = x2;
- }
- if (y1 > y2) {
- ymin = y2;
- ymax = y1;
- } else {
- ymin = y1;
- ymax = y2;
+int32 SwordRouter::VertCheck(int32 x, int32 y1, int32 y2)
+{
+ int32 dx;
+ int32 i;
+ int32 yc;
+ int32 ymin;
+ int32 ymax;
+ int32 linesCrossed = 1;
+
+ if (y1 > y2)
+ {
+ ymin = y2;
+ ymax = y1;
+ }
+ else
+ {
+ ymin = y1;
+ ymax = y2;
}
-
- // line set to go one step in chosen direction
- // so ignore if it hits anything
-
- dirx = x2 - x1;
- diry = y2 - y1;
-
- co = (y1 * dirx)- (x1 * diry); // new line equation
-
- i = 0;
-
- do {
- // skip if not on module
- if (xmax >= _bars[i].xmin && xmin <= _bars[i].xmax) {
- // skip if not on module
- if (ymax >= _bars[i].ymin && ymin <= _bars[i].ymax) {
- // okay its a valid line calculate an intercept
- // wow but all this arithmetic we must have
- // loads of time
-
- // slope it he slope between the two lines
- slope = (_bars[i].dx * diry) - (_bars[i].dy *dirx);
- // assuming parallel lines don't cross
- if (slope != 0) {
- // calculate x intercept and check its
- // on both lines
- xc = ((_bars[i].co * dirx) - (co * _bars[i].dx)) / slope;
-
- // skip if not on module
- if (xc >= xmin - 1 && xc <= xmax + 1) {
- // skip if not on line
- if (xc >= _bars[i].xmin - 1 && xc <= _bars[i].xmax + 1) {
- yc = ((_bars[i].co * diry) - (co * _bars[i].dy)) / slope;
-
- // skip if not on module
- if (yc >= ymin - 1 && yc <= ymax + 1) {
- // skip if not on line
- if (yc >= _bars[i].ymin - 1 && yc <= _bars[i].ymax + 1) {
- linesCrossed = 0;
- }
- }
- }
- }
+ //line set to go one step in chosen direction
+ //so ignore if it hits anything
+ i = 0;
+ do // this is the inner inner loop
+ {
+ if ((x >= bars[i].xmin) && ( x <= bars[i].xmax)) //overlapping
+ {
+ if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //skip if not on module
+ {
+ // okay its a valid line calculate an intersept
+ // wow but all this arithmatic we must have loads of time
+ if (bars[i].dx == 0)//both lines vertical and overlap in x and y so they cross
+ {
+ linesCrossed = 0;
+ }
+ else
+ {
+ dx = x-bars[i].x1;
+ yc = bars[i].y1 + (bars[i].dy * dx)/bars[i].dx;
+ if ((yc >= ymin-1) && (yc <= ymax+1)) //the intersept overlaps
+ {
+ linesCrossed = 0;
+ }
}
}
- }
- i++;
- } while (i < _nBars && linesCrossed);
+ }
+ i = i + 1;
+ }
+ while((i < nbars) && linesCrossed);
- return linesCrossed;
+ return linesCrossed;
}
-int SwordRouter::checkTarget(int16 x, int16 y) {
- int32 dx, dy, xc, yc, xmin, xmax, ymin, ymax;
- int32 onLine = 0;
+int32 SwordRouter::CheckTarget(int32 x , int32 y)
+/*******************************************************************************
+ *******************************************************************************/
+{
+ int32 dx;
+ int32 dy;
+ int32 i;
+ int32 xc;
+ int32 yc;
+ int32 xmin;
+ int32 xmax;
+ int32 ymin;
+ int32 ymax;
+ int32 onLine = 0;
xmin = x - 1;
xmax = x + 1;
ymin = y - 1;
ymax = y + 1;
- for (int i = 0; (i < _nBars) && (onLine == 0); i++) {
- if ((xmax >= _bars[i].xmin) && (xmin <= _bars[i].xmax)) { //overlapping line
- if ((ymax >= _bars[i].ymin) && ( ymin <= _bars[i].ymax)) { //overlapping line
- // okay this line overlaps the target, calculate an y intersept for x
-
- if (_bars[i].dx == 0) // vertical line so we know it overlaps y
+ // check if point +- 1 is on the line
+ //so ignore if it hits anything
+
+ i = 0;
+ do
+ {
+
+ // this is the inner inner loop
+
+ if ((xmax >= bars[i].xmin) && ( xmin <= bars[i].xmax)) //overlapping line
+ {
+ if ((ymax >= bars[i].ymin) && ( ymin <= bars[i].ymax)) //overlapping line
+ {
+
+ // okay this line overlaps the target calculate an y intersept for x
+
+ if (bars[i].dx == 0)// vertical line so we know it overlaps y
+ {
yc = 0;
- else {
- dx = x - _bars[i].x1;
- yc = _bars[i].y1 + (_bars[i].dy * dx) / _bars[i].dx;
+ }
+ else
+ {
+ dx = x-bars[i].x1;
+ yc = bars[i].y1 + (bars[i].dy * dx)/bars[i].dx;
+ }
+
+ if ((yc >= ymin) && (yc <= ymax)) //overlapping point for y
+ {
+ onLine = 3;// target on a line so drop out
+ //Tdebug("RouteFail due to target on a line %d %d",x,y);
}
- if ((yc >= ymin) && (yc <= ymax)) //overlapping point for y
- onLine = 3; // target on a line so drop out
- else {
- if (_bars[i].dy == 0) // vertical line so we know it overlaps y
+ else
+ {
+ if (bars[i].dy == 0)// vertical line so we know it overlaps y
+ {
xc = 0;
- else {
- dy = y- _bars[i].y1;
- xc = _bars[i].x1 + (_bars[i].dx * dy) / _bars[i].dy;
}
- if ((xc >= xmin) && (xc <= xmax)) //skip if not on module
- onLine = 3;// target on a line so drop out
+ else
+ {
+ dy = y-bars[i].y1;
+ xc = bars[i].x1 + (bars[i].dx * dy)/bars[i].dy;
+ }
+
+ if ((xc >= xmin) && (xc <= xmax)) //skip if not on module
+ {
+ onLine = 3;// target on a line so drop out
+ //Tdebug("RouteFail due to target on a line %d %d",x,y);
+ }
}
- }
- }
- }
- return onLine;
-}
+ }
+ }
+ i = i + 1;
+ }
+ while((i < nbars) && (onLine == 0));
-void SwordRouter::resetExtraData(void) {
- _numExtraBars = _numExtraNodes = 0;
-}
-void SwordRouter::setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance) {
- _playerTargetX = x;
- _playerTargetY = y;
- _playerTargetDir = dir;
- _playerTargetStance = stance;
+ return onLine;
}
-void SwordRouter::loadWalkResources(int32 megaId, BsObject *mega, int32 x, int32 y, int32 dir) {
- WalkGridHeader *floorHeader;
-
- int32 walkGridId = _objMan->fetchObject(mega->o_place)->o_resource;
-
- uint8 *fPolyGrid = (uint8*)_resMan->openFetchRes(walkGridId);
- floorHeader = (WalkGridHeader*)(fPolyGrid + sizeof(Header));
- fPolyGrid += sizeof(WalkGridHeader) + sizeof(Header);
-
- _nBars = FROM_LE_32(floorHeader->numBars);
- _nNodes = FROM_LE_32(floorHeader->numNodes) + 1;
- if ((_nBars >= O_GRID_SIZE) || (_nNodes >= O_GRID_SIZE))
- error("loadWalkResources: resource has %d bars and %d nodes", _nBars, _nNodes);
-
- for (int32 cnt = 0; cnt < _nBars; cnt++) {
- _bars[cnt].x1 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].y1 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].x2 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].y2 = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].xmin = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].ymin = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].xmax = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].ymax = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].dx = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].dy = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _bars[cnt].co = READ_LE_UINT32(fPolyGrid); fPolyGrid += 4;
+/*******************************************************************************
+ *******************************************************************************
+ * THE SETUP ROUTINES
+ *******************************************************************************
+ *******************************************************************************/
+
+
+
+int32 SwordRouter::LoadWalkResources(BsObject *megaObject, int32 x, int32 y, int32 dir)
+{
+ WalkGridHeader floorHeader;
+ int32 i;
+ int32 j;
+ uint8 *fPolygrid;
+ uint8 *fMegaWalkData;
+
+ int32 floorId;
+ int32 walkGridResourceId;
+ BsObject *floorObject;
+
+
+
+// load in floor grid for current mega
+
+
+ floorId = megaObject->o_place;
+
+ //floorObject = (object *) Lock_object(floorId);
+ floorObject = _objMan->fetchObject(floorId);
+ walkGridResourceId = floorObject->o_resource;
+ //Unlock_object(floorId);
+
+ //ResOpen(walkGridResourceId); // mouse wiggle
+ //fPolygrid = ResLock(walkGridResourceId); // mouse wiggle
+ fPolygrid = (uint8*)_resMan->openFetchRes(walkGridResourceId);
+
+
+ fPolygrid += sizeof(Header);
+ memcpy(&floorHeader,fPolygrid,sizeof(WalkGridHeader));
+ fPolygrid += sizeof(WalkGridHeader);
+ nbars = FROM_LE_32(floorHeader.numBars);
+
+ if (nbars >= O_GRID_SIZE)
+ {
+ #if DEBUG == YES //check for id > number in file,
+ error("RouteFinder Error too many bars %d", nbars);
+ #endif
+ nbars = 0;
+ }
+
+ nnodes = FROM_LE_32(floorHeader.numNodes)+1; //array starts at 0 begins at a start node has nnodes nodes and a target node
+
+ if (nnodes >= O_GRID_SIZE)
+ {
+ #if DEBUG == YES //check for id > number in file,
+ error("RouteFinder Error too many nodes %d", nnodes);
+ #endif
+ nnodes = 0;
}
- //_nBars = 0;
- // leave node 0 for start node
- for (int32 cnt = 1; cnt < _nNodes; cnt++) {
- _node[cnt].x = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
- _node[cnt].y = READ_LE_UINT16(fPolyGrid); fPolyGrid += 2;
+ /*memmove(&bars[0],fPolygrid,nbars*sizeof(BarData));
+ fPolygrid += nbars*sizeof(BarData);//move pointer to start of node data*/
+ for (int32 cnt = 0; cnt < nbars; cnt++) {
+ bars[cnt].x1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].y1 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].x2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].y2 = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].xmin = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].ymin = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].xmax = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].ymax = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].dx = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].dy = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ bars[cnt].co = READ_LE_UINT32(fPolygrid); fPolygrid += 4;
}
- _resMan->resClose(walkGridId);
-
- // floor grid loaded. Copy george's extra bars and nodes.
- if (megaId == GEORGE) {
- memcpy(_bars + _nBars, _extraBars, _numExtraBars * sizeof(BarData));
- _nBars += _numExtraBars;
- for (int32 cnt = 0; cnt < _numExtraNodes; cnt++) {
- _node[_nNodes + cnt].x = _extraNodes[cnt].x;
- _node[_nNodes + cnt].y = _extraNodes[cnt].y;
+
+ /*j = 1;// leave node 0 for start node
+ do
+ {
+ memmove(&node[j].x,fPolygrid,2*sizeof(int16));
+ fPolygrid += 2*sizeof(int16);
+ j ++;
+ }
+ while(j < nnodes);//array starts at 0*/
+ for (int32 cnt = 1; cnt < nnodes; cnt++) {
+ node[cnt].x = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ node[cnt].y = READ_LE_UINT16(fPolygrid); fPolygrid += 2;
+ }
+
+ //ResUnlock(walkGridResourceId); // mouse wiggle
+ //ResClose(walkGridResourceId); // mouse wiggle
+ _resMan->resClose(walkGridResourceId);
+
+
+// floor grid loaded
+// if its george copy extra bars and nodes
+
+ if (megaId == GEORGE)
+ {
+ // copy any extra bars from extraBars array
+
+ //Zdebug("%d", nExtraBars);
+
+ memmove(&bars[nbars], &_extraBars[0], _numExtraBars*sizeof(BarData));
+ nbars += _numExtraBars;
+
+ // copy any extra nodes from extraNode array
+ j = 0;
+ while(j < _numExtraNodes)//array starts at 0
+ {
+ node[nnodes+j].x = _extraNodes[j].x ;
+ node[nnodes+j].y = _extraNodes[j].y ;
+ j++;
}
- _nNodes += _numExtraNodes;
+
+ nnodes += _numExtraNodes;
}
- uint8 *walkData = (uint8*)_resMan->openFetchRes(mega->o_mega_resource);
- _nWalkFrames = walkData[0];
- _nTurnFrames = walkData[1];
- walkData += 2;
- for (int32 cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) {
- _dx[cnt] = READ_LE_UINT32(walkData);
- walkData += 4;
+// copy the mega structure into the local variables for use in all subroutines
+
+ startX = megaObject->o_xcoord;
+ startY = megaObject->o_ycoord;
+ startDir = megaObject->o_dir;
+ targetX = x;
+ targetY= y;
+ targetDir = dir;
+
+ scaleA = megaObject->o_scale_a;
+ scaleB = megaObject->o_scale_b;
+
+ //ResOpen(megaObject->o_mega_resource); // mouse wiggle
+ //fMegaWalkData = ResLock(megaObject->o_mega_resource); // mouse wiggle
+ fMegaWalkData = (uint8*)_resMan->openFetchRes(megaObject->o_mega_resource);
+
+ nWalkFrames = fMegaWalkData[0];
+ nTurnFrames = fMegaWalkData[1];
+ fMegaWalkData += 2;
+
+ memmove(&dx[0],fMegaWalkData,NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32));
+ fMegaWalkData += NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32);
+ memmove(&dy[0],fMegaWalkData,NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32));
+ fMegaWalkData += NO_DIRECTIONS*(nWalkFrames+1+nTurnFrames)*sizeof(int32);
+
+ memmove(&modX[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32));
+ fMegaWalkData += NO_DIRECTIONS*sizeof(int32);
+ memmove(&modY[0],fMegaWalkData,NO_DIRECTIONS*sizeof(int32));
+ fMegaWalkData += NO_DIRECTIONS*sizeof(int32);
+
+ //ResUnlock(megaObject->o_mega_resource); // mouse wiggle
+ //ResClose(megaObject->o_mega_resource); // mouse wiggle
+ _resMan->resClose(megaObject->o_mega_resource);
+
+ diagonalx = modX[3] ;//36
+ diagonaly = modY[3] ;//8
+
+// mega data ready
+
+
+// finish setting grid by putting mega node at begining
+// and target node at end and reset current values
+ node[0].x = startX;
+ node[0].y = startY;
+ node[0].level = 1;
+ node[0].prev = 0;
+ node[0].dist = 0;
+ i=1;
+ do
+ {
+ node[i].level = 0;
+ node[i].prev = 0;
+ node[i].dist = 9999;
+ i=i+1;
}
- for (int32 cnt = 0; cnt < NO_DIRECTIONS * (_nWalkFrames + 1 + _nTurnFrames); cnt++) {
- _dy[cnt] = READ_LE_UINT32(walkData);
- walkData += 4;
+ while (i < nnodes);
+ node[nnodes].x = targetX;
+ node[nnodes].y = targetY;
+ node[nnodes].level = 0;
+ node[nnodes].prev = 0;
+ node[nnodes].dist = 9999;
+
+ return 1;
+}
+
+
+/*******************************************************************************
+ *******************************************************************************
+ * THE ROUTE EXTRACTOR
+ *******************************************************************************
+ *******************************************************************************/
+
+void SwordRouter::ExtractRoute()
+/****************************************************************************
+ * ExtractRoute gets route from the node data after a full scan, route is
+ * written with just the basic way points and direction options for heading
+ * to the next point.
+ ****************************************************************************/
+{
+ int32 prev;
+ int32 prevx;
+ int32 prevy;
+ int32 last;
+ int32 point;
+ int32 p;
+ int32 dirx;
+ int32 diry;
+ int32 dir;
+ int32 dx;
+ int32 dy;
+
+
+ // extract the route from the node data
+ prev = nnodes;
+ last = prev;
+ point = O_ROUTE_SIZE - 1;
+ route[point].x = node[last].x;
+ route[point].y = node[last].y;
+ do
+ {
+ point = point - 1;
+ prev = node[last].prev;
+ prevx = node[prev].x;
+ prevy = node[prev].y;
+ route[point].x = prevx;
+ route[point].y = prevy;
+ last = prev;
}
- for (int32 cnt = 0; cnt < NO_DIRECTIONS; cnt++) {
- _modX[cnt] = READ_LE_UINT32(walkData);
- walkData += 4;
+ while (prev > 0);
+
+ // now shuffle route down in the buffer
+ routeLength = 0;
+ point;
+ do
+ {
+ route[routeLength].x = route[point].x;
+ route[routeLength].y = route[point].y;
+ point = point + 1;
+ routeLength = routeLength + 1;
+ }
+ while (point < O_ROUTE_SIZE);
+ routeLength = routeLength - 1;
+
+ // okay the route exists as a series point now put in some directions
+ p = 0;
+ do
+ {
+ #ifdef PLOT_PATHS
+ BresenhamLine(route[p+1].x-128,route[p+1].y-128, route[p].x-128,route[p].y-128, (uint8*)screen_ad, true_pixel_size_x, pixel_size_y, ROUTE_END_FLAG);
+ #endif
+ dx = route[p+1].x - route[p].x;
+ dy = route[p+1].y - route[p].y;
+ dirx = 1;
+ diry = 1;
+ if (dx < 0)
+ {
+ dx = -dx;
+ dirx = -1;
+ }
+ if (dy < 0)
+ {
+ dy = -dy;
+ diry = -1;
+ }
+
+ if ((diagonaly * dx) > (diagonalx * dy)) // dir = 1,2 or 2,3 or 5,6 or 6,7
+ {
+ dir = 4 - 2 * dirx; // 2 or 6
+ route[p].dirS = dir;
+ dir = dir + diry * dirx; // 1,3,5 or 7
+ route[p].dirD = dir;
+ }
+ else // dir = 7,0 or 0,1 or 3,4 or 4,5
+ {
+ dir = 2 + 2 * diry; // 0 or 4
+ route[p].dirS = dir;
+ dir = 4 - 2 * dirx; // 2 or 6
+ dir = dir + diry * dirx; // 1,3,5 or 7
+ route[p].dirD = dir;
+ }
+ p = p + 1;
}
- for (int32 cnt = 0; cnt < NO_DIRECTIONS; cnt++) {
- _modY[cnt] = READ_LE_UINT32(walkData);
- walkData += 4;
+ while (p < (routeLength));
+ // set the last dir to continue previous route unless specified
+ if (targetDir == NO_DIRECTIONS)
+ {
+ route[p].dirS = route[p-1].dirS;
+ route[p].dirD = route[p-1].dirD;
}
- _resMan->resClose(mega->o_mega_resource);
- _diagonalx = _modX[3];
- _diagonaly = _modY[3];
- if ((_diagonalx != 36) || (_diagonaly != 8))
- warning("DiagX = %d, DiagY = %d", _diagonalx, _diagonaly);
- // mega data ready
- // finish setting grid by putting mega node at begining
- // and target node at end and reset current values
-
- _node[0].x = mega->o_xcoord; // the start
- _node[0].y = mega->o_ycoord; //
- _node[0].dist = 0;
- _node[0].prev = 0;
- _node[0].level = 1;
-
- for (int32 cnt = 1; cnt <= _nNodes; cnt++) {
- _node[cnt].dist = 9999;
- _node[cnt].prev = 0;
- _node[cnt].level = 0;
+ else
+ {
+ route[p].dirS = targetDir;
+ route[p].dirD = targetDir;
}
- _node[_nNodes].x = x; // the destination
- _node[_nNodes].y = y; //
+ return;
+}
+
+#define screen_ad NULL
+#define pixel_size_y 1
+#define true_pixel_size_x 1
+void SwordRouter::RouteLine(int32 x1,int32 y1,int32 x2,int32 y2 ,int32 colour)
+{
+ BresenhamLine(x1-128, y1-128, x2-128, y2-128, (uint8*)screen_ad, true_pixel_size_x, pixel_size_y, colour);
+ return;
}
+void SwordRouter::BresenhamLine(int32 x1,int32 y1,int32 x2,int32 y2, uint8 *screen, int32 width, int32 height, int32 colour) {
+
+}
+
+#define DIAGONALX 36
+#define DIAGONALY 8
int SwordRouter::whatTarget(int32 startX, int32 startY, int32 destX, int32 destY) {
int tar_dir;
//setting up
@@ -1936,9 +2616,9 @@ int SwordRouter::whatTarget(int32 startX, int32 startY, int32 destX, int32 destY
int signY = (deltaY > 0);
int slope;
- if ( (abs(deltaY) * _diagonalx ) < (abs(deltaX) * _diagonaly / 2))
+ if ( (abs(deltaY) * DIAGONALX ) < (abs(deltaX) * DIAGONALY / 2))
slope = 0;// its flat
- else if ( (abs(deltaY) * _diagonalx / 2) > (abs(deltaX) * _diagonaly ) )
+ else if ( (abs(deltaY) * DIAGONALX / 2) > (abs(deltaX) * DIAGONALY ) )
slope = 2;// its vertical
else
slope = 1;// its diagonal
@@ -1966,3 +2646,14 @@ int SwordRouter::whatTarget(int32 startX, int32 startY, int32 destX, int32 destY
}
return tar_dir;
}
+
+void SwordRouter::resetExtraData(void) {
+ _numExtraBars = _numExtraNodes = 0;
+}
+
+void SwordRouter::setPlayerTarget(int32 x, int32 y, int32 dir, int32 stance) {
+ _playerTargetX = x;
+ _playerTargetY = y;
+ _playerTargetDir = dir;
+ _playerTargetStance = stance;
+}