예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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;
	}



}
예제 #4
0
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);
}
예제 #5
0
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);
}
예제 #6
0
//---------------------------------------------------------------------------
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;
}