Tribe::Memory* Tribe::FindRandomMemory(const char* name, const csVector3 &pos, const iSector* sector, float range, float* foundRange) { csArray<Memory*> nearby; csArray<float> dist; float minRange = range*range; // Working with Squared values if(range == -1) minRange = -1; // -1*-1 = 1, will use -1 later csList<Memory*>::Iterator it(memories); while(it.HasNext()) { Memory* memory = it.Next(); if(memory->name == name && memory->npc == NULL) { float dist2 = npcclient->GetWorld()->Distance(pos,sector,memory->pos,memory->GetSector()); if(minRange < 0 || dist2 < minRange) { nearby.Push(memory); dist.Push(dist2); } } } if(nearby.GetSize()>0) // found one or more closer than range { size_t pick = psGetRandom((uint32)nearby.GetSize()); if(foundRange) *foundRange = sqrt(dist[pick]); return nearby[pick]; } return NULL; }
Waypoint *psPathNetwork::FindRandomWaypoint(int group, csVector3& v,iSector *sector, float range, float * found_range) { csList<Waypoint*>::Iterator iter(waypointGroups[group]); Waypoint *wp; csArray<Waypoint*> nearby; csArray<float> dist; while (iter.HasNext()) { wp = iter.Next(); float dist2 = world->Distance(v,sector,wp->loc.pos,wp->GetSector(engine)); if (range < 0 || dist2 < range) { nearby.Push(wp); dist.Push(dist2); } } if (nearby.GetSize()>0) // found one or more closer than range { size_t pick = psGetRandom((uint32)nearby.GetSize()); if (found_range) *found_range = sqrt(dist[pick]); return nearby[pick]; } return NULL; }
bool Tribe::GetResource(NPC* npc, csVector3 startPos, iSector* startSector, csVector3 &locatedPos, iSector* &locatedSector, float range, bool random) { float locatedRange=0.0; Tribe::Memory* memory = NULL; if(psGetRandom(100) > 10) // 10% chance for go explore a new resource arae { csString neededResource = GetNeededResource(); if(random) { memory = FindRandomMemory(neededResource,startPos,startSector,range,&locatedRange); } else { memory = FindNearestMemory(neededResource,startPos,startSector,range,&locatedRange); } if(memory) { NPCDebug(npc, 5, "Found needed resource: %s at %s",neededResource.GetDataSafe(),toString(memory->pos,memory->GetSector()).GetDataSafe()); } else { NPCDebug(npc, 5, "Didn't find needed resource: %s",neededResource.GetDataSafe()); } } if(!memory) { csString area = GetNeededResourceAreaType(); if(random) { memory = FindRandomMemory(area,startPos,startSector,range,&locatedRange); } else { memory = FindNearestMemory(area,startPos,startSector,range,&locatedRange); } if(memory) { NPCDebug(npc, 5, "Found resource area: %s at %s",area.GetDataSafe(),toString(memory->pos,memory->GetSector()).GetDataSafe()); } else { NPCDebug(npc, 5, "Didn't find resource area: %s",area.GetDataSafe()); } } if(!memory) { NPCDebug(npc, 5, "Couldn't locate resource for npc.",npc->GetName()); return false; } locatedPos = memory->pos; locatedSector = memory->GetSector(); return true; }
Tribe::Asset* Tribe::GetRandomAsset(Tribe::AssetType type, csString name, Tribe::AssetStatus status, csVector3 pos, iSector* sector, float range) { csArray<Tribe::Asset*> nearby; for(size_t i=0; i<assets.GetSize(); i++) { if(assets[i]->type == type && assets[i]->name == name && assets[i]->status == status) { float dist = npcclient->GetWorld()->Distance(pos,sector,assets[i]->pos,assets[i]->GetSector()); if(range < 0 || dist < range) { nearby.Push(assets[i]); } } } if(nearby.GetSize()>0) // found one or more closer than range { size_t pick = psGetRandom((uint32)nearby.GetSize()); return nearby[pick]; } // If we get here, the asset does not exist and we return a null one return NULL; }
Location* LocationManager::FindRandomLocation(psWorld* world, const char* typeName, csVector3 &pos, iSector* sector, float range, float* found_range) { csArray<Location*> nearby; csArray<float> dist; LocationType* found = loctypes.Get(typeName, NULL); if(found) { for(size_t i=0; i<found->locs.GetSize(); i++) { float dist2 = world->Distance(pos,sector,found->locs[i]->pos,found->locs[i]->GetSector(world->GetEngine())); if(range < 0 || dist2 < range) { nearby.Push(found->locs[i]); dist.Push(dist2); } } if(nearby.GetSize()>0) // found one or more closer than range { size_t pick = psGetRandom((uint32)nearby.GetSize()); if(found_range) *found_range = sqrt(dist[pick]); return nearby[pick]; } } return NULL; }
bool Location::GetRandomPosition(iEngine* engine,csVector3 &pos,iSector* §or) { csVector3 randomPos; iSector* randomSector; // TODO: Hack, for now just get the y value and sector from the first point. randomPos.y = locs[0]->pos.y; randomSector = locs[0]->GetSector(engine); do { randomPos.x = boundingBox.MinX() + psGetRandom()*(boundingBox.MaxX() - boundingBox.MinX()); randomPos.z = boundingBox.MinY() + psGetRandom()*(boundingBox.MaxY() - boundingBox.MinY()); } while(!CheckWithinBounds(engine,randomPos,randomSector)); pos = randomPos; sector = randomSector; return true; }
void Reaction::DeepCopy(Reaction& other,BehaviorSet& behaviors) { desireValue = other.desireValue; desireType = other.desireType; for (size_t i = 0; i < other.affected.GetSize(); i++) { Behavior * behavior = behaviors.Find(other.affected[i]->GetName()); affected.Push(behavior); } eventType = other.eventType; range = other.range; factionDiff = other.factionDiff; oper = other.oper; weight = other.weight; values = other.values; valuesValid = other.valuesValid; randoms = other.randoms; randomsValid = other.randomsValid; type = other.type; activeOnly = other.activeOnly; inactiveOnly = other.inactiveOnly; reactWhenDead = other.reactWhenDead; reactWhenInvisible = other.reactWhenInvisible; reactWhenInvincible = other.reactWhenInvincible; onlyInterrupt = other.onlyInterrupt; doNotInterrupt = other.doNotInterrupt; // For now depend on that each npc do a deep copy to create its instance of the reaction for (uint ii=0; ii < values.GetSize(); ii++) { if (GetRandomValid((int)ii)) { values[ii] += psGetRandom(GetRandom((int)ii)); } } }