/* 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; }
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); }
/* 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; }