/* 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;
}
Example #2
0
Targets *XthNearestEnemyOf(Targets *parameters, int count, int ga_flags)
{
	Actor *origin = (Actor *) parameters->GetTarget(0, ST_ACTOR);
	parameters->Clear();
	if (!origin) {
		return parameters;
	}
	//determining the allegiance of the origin
	int type = GetGroup(origin);

	if (type==2) {
		return parameters;
	}
	Map *map = origin->GetCurrentArea();
	int i = map->GetActorCount(true);
	ga_flags |= GA_NO_UNSCHEDULED;
	while (i--) {
		Actor *ac = map->GetActor(i,true);
		if (ac == origin) continue;
		int distance;
		//int distance = Distance(ac, origin);
		// TODO: if it turns out you need to check Sender here, beware you take the right distance!
		// (n the original games, this is only used for NearestEnemyOf(Player1) in obsgolem.bcs)
		if (!DoObjectChecks(map, origin, ac, distance)) continue;
		if (type) { //origin is PC
			if (ac->GetStat(IE_EA) >= EA_EVILCUTOFF) {
				parameters->AddTarget(ac, distance, ga_flags);
			}
		}
		else {
			if (ac->GetStat(IE_EA) <= EA_GOODCUTOFF) {
				parameters->AddTarget(ac, distance, ga_flags);
			}
		}
	}
	return XthNearestOf(parameters,count, ga_flags);
}
Example #3
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...
		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;
}