Example #1
0
void Character::playAnim(int32 animId, int32 unused, int32 flags) {
	debugC(3, kDebugCharacter, "playAnim(%d, unused, %d)", animId, flags);

	if (animId == 0)
		animId = _animSpecialDefaultId;

	// get the anim to load
	const SpecialCharacterAnimation *anim = getSpecialAnimation(_id, animId);

	char animName[20];
	strcpy(animName, anim->_filename);

	int32 facing = _facing;
	if (_id == 1) {
		// flux special case... some animations are not for every facing
		facing = CharacterFlux::fixFacingForAnimation(facing, animId);
	}

	if (strchr(animName, '?'))
		*strchr(animName, '?') = '0' + facing;
	strcat(animName, ".CAF");

	if (_animScriptId != -1 && (flags & 8) == 0)
		_vm->getSceneAnimationScript(_animScriptId)->_frozenForConversation = true;

	stopSpecialAnim();

	if (flags & 8) {
		// talker
		_lineToSayId = _vm->getCurrentLineToSay();

		// make the talker busy
		_flags |= 1;

		// old special anim was talking anim ? in this case we don't wait for the character to be ready
		bool wasTalkAnim = _specialAnim && strstr(_specialAnim->_name, "TLK");

		// wait for the character to be ready
		while (_animScriptId != -1 && _animationInstance && _animationInstance->getFrame() > 0 && !wasTalkAnim && (_specialAnim && _animationInstance->getAnimation() != _specialAnim)) {
			_vm->simpleUpdate(false);
		}
	}

	if (_sceneAnimationId > -1)
		setAnimationInstance(_vm->getSceneAnimation(_sceneAnimationId)->_animInstance);

	_animFlags |= flags;

	delete _specialAnim;
	_specialAnim = new Animation(_vm);
	_specialAnim->loadAnimation(animName);

	_animSpecialId = animId;

	_animationInstance->setAnimation(_specialAnim);
	_animationInstance->setAnimationRange(0, _specialAnim->_numFrames - 1);
	_animationInstance->reset();
	_animationInstance->stopAnimation();
	_animationInstance->setLooping(false);
}
Example #2
0
void CharacterDrew::playStandingAnim() {
    debugC(4, kDebugCharacter, "playStandingAnim()");

    stopSpecialAnim();
    _animationInstance->setAnimation(_walkAnim);
    _animationInstance->setFrame(_facing * 2);
    _shadowAnimationInstance->setFrame(_facing);
    _animationInstance->setAnimationRange(_facing * 2, _facing * 2);
    _animationInstance->stopAnimation();
    _animationInstance->setLooping(true);
    //setVisible(true);
}
Example #3
0
void CharacterDrew::playWalkAnim(int32 start, int32 end) {
    debugC(4, kDebugCharacter, "playWalkAnim(%d, %d)", start, end);

    stopSpecialAnim();
    _animationInstance->setAnimation(_walkAnim);
    _shadowAnimationInstance->setFrame(_facing);
    _animationInstance->setAnimationRange(16 + _facing * 14, 16 + _facing * 14 + 13);
    _animationInstance->playAnimation();
    _animationInstance->setFps(16);
    _animationInstance->setLooping(true);

    //setVisible(true);
}
Example #4
0
void Character::update(int32 timeIncrement) {
	debugC(5, kDebugCharacter, "update(%d)", timeIncrement);
	if ((_flags & 0x1) && _currentPathNodeCount > 0) {
		if (_currentPathNode < _currentPathNodeCount) {
			if (_currentPathNode < _currentPathNodeCount - 10) {
				int32 delta = MIN<int32>(10, _currentPathNodeCount - _currentPathNode);
				int32 dx = _currentPathX[_currentPathNode+delta] - _x;
				int32 dy = _currentPathY[_currentPathNode+delta] - _y;
				setFacing(getFacingFromDirection(dx, dy));
				playWalkAnim(0, 0);
			}

			// in 1/1000 pixels
			_numPixelToWalk += _speed * (_vm->getSystem()->getMillis() - _lastWalkTime) * _scale / 1024;
			_lastWalkTime =  _vm->getSystem()->getMillis();

			while (_numPixelToWalk > 1000 && _currentPathNode < _currentPathNodeCount) {
				_x = _currentPathX[_currentPathNode];
				_y = _currentPathY[_currentPathNode];
				_currentPathNode += 1;
				_numPixelToWalk -= 1000;
			}
			setPosition(_x, _y);
		} else {
			playStandingAnim();
			_flags &= ~0x1;
			_currentPathNodeCount = 0;
		}
	}

	updateIdle();

#if 0
	// handle special anims
	if ((_flags & 4) == 0)
		return;

	if (_animScriptId != -1) {
		_animationInstance = _vm->getSceneAnimation(this->)
#endif

	int32 animId = _animSpecialId;
	if (animId >= 1000)
		animId = 0;

	if (_animSpecialId < 0)
		return;

	int32 currentFrame = _animationInstance->getFrame();

	const SpecialCharacterAnimation *anim = getSpecialAnimation(_id, animId);

	if ((_animFlags & 0x10) == 0) {
		if (_animScriptId != -1 && currentFrame > 0 && !_vm->getSceneAnimationScript(_animScriptId)->_frozen) {
			if (_vm->getCurrentLineToSay() != _lineToSayId && (_animFlags & 8))
				stopSpecialAnim();
			return;
		}

		if (_id == 1 && (_animFlags & 4)) {
			if (_animFlags & 0x10)
				return;
		} else {
			if (_id == 1 && (_animFlags & 0x10) && _vm->getCurrentLineToSay() != -1) {
				return;
			}
			if ((_animFlags & 0x40) == 0 && _vm->getCurrentLineToSay() == -1) {
				stopSpecialAnim();
				return;
			}

			if (_animScriptId != -1)
				_vm->getSceneAnimationScript(_animScriptId)->_frozenForConversation = true;

			// TODO setup backup //

			_animFlags |= 0x10;
			_animationInstance->setAnimation(_specialAnim);
			_animationInstance->setFrame(0);
			_time = _vm->getOldMilli() + 8 * _vm->getTickLength();
		}

	}

	if ((_animFlags & 3) == 2) {
		if ((((_animFlags & 8) == 8) && _vm->getCurrentLineToSay() != _lineToSayId) || !_vm->getAudioManager()->voiceStillPlaying())  // || (_flags & 8)) && _vm->getAudioManager()->voiceStillPlaying())
			_animFlags |= 1;

	}

	if (_time > _vm->getOldMilli())
		return;

	int32 animFlag = anim->_unused;
	int32 nextFrame = currentFrame + 1;
	int32 nextTime = _time;
	int32 animDir = 1;
	if (!animFlag) {
		if (_animFlags & 1) {
			if (anim->_flags7 == 0xff) {
				if (currentFrame > anim->_flag1 / 2)
					animDir = 1;
				else
					animDir = -1;
			} else {
				if (currentFrame >= anim->_flags6) {
					if (currentFrame < anim->_flags7)
						currentFrame = anim->_flags7;
				}
				if (currentFrame > anim->_flags6)
					animDir = 1;
				else
					animDir = -1;
			}

			nextFrame = currentFrame + animDir;
			nextTime = _vm->getOldMilli() + 6 * _vm->getTickLength();
		} else {
			if (_animFlags & 0x20) {
				nextFrame = currentFrame - 1;
				if (nextFrame == anim->_flags6 - 1) {
					if (anim->_flags8 != 1 && (_vm->randRange(0, 1) == 1 || anim->_flags8 == 2)) {
						_animFlags &= ~0x20;
						nextFrame += 2;
						if (nextFrame > anim->_flags7)
							nextFrame = anim->_flags7;
					} else {
						nextFrame = anim->_flags7;
					}
				}
			} else {
				nextFrame = currentFrame + 1;
				if (nextFrame == anim->_flags7 + 1 && (_animFlags & 0x40) == 0) {
					if (anim->_flags8 != 1 && (_vm->randRange(0, 1) || anim->_flags8 == 2)) {
						_animFlags |= 0x20;
						nextFrame -= 2;
						if (nextFrame < anim->_flags6)
							nextFrame = anim->_flags6;
					} else {
						nextFrame = anim->_flags6;
					}
				}
			}

			nextTime = _vm->getOldMilli() + 8 * _vm->getTickLength();
		}
		// goto label78
	}
	// skipped all this part.

	//label78

#if 0
	if (_id == 0)
		debug(" drew animation name %s / flag %d / frame %d", _specialAnim->_name, _animFlags, nextFrame);
	if (_id == 1)
		debug(" flux animation flag %d / frame %d", _animFlags, nextFrame);
	if (_id == 7)
		debug(" footman animation flag %d / frame %d", _animFlags, nextFrame);
#endif

	_time = nextTime;
	if (nextFrame < 0 || nextFrame >= anim->_flag1) {
		if ((_animFlags & 2) == 0 || _vm->getCurrentLineToSay() != _lineToSayId) {
			stopSpecialAnim();
			return;
		}

		// lots skipped here

		_animFlags &= ~0x10;
		_animationInstance->forceFrame(0);
		return;

	}

	//if ((_flags & 8) == 0 || !_vm->getAudioManager()->voiceStillPlaying( ) || )
	_animationInstance->forceFrame(nextFrame);
}
Example #5
0
bool Character::walkTo(int32 newPosX, int32 newPosY) {
	debugC(1, kDebugCharacter, "walkTo(%d, %d)", newPosX, newPosY);

	if (!_visible)
		return true;

	if (_x == newPosX && _y == newPosY)
		return true;

	_vm->getPathFinding()->resetBlockingRects();

	// don't allow flux to go at the same position as drew
	if (_id == 1 ) {
		int32 sizeX = MAX<int32>(5, 30 * _vm->getDrew()->getScale() / 1024);
		int32 sizeY = MAX<int32>(2, 20 * _vm->getDrew()->getScale() / 1024);
		_vm->getPathFinding()->addBlockingEllipse(_vm->getDrew()->getFinalX(), _vm->getDrew()->getFinalY(), sizeX, sizeY);
	}

	_vm->getPathFinding()->findClosestWalkingPoint(newPosX, newPosY, &_finalX, &_finalY, _x, _y);
	if (_x == _finalX && _y == _finalY)
		return true;

	if (_vm->getPathFinding()->findPath(_x, _y, _finalX, _finalY)) {

		int32 localFinalX = _finalX;
		int32 localFinalY = _finalY;
		int32 smoothDx = 0;
		int32 smoothDy = 0;

		for (int32 a = 0; a < _vm->getPathFinding()->getPathNodeCount(); a++) {
			_currentPathX[a] = _vm->getPathFinding()->getPathNodeX(a);
			_currentPathY[a] = _vm->getPathFinding()->getPathNodeY(a);
		}
		_currentPathNodeCount = _vm->getPathFinding()->getPathNodeCount();
		_currentPathNode = 0;
		stopSpecialAnim();

		_lastWalkTime = _vm->getSystem()->getMillis();

		_numPixelToWalk = 0;

		_flags |= 0x1;

		_currentWalkStamp++;

		int32 localWalkStamp = _currentWalkStamp;

		if (_blockingWalk) {
			while ((_x != newPosX || _y != newPosY) && _currentPathNode < _currentPathNodeCount && !_vm->shouldQuitGame()) {
				if (_currentPathNode < _currentPathNodeCount - 4) {
					int32 delta = MIN<int32>(4, _currentPathNodeCount - _currentPathNode);

					int32 dx = _currentPathX[_currentPathNode+delta] - _x;
					int32 dy = _currentPathY[_currentPathNode+delta] - _y;

					// smooth the facing computation. It prevents some ugly flickering from happening
					if (!smoothDx && !smoothDy) {
						smoothDx = dx;
						smoothDy = dy;
					} else {
						smoothDx = (dx + smoothDx * 3) / 4;
						smoothDy = (dy + smoothDy * 3) / 4;
					}

					setFacing(getFacingFromDirection(smoothDx, smoothDy));
					playWalkAnim(0, 0);
				}

				// in 1/1000 pixels
				_numPixelToWalk += _speed * (_vm->getSystem()->getMillis() - _lastWalkTime) * _scale / 1024;
				_lastWalkTime =  _vm->getSystem()->getMillis();

				while (_numPixelToWalk >= 1000 && _currentPathNode < _currentPathNodeCount) {
					_x = _currentPathX[_currentPathNode];
					_y = _currentPathY[_currentPathNode];
					_currentPathNode += 1;
					_numPixelToWalk -= 1000;
				}
				setPosition(_x, _y);

				_vm->doFrame();
				if (_currentWalkStamp != localWalkStamp) {
					// another walkTo was started in doFrame, we need to cancel this one.
					return false;
				}

			}
			playStandingAnim();
			_flags &= ~0x1;
			_currentPathNode = 0;
			_currentPathNodeCount = 0;

			if (_x != localFinalX || _y != localFinalY) {
				return false;
			}
		}
	}

	return true;
}