Пример #1
0
int AndroidAssetArchive::listMembers(Common::ArchiveMemberList &member_list) {
	JNIEnv *env = JNI::getEnv();
	Common::List<Common::String> dirlist;
	dirlist.push_back("");

	int count = 0;
	while (!dirlist.empty()) {
		const Common::String dir = dirlist.back();
		dirlist.pop_back();

		jstring jpath = env->NewStringUTF(dir.c_str());
		jobjectArray jpathlist =
			(jobjectArray)env->CallObjectMethod(_am, MID_list, jpath);

		if (env->ExceptionCheck()) {
			warning("Error while calling AssetManager->list(%s). Ignoring.",
					dir.c_str());
			env->ExceptionDescribe();
			env->ExceptionClear();

			// May as well keep going ...
			continue;
		}

		env->DeleteLocalRef(jpath);

		for (jsize i = 0; i < env->GetArrayLength(jpathlist); ++i) {
			jstring elem = (jstring)env->GetObjectArrayElement(jpathlist, i);
			const char *p = env->GetStringUTFChars(elem, 0);
			Common::String thispath = dir;

			if (!thispath.empty())
				thispath += "/";

			thispath += p;

			// Assume files have a . in them, and directories don't
			if (strchr(p, '.')) {
				member_list.push_back(getMember(thispath));
				++count;
			} else {
				dirlist.push_back(thispath);
			}

			env->ReleaseStringUTFChars(elem, p);
			env->DeleteLocalRef(elem);
		}

		env->DeleteLocalRef(jpathlist);
	}

	return count;
}
Пример #2
0
void Actor::walkTo(const Math::Vector3d &p) {
	if (p == _pos)
		_walking = false;
	else {
		_walking = true;
		_destPos = p;
		_path.clear();

		if (_constrain) {
			g_grim->getCurrSet()->findClosestSector(p, NULL, &_destPos);

			Common::List<PathNode *> openList;
			Common::List<PathNode *> closedList;

			PathNode *start = new PathNode;
			start->parent = NULL;
			start->pos = _pos;
			start->dist = 0.f;
			start->cost = 0.f;
			openList.push_back(start);
			g_grim->getCurrSet()->findClosestSector(_pos, &start->sect, NULL);

			Common::List<Sector *> sectors;
			for (int i = 0; i < g_grim->getCurrSet()->getSectorCount(); ++i) {
				Sector *s = g_grim->getCurrSet()->getSectorBase(i);
				int type = s->getType();
				if ((type == Sector::WalkType || type == Sector::HotType || type == Sector::FunnelType) && s->isVisible()) {
					sectors.push_back(s);
				}
			}

			Sector *endSec = NULL;
			g_grim->getCurrSet()->findClosestSector(_destPos, &endSec, NULL);

			do {
				PathNode *node = NULL;
				float cost = -1.f;
				for (Common::List<PathNode *>::iterator j = openList.begin(); j != openList.end(); ++j) {
					PathNode *n = *j;
					float c = n->dist + n->cost;
					if (cost < 0.f || c < cost) {
						cost = c;
						node = n;
					}
				}
				closedList.push_back(node);
				openList.remove(node);
				Sector *sector = node->sect;

				if (sector == endSec) {
					PathNode *n = closedList.back();
					// Don't put the start position in the list, or else
					// the first angle calculated in updateWalk() will be
					// meaningless. The only node without parent is the start
					// one.
					while (n->parent) {
						_path.push_back(n->pos);
						n = n->parent;
					}

					break;
				}

				for (Common::List<Sector *>::iterator i = sectors.begin(); i != sectors.end(); ++i) {
					Sector *s = *i;
					bool inClosed = false;
					for (Common::List<PathNode *>::iterator j = closedList.begin(); j != closedList.end(); ++j) {
						if ((*j)->sect == s) {
							inClosed = true;
							break;
						}
					}
					if (inClosed)
						continue;

					Common::List<Math::Line3d> bridges = sector->getBridgesTo(s);
					if (bridges.empty())
						continue; // The sectors are not adjacent.

					Math::Vector3d closestPoint = s->getClosestPoint(_destPos);
					Math::Vector3d best;
					float bestDist = 1e6f;
					Math::Line3d l(node->pos, closestPoint);
					while (!bridges.empty()) {
						Math::Line3d bridge = bridges.back();
						Math::Vector3d pos;
						const bool useXZ = (g_grim->getGameType() == GType_MONKEY4);
						if (!bridge.intersectLine2d(l, &pos, useXZ)) {
							pos = bridge.middle();
						}
						float dist = (pos - closestPoint).getMagnitude();
						if (dist < bestDist) {
							bestDist = dist;
							best = pos;
						}
						bridges.pop_back();
					}
					best = handleCollisionTo(node->pos, best);

					PathNode *n = NULL;
					for (Common::List<PathNode *>::iterator j = openList.begin(); j != openList.end(); ++j) {
						if ((*j)->sect == s) {
							n = *j;
							break;
						}
					}
					if (n) {
						float newCost = node->cost + (best - node->pos).getMagnitude();
						if (newCost < n->cost) {
							n->cost = newCost;
							n->parent = node;
							n->pos = best;
							n->dist = (n->pos - _destPos).getMagnitude();
						}
					} else {
						n = new PathNode;
						n->parent = node;
						n->sect = s;
						n->pos = best;
						n->dist = (n->pos - _destPos).getMagnitude();
						n->cost = node->cost + (n->pos - node->pos).getMagnitude();
						openList.push_back(n);
					}
				}
			} while (!openList.empty());

			for (Common::List<PathNode *>::iterator j = closedList.begin(); j != closedList.end(); ++j) {
				delete *j;
			}
			for (Common::List<PathNode *>::iterator j = openList.begin(); j != openList.end(); ++j) {
				delete *j;
			}
		}

		_path.push_front(_destPos);
	}
}