void TeamSensorSystem::update (void) { if (numSensors > 0) { #if 0 //DEBUGGING for (long k = 0; k < numContacts; k++) { MoverPtr mover = (MoverPtr)ObjectManager->get(contacts[k]); Assert(mover->getContactInfo()->teams[teamId] == k, 0, " Bad teams/contact link "); } #endif if (Team::teams[teamId] == Team::home) SoundSystem::largestSensorContact = -1; //--------------------------------- // First, update actual scanning... for (long i = 0; i < numSensors; i++) sensors[i]->updateScan(); if (Team::teams[teamId]->rosterSize < NUM_CONTACT_UPDATES_PER_PASS) numContactUpdatesPerPass = Team::teams[teamId]->rosterSize; else numContactUpdatesPerPass = NUM_CONTACT_UPDATES_PER_PASS; //-------------------------------- // Now, update current contacts... for (i = 0; i < numContactUpdatesPerPass; i++) { if (curContactUpdate >= numSensors) curContactUpdate = 0; sensors[curContactUpdate]->updateContacts(); curContactUpdate++; } } }
bool Team::isCapturing(GameObjectWatchID targetWID, GameObjectWatchID exceptWID) { if(exceptWID) for(size_t i = 0; i < rosterSize; i++) { if(roster[i] == exceptWID) continue; MoverPtr mover = dynamic_cast<MoverPtr>(ObjectManager->getByWatchID(roster[i])); Assert(mover != nullptr, roster[i], " Team.isTargeting: nullptr mover "); MechWarriorPtr pilot = mover->getPilot(); if(pilot && (pilot->getCurTacOrder()->code == TACTICAL_ORDER_CAPTURE)) { GameObjectPtr target = pilot->getCurTacOrder()->getTarget(); if(target && (target->getWatchID() == targetWID)) return(true); } } else for(size_t i = 0; i < rosterSize; i++) { MoverPtr mover = dynamic_cast<MoverPtr>(ObjectManager->getByWatchID(roster[i])); Assert(mover != nullptr, roster[i], " Team.isTargeting: nullptr mover "); MechWarriorPtr pilot = mover->getPilot(); if(pilot && (pilot->getCurTacOrder()->code == TACTICAL_ORDER_CAPTURE)) { GameObjectPtr target = pilot->getCurTacOrder()->getTarget(); if(target && (target->getWatchID() == targetWID)) return(true); } } return(false); }
long TeamSensorSystem::getContacts (GameObjectPtr looker, long* contactList, long contactCriteria, long sortType) { if ((sortType != CONTACT_SORT_NONE) && !looker) return(0); static float sortValues[MAX_CONTACTS_PER_SENSOR]; float CV = 0; long numValidContacts = 0; long handleList[MAX_CONTACTS_PER_SENSOR]; for (long i = 0; i < numContacts; i++) { MoverPtr mover = (MoverPtr)ObjectManager->get(contacts[i]); if (!meetsCriteria(looker, mover, contactCriteria)) continue; handleList[numValidContacts] = mover->getHandle(); switch (sortType) { case CONTACT_SORT_NONE: sortValues[numValidContacts] = 0.0; break; case CONTACT_SORT_CV: CV = (float)mover->getCurCV(); sortValues[numValidContacts] = CV; break; case CONTACT_SORT_DISTANCE: sortValues[numValidContacts] = looker->distanceFrom(mover->getPosition()); break; } numValidContacts++; } if ((numValidContacts > 0) && (sortType != CONTACT_SORT_NONE)) { //--------------------------------------------------------- // BIG ASSUMPTION HERE: That a mech will not have more than // MAX_CONTACTS_PER_SENSOR contacts. if (!SensorSystem::sortList) { SensorSystem::sortList = new SortList; if (!SensorSystem::sortList) Fatal(0, " Unable to create Contact sortList "); SensorSystem::sortList->init(MAX_CONTACTS_PER_SENSOR); } bool descendSort = true; if (sortType == CONTACT_SORT_DISTANCE) descendSort = false; SensorSystem::sortList->clear(descendSort); for (long contact = 0; contact < numValidContacts; contact++) { SensorSystem::sortList->setId(contact, handleList[contact]); SensorSystem::sortList->setValue(contact, sortValues[contact]); } SensorSystem::sortList->sort(descendSort); for (contact = 0; contact < numValidContacts; contact++) contactList[contact] = SensorSystem::sortList->getId(contact); } else if (contactList) for (long contact = 0; contact < numValidContacts; contact++) contactList[contact] = handleList[contact]; return(numValidContacts); }
//--------------------------------------------------------------------------- int32_t GameCamera::activate(void) { //------------------------------------------ // If camera is already active, just return if (ready && active) return (NO_ERROR); //--------------------------------------------------------- // Camera always starts pointing at first mover in lists // CANNOT be infinite because we don't allow missions without at least 1 // player mech!! MoverPtr firstMover = nullptr; if (ObjectManager->getNumMovers() > 0) { int32_t i = 0; firstMover = ObjectManager->getMover(i); while (firstMover && ((firstMover->getCommander()->getId() != Commander::home->getId()) || !firstMover->isOnGUI())) { i++; if (i == ObjectManager->getNumMovers()) break; firstMover = ObjectManager->getMover(i); } } if (firstMover) { Stuff::Vector3D newPosition(firstMover->getPosition()); setPosition(newPosition); } if (land) { land->update(); } allNormal(); // updateDaylight(true); lastShadowLightPitch = lightPitch; // Startup the SKYBox int32_t appearanceType = (GENERIC_APPR_TYPE << 24); AppearanceTypePtr genericAppearanceType = nullptr; genericAppearanceType = appearanceTypeList->getAppearance(appearanceType, "skybox"); if (!genericAppearanceType) { char msg[1024]; sprintf(msg, "No Generic Appearance Named %s", "skybox"); Fatal(0, msg); } theSky = new GenericAppearance; gosASSERT(theSky != nullptr); //-------------------------------------------------------------- gosASSERT(genericAppearanceType->getAppearanceClass() == GENERIC_APPR_TYPE); theSky->init((GenericAppearanceType*)genericAppearanceType, nullptr); theSky->setSkyNumber(mission->theSkyNumber); return NO_ERROR; }
bool SensorSystem::isContact (MoverPtr mover) { if (mover->getFlag(OBJECT_FLAG_REMOVED)) return(false); if (notShutdown) return(mover->getContactInfo()->getSensor(id) < 255); for (long i = 0; i < numContacts; i++) if ((contacts[i] & 0x7FFF) == mover->getHandle()) return(true); return(false); }
long TeamSensorSystem::getVisualContacts (MoverPtr* moverList) { long numVisualContacts = 0; for (long i = 0; i < numContacts; i++) { MoverPtr contact = (MoverPtr)ObjectManager->get(contacts[i]); if (!contact->getFlag(OBJECT_FLAG_REMOVED)) if (contact->getContactStatus(teamId, true) == CONTACT_VISUAL) moverList[numVisualContacts++] = contact; } return(numVisualContacts); }
long TeamSensorSystem::getSensorContacts (MoverPtr* moverList) { static bool isSensor[NUM_CONTACT_STATUSES] = {false, true, true, true, true, false}; long numSensorContacts = 0; for (long i = 0; i < numContacts; i++) { MoverPtr contact = (MoverPtr)ObjectManager->get(contacts[i]); if (!contact->getFlag(OBJECT_FLAG_REMOVED)) if (isSensor[contact->getContactStatus(teamId, true)]) moverList[numSensorContacts++] = contact; } return(numSensorContacts); }
bool TeamSensorSystem::hasSensorContact (long teamID) { for (long i = 0; i < numContacts; i++) { MoverPtr mover = (MoverPtr)ObjectManager->get(contacts[i]); if (!mover->getFlag(OBJECT_FLAG_REMOVED)) { static bool isSensor[NUM_CONTACT_STATUSES] = {false, true, true, true, true, false}; if (isSensor[mover->getContactStatus(teamID, true)]) return(true); } } return(false); }
bool MoverGroup::add(MoverPtr mover) { if (numMovers == MAX_MOVERGROUP_COUNT) { Fatal(0, " MoverGroup.add: Group too big "); //---------------------------------------- // Should we choose to remove the fatal... return (false); } moverWIDs[numMovers++] = mover->getWatchID(); mover->setGroupId(id, true); return (true); }
void SensorSystem::modifyContact(MoverPtr mover, bool visual) { int32_t contactNum = mover->getContactInfo()->getSensor(id); if(contactNum < MAX_CONTACTS_PER_SENSOR) { if(visual) contacts[contactNum] = mover->getHandle() | 0x8000; else contacts[contactNum] = mover->getHandle(); } if(notShutdown) master->modifyContact(this, mover, visual ? CONTACT_VISUAL : getSensorQuality()); }
//--------------------------------------------------------------------------- long SensorSystem::scanBattlefield (void) { //NOW returns size of largest contact! long currentLargest = -1; if (!owner) Fatal(0, " Sensor has no owner "); if (!master) Fatal(0, " Sensor has no master "); if ((masterIndex == -1) || (range < 0.0)) return(0); long numNewContacts = 0; long numMovers = ObjectManager->getNumMovers(); for (long i = 0; i < numMovers; i++) { MoverPtr mover = (MoverPtr)ObjectManager->getMover(i); if (mover->getExists() && (mover->getTeamId() != owner->getTeamId())) { long contactStatus = calcContactStatus(mover); if (isContact(mover)) { if (contactStatus == CONTACT_NONE) removeContact(mover); else { modifyContact(mover, contactStatus == CONTACT_VISUAL ? true : false); getLargest(currentLargest,mover,contactStatus); } } else { if (contactStatus != CONTACT_NONE) { addContact(mover, contactStatus == CONTACT_VISUAL ? true : false); getLargest(currentLargest,mover,contactStatus); numNewContacts++; } } } } totalContacts += numNewContacts; return(currentLargest); }
long MoverGroup::disband (void) { for (long i = 0; i < numMovers; i++) { MoverPtr mover = getMover(i); mover->setGroupId(-1, true); } #ifdef USE_IFACE if (pointHandle) theInterface->setPoint(pointHandle, false); #endif pointWID = 0; numMovers = 0; return(NO_ERR); }
long MoverGroup::setPoint (MoverPtr mover) { if (isMember(mover)) { #ifdef USE_IFACE if (pointHandle) theInterface->setPoint(pointHandle, false); #endif pointWID = mover->getWatchID(); #ifdef USE_IFACE theInterface->setPoint(mover->getPartId(), true); #endif } return(NO_ERR); }
void MoverGroup::statusCount (long* statusTally) { for (long i = 0; i < numMovers; i++) { MoverPtr mover = getMover(i); MechWarriorPtr pilot = mover->getPilot(); if (!mover->getExists()) statusTally[8]++; else if (!mover->getAwake()) statusTally[7]++; else if (pilot && (pilot->getStatus() == WARRIOR_STATUS_WITHDRAWN)) statusTally[6]++; else statusTally[mover->getStatus()]++; } }
//--------------------------------------------------------------------------- __inline void getLargest (long ¤tLargest, MoverPtr mover, long contactStatus) { long thisMoverSize = -1; switch (contactStatus) { case CONTACT_SENSOR_QUALITY_1: case CONTACT_SENSOR_QUALITY_2: thisMoverSize = 0; break; case CONTACT_SENSOR_QUALITY_3: case CONTACT_SENSOR_QUALITY_4: case CONTACT_VISUAL: float tonnage = mover->getTonnage(); if (tonnage < 35.0f) thisMoverSize = 1; else if (tonnage < 55.0f) thisMoverSize = 2; else if (tonnage < 75.0f) thisMoverSize = 3; else thisMoverSize = 4; break; } if (thisMoverSize > currentLargest) currentLargest = thisMoverSize; }
void TeamSensorSystem::modifyContact(SensorSystemPtr sensor, MoverPtr contact, int32_t contactStatus) { ContactInfoPtr contactInfo = contact->getContactInfo(); if(contactInfo->teamSpotter[teamId] == sensor->owner->getHandle()) { int32_t curStatus = contactInfo->contactStatus[teamId]; if(contactStatus > curStatus) contactInfo->contactStatus[teamId] = contactStatus; else if(contactStatus < curStatus) { int32_t bestStatus; SensorSystemPtr bestSensor = findBestSpotter(contact, &bestStatus); contactInfo->contactStatus[teamId] = bestStatus; contactInfo->teamSpotter[teamId] = bestSensor->owner->getHandle(); } } else { int32_t curStatus = contactInfo->contactStatus[teamId]; if(contactStatus > curStatus) { contactInfo->contactStatus[teamId] = contactStatus; contactInfo->teamSpotter[teamId] = sensor->owner->getHandle(); } } }
SensorSystemPtr TeamSensorSystem::findBestSpotter (MoverPtr contact, long* status) { ContactInfoPtr contactInfo = contact->getContactInfo(); if (!contactInfo) { char s[256]; sprintf(s, "TeamSensorSystem.findBestSpotter: NULL contactInfo for objClass %d partID %d team %d", contact->getObjectClass(), contact->getPartId(), contact->getTeamId()); STOP((s)); } SensorSystemPtr bestSensor = NULL; long bestStatus = CONTACT_NONE; for (long i = 0; i < MAX_SENSORS; i++) if (contactInfo->sensors[i] != 255) { SensorSystemPtr sensor = SensorManager->getSensor(i); if (sensor && sensor->owner && (teamId == sensor->owner->getTeamId())) { long status = sensor->calcContactStatus(contact); if (status >= bestStatus) { bestSensor = sensor; bestStatus = status; } } } if (status) *status = bestStatus; return(bestSensor); }
Stuff::Vector3D Team::calcEscapeVector(MoverPtr mover, float threatRange) { static float distance[100]; static Stuff::Vector3D delta[100]; Stuff::Vector3D escapeVector; escapeVector.Zero(); //------------------------------ // Get the initial delta info... int32_t shortest = 0; int32_t longest = 0; for(size_t i = 0; i < rosterSize; i++) { GameObjectPtr obj = ObjectManager->getByWatchID(roster[i]); if(obj) { float distanceToObj = mover->distanceFrom(obj->getPosition()); if(distanceToObj <= threatRange) { delta[i].Subtract(mover->getPosition(), obj->getPosition()); distance[i] = distanceToObj; if(distance[i] > longest) longest = i; if(distance[i] < shortest) shortest = i; } else distance[i] = -999.0; } else distance[i] = -999.0; } //----------------------------------------------------------------- // Now, find the furthest enemy and scale the deltas accordingly... for(i = 0; i < rosterSize; i++) if(distance[i] >= 0.0) { float scale = distance[longest] / distance[i]; delta[i] *= scale; escapeVector += delta[i]; } //-------------------------------------------------------------------------------- // We don't care about the length, just the direction (we assume you want to go as // FAR as necessary)... escapeVector.Normalize(escapeVector); return(escapeVector); }
void TeamSensorSystem::addContact (SensorSystemPtr sensor, MoverPtr contact, long contactIndex, long contactStatus) { Assert(numContacts < MAX_CONTACTS_PER_TEAM, numContacts, " TeamSensorSystem.addContact: max team contacts "); ContactInfoPtr contactInfo = contact->getContactInfo(); contactInfo->sensors[sensor->id] = contactIndex; contactInfo->contactCount[teamId]++; if (contactInfo->contactStatus[teamId] < contactStatus) { contactInfo->contactStatus[teamId] = contactStatus; contactInfo->teamSpotter[teamId] = sensor->owner->getHandle(); } if (contactInfo->contactCount[teamId] == 1) { contacts[numContacts] = contact->getHandle(); contactInfo->teams[teamId] = numContacts; numContacts++; sensor->numExclusives++; } }
void Team::buildRoster(void) { //--------------------------------------------------------------------- // This function builds a roster for the team from the movers currently // registered in the object manager. It assumes the teamId is already // set for each mover, and compares this team's id to that of the // objects to determine which objects belong on this team... rosterSize = 0; for(size_t i = 0; i < ObjectManager->getNumMovers(); i++) { MoverPtr mover = ObjectManager->getMover(i); if(mover->getTeamId() == id) roster[rosterSize++] = mover->getWatchID(); } // numMechs = objClassTally[0]; // numVehicles = objClassTally[1]; // numElementals = objClassTally[2]; }
void Team::removeFromRoster(MoverPtr mover) { for(size_t i = 0; i < rosterSize; i++) if(roster[i] == mover->getWatchID()) { roster[i] = roster[--rosterSize]; break; } }
void Team::eject(void) { for(size_t i = 0; i < rosterSize; i++) { MoverPtr mover = (MoverPtr)ObjectManager->getByWatchID(roster[i]); if(mover) { if(mover->getObjectClass() == BATTLEMECH) mover->getPilot()->orderEject(false, true, ORDER_ORIGIN_COMMANDER); else { WeaponShotInfo shot; shot.init(nullptr, -3, 254.0, 0, 0); mover->handleWeaponHit(&shot, (MPlayer != nullptr)); } } } }
void SensorSystem::removeContact(int32_t contactIndex) { //----------------------------------------------- // This assumes the contactIndex is legitimate... MoverPtr contact = (MoverPtr)ObjectManager->get(contacts[contactIndex] & 0x7FFF); Assert(contact != nullptr, contacts[contactIndex] & 0x7FFF, " SensorSystem.removeContact: bad contact "); numContacts--; if((numContacts > 0) && (contactIndex != numContacts)) { //----------------------------------------------- // Fill vacated slot with contact in last slot... contacts[contactIndex] = contacts[numContacts]; MoverPtr contact = (MoverPtr)ObjectManager->get(contacts[numContacts] & 0x7FFF); contact->getContactInfo()->sensors[id] = contactIndex; } if(notShutdown) master->removeContact(this, contact); }
bool MoverGroup::isMember(MoverPtr mover) { if (!mover) return (false); GameObjectWatchID moverWID = mover->getWatchID(); for (size_t i = 0; i < numMovers; i++) if (moverWIDs[i] == moverWID) return (true); return (false); }
void TeamSensorSystem::updateContactList (void) { numAllContacts = 0; for (long i = 0; i < ObjectManager->getNumMovers(); i++) { MoverPtr mover = ObjectManager->getMover(i); if (mover) { long bestStatus = CONTACT_NONE; for (long i = 0; i < Team::numTeams; i++) { if (Team::teams[teamId]->isFriendly(Team::teams[i])) if (mover->contactInfo->contactStatus[i] > bestStatus) bestStatus = mover->contactInfo->contactStatus[i]; } mover->contactInfo->allContactStatus[teamId] = bestStatus; if (bestStatus != CONTACT_NONE) { allContacts[numAllContacts++] = mover->getHandle(); } } } }
bool MoverGroup::remove (MoverPtr mover) { GameObjectWatchID moverWID = mover->getWatchID(); if (moverWID == pointWID) { disband(); return(true); } else { for (long i = 0; i < numMovers; i++) if (moverWIDs[i] == moverWID) { mover->setGroupId(-1, true); moverWIDs[i] = moverWIDs[numMovers - 1]; moverWIDs[numMovers - 1] = 0; numMovers--; return(true); } } return(false); }
MoverPtr MoverGroup::selectPoint (bool excludePoint) { for (long i = 0; i < numMovers; i++) if (!excludePoint || (moverWIDs[i] != pointWID)) { MoverPtr mover = getMover(i); MechWarriorPtr pilot = mover->getPilot(); if (pilot && pilot->alive()) { //---------------------------------------- // Found a legitimate point, so set him... setPoint(mover); return(mover); } } //----------------------- // No legitimate point... setPoint(NULL); return(NULL); }
void MultiPlayer::addToMoverRoster(MoverPtr mover) { for(size_t i = 0; i < MAX_MULTIPLAYER_MOVERS; i++) if(!moverRoster[i]) { moverRoster[i] = mover; mover->setNetRosterIndex(i); return; } STOP(("MultiPlayer.addToMoverRoster: too many movers")); }
void SensorSystem::addContact (MoverPtr mover, bool visual) { Assert(!isContact(mover), 0, " SensorSystem.addContact: already contact "); if (numContacts < MAX_CONTACTS_PER_SENSOR) { contacts[numContacts] = mover->getHandle(); if (visual) contacts[numContacts] |= VISUAL_CONTACT_FLAG; if (notShutdown) master->addContact(this, mover, numContacts, visual ? CONTACT_VISUAL : getSensorQuality()); numContacts++; } }
void SensorSystem::updateContacts (void) { if ((masterIndex == -1) || (range < 0.0)) return; if (!enabled()) { clearContacts(); return; } //--------------------------------------------------------------------- // If we've already scanned this frame, don't bother updating contacts. // Otherwise, update contacts... if (scenarioTime == lastScanUpdate) return; long i = 0; while (i < numContacts) { MoverPtr contact = (MoverPtr)ObjectManager->get(contacts[i] & 0x7FFF); long contactStatus = calcContactStatus(contact); if (contactStatus == CONTACT_NONE) removeContact(i); else { contacts[i] = contact->getHandle(); if (contactStatus == CONTACT_VISUAL) contacts[i] |= 0x8000; modifyContact(contact, contactStatus == CONTACT_VISUAL); /* if (teamContactStatus < contactStatus) { //-------------------------------------------------- // Better sensor info, so update the team sensors... contactInfo->contactStatus[owner->getTeamId()] = contactStatus; contactInfo->teamSpotter[owner->getTeamId()] = (unsigned char)owner->getHandle(); } */ i++; } } }