diff options
| author | Andrew Kurushin | 2004-12-29 21:49:25 +0000 | 
|---|---|---|
| committer | Andrew Kurushin | 2004-12-29 21:49:25 +0000 | 
| commit | 41a5251e28898f4a34ab51c01325d61c2510daf8 (patch) | |
| tree | 4ccea652e5a4686a15c9bb9f26750deb01cceb52 | |
| parent | 8cf04e39285216f464ca14afacb74b6b49b0a924 (diff) | |
| download | scummvm-rg350-41a5251e28898f4a34ab51c01325d61c2510daf8.tar.gz scummvm-rg350-41a5251e28898f4a34ab51c01325d61c2510daf8.tar.bz2 scummvm-rg350-41a5251e28898f4a34ab51c01325d61c2510daf8.zip | |
- some work in progress
svn-id: r16375
| -rw-r--r-- | saga/actor.cpp | 466 | ||||
| -rw-r--r-- | saga/actor.h | 30 | ||||
| -rw-r--r-- | saga/script.h | 11 | ||||
| -rw-r--r-- | saga/sfuncs.cpp | 76 | 
4 files changed, 512 insertions, 71 deletions
| diff --git a/saga/actor.cpp b/saga/actor.cpp index f37ddbe799..0efea40548 100644 --- a/saga/actor.cpp +++ b/saga/actor.cpp @@ -56,7 +56,7 @@ static int actorCompare(const ActorDataPointer& actor1, const ActorDataPointer&  // Lookup table to convert 8 cardinal directions to 4  int actorDirectectionsLUT[8] = {  	ACTOR_DIRECTION_BACK,	// kDirUp -	ACTOR_DIRECTION_RIGHT,	// kkDirUpRight +	ACTOR_DIRECTION_RIGHT,	// kDirUpRight  	ACTOR_DIRECTION_RIGHT,	// kDirRight  	ACTOR_DIRECTION_RIGHT,	// kDirDownRight  	ACTOR_DIRECTION_FORWARD,// kDirDown @@ -76,6 +76,36 @@ PathDirectionData pathDirectionLUT[8][4] = {  	{{3, -1,  0}, {0,  0, -1}, {7, -1, -1}}  }; +int pathDirectionLUT2[8][2] =  { +	0,	-1, +	1,	0, +	0,	1, +	-1,	0, +	1,	-1, +	1,	1, +	-1,	1, +	-1,	-1 +}; + +int angleLUT[16][2] = { +	0,		-256, +	98,		-237, +	181,	-181, +	237,	-98, +	256,	0, +	237,	98, +	181,	181, +	98,		237, +	0,		256, +	-98,	237, +	-181,	181, +	-237,	98, +	-256,	0, +	-237,	-98, +	-181,	-181, +	-98,	-237 +}; +  Actor::Actor(SagaEngine *vm) : _vm(vm) {  	int i; @@ -96,6 +126,7 @@ Actor::Actor(SagaEngine *vm) : _vm(vm) {  	_pathCellCount = _yCellCount * _xCellCount;  	_pathCell = (int*)malloc(_pathCellCount * sizeof *_pathCell); +  	_pathRect.left = 0;  	_pathRect.right = _vm->getDisplayWidth();  	_pathRect.top = _vm->getPathYOffset(); @@ -215,6 +246,34 @@ bool Actor::loadActorResources(ActorData * actor) {  	return true;  } +void Actor::realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags) { +	int angle; +	int distance; +	ActorData *actor; +	if (walkFlags & kWalkUseAngle) { +		// tiled stuff +		if (_vm->_scene->getMode() == SCENE_MODE_ISO) { +			//todo: it +		} else { +			angle = location.x & 15;   +			distance = location.y; + +			location.x = (angleLUT[angle][0] * distance) >> 6; //fixme - call real angle calc +			location.y = (angleLUT[angle][1] * distance) >> 6; +		} +	} + +	if (objectId != ID_NOTHING) { +		if (IS_VALID_ACTOR_ID(objectId)) { +			actor = getActor(objectId); +			location = actor->location; +		} else { +			warning("ObjectId unsupported"); //TODO: do it +		} +		 +	} +} +  ActorData *Actor::getActor(uint16 actorId) {  	ActorData *actor; @@ -1114,7 +1173,7 @@ void Actor::abortSpeech() {  	_activeSpeech.playingTime = 0;  } -void Actor::findActorPath(ActorData * actor, const Point &pointFrom, const Point &pointTo) { +void Actor::findActorPath(ActorData * actor, const Point &fromPoint, const Point &toPoint) {  	Point tempPoint;  	Point iteratorPoint;  	Point bestPoint; @@ -1124,11 +1183,11 @@ void Actor::findActorPath(ActorData * actor, const Point &pointFrom, const Point  	int i;  	Rect intersect; -	tempPoint.y = pointTo.y; -	tempPoint.x = pointTo.x >> 1; +	tempPoint.y = toPoint.y; +	tempPoint.x = toPoint.x >> 1;  	actor->walkStepsCount = 0; -	if (pointFrom == pointTo) { +	if (fromPoint == toPoint) {  		actor->addWalkPath(tempPoint.x, tempPoint.y);  		return;  	} @@ -1165,27 +1224,26 @@ void Actor::findActorPath(ActorData * actor, const Point &pointFrom, const Point -	if (scanPathLine(pointFrom, pointTo)) { -		iteratorPoint.y = pointFrom.y; -		iteratorPoint.x = pointFrom.x >> 1; +	if (scanPathLine(fromPoint, toPoint)) { +		iteratorPoint.y = fromPoint.y; +		iteratorPoint.x = fromPoint.x >> 1;  		actor->addWalkPath(iteratorPoint.x, iteratorPoint.y);  		actor->addWalkPath(tempPoint.x, tempPoint.y);  		return;  	} -	i = fillPathArray(pointFrom, pointTo, bestPoint); +	i = fillPathArray(fromPoint, toPoint, bestPoint); -	if (pointFrom == bestPoint) { +	if (fromPoint == bestPoint) {  		iteratorPoint.y = bestPoint.y;  		iteratorPoint.x = bestPoint.x >> 1;  		actor->addWalkPath(iteratorPoint.x, iteratorPoint.y);  		return;  	} -/* +  	if (i != 0) -		result = SetPath(pcell, from, &bestpoint, nodelist); -*/ +		setActorPath(actor, fromPoint, bestPoint);  }  bool Actor::scanPathLine(const Point &point1, const Point &point2) { @@ -1240,9 +1298,9 @@ bool Actor::scanPathLine(const Point &point1, const Point &point2) {  	return true;  } -int Actor::fillPathArray(const Point &pointFrom, const Point &pointTo, Point &bestPoint) { -	Point  pathFrom; -	Point  pathTo; +int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint) { +	Point  pathFromPoint; +	Point  pathToPoint;  	int bestRating;  	int currentRating;  	Point bestPath; @@ -1256,24 +1314,24 @@ int Actor::fillPathArray(const Point &pointFrom, const Point &pointTo, Point &be  	int directionCount; -	pathFrom.x = pointFrom.x >> 1; -	pathFrom.y = pointFrom.y - _vm->getPathYOffset(); +	pathFromPoint.x = fromPoint.x >> 1; +	pathFromPoint.y = fromPoint.y - _vm->getPathYOffset(); -	pathTo.x = pointTo.x >> 1; -	pathTo.y = pointTo.y - _vm->getPathYOffset(); +	pathToPoint.x = toPoint.x >> 1; +	pathToPoint.y = toPoint.y - _vm->getPathYOffset();  	pointCounter = 0; -	bestRating = quickDistance(pathFrom, pathTo); -	bestPath = pathFrom; +	bestRating = quickDistance(pathFromPoint, pathToPoint); +	bestPath = pathFromPoint;  	for (startDirection = 0; startDirection < 4; startDirection++) {  		newPathDirectionIterator = pathDirectionList.pushBack();  		pathDirection = newPathDirectionIterator.operator->(); -		pathDirection->x = pathFrom.x; -		pathDirection->y = pathFrom.y; +		pathDirection->x = pathFromPoint.x; +		pathDirection->y = pathFromPoint.y;  		pathDirection->direction = startDirection;  	} -	setPathCell(pathFrom, 0); +	setPathCell(pathFromPoint, 0);  	pathDirectionIterator = pathDirectionList.begin(); @@ -1293,12 +1351,12 @@ int Actor::fillPathArray(const Point &pointFrom, const Point &pointTo, Point &be  				pathDirection->y = nextPoint.y;  				pathDirection->direction = samplePathDirection->direction;  				++pointCounter; -				if (nextPoint == pathTo) { -					bestPoint.x = pointTo.x & ~1; -					bestPoint.y = pointTo.y; +				if (nextPoint == pathToPoint) { +					bestPoint.x = toPoint.x & ~1; +					bestPoint.y = toPoint.y;  					return pointCounter;  				} -				currentRating = quickDistance(nextPoint, pathTo); +				currentRating = quickDistance(nextPoint, pathToPoint);  				if (currentRating  < bestRating) {  					bestRating = currentRating;  					bestPath = nextPoint; @@ -1314,6 +1372,356 @@ int Actor::fillPathArray(const Point &pointFrom, const Point &pointTo, Point &be  	return pointCounter;  } +void Actor::setActorPath(ActorData * actor, const Point &fromPoint, const Point &toPoint) { +	Point  pathFromPoint; +	Point  pathToPoint; +	Point *point; +	Point nextPoint; +	int direction; +	PathNode *node; +	int i, last; + +	pathFromPoint.x = fromPoint.x >> 1; +	pathFromPoint.y = fromPoint.y - _vm->getPathYOffset(); + +	pathToPoint.x = toPoint.x >> 1; +	pathToPoint.y = toPoint.y - _vm->getPathYOffset(); + + + +	_pathList[0].x = pathToPoint.x; +	_pathList[0].y = toPoint.y; +	nextPoint = pathToPoint; +	_pathListIndex = 0; + +	point = _pathList; +	while ( !(nextPoint == pathFromPoint)) { +		_pathListIndex++; +		if (_pathListIndex >= PATH_LIST_MAX) { +			error("Actor::setActorPath PATH_LIST_MAX"); +		} +		point++; +		direction = getPathCell(nextPoint); +		nextPoint.x -= pathDirectionLUT2[direction][0]; +		nextPoint.y -= pathDirectionLUT2[direction][1]; +		point->x = nextPoint.x; +		point->y = nextPoint.y + _vm->getPathYOffset(); +	} + +	pathToNode(); + +	removeNodes(); + +    nodeToPath(); + +	removePathPoints(); + +	_pathNodeIndex++; +	last = min(_pathNodeIndex, PATH_NODE_MAX); +	for (i = 0, node = _pathNodeList; i < last; i++, node++) { +		actor->addWalkPath(node->x, node->y); +	} + +} + +void Actor::pathToNode() { +	Point point1, point2, delta; +	int direction; +	int i; +	WORD 	nodeindex = 0; +	Point *point; +	PathNode *nodeList; + +	_pathNodeIndex = 0; +	point= &_pathList[_pathListIndex];	 +	direction = 0, + +	_pathNodeList->x = point->x; +	_pathNodeList->y = point->y; +	nodeList = _pathNodeList; + +	for (i = _pathListIndex; i > 0; i--) { +		point1 = *point; +		--point; +		point2 = *point; +		if (direction == 0) { +			delta.x = integerCompare(point2.x, point1.x); +			delta.y = integerCompare(point2.y, point1.y); +			direction++; +		} +		if ((point1.x + delta.x != point2.x) || (point1.y + delta.y != point2.y)) { +			++nodeList; +			++_pathNodeIndex; +			nodeList->x = point1.x; +			nodeList->y = point2.x; +			direction--; +			i++; +			point++; +		} +	} +	++nodeList; +	++_pathNodeIndex; +	nodeList->x = _pathList->x; +	nodeList->y = _pathList->y; +} + +int pathLine(Point *pointList, const Point &point1, const Point &point2) { +	Point point; +	Point delta; +	Point tempPoint; +	int s1; +	int s2; +	bool interchange = false; +	int errterm; +	int i; + +	delta.x = abs(point2.x - point1.x); +	delta.y = abs(point2.y - point1.y); +	point = point1; +	s1 = integerCompare(point2.x, point1.x); +	s2 = integerCompare(point2.y, point1.y); + +	if (delta.y > delta.x) { +		SWAP(delta.y, delta.x); +		interchange = true; +	} + +	tempPoint.x = delta.x * 2; +	tempPoint.y = delta.y * 2; + +	errterm = tempPoint.y - delta.x; + +	for (i = 0; i < delta.x; i++) { +		while (errterm >= 0) { +			if (interchange) { +				point.x += s1; +			} else { +				point.y += s2; +			} +			errterm -= tempPoint.x; +		} +		if (interchange) { +			point.y += s2; +		} else { +			point.x += s1; +		} +		errterm += tempPoint.y; + +		pointList[i] = point; +	} +	return delta.x; +} + +void Actor::nodeToPath() { +	int i; +	Point point1, point2; +	PathNode *node; +	Point *point; + +	for (i = 0, point = _pathList; i < PATH_LIST_MAX; i++, point++) { +		point->x = point->y = PATH_NODE_EMPTY; +	} + +	_pathListIndex = 1; +	_pathList[0].x = _pathNodeList[0].x; +	_pathList[0].y = _pathNodeList[0].y; +	_pathNodeList[0].link = 0; +	for (i = 0, node = _pathNodeList; i < _pathNodeIndex; i++) { +		point1.x = node->x; +		point1.y = node->y; +		node++; +		point2.x = node->x; +		point2.y = node->y; +		_pathListIndex += pathLine(&_pathList[_pathListIndex], point1, point2); +		node->link = _pathListIndex - 1; +	} +	_pathListIndex--; +	_pathNodeList[_pathNodeIndex].link = _pathListIndex; + +} + +void Actor::removeNodes() { +	int i, j, k; +	PathNode *iNode, *jNode, *kNode, *fNode; +	Point point1, point2; +	fNode = &_pathNodeList[_pathNodeIndex]; +	 +	point1.x = _pathNodeList[0].x * 2; +	point1.y = _pathNodeList[0].y; +	point2.x = fNode->x * 2; +	point2.y = fNode->y; + +	if (scanPathLine(point1, point2)) { +		_pathNodeList[1] = *fNode; +		_pathNodeIndex = 1; +	} + +	if (_pathNodeIndex < 4) { +		return; +	} + +	for (i = _pathNodeIndex - 1, iNode = fNode-1; i > 1 ; i--, iNode--) { +		if (iNode->x == PATH_NODE_EMPTY) { +			continue; +		} + +		point1.x = _pathNodeList[0].x * 2; +		point1.y = _pathNodeList[0].y; +		point2.x = iNode->x * 2; +		point2.y = iNode->y; + +		if (scanPathLine(point1, point2)) { +			for (j = 1, jNode = _pathNodeList + 1; j < i; j++, jNode++) { +				jNode->x = PATH_NODE_EMPTY; +			} +		} +	} + +	for (i = 1, iNode = _pathNodeList + 1; i < _pathNodeIndex - 1; i++, iNode++) { +		if (iNode->x == PATH_NODE_EMPTY) { +			continue; +		} +		point1.x = fNode->x * 2; +		point1.y = fNode->y; +		point2.x = iNode->x * 2; +		point2.y = iNode->y; + +		if (scanPathLine(point1, point2)) { +			for (j = i + 1, jNode = iNode + 1; j < _pathNodeIndex; j++, jNode++) { +				jNode->x = PATH_NODE_EMPTY; +			} +		} +	} +	condenseNodeList(); + +	for (i = 1, iNode = _pathNodeList + 1; i < _pathNodeIndex - 1; i++, iNode++) { +		if (iNode->x == PATH_NODE_EMPTY) { +			continue; +		} +		for (j = i + 2,jNode = iNode + 2; j < _pathNodeIndex; j++, jNode++) +		{ +			if (jNode->x == PATH_NODE_EMPTY) { +				continue; +			} + +			point1.x = iNode->x * 2; +			point1.y = iNode->y; +			point2.x = jNode->x * 2; +			point2.y = jNode->y; + +			if (scanPathLine(point1, point2)) { +				for (k = i + 1,kNode = iNode + 1; k < j; k++, kNode++) { +					kNode->x = PATH_NODE_EMPTY; +				} +			} +		} +	} +	condenseNodeList(); +} + +void Actor::condenseNodeList() { +	int i, j, count; +	PathNode *iNode, *jNode; +	 +	count = _pathNodeIndex; + +	for (i = 1, iNode = _pathNodeList+1; i < _pathNodeIndex; i++, iNode++) { +		if (iNode->x == PATH_NODE_EMPTY) { +			j = i + 1; +			jNode = iNode + 1; +			while ( jNode->x == PATH_NODE_EMPTY ) { +				j++; +				jNode++; +			} +			*iNode = *jNode; +			count = i; +			jNode->x = PATH_NODE_EMPTY; +			if (j == _pathNodeIndex) { +				break; +			} +		} +	} +	_pathNodeIndex = count; +} + +void Actor::removePathPoints() { +	int i, j, k, l; +	PathNode *node; +	int newPathNodeIndex; +	int start; +	int end; +	Point point1, point2, point3, point4; + + +	if (_pathNodeIndex < 2) +		return; + + +	_newPathNodeList[0] = _pathNodeList[0]; +	newPathNodeIndex = 0; + +	for (i = 1, node = _pathNodeList + 1; i < _pathNodeIndex; i++, node++) { +		newPathNodeIndex++; +		_newPathNodeList[newPathNodeIndex] = *node; + +		for (j = 5; j > 0; j--) { +			start = node->link - j; +			end = node->link + j; +		 +			if (start < 0 || end > _pathListIndex) { +				continue; +			} + +			point1.x = _pathList[start].x; +			if (point1.x == PATH_NODE_EMPTY) { +				continue; +			} +			point2.x = _pathList[end].x; +			if (point2.x == PATH_NODE_EMPTY) { +				continue; +			} + +			point1.y = _pathList[start].y; +			point2.y = _pathList[end].y; +			 +			point3.x = point1.x * 2; +			point3.y = point1.y; +			point4.x = point2.x * 2; +			point4.y = point2.y; +			if (scanPathLine( point3, point4)) { +				for (l = 1; l <= newPathNodeIndex; l++) { +					if (start <= _newPathNodeList[l].link) { +						newPathNodeIndex = l; +						_newPathNodeList[newPathNodeIndex].x = point1.x; +						_newPathNodeList[newPathNodeIndex].y = point1.y; +						_newPathNodeList[newPathNodeIndex].link = start; +						newPathNodeIndex++; +						break; +					} +				} +				_newPathNodeList[newPathNodeIndex].x = point2.x; +				_newPathNodeList[newPathNodeIndex].y = point2.y; +				_newPathNodeList[newPathNodeIndex].link = end; + +				for (k = start + 1; k < end; k++) { +					_pathList[k].x = PATH_NODE_EMPTY; +				} +				break; +			} +		} +	} + +	newPathNodeIndex++; +	_newPathNodeList[newPathNodeIndex] = _pathNodeList[_pathNodeIndex]; + +	for (i = 0, j = 0; i <= newPathNodeIndex; i++) { +		if (newPathNodeIndex == i || (_newPathNodeList[i].y != _newPathNodeList[i+1].y +			|| _newPathNodeList[i].x != _newPathNodeList[i+1].x) ) +			_pathNodeList[j++] = _newPathNodeList[i]; +	} +	_pathNodeIndex = j - 1; +} +  /*  // Console wrappers - must be safe to run  // TODO - checkup ALL arguments, cause wrong arguments may fall function with "error" diff --git a/saga/actor.h b/saga/actor.h index 60e5de9f3f..4ab3f07efe 100644 --- a/saga/actor.h +++ b/saga/actor.h @@ -53,6 +53,12 @@ namespace Saga {  #define ACTOR_SPEECH_STRING_MAX 16	// speech const  #define ACTOR_SPEECH_ACTORS_MAX 8 +#define PATH_NODE_MAX 100 +#define PATH_LIST_MAX 500 + +#define PATH_NODE_EMPTY -1 + +  #define ID_NOTHING 0  #define ID_PROTAG 1 @@ -124,6 +130,12 @@ struct PathDirectionData {  typedef SortedList<PathDirectionData> PathDirectionList; +struct PathNode { +	int x; +	int y; +	int link; +}; +  struct ActorFrameRange {  	int frameIndex;  	int frameCount; @@ -259,6 +271,7 @@ public:  	bool actorWalkTo(uint16 actorId, const ActorLocation &toLocation);  	ActorData *getActor(uint16 actorId);  	ActorFrameRange *getActorFrameRange(uint16 actorId, int frameType); +	void realLocation(ActorLocation &location, uint16 objectId, uint16 walkFlags);  //	speech   	void actorSpeech(uint16 actorId, const char **strings, int stringsCount, uint16 sampleResourceId, int speechFlags); @@ -280,7 +293,7 @@ private:  	void createDrawOrderList();  	void calcActorScreenPosition(ActorData * actor);  	bool followProtagonist(ActorData * actor); -	void findActorPath(ActorData * actor, const Point &pointFrom, const Point &pointTo); +	void findActorPath(ActorData * actor, const Point &fromPoint, const Point &toPoint);  	void handleSpeech(int msec);  	void handleActions(int msec, bool setup);  	void setPathCell(const Point &testPoint, int value) { @@ -290,7 +303,13 @@ private:  		return _pathCell[testPoint.x + testPoint.y * _xCellCount];  	}  	bool scanPathLine(const Point &point1, const Point &point2); -	int fillPathArray(const Point &pointFrom, const Point &pointTo, Point &bestPoint); +	int fillPathArray(const Point &fromPoint, const Point &toPoint, Point &bestPoint); +	void setActorPath(ActorData * actor, const Point &fromPoint, const Point &toPoint); +	void pathToNode(); +	void condenseNodeList(); +	void removeNodes(); +	void nodeToPath(); +	void removePathPoints();  	int _lastTickMsec;  	SagaEngine *_vm; @@ -298,6 +317,8 @@ private:  	ActorOrderList _drawOrderList;  	ActorData _actors[ACTORCOUNT];  	SpeechData _activeSpeech; + +//path stuff  	Rect _barrierList[ACTOR_BARRIERS_MAX];  	int _barrierCount;  	int *_pathCell; @@ -305,6 +326,11 @@ private:  	int _xCellCount;  	int _yCellCount;  	Rect _pathRect; +	Point _pathList[PATH_LIST_MAX]; +	int _pathListIndex; +	PathNode _pathNodeList[PATH_NODE_MAX]; +	PathNode _newPathNodeList[PATH_NODE_MAX]; +	int _pathNodeIndex;  }; diff --git a/saga/script.h b/saga/script.h index 804b311150..0808f7fb6b 100644 --- a/saga/script.h +++ b/saga/script.h @@ -114,6 +114,13 @@ enum CycleFlags {  	kCycleReverse = (1 << 3)  }; +enum WalkFlags { +	kWalkBackPedal = (1<<0), +	kWalkAsync = (1<<1), +	kWalkUseAngle = (1<<2), +	kWalkFace = (1<<5) +}; +  struct SCRIPT_THREAD {  	int flags;				// ThreadFlags  	int waitType;			// ThreadWaitTypes @@ -325,7 +332,7 @@ private:  	int SF_cycleColors(SCRIPTFUNC_PARAMS);  	int sfDoCenterActor(SCRIPTFUNC_PARAMS);  	int sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS); -	int SF_actorWalkToAsync(SCRIPTFUNC_PARAMS); +	int sfScriptWalkToAsync(SCRIPTFUNC_PARAMS);  	int SF_enableZone(SCRIPTFUNC_PARAMS);  	int sfSetActorState(SCRIPTFUNC_PARAMS);  	int scriptMoveTo(SCRIPTFUNC_PARAMS); @@ -334,7 +341,7 @@ private:  	int sfFinishBgdAnim(SCRIPTFUNC_PARAMS);  	int sfSwapActors(SCRIPTFUNC_PARAMS);  	int sfSimulSpeech(SCRIPTFUNC_PARAMS); -	int SF_actorWalk(SCRIPTFUNC_PARAMS); +	int sfScriptWalk(SCRIPTFUNC_PARAMS);  	int sfCycleFrames(SCRIPTFUNC_PARAMS);  	int sfSetFrame(SCRIPTFUNC_PARAMS);  	int SF_setRightPortrait(SCRIPTFUNC_PARAMS); diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp index 805801fa8b..e5a74aefea 100644 --- a/saga/sfuncs.cpp +++ b/saga/sfuncs.cpp @@ -74,7 +74,7 @@ void Script::setupScriptFuncList(void) {  		OPCODE(SF_cycleColors),  		OPCODE(sfDoCenterActor),  		OPCODE(sfStartBgdAnimSpeed), -		OPCODE(SF_actorWalkToAsync), +		OPCODE(sfScriptWalkToAsync),  		OPCODE(SF_enableZone),  		OPCODE(sfSetActorState),  		OPCODE(scriptMoveTo), @@ -83,7 +83,7 @@ void Script::setupScriptFuncList(void) {  		OPCODE(sfFinishBgdAnim),  		OPCODE(sfSwapActors),  		OPCODE(sfSimulSpeech), -		OPCODE(SF_actorWalk), +		OPCODE(sfScriptWalk),  		OPCODE(sfCycleFrames),  		OPCODE(sfSetFrame),  		OPCODE(SF_setRightPortrait), @@ -197,7 +197,6 @@ int Script::SF_commandMode(SCRIPTFUNC_PARAMS) {  }  // Script function #6 (0x06) blocking -// Commands the specified actor to walk to the given position  // Param1: actor id  // Param2: actor x  // Param3: actor y @@ -478,28 +477,24 @@ int Script::sfStartBgdAnimSpeed(SCRIPTFUNC_PARAMS) {  }  // Script function #27 (0x1B) nonblocking -// Commands the specified actor to walk to the given position  // Param1: actor id -// Param2: actor destination x -// Param3: actor destination y -int Script::SF_actorWalkToAsync(SCRIPTFUNC_PARAMS) { -	ScriptDataWord actor_parm; -	ScriptDataWord x_parm; -	ScriptDataWord y_parm; +// Param2: actor x +// Param3: actor y +int Script::sfScriptWalkToAsync(SCRIPTFUNC_PARAMS) {  	uint16 actorId; -	Point pt; - -	actor_parm = thread->pop(); +	ActorLocation actorLocation; +	ActorData *actor; -	x_parm = thread->pop(); -	y_parm = thread->pop(); +	actorId = getSWord(thread->pop()); +	actorLocation.x = getSWord(thread->pop()); +	actorLocation.y = getSWord(thread->pop()); -	actorId = getSWord(actor_parm); +	actor = _vm->_actor->getActor(actorId); +	actorLocation.z = actor->location.z; -	pt.x = getSWord(x_parm); -	pt.y = getSWord(y_parm); -//	error("!"); +	actor->flags &= ~kFollower; +	_vm->_actor->actorWalkTo(actorId, actorLocation);  	return SUCCESS;  } @@ -666,32 +661,37 @@ int Script::sfSimulSpeech(SCRIPTFUNC_PARAMS) {  }  // Script function #36 (0x24) ? -// Commands the specified actor to walk to the given position  // Param1: actor id -// Param2: actor destination x -// Param3: actor destination y -// Param4: flags telling how to walk -int Script::SF_actorWalk(SCRIPTFUNC_PARAMS) { -	// INCOMPLETE -	ScriptDataWord actor_parm; -	ScriptDataWord x_parm; -	ScriptDataWord y_parm; -	ScriptDataWord flags_parm; +// Param2: actor x +// Param3: actor y +// Param4: actor walk flag +int Script::sfScriptWalk(SCRIPTFUNC_PARAMS) {  	uint16 actorId; -	Point pt; +	ActorLocation actorLocation; +	ActorData *actor; +	uint16 walkFlags; -	actor_parm = thread->pop(); -	x_parm = thread->pop(); -	y_parm = thread->pop(); -	flags_parm = thread->pop(); +	actorId = getSWord(thread->pop()); +	actorLocation.x = getSWord(thread->pop()); +	actorLocation.y = getSWord(thread->pop()); +	walkFlags = getUWord(thread->pop()); -	actorId = getSWord(actor_parm); +	actor = _vm->_actor->getActor(actorId); +	actorLocation.z = actor->location.z; -	pt.x = getSWord(x_parm); -	pt.y = getSWord(y_parm); +	_vm->_actor->realLocation(actorLocation, ID_NOTHING, walkFlags); -//	error("!"); +	actor->flags &= ~kFollower; + +	if (_vm->_actor->actorWalkTo(actorId, actorLocation) && !(walkFlags & kWalkAsync)) { +		thread->waitWalk(actor); +	} + +	if (walkFlags & kWalkBackPedal) { +		actor->actorFlags |= kActorBackwards; +	} +	actor->actorFlags = (actor->actorFlags & ~kActorFacingMask) | (walkFlags & kActorFacingMask);  	return SUCCESS;  } | 
