Esempio n. 1
0
int Router::faceXY(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y) {
	uint8 target_dir = 0;

	// If this is the start of the turn, get the mega's current feet
	// coords + the required direction

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		ObjectMega obMega(ob_mega);

		target_dir = whatTarget(obMega.getFeetX(), obMega.getFeetY(), target_x, target_y);
	}

	return doFace(ob_logic, ob_graph, ob_mega, ob_walkdata, target_dir);
}
Esempio n. 2
0
int Router::walkToTalkToMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId, uint32 separation) {
	ObjectMega obMega(ob_mega);

	int16 target_x = 0;
	int16 target_y = 0;
	uint8 target_dir = 0;

	// If this is the start of the walk, calculate the route.

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		assert(_vm->_resman->fetchType(megaId) == GAME_OBJECT);

		// Call the base script. This is the graphic/mouse service
		// call, and will set _engineMega to the ObjectMega of mega we
		// want to route to.

		_vm->_logic->runResScript(megaId, 3);

		ObjectMega targetMega(_vm->_logic->getEngineMega());

		// Stand exactly beside the mega, ie. at same y-coord
		target_y = targetMega.getFeetY();

		int scale = obMega.calcScale();
		int mega_separation = (separation * scale) / 256;

		debug(4, "Target is at (%d, %d), separation %d", targetMega.getFeetX(), targetMega.getFeetY(), mega_separation);

		if (targetMega.getFeetX() < obMega.getFeetX()) {
			// Target is left of us, so aim to stand to their
			// right. Face down_left

			target_x = targetMega.getFeetX() + mega_separation;
			target_dir = 5;
		} else {
			// Ok, must be right of us so aim to stand to their
			// left. Face down_right.

			target_x = targetMega.getFeetX() - mega_separation;
			target_dir = 3;
		}
	}

	return doWalk(ob_logic, ob_graph, ob_mega, ob_walkdata, target_x, target_y, target_dir);
}
Esempio n. 3
0
int Router::megaTableAnimate(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *animTable, bool reverse) {
	int32 animRes = 0;

	// If this is the start of the anim, read the anim table to get the
	// appropriate anim resource

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		ObjectMega obMega(ob_mega);

		// Appropriate anim resource is in 'table[direction]'
		animRes = READ_LE_UINT32(animTable + 4 * obMega.getCurDir());
	}

	return doAnimate(ob_logic, ob_graph, animRes, reverse);
}
Esempio n. 4
0
int Router::doFace(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint8 target_dir) {
	int16 target_x = 0;
	int16 target_y = 0;

	// If this is the start of the turn, get the mega's current feet
	// coords + the required direction

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		assert(target_dir <= 7);

		ObjectMega obMega(ob_mega);

		target_x = obMega.getFeetX();
		target_y = obMega.getFeetY();
	}

	return doWalk(ob_logic, ob_graph, ob_mega, ob_walkdata, target_x, target_y, target_dir);
}
Esempio n. 5
0
int Router::walkToAnim(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 animRes) {
	int16 target_x = 0;
	int16 target_y = 0;
	uint8 target_dir = 0;

	// Walkdata is needed for earlySlowOut if player clicks elsewhere
	// during the walk.

	// If this is the start of the walk, read anim file to get start coords

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		byte *anim_file = _vm->_resman->openResource(animRes);
		AnimHeader anim_head;

		anim_head.read(_vm->fetchAnimHeader(anim_file));

		target_x = anim_head.feetStartX;
		target_y = anim_head.feetStartY;
		target_dir = anim_head.feetStartDir;

		_vm->_resman->closeResource(animRes);

		// If start coords not yet set in anim header, use the standby
		// coords (which should be set beforehand in the script).

		if (target_x == 0 && target_y == 0) {
			target_x = _standbyX;
			target_y = _standbyY;
			target_dir = _standbyDir;
		}

		assert(target_dir <= 7);
	}

	return doWalk(ob_logic, ob_graph, ob_mega, ob_walkdata, target_x, target_y, target_dir);
}
Esempio n. 6
0
int Router::faceMega(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, uint32 megaId) {
	uint8 target_dir = 0;

	// If this is the start of the walk, decide where to walk to.

	ObjectLogic obLogic(ob_logic);

	if (obLogic.getLooping() == 0) {
		assert(_vm->_resman->fetchType(megaId) == GAME_OBJECT);

		// Call the base script. This is the graphic/mouse service
		// call, and will set _engineMega to the ObjectMega of mega we
		// want to turn to face.

		_vm->_logic->runResScript(megaId, 3);

		ObjectMega obMega(ob_mega);
		ObjectMega targetMega(_vm->_logic->getEngineMega());

		target_dir = whatTarget(obMega.getFeetX(), obMega.getFeetY(), targetMega.getFeetX(), targetMega.getFeetY());
	}

	return doFace(ob_logic, ob_graph, ob_mega, ob_walkdata, target_dir);
}
Esempio n. 7
0
int Router::doWalk(byte *ob_logic, byte *ob_graph, byte *ob_mega, byte *ob_walkdata, int16 target_x, int16 target_y, uint8 target_dir) {
	ObjectLogic obLogic(ob_logic);
	ObjectGraphic obGraph(ob_graph);
	ObjectMega obMega(ob_mega);

	// If this is the start of the walk, calculate the route.

	if (obLogic.getLooping() == 0) {
		// If we're already there, don't even bother allocating
		// memory and calling the router, just quit back & continue
		// the script! This avoids an embarassing mega stand frame
		// appearing for one cycle when we're already in position for
		// an anim eg. repeatedly clicking on same object to repeat
		// an anim - no mega frame will appear in between runs of the
		// anim.

		if (obMega.getFeetX() == target_x && obMega.getFeetY() == target_y && obMega.getCurDir() == target_dir) {
			_vm->_logic->writeVar(RESULT, 0);
			return IR_CONT;
		}

		assert(target_dir <= 8);

		obMega.setWalkPc(0);

		// Set up mem for _walkData in route_slots[] & set mega's
		// 'route_slot_id' accordingly
		allocateRouteMem();

		int32 route = routeFinder(ob_mega, ob_walkdata, target_x, target_y, target_dir);

		// 0 = can't make route to target
		// 1 = created route
		// 2 = zero route but may need to turn

		if (route != 1 && route != 2) {
			freeRouteMem();
			_vm->_logic->writeVar(RESULT, 1);
			return IR_CONT;
		}

		// Walk is about to start

		obMega.setIsWalking(1);
		obLogic.setLooping(1);
		obGraph.setAnimResource(obMega.getMegasetRes());
	} else if (_vm->_logic->readVar(EXIT_FADING) && _vm->_screen->getFadeStatus() == RDFADE_BLACK) {
		// Double clicked an exit, and the screen has faded down to
		// black. Ok, that's it. Back to script and change screen.

		// We have to clear te EXIT_CLICK_ID variable in case there's a
		// walk instruction on the new screen, or it'd be cut short.

		freeRouteMem();

		obLogic.setLooping(0);
		obMega.setIsWalking(0);
		_vm->_logic->writeVar(EXIT_CLICK_ID, 0);
		_vm->_logic->writeVar(RESULT, 0);

		return IR_CONT;
	}

	// Get pointer to walkanim & current frame position

	WalkData *walkAnim = getRouteMem();
	int32 walk_pc = obMega.getWalkPc();

	// If stopping the walk early, overwrite the next step with a
	// slow-out, then finish

	if (_vm->_logic->checkEventWaiting() && walkAnim[walk_pc].step == 0 && walkAnim[walk_pc + 1].step == 1) {
		// At the beginning of a step
		earlySlowOut(ob_mega, ob_walkdata);
	}

	// Get new frame of walk

	obGraph.setAnimPc(walkAnim[walk_pc].frame);
	obMega.setCurDir(walkAnim[walk_pc].dir);
	obMega.setFeetX(walkAnim[walk_pc].x);
	obMega.setFeetY(walkAnim[walk_pc].y);

	// Is the NEXT frame is the end-marker (512) of the walk sequence?

	if (walkAnim[walk_pc + 1].frame != 512) {
		// No, it wasn't. Increment the walk-anim frame number and
		// come back next cycle.
		obMega.setWalkPc(obMega.getWalkPc() + 1);
		return IR_REPEAT;
	}

	// We have reached the end-marker, which means we can return to the
	// script just as the final (stand) frame of the walk is set.

	freeRouteMem();
	obLogic.setLooping(0);
	obMega.setIsWalking(0);

	// If George's walk has been interrupted to run a new action script for
	// instance or Nico's walk has been interrupted by player clicking on
	// her to talk

	// There used to be code here for checking if two megas were colliding,
	// but it had been commented out, and it was only run if a function
	// that always returned zero returned non-zero.

	if (_vm->_logic->checkEventWaiting()) {
		_vm->_logic->startEvent();
		_vm->_logic->writeVar(RESULT, 1);
		return IR_TERMINATE;
	}

	_vm->_logic->writeVar(RESULT, 0);

	// CONTINUE the script so that RESULT can be checked! Also, if an anim
	// command follows the fnWalk command, the 1st frame of the anim (which
	// is always a stand frame itself) can replace the final stand frame of
	// the walk, to hide the slight difference between the shrinking on the
	// mega frames and the pre-shrunk anim start-frame.

	return IR_CONT;
}
Esempio n. 8
0
int Router::doAnimate(byte *ob_logic, byte *ob_graph, int32 animRes, bool reverse) {
	AnimHeader anim_head;
	byte *anim_file;

	ObjectLogic obLogic(ob_logic);
	ObjectGraphic obGraph(ob_graph);

	if (obLogic.getLooping() == 0) {
		// This is the start of the anim - set up the first frame

		// For testing all anims!
		// A script loop can send every resource number to the anim
		// function & it will only run the valid ones. See
		// 'testing_routines' object in George's Player Character
		// section of linc

		if (_vm->_logic->readVar(SYSTEM_TESTING_ANIMS)) {
			if (!_vm->_resman->checkValid(animRes)) {
				// Not a valid resource number. Switch off
				// the sprite. Don't animate - just continue
				// script next cycle.
				setSpriteStatus(ob_graph, NO_SPRITE);
				return IR_STOP;
			}

			// if it's not an animation file
			if (_vm->_resman->fetchType(animRes) != ANIMATION_FILE) {
				// switch off the sprite
				// don't animate - just continue
				// script next cycle
				setSpriteStatus(ob_graph, NO_SPRITE);
				return IR_STOP;
			}

			// switch on the sprite
			setSpriteStatus(ob_graph, SORT_SPRITE);
		}

		assert(animRes);

		// open anim file
		anim_file = _vm->_resman->openResource(animRes);

		assert(_vm->_resman->fetchType(animRes) == ANIMATION_FILE);

		// point to anim header
		anim_head.read(_vm->fetchAnimHeader(anim_file));

		// now running an anim, looping back to this call again
		obLogic.setLooping(1);
		obGraph.setAnimResource(animRes);

		if (reverse)
			obGraph.setAnimPc(anim_head.noAnimFrames - 1);
		else
			obGraph.setAnimPc(0);
	} else if (_vm->_logic->getSync() != -1) {
		// We've received a sync - return to script immediately
		debug(5, "**sync stopped %d**", _vm->_logic->readVar(ID));

		// If sync received, anim finishes right now (remaining on
		// last frame). Quit animation, but continue script.
		obLogic.setLooping(0);
		return IR_CONT;
	} else {
		// Not first frame, and no sync received - set up the next
		// frame of the anim.

		// open anim file and point to anim header
		anim_file = _vm->_resman->openResource(obGraph.getAnimResource());
		anim_head.read(_vm->fetchAnimHeader(anim_file));

		if (reverse)
			obGraph.setAnimPc(obGraph.getAnimPc() - 1);
		else
			obGraph.setAnimPc(obGraph.getAnimPc() + 1);
	}

	// check for end of anim

	if (reverse) {
		if (obGraph.getAnimPc() == 0)
			obLogic.setLooping(0);
	} else {
		if (obGraph.getAnimPc() == anim_head.noAnimFrames - 1)
			obLogic.setLooping(0);
	}

	// close the anim file
	_vm->_resman->closeResource(obGraph.getAnimResource());

	// check if we want the script to loop back & call this function again
	return obLogic.getLooping() ? IR_REPEAT : IR_STOP;
}