bool TeamSensorSystem::meetsCriteria (GameObjectPtr looker, MoverPtr mover, long contactCriteria) { bool isSensor[NUM_CONTACT_STATUSES] = {false, true, true, true, true, false}; long status = mover->getContactStatus(teamId, true); if (mover->getFlag(OBJECT_FLAG_REMOVED)) return(false); if (status == CONTACT_NONE) return(false); if (contactCriteria & CONTACT_CRITERIA_VISUAL_OR_SENSOR) if ((status != CONTACT_VISUAL) && !isSensor[status]) return(false); if (contactCriteria & CONTACT_CRITERIA_VISUAL) if (status != CONTACT_VISUAL) return(false); if (contactCriteria & CONTACT_CRITERIA_SENSOR) if (!isSensor[status]) return(false); if (contactCriteria & CONTACT_CRITERIA_NOT_CHALLENGED) { if (mover->getChallenger() != NULL) return(false); } if (contactCriteria & CONTACT_CRITERIA_NOT_DISABLED) { if (mover->isDisabled()) return(false); } if (contactCriteria & CONTACT_CRITERIA_ENEMY) { if ((teamId == -1) || !mover->getTeam()) return(false); if (!Team::teams[teamId]->isEnemy(mover->getTeam())) return(false); } if (contactCriteria & CONTACT_CRITERIA_ARMED) { if (mover->numFunctionalWeapons == 0) return(false); } return(true); }
long SensorSystem::calcContactStatus (MoverPtr mover) { if (!owner->getTeam()) return(CONTACT_NONE); if (mover->getFlag(OBJECT_FLAG_REMOVED)) { return(CONTACT_NONE); } //---------------------------------------------------------- //If object we are looking for is at the edge, NO CONTACT!! if (!Terrain::IsGameSelectTerrainPosition(mover->getPosition())) return CONTACT_NONE; //------------------------------------------------------------- // Should be properly set when active probes are implemented... long newContactStatus = CONTACT_NONE; if (!notShutdown || (range == 0.0) && !broken) { if (owner->lineOfSight(mover) && !mover->isDisabled()) newContactStatus = CONTACT_VISUAL; return(newContactStatus); } if ((masterIndex == -1) || (range < 0.0)) { return(CONTACT_NONE); } if (owner->isMover()) { MoverPtr mover = (MoverPtr)owner; if ((mover->sensor == 255) || mover->inventory[mover->sensor].disabled || broken) { return(CONTACT_NONE); } } if (mover->getFlag(OBJECT_FLAG_SENSOR) && !mover->isDisabled()) { bool moverNotContact = mover->hasNullSignature() || (mover->getEcmRange() != 0.0f); bool moverInvisible = (mover->getStatus() == OBJECT_STATUS_SHUTDOWN); if (!moverInvisible && !moverNotContact) { float distanceToMover = owner->distanceFrom(mover->getPosition()); float sensorRange = getEffectiveRange(); if (distanceToMover <= sensorRange) { //------------------------------------------- //No need to check shutdown and probe AGAIN! newContactStatus = getSensorQuality(); //--------------------------------------- // If ecm affecting me, my skill drops... // CUT, per Mitch 2/10/00 if ((ecmEffect < 1.0) && (newContactStatus > CONTACT_SENSOR_QUALITY_1)) newContactStatus--; //--------------------------------------------------- // We now we are within sensor range, check visual. float startRadius = 0.0f; if (!owner->isMover()) startRadius = owner->getAppearRadius(); if (hasLOSCapability && owner->lineOfSight(mover,startRadius)) newContactStatus = CONTACT_VISUAL; } else //Still need to check if visual!!! ECM and Lookout Towers!! { float startRadius = 0.0f; if (!owner->isMover()) startRadius = owner->getAppearRadius(); if (hasLOSCapability && owner->lineOfSight(mover,startRadius)) newContactStatus = CONTACT_VISUAL; } } else { //Target is shutdown, can ONLY be visual cause this platform has no probe. float startRadius = 0.0f; if (!owner->isMover()) startRadius = owner->getAppearRadius(); if (hasLOSCapability && owner->lineOfSight(mover,startRadius)) newContactStatus = CONTACT_VISUAL; } } //Let us know that we can see something, sensor or otherwise!! if (mover->getTeam() && (owner->getTeam() == Team::home) && mover->getTeam()->isEnemy(Team::home) && (newContactStatus != CONTACT_NONE)) { SensorSystemManager::enemyInLOS = true; } return(newContactStatus); }
void GameTacMap::render() { if (turn < 2) //Terrain not setup yet. Left,Right,Top,Bottom are poopy! return; gos_VERTEX corners[5]; gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_OneZero ); gos_SetRenderState( gos_State_Specular,FALSE ); gos_SetRenderState( gos_State_AlphaTest, FALSE ); gos_SetRenderState( gos_State_Filter, gos_FilterNone ); gos_SetRenderState( gos_State_ZWrite, 0 ); gos_SetRenderState( gos_State_ZCompare, 0 ); gos_SetRenderState( gos_State_Texture, textureHandle ); for ( int i = 0; i < 4; ++i ) { corners[i].rhw = 1.0f; corners[i].argb = 0xffffffff; corners[i].frgb = 0; corners[i].z = 0.0f; } corners[0].x = corners[2].x = left; corners[1].x = corners[3].x = right; corners[3].y = corners[2].y = bottom; corners[0].y = corners[1].y = top; corners[0].u = 2.f/(float)bmpWidth; corners[3].u = 128.f/(float)bmpWidth; corners[2].u = 2.f/(float)bmpWidth; corners[1].u = 128.f/(float)bmpWidth; corners[0].v = 2.f/(float)bmpWidth; corners[3].v = 128.f/(float)bmpHeight; corners[2].v = 128.f/(float)bmpHeight; corners[1].v = 2.f/(float)bmpWidth; gos_DrawTriangles( corners, 3 ); gos_DrawTriangles( &corners[1], 3 ); Stuff::Vector2DOf<long> screen; Stuff::Vector4D nScreen; Stuff::Vector3D world; //----------------------------------------------------------- // Render the objective markers long count = 0; for ( EList< CObjective*, CObjective* >::EIterator iter = Team::home->objectives.Begin(); !iter.IsDone(); iter++ ) { //We are there. Start flashing. if ((objectiveAnimationId == count) && objectiveNumFlashes) { objectiveFlashTime += g_deltaTime; if ( objectiveFlashTime > .5f ) { objectiveFlashTime = 0.0f; objectiveNumFlashes--; } else if ( objectiveFlashTime > 0.25f) { (*iter)->RenderMarkers(this, 0); } if (objectiveNumFlashes == 0) { //Flashing is done. We now return you to your regularly scheduled program. objectiveAnimationId = 0; } } else { (*iter)->RenderMarkers(this, 0); } count++; } // this is the little viewing rect // Routine that InverseProjects is slightly less accurate but an order of magnitude faster. // Can make more accurate later at very little expense to performance. // Easy to fix with camera later. -fs screen.x = 1; screen.y = 1; nScreen.x = nScreen.y = 1.0f; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[0] ); screen.y = Environment.screenHeight - 1; nScreen.y = (Environment.screenHeight * 0.6667f) - 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[1] ); screen.x = Environment.screenWidth - 1; nScreen.x = Environment.screenWidth - 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[2] ); screen.y = 1; nScreen.y = 1; nScreen.z = nScreen.w = 0.0f; eye->inverseProjectZ( nScreen, world ); worldToTacMap( world, corners[3] ); corners[0].argb = 0xffffffff; corners[1].argb = 0xffffffff; corners[2].argb = 0xffffffff; corners[3].argb = 0xffffffff; corners[0].u = corners[1].u = 0.078125f; corners[3].u = corners[2].u = .99875f; corners[0].v = corners[3].v = 0.078125f; corners[1].v = corners[2].v = .99875f; corners[4] = corners[0]; gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha); gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud); gos_SetRenderState( gos_State_MonoEnable, 0); gos_SetRenderState( gos_State_Perspective, 0); gos_SetRenderState( gos_State_Clipping, 2); gos_SetRenderState( gos_State_AlphaTest, 0); gos_SetRenderState( gos_State_Specular, 0); gos_SetRenderState( gos_State_Dither, 1); gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate); gos_SetRenderState( gos_State_Filter, gos_FilterBiLinear); gos_SetRenderState( gos_State_TextureAddress, gos_TextureWrap ); gos_SetRenderState( gos_State_ZCompare, 0); gos_SetRenderState( gos_State_ZWrite, 0); DWORD gosTextureHandle = mcTextureManager->get_gosTextureHandle(viewRectHandle); gos_SetRenderState( gos_State_Texture, gosTextureHandle ); gos_DrawQuads( &corners[0], 4 ); unsigned long colors[MAX_MOVERS]; unsigned long ringColors[MAX_MOVERS]; Stuff::Vector3D positions[MAX_MOVERS]; unsigned long ranges[MAX_MOVERS]; bool selected[MAX_MOVERS]; count = 0; //------------------------------------------------------------ // draw non-movers, must do separate check for vehicles, I'm not sure they // have sensors for ( i = 0; i < MAX_TEAMS; ++i ) { TeamSensorSystem* pSys = SensorManager->getTeamSensor( i ); if ( pSys ) { for ( int j = 0; j < pSys->numSensors; ++j ) { SensorSystem* pSensor = pSys->sensors[j]; if ( !pSensor ) continue; if ( pSensor->owner->isDestroyed() || pSensor->owner->isDisabled() || pSensor->owner->getStatus() == OBJECT_STATUS_SHUTDOWN ) continue; if ( pSensor->getRange() < 1.1 || pSensor->broken) continue; if (!pSensor->owner->getTeam()) continue; ObjectClass objClass = pSensor->owner->getObjectClass(); unsigned long colorBlip = pSensor->owner->getSelected() ? 0xff4bff4b : 0xff00cc00; unsigned long colorRing = 0xff00cc00; if ( pSensor->owner->getTeam()->isNeutral( Team::home ) ) { colorBlip = pSensor->owner->getSelected() ? 0xff4c4cff : 0xff0000ff; colorRing = 0xff0000ff; } else if ( pSensor->owner->getTeam()->isEnemy( Team::home ) ) // enemy { { colorBlip = pSensor->owner->getSelected() ? 0xffff3f3f : 0xffff0000; colorRing = 0xffff0000; } } if ( objClass != BATTLEMECH && objClass != GROUNDVEHICLE) { if ( objClass == ARTILLERY ) { // blink s_lastBlinkTime += g_deltaTime; if ( s_lastBlinkTime > s_blinkLength ) { colorBlip = 0; colorRing = 0; s_lastBlinkTime = 0.f; } } colors[count] = colorBlip; ringColors[count] = colorRing; ranges[count] = pSensor->getRange(); selected[count] = 0; positions[count] = pSensor->owner->getPosition(); count++; } } } } unsigned long colorBlip, colorRing; //----------------------------------------------------- // draw the movers for (i=0;i<(ObjectManager->numMovers);i++) { MoverPtr mover = ObjectManager->getMover(i); if (mover && mover->getExists() && !(mover->isDestroyed() || mover->isDisabled())) { SensorSystem* pSensor = mover->getSensorSystem(); float range = pSensor ? pSensor->getRange() : 0; long contactStatus = mover->getContactStatus(Team::home->getId(), true); if (mover->getTeamId() == Team::home->id) { if (mover->getCommanderId() == Commander::home->getId()) { if (mover->isOnGUI()) { colorBlip = mover->getSelected() ? 0xff4bff4b : 0xff00cc00; mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff00cc00; } else continue; } else { if (mover->isOnGUI() && land->IsGameSelectTerrainPosition(mover->getPosition()) && mover->pathLocks) { colorBlip = mover->getSelected() ? 0xff4b4bff : 0xff0000cc; mover->getStatus() == OBJECT_STATUS_SHUTDOWN ? colorRing = 0 : colorRing = 0xff0000cc; } else continue; } } else if (g_dbgShowMovers || (MPlayer && MPlayer->allUnitsDestroyed[MPlayer->commanderID]) || ((mover->getTeamId() != Team::home->id) && ( contactStatus != CONTACT_NONE ) && (mover->getStatus() != OBJECT_STATUS_SHUTDOWN) && (!mover->hasNullSignature()) && (mover->getEcmRange() <= 0.0f) ) ) //Do not draw ECM mechs!!) { //Not on our side. Draw by contact status colorBlip = mover->getSelected() ? 0xffff3f3f : 0xffff0000; colorRing = 0xffff0000; } else continue; colors[count] = colorBlip; ringColors[count] = colorRing; ranges[count] = range; selected[count] = mover->getSelected(); positions[count] = mover->getPosition(); count++; } } for ( i = 0; i < count; i++ ) { drawSensor( positions[i], ranges[i], ringColors[i] ); } bool bSel = 0; // draw unselected first for ( int j = 0; j < 2; j++ ) { for ( int i = 0; i < count; i++ ) { if ( selected[i] == bSel ) { drawBlip( positions[i], colors[i], DOT_BLIP ); } } bSel = 1; } }
long MoverGroup::handleTacticalOrder (TacticalOrder tacOrder, long priority, Stuff::Vector3D* jumpGoalList, bool queueGroupOrder) { if (numMovers == 0) return(NO_ERR); if (queueGroupOrder) tacOrder.pack(NULL, NULL); //bool processOrder = true; bool isJump = false; bool isMove = false; Stuff::Vector3D goalList[MAX_MOVERGROUP_COUNT]; Stuff::Vector3D location = tacOrder.getWayPoint(0); //MoverPtr pointVehicle = getPoint(); if (tacOrder.code == TACTICAL_ORDER_ATTACK_OBJECT) if (tacOrder.attackParams.method == ATTACKMETHOD_DFA) { //------------------------------------------------- // Let's just make it a move/jump order, for now... tacOrder.code = TACTICAL_ORDER_JUMPTO_OBJECT; tacOrder.moveParams.wait = false; tacOrder.moveParams.wayPath.mode[0] = TRAVEL_MODE_SLOW; GameObjectPtr target = ObjectManager->getByWatchID(tacOrder.targetWID); Assert(tacOrder.targetWID != 0, 0, " DFA AttackObject WID is 0 "); if (!target) return(NO_ERR); tacOrder.setWayPoint(0, target->getPosition()); } if (tacOrder.code == TACTICAL_ORDER_JUMPTO_OBJECT) { tacOrder.code = TACTICAL_ORDER_JUMPTO_POINT; GameObjectPtr target = ObjectManager->get(tacOrder.targetWID); Assert(tacOrder.targetWID != 0, 0, " DFA AttackObject WID is 0 "); if (!target) return(NO_ERR); tacOrder.setWayPoint(0, target->getPosition()); } //vector_3d offsetTable[MAX_GROUPMOVE_OFFSETS]; //long numOffsets = 0; switch (tacOrder.code) { case TACTICAL_ORDER_WAIT: break; case TACTICAL_ORDER_MOVETO_POINT: case TACTICAL_ORDER_MOVETO_OBJECT: { Fatal(0, "Need to support jumpGoalList (and goalList) for MOVETO as well in mc2 "); isMove = true; //----------------------------------------------------------- // Sort by distance to destination. Their selectionIndex will // be set to modify this goal... SortListPtr list = Mover::sortList; if (list) { list->clear(false); long moverCount = 0; for (long i = 0; i < numMovers; i++) { MoverPtr mover = getMover(i); Assert(mover != NULL, moverWIDs[i], " MoverGroup.handleTacticalOrder: NULL mover "); if (!mover->isDisabled()) { list->setId(moverCount, i); list->setValue(moverCount, mover->distanceFrom(location)); moverCount++; } } list->sort(false); //-------------------------------- // Let's build the offset table... /* numOffsets = moverCount - 1; if (numOffsets > MAX_GROUPMOVE_OFFSETS) numOffsets = MAX_GROUPMOVE_OFFSETS; long offsetsStart = GroupMoveOffsetsIndex[numOffsets - 1]; for (i = 0; i < numOffsets; i++) offsetTable[i] = relativePositionToPoint(location, GroupMoveOffsets[offsetsStart + i][0], GroupMoveOffsets[offsetsStart + i][1], RELPOS_FLAG_PASSABLE_START); */ //----------------------------------- // Now, calc the order of movement... long curIndex = 1; for (i = 0; i < moverCount; i++) { MoverPtr mover = getMover(list->getId(i)); if (mover->getWatchID() == pointWID) mover->selectionIndex = 0; else mover->selectionIndex = curIndex++; } } } break; case TACTICAL_ORDER_JUMPTO_POINT: case TACTICAL_ORDER_JUMPTO_OBJECT: { //----------------------------------------------------------- // Sort by distance to destination. Their selectionIndex will // be set to modify this goal... isJump = true; //------------------------------------------------------------------------- // We can assume that all movers in this group are jump-capable. Otherwise, // the group wouldn't be allowed to jump by the interface. In addition, // we KNOW that all movers in this group can jump to the selected // goal (of course, they won't due to terrain and crowding)... GameObjectPtr target = ObjectManager->getByWatchID(tacOrder.targetWID); if (jumpGoalList) for (long j = 0; j < numMovers; j++) goalList[j] = jumpGoalList[j]; else calcJumpGoals(tacOrder.getWayPoint(0), goalList, target); for (long i = 0; i < numMovers; i++) { MoverPtr mover = getMover(i); bool canJump = (goalList[i].x > -99000.0); if (canJump) mover->selectionIndex = 0; else mover->selectionIndex = -2; } } break; case TACTICAL_ORDER_TRAVERSE_PATH: case TACTICAL_ORDER_PATROL_PATH: case TACTICAL_ORDER_ESCORT: case TACTICAL_ORDER_FOLLOW: case TACTICAL_ORDER_GUARD: case TACTICAL_ORDER_STOP: case TACTICAL_ORDER_POWERUP: case TACTICAL_ORDER_POWERDOWN: case TACTICAL_ORDER_WAYPOINTS_DONE: case TACTICAL_ORDER_EJECT: case TACTICAL_ORDER_ATTACK_OBJECT: case TACTICAL_ORDER_ATTACK_POINT: case TACTICAL_ORDER_HOLD_FIRE: case TACTICAL_ORDER_WITHDRAW: case TACTICAL_ORDER_CAPTURE: case TACTICAL_ORDER_LOAD_INTO_CARRIER: case TACTICAL_ORDER_REFIT: case TACTICAL_ORDER_RECOVER: case TACTICAL_ORDER_GETFIXED: break; default: { char s[256]; sprintf(s, "Unit::handleTacticalOrder->Bad TacOrder Code (%d)", tacOrder.code); Assert(false, tacOrder.code, s); return(1); } } tacOrder.unitOrder = true; for (long i = 0; i < numMovers; i++) { MoverPtr mover = getMover(i); if (mover && !mover->isDisabled()) { if (mover->selectionIndex == -2) { mover->selectionIndex = -1; continue; } tacOrder.selectionIndex = mover->selectionIndex; if (tacOrder.selectionIndex != -1) { if (isMove) tacOrder.setWayPoint(0, location); else if (isJump) tacOrder.setWayPoint(0, goalList[i]); tacOrder.delayedTime = scenarioTime + (mover->selectionIndex * DelayedOrderTime); } switch (tacOrder.origin) { case ORDER_ORIGIN_PLAYER: if (queueGroupOrder) mover->getPilot()->addQueuedTacOrder(tacOrder); else { if (mover->getPilot()->getNumTacOrdersQueued()) //This is a hack to simply trigger the execution of //the queued orders. The current order is ignored (and //is simply used for this trigger)... mover->getPilot()->executeTacOrderQueue(); else mover->getPilot()->setPlayerTacOrder(tacOrder); } break; case ORDER_ORIGIN_COMMANDER: mover->getPilot()->setGeneralTacOrder(tacOrder); break; case ORDER_ORIGIN_SELF: mover->getPilot()->setAlarmTacOrder(tacOrder, priority); break; } mover->selectionIndex = -1; } } return(NO_ERR); }
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); }
//--------------------------------------------------------------------------- bool Team::teamLineOfSight(Stuff::Vector3D tPos, float extRad) { //----------------------------------------------------------- // For each member of the team, check LOS to point provided. for(size_t i = 0; i < rosterSize; i++) { MoverPtr obj = (MoverPtr)ObjectManager->getByWatchID(roster[i]); if(!obj->isDisabled() && !obj->isDestroyed() && (obj->getStatus() != OBJECT_STATUS_SHUTDOWN)) { Stuff::Vector3D distance; distance.Subtract(tPos, obj->getPosition()); float dist = distance.GetApproximateLength(); //Figure out altitude above minimum terrain altitude and look up in table. float baseElevation = MapData::waterDepth; if(MapData::waterDepth < Terrain::userMin) baseElevation = Terrain::userMin; float altitude = obj->getPosition().z - baseElevation; float altitudeIntegerRange = (Terrain::userMax - baseElevation) * 0.00390625f; int32_t altLevel = 0; if(altitudeIntegerRange > Stuff::SMALL) altLevel = altitude / altitudeIntegerRange; if(altLevel < 0) altLevel = 0; if(altLevel > 255) altLevel = 255; float radius = visualRangeTable[altLevel]; //Scouting specialty skill. if(obj->isMover()) { MoverPtr mover = (MoverPtr)obj; if(mover->pilot && mover->pilot->isScout()) radius += (radius * 0.2f); radius *= mover->getLOSFactor(); } if(dist <= (radius * 25.0f * worldUnitsPerMeter)) { if(lineOfSight(obj->getLOSPosition(), tPos, id, extRad, 0.0f, false)) return true; } } } //------------------------------------------------------------------------- // Check the lookout towers now. You can find them in special Buildings!! for(size_t spBuilding = 0; spBuilding < ObjectManager->numSpecialBuildings; spBuilding++) { if(ObjectManager->specialBuildings[spBuilding] && ObjectManager->specialBuildings[spBuilding]->getExists() && ObjectManager->specialBuildings[spBuilding]->isLookoutTower() && (ObjectManager->specialBuildings[spBuilding]->getTeamId() == id)) { GameObjectPtr obj = ObjectManager->specialBuildings[spBuilding]; if(!obj->isDisabled() && !obj->isDestroyed() && (obj->getStatus() != OBJECT_STATUS_SHUTDOWN)) { Stuff::Vector3D distance; distance.Subtract(tPos, obj->getPosition()); float dist = distance.GetApproximateLength(); //Figure out altitude above minimum terrain altitude and look up in table. float baseElevation = MapData::waterDepth; if(MapData::waterDepth < Terrain::userMin) baseElevation = Terrain::userMin; float altitude = obj->getPosition().z - baseElevation; float altitudeIntegerRange = (Terrain::userMax - baseElevation) * 0.00390625f; int32_t altLevel = 0; if(altitudeIntegerRange > Stuff::SMALL) altLevel = altitude / altitudeIntegerRange; if(altLevel < 0) altLevel = 0; if(altLevel > 255) altLevel = 255; float radius = visualRangeTable[altLevel]; //Scouting specialty skill. if(obj->isMover()) { MoverPtr mover = (MoverPtr)obj; if(mover->pilot && mover->pilot->isScout()) radius += (radius * 0.2f); radius *= mover->getLOSFactor(); } if(dist <= (radius * 25.0f * worldUnitsPerMeter)) { if(lineOfSight(obj->getLOSPosition(), tPos, id, 0.0f, obj->getAppearRadius(), false)) return true; } } } } return false; }