コード例 #1
0
/* returns actors that match the [x.y.z] expression */
static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_flags)
{
	// if you ActionOverride a global actor, they might not have a map :(
	// TODO: don't allow this to happen?
	if (!map) {
		return NULL;
	}

	if (oC->objectName[0]) {
		//We want the object by its name... (doors/triggers don't play here!)
		Actor* aC = map->GetActor( oC->objectName, ga_flags );

		/*if (!aC && (ga_flags&GA_GLOBAL) ) {
			aC = FindActorNearby(oC->objectName, map, ga_flags );
		}*/

		//return here because object name/IDS targeting are mutually exclusive
		return ReturnActorAsTarget(aC);
	}

	if (oC->objectFields[0]==-1) {
		// this is an internal hack, allowing us to pass actor ids around as objects
		Actor* aC = map->GetActorByGlobalID( (ieDword) oC->objectFields[1] );
		/* TODO: this hack will throw away an invalid target */
		/* Consider putting this in GetActorByGlobalID */
		if (aC && !aC->ValidTarget(ga_flags)) {
			aC = NULL;
		}
		return ReturnActorAsTarget(aC);
	}

	Targets *tgts = NULL;

	//we need to get a subset of actors from the large array
	//if this gets slow, we will need some index tables
	int i = map->GetActorCount(true);
	while (i--) {
		Actor *ac = map->GetActor(i, true);
		if (!ac) continue; // is this check really needed?
		// don't return Sender in IDS targeting!
		if (ac == Sender) continue;
		bool filtered = false;
		if (DoObjectIDSCheck(oC, ac, &filtered)) {
			if (!filtered) {
				// if no filters were applied..
				assert(!tgts);
				return NULL;
			}
			int dist;
			if (DoObjectChecks(map, Sender, ac, dist, (ga_flags & GA_DETECT) != 0)) {
				if (!tgts) tgts = new Targets();
				tgts->AddTarget((Scriptable *) ac, dist, ga_flags);
			}
		}
	}

	return tgts;
}
コード例 #2
0
ファイル: Matching.cpp プロジェクト: AlanWasTaken/gemrb
bool MatchActor(Scriptable *Sender, ieDword actorID, Object* oC)
{
	if (!Sender) {
		return false;
	}
	Actor *ac = Sender->GetCurrentArea()->GetActorByGlobalID(actorID);
	if (!ac) {
		return false;
	}

	// [0]/[ANYONE] can match all actors
	if (!oC) {
		return true;
	}

	bool filtered = false;

	// name matching
	if (oC->objectName[0]) {
		if (strnicmp(ac->GetScriptName(), oC->objectName, 32) != 0) {
			return false;
		}
		filtered = true;
	}

	// IDS targeting
	// (if we already matched by name, we don't do this)
	// TODO: check distance? area? visibility?
	if (!filtered && !DoObjectIDSCheck(oC, ac, &filtered)) return false;

	// globalID hack should never get here
	assert(oC->objectFilters[0] != -1);

	// object filters
	if (oC->objectFilters[0]) {
		// object filters insist on having a stupid targets list,
		// so we waste a lot of time here
		Targets *tgts = new Targets();
		int ga_flags = 0; // TODO: correct?

		// handle already-filtered vs not-yet-filtered cases
		// e.g. LastTalkedToBy(Myself) vs LastTalkedToBy
		if (filtered) tgts->AddTarget(ac, 0, ga_flags);

		tgts = DoObjectFiltering(Sender, tgts, oC, ga_flags);
		if (!tgts) return false;

		// and sometimes object filters are lazy and not only don't filter
		// what we give them, they clear it and return a list :(
		// so we have to search the whole list..
		bool ret = false;
		targetlist::iterator m;
		const targettype *tt = tgts->GetFirstTarget(m, ST_ACTOR);
		while (tt) {
			Actor *actor = (Actor *) tt->actor;
			if (actor->GetGlobalID() == actorID) {
				ret = true;
				break;
			}
			tt = tgts->GetNextTarget(m, ST_ACTOR);
		}
		delete tgts;
		if (!ret) return false;
	}
	return true;
}
コード例 #3
0
ファイル: Matching.cpp プロジェクト: AlanWasTaken/gemrb
/* returns actors that match the [x.y.z] expression */
static Targets* EvaluateObject(Map *map, Scriptable* Sender, Object* oC, int ga_flags)
{
	// if you ActionOverride a global actor, they might not have a map :(
	// TODO: don't allow this to happen?
	if (!map) {
		return NULL;
	}

	if (oC->objectName[0]) {
		//We want the object by its name...
		Scriptable* aC = map->GetActor( oC->objectName, ga_flags );

		/*if (!aC && (ga_flags&GA_GLOBAL) ) {
			aC = FindActorNearby(oC->objectName, map, ga_flags );
		}*/

		//This order is the same as in GetActorObject
		//TODO:merge them
		if (!aC) {
			aC = map->GetTileMap()->GetDoor(oC->objectName);
		}
		if (!aC) {
			aC = map->GetTileMap()->GetContainer(oC->objectName);
		}
		if (!aC) {
			aC = map->GetTileMap()->GetInfoPoint(oC->objectName);
		}

		//return here because object name/IDS targeting are mutually exclusive
		return ReturnScriptableAsTarget(aC);
	}

	if (oC->objectFields[0]==-1) {
		// this is an internal hack, allowing us to pass actor ids around as objects
		Actor* aC = map->GetActorByGlobalID( (ieDword) oC->objectFields[1] );
		if (aC) {
			if (!aC->ValidTarget(ga_flags)) {
				return NULL;
			}
			return ReturnScriptableAsTarget(aC);
		}
		Door *door = map->GetDoorByGlobalID( (ieDword) oC->objectFields[1]);
		if (door) {
			return ReturnScriptableAsTarget(door);
		}

		Container* cont = map->GetContainerByGlobalID((ieDword) oC->objectFields[1]);
		if (cont) {
			return ReturnScriptableAsTarget(cont);
		}

		InfoPoint* trap = map->GetInfoPointByGlobalID((ieDword) oC->objectFields[1]);
		if (trap) {
			return ReturnScriptableAsTarget(trap);
		}

		return NULL;
	}

	Targets *tgts = NULL;

	//we need to get a subset of actors from the large array
	//if this gets slow, we will need some index tables
	int i = map->GetActorCount(true);
	while (i--) {
		Actor *ac = map->GetActor(i, true);
		if (!ac) continue; // is this check really needed?
		// don't return Sender in IDS targeting!
		if (ac == Sender) continue;
		bool filtered = false;
		if (DoObjectIDSCheck(oC, ac, &filtered)) {
			// this is needed so eg. Range trigger gets a good object
			// HACK: our parsing of Attack([0]) is broken
			if (!filtered) {
				// if no filters were applied..
				assert(!tgts);
				return NULL;
			}
			int dist;
			if (DoObjectChecks(map, Sender, ac, dist, (ga_flags & GA_DETECT) != 0)) {
				if (!tgts) tgts = new Targets();
				tgts->AddTarget((Scriptable *) ac, dist, ga_flags);
			}
		}
	}

	return tgts;
}