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)); } } } }
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); }
int _stdcall Logistics::beginMission(void*, int, void*[]) { if (MPlayer) MPlayer->setMode(MULTIPLAYER_MODE_LOADING); char commandersToLoad[MAX_MC_PLAYERS][3] = {{0, 0, 0}, {1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {4, 4, 4}, {5, 5, 5}, {6, 6, 6}, {7, 7, 7}}; long missionLoadType = LogisticsData::instance->skipLogistics() ? MISSION_LOAD_SP_QUICKSTART : MISSION_LOAD_SP_LOGISTICS; if (MPlayer) { //--------------------------- // Calc valid commanderIDs... long curCommanderID = 0; for (long CID = 0; CID < MAX_MC_PLAYERS; CID++) { MPlayer->availableCIDs[CID] = true; if (MPlayer->playerInfo[CID].player && (MPlayer->playerInfo[CID].commanderID > -1)) { if (CID != curCommanderID) { long oldCommanderID = CID; MPlayer->playerInfo[CID].commanderID = curCommanderID; memcpy(&MPlayer->playerInfo[curCommanderID], &MPlayer->playerInfo[CID], sizeof(MC2Player)); MPlayer->playerInfo[CID].player = NULL; MPlayer->playerInfo[CID].commanderID = -1; for (long j = 0; j < MAX_MC_PLAYERS; j++) if (MPlayer->playerList[j].player == MPlayer->playerInfo[curCommanderID].player) MPlayer->playerList[j].commanderID = curCommanderID; if (oldCommanderID == MPlayer->commanderID) MPlayer->commanderID = curCommanderID; } MPlayer->availableCIDs[curCommanderID] = false; curCommanderID++;; } } //---------------------- // Calc valid teamIDs... long curTeamID = 0; for (long teamID = 0; teamID < MAX_MC_PLAYERS; teamID++) { bool teamFound = false; for (long i = 0; i < MAX_MC_PLAYERS; i++) if (MPlayer->playerInfo[i].player && (MPlayer->playerInfo[i].team == teamID)) { MPlayer->playerInfo[i].team = curTeamID; teamFound = true; } if (teamFound) curTeamID++; } if (MPlayer->isHost()) { // Determine drop zone order here... char dropZoneList[8]; char hqs[MAX_TEAMS]; if (MPlayer->missionSettings.missionType == MISSION_TYPE_OTHER) { bool goodToLoad = mission->calcComplexDropZones((char*)(const char*)LogisticsData::instance->getCurrentMission(), dropZoneList); if (!goodToLoad) STOP(("Logisitics.beginMission: teams do not match up for complex mission")); for (long i = 0; i < MAX_TEAMS; i++) hqs[i] = i; } else MPlayer->calcDropZones(dropZoneList, hqs); if (MPlayer->missionSettings.quickStart) for (long i = 0; i < MAX_MC_PLAYERS; i++) { MPlayer->commandersToLoad[i][0] = (long)dropZoneList[i]; //MPlayer->playerInfo[i].commanderID; MPlayer->commandersToLoad[i][1] = (long)(dropZoneList[i] > -1) ? MPlayer->playerInfo[dropZoneList[i]].team : 0; MPlayer->commandersToLoad[i][2] = hqs[i]; } else for (long i = 0; i < MAX_MC_PLAYERS; i++) { MPlayer->commandersToLoad[i][0] = dropZoneList[i]; //-1; MPlayer->commandersToLoad[i][1] = (dropZoneList[i] > -1) ? MPlayer->playerInfo[dropZoneList[i]].team : 0; //-1; MPlayer->commandersToLoad[i][2] = hqs[i]; } MPlayer->sendMissionSetup(0, 0, NULL); } if (!MPlayer->waitTillStartLoading()) { // SERVER DROPPED return(0); } if (MPlayer->commandersToLoad[0][0] < -1) PAUSE(("Logistics.beginMission: bad commandersToLoad")); for (long i = 0; i < MAX_MC_PLAYERS; i++) { commandersToLoad[i][0] = MPlayer->commandersToLoad[i][0]; commandersToLoad[i][1] = MPlayer->commandersToLoad[i][1]; commandersToLoad[i][2] = MPlayer->commandersToLoad[i][2]; } if (MPlayer->missionSettings.quickStart) { MultiPlayTeamId = MPlayer->playerInfo[MPlayer->commanderID].team; if (MultiPlayTeamId < 0) STOP(("Bad commanderID")); MultiPlayCommanderId = MPlayer->commanderID; if (MultiPlayCommanderId < 0) STOP(("Bad commanderID")); missionLoadType = MISSION_LOAD_MP_QUICKSTART; } else { MultiPlayTeamId = MPlayer->playerInfo[MPlayer->commanderID].team; MultiPlayCommanderId = MPlayer->commanderID; missionLoadType = MISSION_LOAD_MP_LOGISTICS; } long maxTeam = -1; for (i = 0; i < MAX_MC_PLAYERS; i++) if (MPlayer->playerInfo[i].team > maxTeam) maxTeam = MPlayer->playerInfo[i].team; MPlayer->numTeams = maxTeam + 1; } else if (missionLoadType == MISSION_LOAD_SP_LOGISTICS) { commandersToLoad[0][0] = -1; commandersToLoad[0][1] = -1; commandersToLoad[0][2] = -1; } else { commandersToLoad[0][0] = 0; commandersToLoad[0][1] = 0; commandersToLoad[0][2] = -1; } if (mission) mission->destroy(); long numPlayers = 1; if ( MPlayer ) MPlayer->getPlayers(numPlayers); long numMoversPerCommander[MAX_MC_PLAYERS] = {12, 12, 12, 9, 7, 6, 5, 4}; Stuff::Vector3D dropZoneList[255]; // ubsurdly large, but sometimes we overrun this. long dropZoneID = 0; if (MPlayer) { //dropZoneID = MPlayer->commanderID; for (long i = 0; i < MAX_MC_PLAYERS; i++) if (commandersToLoad[i][0] == MPlayer->commanderID) { dropZoneID = i; break; } useUnlimitedAmmo = MPlayer->missionSettings.unlimitedAmmo; } mission->init((char*)(const char*)LogisticsData::instance->getCurrentMission(), missionLoadType, dropZoneID, dropZoneList, commandersToLoad, numMoversPerCommander[numPlayers - 1]); LogisticsData::instance->rpJustAdded = 0; if (MPlayer) { if (missionLoadType == MISSION_LOAD_MP_LOGISTICS) { EList< LogisticsMech*, LogisticsMech* > list; LogisticsData::instance->getForceGroup(list); long dropZoneIndex = 0; long numMechs = 0; for (EList< LogisticsMech*, LogisticsMech* >::EIterator iter = list.Begin(); !iter.IsDone(); iter++) { numMechs++; if ( !(*iter)->getPilot() ) continue; CompressedMech mechData; mechData.lastMech = (list.Count() == numMechs); mechData.objNumber = (*iter)->getFitID(); mechData.commanderID = MPlayer->commanderID; mechData.baseColor = MPlayer->colors[MPlayer->playerInfo[MPlayer->commanderID].baseColor[BASECOLOR_TEAM]]; mechData.highlightColor1 = MPlayer->colors[MPlayer->playerInfo[MPlayer->commanderID].stripeColor]; mechData.highlightColor2 = MPlayer->colors[MPlayer->playerInfo[MPlayer->commanderID].stripeColor]; strcpy(mechData.pilotFile, (*iter)->getPilot()->getFileName()); strcpy(mechData.mechFile, (*iter)->getFileName()); strcpy(mechData.variantName, (*iter)->getName()); mechData.variantNum = (*iter)->getVariant()->getFileID(); mechData.cBills = (*iter)->getVariant()->getCost(); mechData.pos[0] = dropZoneList[dropZoneIndex].x; mechData.pos[1] = dropZoneList[dropZoneIndex++].y; mechData.designerMech = (*iter)->getVariant()->isDesignerMech(); mechData.numComponents = (*iter)->getComponentCount(); if (mechData.numComponents) { long* componentList = (long*)systemHeap->Malloc(sizeof(long) * mechData.numComponents); long otherCount = mechData.numComponents; (*iter)->getComponents(otherCount, componentList); if (otherCount != mechData.numComponents) STOP(("Heidi's getComponentCount does not agree with count returned from getComponents")); for (long i = 0; i < mechData.numComponents; i++) mechData.components[i] = (unsigned char)componentList[i]; } MPlayer->sendMissionSetup(0, 1, &mechData); } if (!MPlayer->waitTillMechDataReceived()) { // SERVER DROPPED mission->destroy(); return(0); } ObjectManager->numMechs = 0; ObjectManager->numVehicles = 0; for (long i = 0; i < MAX_MC_PLAYERS; i++) { if (MPlayer->mechDataReceived[i]) { for (long j = 0; j < 12; j++) { if (MPlayer->mechData[i][j].objNumber > -1) { MoverInitData data; memset(&data, 0, sizeof(MoverInitData)); data.objNumber = MPlayer->mechData[i][j].objNumber; data.rosterIndex = 255; data.controlType = 2; data.controlDataType = 1; data.position.x = MPlayer->mechData[i][j].pos[0]; data.position.y = MPlayer->mechData[i][j].pos[1]; data.position.z = 0.0; data.rotation = 0; data.teamID = MPlayer->playerInfo[MPlayer->mechData[i][j].commanderID].team; data.commanderID = MPlayer->mechData[i][j].commanderID; data.baseColor = MPlayer->mechData[i][j].baseColor; data.highlightColor1 = MPlayer->mechData[i][j].highlightColor1; data.highlightColor2 = MPlayer->mechData[i][j].highlightColor2; data.gestureID = 2; data.active = 1; data.exists = 1; data.capturable = 0; data.icon = 0; strcpy(data.pilotFileName, MPlayer->mechData[i][j].pilotFile); strcpy(data.brainFileName, "pbrain"); strcpy(data.csvFileName, MPlayer->mechData[i][j].mechFile); data.numComponents = MPlayer->mechData[i][j].numComponents; for (long k = 0; k < MPlayer->mechData[i][j].numComponents; k++) data.components[k] = MPlayer->mechData[i][j].components[k]; long moverHandle = mission->addMover(&data); if (moverHandle < 1) STOP(("Logistics.beginMission: unable to addMover")); MoverPtr mover = (MoverPtr)ObjectManager->get(moverHandle); if (!mover) STOP(("Logistics.beginMission: NULL mover")); if (mover->getObjectClass() != BATTLEMECH) STOP(("Logistics.beginMission: not a mech")); ((BattleMech*)mover)->cBills = MPlayer->mechData[i][j].cBills; strcpy(((BattleMech*)mover)->variantName, MPlayer->mechData[i][j].variantName); data.variant = MPlayer->mechData[i][j].variantNum; } } } } } else // gotta update pilot availability { long count = 256; LogisticsPilot* pilots[256]; LogisticsData::instance->getPilots( pilots, count ); for ( int i = 0; i < count; i++ ) { pilots[i]->setUsed(0); } Team* pTeam = Team::home; if ( pTeam ) { for ( i = pTeam->getRosterSize() - 1; i > -1; i-- ) { Mover* pMover = (Mover*)pTeam->getMover( i ); if ( pMover && pMover->getCommander()->getId() == Commander::home->getId() ) { LogisticsPilot* pPilot = LogisticsData::instance->getPilot( pMover->getPilot()->getName() ); if ( pPilot ) pPilot->setUsed( true ); } } } } CompressedMech mechData; mechData.commanderID = MPlayer->commanderID; MPlayer->sendMissionSetup(0, 2, &mechData); if (!MPlayer->waitTillMissionLoaded()) { // SERVER DROPPED mission->destroy(); return(0); } } else if (missionLoadType == MISSION_LOAD_SP_LOGISTICS) { EList< LogisticsMech*, LogisticsMech* > list; LogisticsData::instance->getForceGroup( list ); float rotation = list.Count() ? 360.f/list.Count() : 0.f; MoverInitData data; memset( &data, 0, sizeof( data ) ); data.rosterIndex = 255; data.controlType = 2; data.controlDataType = 1; data.position.Zero(); // need to get the drop zone location data.rotation = 0; data.teamID = Team::home->getId(); data.commanderID = Team::home->getId(); data.active = 1; data.exists = 1; data.capturable = 0; data.baseColor = prefs.baseColor; data.highlightColor1 = prefs.highlightColor; data.highlightColor2 = prefs.highlightColor; strcpy( data.pilotFileName, "pmw00031" ); strcpy( data.brainFileName, "pbrain" ); Stuff::Vector3D vector; vector.x = 0.f; vector.y = 1.f; vector.z = 0.f; Stuff::Vector3D scaled; for ( EList< LogisticsMech*, LogisticsMech* >::EIterator iter = list.Begin(); !iter.IsDone(); iter++) { scaled = vector; scaled *= 128.; data.position.Add(dropZoneList[0], scaled); //data.position = dropZoneList[dropZoneIndex++]; data.objNumber = (*iter)->getFitID(); strcpy( data.csvFileName, (*iter)->getFileName() ); if ( !(*iter)->getPilot() ) continue; strcpy( data.pilotFileName, (*iter)->getPilot()->getFileName() ); data.overrideLoadedPilot = true; data.gunnerySkill = (*iter)->getPilot()->getGunnery(); data.pilotingSkill = (*iter)->getPilot()->getPiloting(); memcpy(data.specialtySkills,(*iter)->getPilot()->getSpecialtySkills(),sizeof(bool) * NUM_SPECIALTY_SKILLS); if ( !(*iter)->getVariant()->isDesignerMech()) { data.variant = 0; mission->addMover( &data, (*iter)); } else { data.variant = (*iter)->getVariant()->getFileID(); mission->addMover( &data ); } Rotate( vector, rotation ); } } /* if (MPlayer) { if (MPlayer->isHost()) MPlayer->serverCID = MPlayer->commanderID; else { for (long i = 0; i < MAX_MC_PLAYERS; i++) if (MPlayer->serverPlayer && (MPlayer->playerList[i].player == MPlayer->serverPlayer)) MPlayer->serverCID = MPlayer->playerList[i].commanderID; if (MPlayer->serverCID == -1) STOP(("Logistics.beginMission: bad serverCID")); } } */ mission->missionInterface->initMechs(); eye->activate(); eye->update(); mission->start(); mission->update(); // force this, so we don't render first if (MPlayer) { CompressedMech mechData; mechData.commanderID = MPlayer->commanderID; MPlayer->sendMissionSetup(0, 4, &mechData); if (!MPlayer->waitTillMissionSetup()) { // SERVER DROPPED mission->destroy(); return(0); } MPlayer->setMode(MULTIPLAYER_MODE_MISSION); } if (MPlayer && MPlayer->hostLeft) { mission->destroy(); return(0); } return(1); }
long MoverGroup::calcJumpGoals (Stuff::Vector3D goal, long numMovers, Stuff::Vector3D* goalList, GameObjectPtr DFATarget) { long numJumping = 0; //----------------------------- // First, build the jump map... long jumpMap[JUMPMAP_CELL_DIM][JUMPMAP_CELL_DIM]; //------------------------------------------------------------ // The initial goal tile is placed at the center of the map... long goalCell[2] = {0, 0}; land->worldToCell(goal, goalCell[0], goalCell[1]); long mapCellUL[2] = {0, 0}; mapCellUL[0] = goalCell[0] - JUMPMAP_CELL_DIM / 2; mapCellUL[1] = goalCell[1] - JUMPMAP_CELL_DIM / 2; // -1 = OPEN // -2 = BLOCKED // 0 thru # = already selected for that # mover in the group for (long r = 0; r < JUMPMAP_CELL_DIM; r++) for (long c = 0; c < JUMPMAP_CELL_DIM; c++) { long cellRow = mapCellUL[0] + r; long cellCol = mapCellUL[1] + c; if (GameMap->inBounds(cellRow, cellCol)) { MapCellPtr mapCell = GameMap->getCell(cellRow, cellCol); //----------------------- // Tile (terrain) type... //long tileType = curTile.getTileType(); if (!mapCell->getPassable()) jumpMap[r][c] = -2; else jumpMap[r][c] = -1; #ifdef USE_OVERLAYS_IN_MC2 long overlay = mapCell->getOverlay(); if (OverlayIsBridge[overlay]) { switch (overlay) { case OVERLAY_WATER_BRIDGE_NS: case OVERLAY_RAILROAD_WATER_BRIDGE_NS: jumpMap[row][col] = -2; jumpMap[row][col + 2] = -2; jumpMap[row + 1][col] = -2; jumpMap[row + 1][col + 2] = -2; jumpMap[row + 2][col] = -2; jumpMap[row + 2][col + 2] = -2; break; case OVERLAY_WATER_BRIDGE_EW: case OVERLAY_RAILROAD_WATER_BRIDGE_EW: jumpMap[row][col] = -2; jumpMap[row][col + 1] = -2; jumpMap[row][col + 2] = -2; jumpMap[row + 2][col] = -2; jumpMap[row + 2][col + 1] = -2; jumpMap[row + 2][col + 2] = -2; break; case OVERLAY_WATER_BRIDGE_NS_DESTROYED: case OVERLAY_RAILROAD_WATER_BRIDGE_NS_DESTROYED: case OVERLAY_WATER_BRIDGE_EW_DESTROYED: case OVERLAY_RAILROAD_WATER_BRIDGE_EW_DESTROYED: jumpMap[row][col] = -2; jumpMap[row][col + 1] = -2; jumpMap[row][col + 2] = -2; jumpMap[row + 1][col] = -2; jumpMap[row + 1][col + 1] = -2; jumpMap[row + 1][col + 2] = -2; jumpMap[row + 2][col] = -2; jumpMap[row + 2][col + 1] = -2; jumpMap[row + 2][col + 2] = -2; break; } } #endif } else jumpMap[r][c] = -2; } long moverCount = ObjectManager->getNumMovers(); for (long i = 0; i < moverCount; i++) { MoverPtr mover = ObjectManager->getMover(i); if ((mover->getObjectClass() != ELEMENTAL) && (mover != DFATarget) && !mover->isDisabled()) { long mapCellRow, mapCellCol; mover->getCellPosition(mapCellRow, mapCellCol); mapCellRow -= mapCellUL[0]; mapCellCol -= mapCellUL[1]; if (inMapBounds(mapCellRow, mapCellCol, JUMPMAP_CELL_DIM, JUMPMAP_CELL_DIM)) jumpMap[mapCellRow][mapCellCol] = -2; } } #ifdef _DEBUG #if DEBUGJUMPGOALS char debugStr[256]; sprintf(debugStr, "GROUP JUMP(%.2f,%.2f,%.2f)--UL = %d,%d: ", goal.x, goal.y, goal.z,mapCellUL[0], mapCellUL[1]); #endif #endif //----------------------------------------------------------------- // Now, for each jumper, select a closest cell to the goal, mark it // as theirs and close it... for (i = 0; i < numMovers; i++) { //long startCellRow = 0; //long startCellCol = 0; long curCellRow = goalCell[0] - mapCellUL[0]; long curCellCol = goalCell[1] - mapCellUL[1]; bool notFound = true; long spiralIndex = 0; while (notFound) { if (jumpMap[curCellRow][curCellCol] == -1) { // Should check to see if the cell is within range... //---------------------------------- // Found an open cell, so take it... jumpMap[curCellRow][curCellCol] = i; land->cellToWorld(mapCellUL[0] + curCellRow, mapCellUL[1] + curCellCol, goalList[i]); numJumping++; notFound = false; #ifdef _DEBUG #if DEBUGJUMPGOALS char s[30]; sprintf(s, "[%d,%d] ", curCellRow, curCellCol); strcat(debugStr, s); #endif #endif } else { //------------------------------------- // Go to the next cell in our search... do { if (spiralIndex == (JUMPMAP_CELL_DIM * JUMPMAP_CELL_DIM * 2)) { goalList[i].x = -99999.0; goalList[i].y = -99999.0; goalList[i].z = -99999.0; notFound = false; break; } curCellRow += CellSpiralIncrement[spiralIndex++]; curCellCol += CellSpiralIncrement[spiralIndex++]; } while (!inMapBounds(curCellRow, curCellCol, JUMPMAP_CELL_DIM, JUMPMAP_CELL_DIM)); } } } return(numJumping); }