Ejemplo n.º 1
0
void EntGhost::think() {
	// animate
	roto = (roto + 3) % 360;

	// scatterDetails
	if (--scatterTime <= 0) {
		scattering = false;
	}

	// returning home details
	if (homebound) {
		if ((homeLocation - getPosition()).length() <= 32) {
			homebound = false;
		}
	}

	// if we do not have a map object, bail since the rest of this method relies on it for path finding
	if (!map)
		return;

	// where are we
	MapTile current = map->TileFromVect(getPosition());

	// are we in a different place since last time?
	if (current != lastTile) {
		// if we are but we are in a wall (corner case) turn right around and hope for the best
		if (!(map->getTile(current) & 1)) {
			setOrientation(getOrientation() * quat(0,0,0,1));	
		} else {
			// otherwise plan to wander toward a new tile

			// what are our options
			MapTile up = current.up();
			MapTile left = current.left();
			MapTile down = current.down();
			MapTile right = current.right();
			// where do we want to get to
			MapTile targetTile = map->TileFromVect(target);
			
			// find out the distance each option gets us
			double updist = (map->VectFromTile(up) - map->VectFromTile(targetTile)).length();
			double leftdist = (map->VectFromTile(left) - map->VectFromTile(targetTile)).length();
			double downdist = (map->VectFromTile(down) - map->VectFromTile(targetTile)).length();
			double rightdist = (map->VectFromTile(right) - map->VectFromTile(targetTile)).length();

			// fallback options
			MapTile newTarget = current;
			double newTargetdist = 0;
			
			// whats the worst case? (we will substitute better options as we find them later
			// simple linear search
			if ((rightdist >= newTargetdist) && (map->getTile(right) & 1) && (right != lastTile))
				newTargetdist = rightdist;
			if ((downdist >= newTargetdist) && (map->getTile(down) & 1) && (down != lastTile))
				newTargetdist = downdist;
			if ((leftdist >= newTargetdist) && (map->getTile(left) & 1) && (left != lastTile))
				newTargetdist = leftdist;
			if ((updist >= newTargetdist) && (map->getTile(up) & 1) && (up != lastTile))
				newTargetdist = updist;

			// now do the acctual direction finding (bring us to the best case direction)
			// simple linear search
			if ((rightdist <= newTargetdist) && (map->getTile(right) & 1) && (right != lastTile)) {
				newTarget = right;
				newTargetdist = rightdist;
				orientation = DIR_RIGHT;
			}
			if ((downdist <= newTargetdist) && (map->getTile(down) & 1) && (down != lastTile)) {
				newTarget = down;
				newTargetdist = downdist;
				orientation = DIR_DOWN;
			}
			if ((leftdist <= newTargetdist) && (map->getTile(left) & 1) && (left != lastTile)) {
				newTarget = left;
				newTargetdist = leftdist;
				orientation = DIR_LEFT;
			}
			if ((updist <= newTargetdist) && (map->getTile(up) & 1) && (up != lastTile)) {
				newTarget = up;
				newTargetdist = updist;
				orientation = DIR_UP;
			}
		}
		// now are are somewhere new
		lastTile = current;
	}
	// acctually move us (speed controlled by scatter state)
	setPosition(getPosition() + getOrientation().rotate(vect::FORWARD * (scattering?0.5:2.0)));
}