Ejemplo n.º 1
0
void SetFinalTile( SOLDIERTYPE *pSoldier, INT16 sGridNo, BOOLEAN fGivenUp )
{
	// OK, If we were waiting for stuff, do it here...

	// ATE: Disabled stuff below, made obsolete by timeout...
	//if ( pSoldier->ubWaitActionToDo  )
	//{
	//	pSoldier->ubWaitActionToDo = 0;
	//	gbNumMercsUntilWaitingOver--;
	//}
	pSoldier->sFinalDestination = pSoldier->sGridNo;

	#ifdef JA2BETAVERSION
		if ( gTacticalStatus.uiFlags & INCOMBAT )
		{
			OutputDebugInfoForTurnBasedNextTileWaiting( pSoldier );
		}
	#endif

  if ( pSoldier->bTeam == gbPlayerNum  && fGivenUp )
  {
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, TacticalStr[ NO_PATH_FOR_MERC ], pSoldier->name );
  }

	EVENT_StopMerc( pSoldier, pSoldier->sGridNo, pSoldier->bDirection );

}
Ejemplo n.º 2
0
UINT32 AddHistoryToPlayersLog(UINT8 ubCode, UINT8 ubSecondCode, UINT32 uiDate, INT16 sSectorX, INT16 sSectorY)
{
	// adds History item to player's log(History List), returns unique id number of it
	// outside of the History system(the code in this .c file), this is the only function you'll ever need
  UINT32 uiId=0;
  HistoryUnitPtr pHistory = pHistoryListHead;
  
	// clear the list
  ClearHistoryList( );

	// process the actual data
  uiId = ProcessAndEnterAHistoryRecord(ubCode, uiDate,  ubSecondCode, sSectorX, sSectorY, 0, 0);
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_HISTORY_UPDATED ] );
	
	// history list head
  pHistory = pHistoryListHead;
  
	// append to end of file
  AppendHistoryToEndOfFile( pHistory );
  
	
	// if in history mode, reload current page
  if( fInHistoryMode )
	{
	  iCurrentHistoryPage--;
    
		// load in first page
	  LoadNextHistoryPage( );
	}
 

	// return unique id of this transaction
	return uiId;
}
Ejemplo n.º 3
0
void EndUIPlan(  )
{
	int				cnt;
	SOLDIERTYPE *pSoldier;

	// Zero out any planned soldiers
	for( cnt = MAX_NUM_SOLDIERS; cnt < TOTAL_SOLDIERS; cnt++ )
	{
		pSoldier = MercPtrs[ cnt ];

		if ( pSoldier->bActive )
		{
			if ( pSoldier->sPlannedTargetX != -1 )
			{
				SetRenderFlags(RENDER_FLAG_FULL );
			}
			TacticalRemoveSoldier( pSoldier->ubID );
		}


	}
	gfInUIPlanMode			 = FALSE;
	gusSelectedSoldier   = gpUIStartPlannedSoldier->ubID;

	gfPlotNewMovement    = TRUE;

	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Leaving Planning Mode" );

}
Ejemplo n.º 4
0
void SetBoxingState( INT8 bNewState )
{
	if ( gTacticalStatus.bBoxingState == NOT_BOXING )
	{
		if ( bNewState != NOT_BOXING )
		{
			// pause time
			PauseGame();
		}
	}
	else
	{
		if ( bNewState == NOT_BOXING )
		{
			// unpause time
			UnPauseGame();

			if ( BoxersAvailable() == NUM_BOXERS )
			{
				// set one boxer to be set as boxed so that the game will allow another
				// fight to occur
				gfBoxerFought[ 0 ] = TRUE;
			}
		}
	}
	gTacticalStatus.bBoxingState = bNewState;
	#ifdef JA2TESTVERSION
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, L"Boxing state now %d", bNewState );
	#endif
}
Ejemplo n.º 5
0
void DisplayGameSettings( )
{
	//Display the version number
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s (%S)", pMessageStrings[ MSG_VERSION ], zVersionLabel, czVersionNumber );

	//Display the difficulty level
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_DIF_LEVEL_TEXT ], gzGIOScreenText[ gGameOptions.ubDifficultyLevel + GIO_EASY_TEXT - 1 ] );

	//Iron man option
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_GAME_SAVE_STYLE_TEXT ], gzGIOScreenText[ GIO_SAVE_ANYWHERE_TEXT + gGameOptions.fIronManMode ] );

	// Gun option 
	if( gGameOptions.fGunNut )
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_GUN_OPTIONS_TEXT ], gzGIOScreenText[ GIO_GUN_NUT_TEXT ] );
	else
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_GUN_OPTIONS_TEXT ], gzGIOScreenText[ GIO_REDUCED_GUNS_TEXT ] );

	//Sci fi option
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_GAME_STYLE_TEXT ], gzGIOScreenText[ GIO_REALISTIC_TEXT + gGameOptions.fSciFi ] );

	//Timed Turns option
	// JA2Gold: no timed turns
	//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s: %s", gzGIOScreenText[ GIO_TIMED_TURN_TITLE_TEXT ], gzGIOScreenText[ GIO_NO_TIMED_TURNS_TEXT + gGameOptions.fTurnTimeLimit ] );

	if( CHEATER_CHEAT_LEVEL() )
	{
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[58], CurrentPlayerProgressPercentage(), HighestPlayerProgressPercentage() );
	}
}
Ejemplo n.º 6
0
void SwitchMineViewOff()
{
	if (gubDrawModeMine == MINES_DRAW_OFF)
		return;

	gubDrawModeMine = MINES_DRAW_OFF;
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Turning off trap display");
	DisplayMines(TRUE);
}
Ejemplo n.º 7
0
void SwitchToHostileTrapsView()
{
	if (gubDrawModeMine == MINES_DRAW_DETECT_ENEMY)
		return;

	gubDrawModeMine = MINES_DRAW_DETECT_ENEMY;
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display nearby traps");
	DisplayMines(TRUE);
}
Ejemplo n.º 8
0
///BEGIN key binding functions
void SwitchToTrapNetworkView()
{
	if (gubDrawModeMine == MINES_DRAW_PLAYERTEAM_NETWORKS)
		return;

	gubDrawModeMine = MINES_DRAW_PLAYERTEAM_NETWORKS;
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network");
	DisplayMines(TRUE);
}
Ejemplo n.º 9
0
void SwitchViewOff()
{
	if (gubDrawMode == COVER_DRAW_OFF)
		return;

	gubDrawMode = COVER_DRAW_OFF;
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzDisplayCoverText[DC_MSG__COVER_DRAW_OFF]);
	DisplayCover(TRUE);
}
Ejemplo n.º 10
0
void SwitchToEnemyView()
{
	if (gubDrawMode == COVER_DRAW_ENEMY_VIEW)
		return;

	gubDrawMode = COVER_DRAW_ENEMY_VIEW;
	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzDisplayCoverText[DC_MSG__COVER_DRAW_ENEMY_VIEW]);
	DisplayCover(TRUE);
}
Ejemplo n.º 11
0
void
Campaign_Stats::AddMoneyEarned(UINT8 aType, INT32 aVal)
{
	if ( aType >= CAMPAIGN_MONEY_MAX )
	{
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Error: Unknown money type!" );
		return;
	}

	sMoneyEarned[aType] += aVal;
}
Ejemplo n.º 12
0
void
Campaign_Stats::AddConsumption(UINT8 aType, FLOAT aVal)
{
	if ( aType >= CAMPAIGN_CONSUMED_MAX )
	{
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Error: Unknown consumption type!" );
		return;
	}

	usConsumed[aType] += aVal;
}
Ejemplo n.º 13
0
void ChatLogMessage( UINT16 usColor, UINT8 ubPriority, STR16 pStringA, ... )
{
	// this function sets up the string into several single line structures

	//ScrollStringStPtr pStringSt;
	UINT32 uiFont = CHAT_MESSAGE_FONT;
	//STR16pString;
	va_list argptr;
	CHAR16	DestString[512];
	WRAPPED_STRING *pStringWrapper=NULL;
	WRAPPED_STRING *pStringWrapperHead=NULL;
	BOOLEAN fNewString = FALSE;
	UINT16	usLineWidthIfWordIsWiderThenWidth;


	/*pStringSt=pStringS;
	while(GetNextString(pStringSt))
		 pStringSt=GetNextString(pStringSt);*/

	va_start(argptr, pStringA);			// Set up variable argument pointer
	vswprintf(DestString, pStringA, argptr);	// process gprintf string (get output str)
	va_end(argptr);

	// send message to tactical screen and map screen
	ScreenMsg( usColor, ubPriority, DestString );
	
	pStringWrapperHead=LineWrap(uiFont, CHAT_LINE_WIDTH, &usLineWidthIfWordIsWiderThenWidth, DestString);
	pStringWrapper=pStringWrapperHead;
	if(!pStringWrapper)
	return;

	fNewString = TRUE;

	while(pStringWrapper->pNextWrappedString!=NULL)
	{
		AddStringToChatLogMessageList(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority );
		fNewString = FALSE;

		pStringWrapper=pStringWrapper->pNextWrappedString;
	}

	AddStringToChatLogMessageList(pStringWrapper->sString, usColor, uiFont, fNewString, ubPriority );


	// clear up list of wrapped strings
	ClearWrappedStringsCHAT( pStringWrapperHead );

	// play new message beep
	//PlayNewMessageSound( );

	MoveToEndOfChatScreenMessageList( );

	//LeaveMutex(SCROLL_MESSAGE_MUTEX, __LINE__, __FILE__);
}
Ejemplo n.º 14
0
void HourlyCamouflageUpdate( void )
{
	INT8 bMercID, bLastTeamID;
	SOLDIERTYPE * pSoldier;

	bMercID = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
	bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;

	// loop through all mercs
  for ( pSoldier = MercPtrs[ bMercID ]; bMercID <= bLastTeamID; bMercID++,pSoldier++)
	{	
		if ( pSoldier->bActive )
		{
			// if the merc has non-zero camo, degrade it by 1%
			if( ( pSoldier->bCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED) ) ) )
			{
				pSoldier->bCamo -= 2;
				if (pSoldier->bCamo <= 0)
				{
					pSoldier->bCamo = 0;
					// Reload palettes....
					if ( pSoldier->bInSector )
					{	
						CreateSoldierPalettes( pSoldier );
					}

					ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
					DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
				}
			}
			// if the merc has non-zero monster smell, degrade it by 1
			if ( pSoldier->bMonsterSmell > 0 )
			{
				pSoldier->bMonsterSmell--;

				/*
				if (pSoldier->bMonsterSmell == 0)
				{
					// Reload palettes....

					if ( pSoldier->bInSector )
					{	
						CreateSoldierPalettes( pSoldier );
					}

					ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
					DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );				
				}
				*/
			}
		}
	}
}
Ejemplo n.º 15
0
BOOLEAN BeginUIPlan( SOLDIERTYPE *pSoldier )
{
	gubNumUIPlannedMoves = 0;
	gpUIPlannedSoldier				= pSoldier;
	gpUIStartPlannedSoldier		= pSoldier;
	gfInUIPlanMode			 = TRUE;

	gfPlotNewMovement    = TRUE;

	ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Entering Planning Mode" );

	return( TRUE );
}
Ejemplo n.º 16
0
void SwitchMinesDrawModeForNetworks()
{
	switch ( gubDrawModeMine )
	{
		case MINES_DRAW_OFF:
		case MINES_DRAW_DETECT_ENEMY:
			gubDrawModeMine = MINES_DRAW_PLAYERTEAM_NETWORKS;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network");
			DisplayMines(TRUE);
			break;

		case MINES_DRAW_PLAYERTEAM_NETWORKS:
			gubDrawModeMine = MINES_DRAW_NETWORKCOLOURING;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network colouring");
			DisplayMines(TRUE);
			break;
		case MINES_DRAW_NETWORKCOLOURING:
			gubDrawModeMine = MINES_DRAW_NET_A;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network A");
			DisplayMines(TRUE);
			break;
		case MINES_DRAW_NET_A:
			gubDrawModeMine = MINES_DRAW_NET_B;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network B");
			DisplayMines(TRUE);
			break;
		case MINES_DRAW_NET_B:
			gubDrawModeMine = MINES_DRAW_NET_C;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network C");
			DisplayMines(TRUE);
			break;
		case MINES_DRAW_NET_C:
			gubDrawModeMine = MINES_DRAW_NET_D;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Display trap network D");
			DisplayMines(TRUE);
			break;
		case MINES_DRAW_NET_D:
		case MINES_DRAW_MAX:
		default:
			gubDrawModeMine = MINES_DRAW_OFF;
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Turning off trap display");
			DisplayMines(TRUE);
			break;
	}
}
Ejemplo n.º 17
0
// MercDailyUpdate() gets called every day at midnight.  If something is to happen to a merc that day, add an event for it.
void MercDailyUpdate()
{
	INT32		cnt;
	INT8		bLastTeamID;
	SOLDIERTYPE		*pSoldier;
	//SOLDIERTYPE *pQuitList[ 21 ];
	MERCPROFILESTRUCT *pProfile;
	UINT32 uiChance;
	INT32 iOffset = 0;
	BOOLEAN fFoundSomeOneForMenuShowing = FALSE;

	//if its the first day, leave
	if( GetWorldDay() == 1 )
		return;

	// debug message
	ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s - Doing MercDailyUpdate", WORLDTIMESTR );

	// if the death rate is very low (this is independent of mercs' personal deathrate tolerances)
	if (CalcDeathRate() < 5)
	{
		// everyone gets a morale bonus, which also gets player a reputation bonus.
		HandleMoraleEvent( NULL, MORALE_LOW_DEATHRATE, -1, -1, -1 );
	}


	//add an event so the merc will say the departing warning ( 2 hours prior to leaving
	// Do so for all time slots they will depart from
	AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_1 - ( 2 * 60 ),	0 );
	AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_2 - ( 2 * 60 ),	0 );
	AddSameDayStrategicEvent( EVENT_MERC_ABOUT_TO_LEAVE, MERC_ARRIVE_TIME_SLOT_3 - ( 2 * 60 ),	0 );


	AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_1,	0 );
	AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_2,	0 );
	AddSameDayStrategicEvent( EVENT_BEGIN_CONTRACT_RENEWAL_SEQUENCE, MERC_ARRIVE_TIME_SLOT_3,	0 );


	cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
	bLastTeamID = gTacticalStatus.Team[ gbPlayerNum ].bLastID;

	
	
	//loop though all the mercs
  for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++)
	{
		//if the merc is active
		if ( ( pSoldier->bActive )&&( pSoldier->bAssignment != ASSIGNMENT_POW ) && ( pSoldier->bAssignment != IN_TRANSIT ) )
		{
			//CJC: Reset dialogue flags for quotes that can be said once/day
			pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_ANNOYING_MERC );
			// ATE: Reset likes gun flag
			pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_LIKESGUN );
			// ATE: Reset seen corpse flag
			pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_ROTTINGCORPSE );
			// ATE; Reset found something nice flag...
			pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_FOUND_SOMETHING_NICE );

      // ATE: Decrement tolerance value...
      pSoldier->bCorpseQuoteTolerance--;

      if ( pSoldier->bCorpseQuoteTolerance < 0 )
      {
        pSoldier->bCorpseQuoteTolerance = 0;
      }

			// CJC: For some personalities, reset personality quote said flag
			if ( pSoldier->ubProfile != NO_PROFILE )
			{
				switch( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait )
				{
					case HEAT_INTOLERANT:
					case CLAUSTROPHOBIC:
					case NONSWIMMER:
					case FEAR_OF_INSECTS:
						// repeatable once per day
						pSoldier->usQuoteSaidFlags &= ( ~SOLDIER_QUOTE_SAID_PERSONALITY );
						break;
					default:
						break;
				}
			}


			//ATE: Try to see if our equipment sucks!
			if ( SoldierHasWorseEquipmentThanUsedTo( pSoldier ) )
			{
				// Randomly anytime between 6:00, and 10:00
				AddSameDayStrategicEvent( EVENT_MERC_COMPLAIN_EQUIPMENT, 360 + Random( 1080 ) , pSoldier->ubProfile );
			}

			// increment days served by this grunt
			gMercProfiles[pSoldier->ubProfile].usTotalDaysServed++;

			// player has hired him, so he'll eligible to get killed off on another job
			gMercProfiles[pSoldier->ubProfile].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE;
			
			
			//if the character is an RPC
			if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
			{
				INT16	sSalary = gMercProfiles[ pSoldier->ubProfile ].sSalary;
				INT32	iMoneyOwedToMerc = 0;  

				//increment the number of days the mercs has been on the team
				pSoldier->iTotalContractLength++;

				//if the player owes the npc money, the balance field will be negative
				if( gMercProfiles[ pSoldier->ubProfile ].iBalance < 0 )
				{
					//the player owes the npc the salary and whatever money the player owes the npc
					iMoneyOwedToMerc = sSalary + ( - gMercProfiles[ pSoldier->ubProfile ].iBalance );
				}
				else
				{
					//else the player only owes the salary
					iMoneyOwedToMerc = sSalary;
				}

				//if the player owes money
				if( iMoneyOwedToMerc != 0 )
				{
					//if the player can afford to pay them
					if( LaptopSaveInfo.iCurrentBalance >= iMoneyOwedToMerc )
					{
						//add the transaction to the player
						AddTransactionToPlayersBook( PAYMENT_TO_NPC, pSoldier->ubProfile, GetWorldTotalMin(), -iMoneyOwedToMerc);

						//if the player owed money to the npc
						if( gMercProfiles[ pSoldier->ubProfile ].iBalance < 0 )
						{
							// reset the amount
							gMercProfiles[ pSoldier->ubProfile ].iBalance = 0;
						}
					}
					else
					{
						CHAR16	zMoney[128];

						//create a string for the salary owed to the npc
						swprintf( zMoney, L"%d", sSalary );
						InsertCommasForDollarFigure( zMoney );
						InsertDollarSignInToString( zMoney );

						//Display a screen msg indicating that the npc was NOT paid
						ScreenMsg( FONT_MCOLOR_WHITE, MSG_INTERFACE, pMessageStrings[ MSG_CANT_AFFORD_TO_PAY_NPC_DAILY_SALARY_MSG ], gMercProfiles[ pSoldier->ubProfile ].zNickname, zMoney );

						//if the merc hasnt been paid for NUM_DAYS_TILL_UNPAID_RPC_QUITS days, the merc will quit
						if( ( gMercProfiles[ pSoldier->ubProfile ].iBalance - sSalary ) <= -( sSalary * NUM_DAYS_TILL_UNPAID_RPC_QUITS ) )
						{
							//
							//Set it up so the merc quits
							//
							MercsContractIsFinished( pSoldier->ubID );
						}
						else
						{
							//set how much money the player owes the merc
							gMercProfiles[ pSoldier->ubProfile ].iBalance -= sSalary;

							// Add even for displaying a dialogue telling the player this....
							AddSameDayStrategicEvent( EVENT_RPC_WHINE_ABOUT_PAY, MERC_ARRIVE_TIME_SLOT_1, pSoldier->ubID );

						}
					}
				}
			}


			DailyMoraleUpdate( pSoldier );

			CheckIfMercGetsAnotherContract( pSoldier );
		}
		else
		{
			if( ( pSoldier->bActive ) && ( pSoldier->bAssignment == ASSIGNMENT_POW ) )
			{
				pSoldier->iEndofContractTime += 1440;
			}
		}

		// if active, here, & alive (POW is ok, don't care)
		if( ( pSoldier->bActive ) && ( pSoldier->bAssignment != ASSIGNMENT_DEAD ) &&
																 ( pSoldier->bAssignment != IN_TRANSIT ) )
		{
			// increment the "man days" played counter for each such merc in the player's employment
			gStrategicStatus.uiManDaysPlayed++;
		}
	}

	//r eset the counter
	cnt = 0;

	for ( pSoldier = MercPtrs[ cnt ]; cnt <= bLastTeamID; cnt++,pSoldier++)
	{
		//if the merc is active
		if ( ( pSoldier->bActive )&&( pSoldier->bAssignment != ASSIGNMENT_POW ) && ( pSoldier->bAssignment != IN_TRANSIT ) )
		{
			//if its a MERC merc, determine if the merc should leave ( because player refused to pay for merc )
			if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC )
			{
				//if the players account status is invalid
				if( LaptopSaveInfo.gubPlayersMercAccountStatus == MERC_ACCOUNT_INVALID )
				{
					//if the soldier is alive anc concious
					if( IsTheSoldierAliveAndConcious( pSoldier ) )
					{
						//if the merc should leave today
						MercsContractIsFinished( pSoldier->ubID );
					}
				}
			}
		}
	}

	//Loop through all the profiles
	for( cnt = 0; cnt < NUM_PROFILES; cnt++)
	{
		pProfile = &(gMercProfiles[ cnt ]);

		// dead guys don't do nuthin' !
		if ( pProfile->bMercStatus == MERC_IS_DEAD )
		{
			continue;
		}

		//Every day reset this variable
		pProfile->uiPrecedentQuoteSaid = 0;

		// skip anyone currently on the player's team
		if ( IsMercOnTeam( (UINT8) cnt ))
		{
			continue;
		}

		// if he's an AIM/M.E.R.C. merc
		if ( cnt < AIM_AND_MERC_MERCS )
		{
			// if he's not just on his way home
			if ( pProfile->bMercStatus != MERC_RETURNING_HOME )
			{
				// check if any of his stats improve through working or training
				HandleUnhiredMercImprovement(pProfile);

				// if he's working on another job
				if (pProfile->bMercStatus == MERC_WORKING_ELSEWHERE)
				{
					// check if he's killed
					HandleUnhiredMercDeaths( cnt );
				}
			}
		}

		// if merc is currently unavailable
		if( pProfile->uiDayBecomesAvailable > 0 )
		{
			// reduce time til available by one day
			pProfile->uiDayBecomesAvailable--;

			// Check to see if the merc has become available
			if (pProfile->uiDayBecomesAvailable == 0)
			{
				//if the merc CAN become ready
				if( pProfile->bMercStatus != MERC_FIRED_AS_A_POW )
				{
					pProfile->bMercStatus = MERC_OK;			

					// if the player has left a message for this merc
					if ( pProfile->ubMiscFlags3 & PROFILE_MISC_FLAG3_PLAYER_LEFT_MSG_FOR_MERC_AT_AIM )
					{
						iOffset = AIM_REPLY_BARRY;

						//remove the Flag, so if the merc goes on another assignment, the player can leave an email.
						pProfile->ubMiscFlags3 &= ~PROFILE_MISC_FLAG3_PLAYER_LEFT_MSG_FOR_MERC_AT_AIM;

						// TO DO: send E-mail to player telling him the merc has returned from an assignment
						AddEmail( ( UINT8 )( iOffset + ( cnt * AIM_REPLY_LENGTH_BARRY ) ), AIM_REPLY_LENGTH_BARRY, ( UINT8 )( 6 + cnt ), GetWorldTotalMin() );
					}
				}
			}
		}
		else	// was already available today
		{
			// if it's an AIM or M.E.R.C. merc
			if (cnt < AIM_AND_MERC_MERCS)
			{
				// check to see if he goes on another assignment
				if (cnt < MAX_NUMBER_MERCS)
				{
					// A.I.M. merc
					uiChance = 2 * pProfile->bExpLevel;

					// player has now had a chance to hire him, so he'll eligible to get killed off on another job
					pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE;
				}
				else
				{
					// M.E.R.C. merc - very rarely get other work
					uiChance = 1 * pProfile->bExpLevel;

					// player doesn't have a chance to hire any M.E.R.C's until after Speck's E-mail is sent
					if (GetWorldDay() > DAYS_TIL_M_E_R_C_AVAIL)
					{
						// player has now had a chance to hire him, so he'll eligible to get killed off on another job
						pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE;
					}
				}

				if (Random(100) < uiChance)
				{
					pProfile->bMercStatus = MERC_WORKING_ELSEWHERE;
					pProfile->uiDayBecomesAvailable = 1 + Random(6 + (pProfile->bExpLevel / 2) );		// 1-(6 to 11) days
				}
			}
		}

		// Decrement morale hangover (merc appears hirable, he just gives lame refusals during this time, though)
		if( pProfile->ubDaysOfMoraleHangover > 0 )
		{
			pProfile->ubDaysOfMoraleHangover--;
		}
	}


	// build quit list
	//BuildMercQuitList( pQuitList );
	HandleSlayDailyEvent( );

	// rebuild list for mapscreen
	ReBuildCharactersList( );	
}
Ejemplo n.º 18
0
void CountPeopleInBoxingRingAndDoActions( void )
{
	UINT32				uiLoop;
	UINT8				ubTotalInRing = 0;
	//DBrot: More Rooms
	UINT16				usRoom;
	UINT16				ubPlayersInRing = 0;
	SOLDIERTYPE *		pSoldier;
	SOLDIERTYPE *		pInRing[2] = { NULL, NULL };
	SOLDIERTYPE *		pNonBoxingPlayer = NULL;

	for ( uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop )
	{
		pSoldier = MercSlots[ uiLoop ];

		if ( pSoldier != NULL )
		{
			if ( InARoom( pSoldier->sGridNo, &usRoom ) && usRoom == BOXING_RING)
			{
				if ( ubTotalInRing < 2 )
				{
					pInRing[ ubTotalInRing ] = pSoldier;
				}
				++ubTotalInRing;

				if ( pSoldier->flags.uiStatusFlags & SOLDIER_PC )
				{
					++ubPlayersInRing;

					if ( !pNonBoxingPlayer && !(pSoldier->flags.uiStatusFlags & SOLDIER_BOXER) )
					{
						pNonBoxingPlayer = pSoldier;
					}
				}
			}
		}
	}

	if ( ubPlayersInRing > 1 )
	{
		// boxing match just became invalid!
		if ( gTacticalStatus.bBoxingState <= PRE_BOXING )
		{
			BoxingPlayerDisqualified( pNonBoxingPlayer, NON_BOXER_IN_RING );
			// set to not in boxing or it won't be handled otherwise
			SetBoxingState( NOT_BOXING );
		}
		else
		{
			BoxingPlayerDisqualified( pNonBoxingPlayer, NON_BOXER_IN_RING );
		}

		return;
	}

	if ( gTacticalStatus.bBoxingState == BOXING_WAITING_FOR_PLAYER )
	{
		if ( ubTotalInRing == 1 && ubPlayersInRing == 1 )
		{
			// time to go to pre-boxing
			SetBoxingState( PRE_BOXING );
			PickABoxer();
		}
	}
	else
	{
		// if pre-boxing, check for two people (from different teams!) in the ring
		if (gTacticalStatus.bBoxingState == PRE_BOXING)
		{
			if (ubTotalInRing == 2 && ubPlayersInRing == 1)
			{
				// ladieees and gennleman, we have a fight!
				for (uiLoop = 0; uiLoop < 2; ++uiLoop)
				{
					if (!(pInRing[uiLoop]->flags.uiStatusFlags & SOLDIER_BOXER))
					{
						// set as boxer!
						pInRing[uiLoop]->flags.uiStatusFlags |= SOLDIER_BOXER;
					}
				}
				// start match!
				SetBoxingState(BOXING);
				gfLastBoxingMatchWonByPlayer = FALSE;

#ifdef JA2TESTVERSION
				ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Boxer APs %d %d", pInRing[0]->bActionPoints, pInRing[1]->bActionPoints );
#endif
				// give the first turn to a randomly chosen boxer
				EnterCombatMode(pInRing[Random(2)]->bTeam);
			}
		}
		/*
		else
		{
		// check to see if the player has more than one person in the ring
		if ( ubPlayersInRing > 1 )
		{
		// boxing match just became invalid!
		BoxingPlayerDisqualified( pNonBoxingPlayer, NON_BOXER_IN_RING );
		return;
		}
		}
		*/
	}
}
Ejemplo n.º 19
0
BOOLEAN CanExchangePlaces( SOLDIERTYPE *pSoldier1, SOLDIERTYPE *pSoldier2, BOOLEAN fShow )
{
	// NB checks outside of this function 
	if ( EnoughPoints( pSoldier1, AP_EXCHANGE_PLACES, 0, fShow ) )
	{
	  if ( EnoughPoints( pSoldier2, AP_EXCHANGE_PLACES, 0, fShow ) )
	  {
      if ( ( gAnimControl[ pSoldier2->usAnimState ].uiFlags & ANIM_MOVING ) )
      {
        return( FALSE );
      }

      if ( ( gAnimControl[ pSoldier1->usAnimState ].uiFlags & ANIM_MOVING ) && !(gTacticalStatus.uiFlags & INCOMBAT) )
      {
        return( FALSE );
      }

		  if ( pSoldier2->bSide == 0 )
		  {
			  return( TRUE );
		  }

      // hehe - don't allow animals to exchange places
      if ( pSoldier2->uiStatusFlags & ( SOLDIER_ANIMAL ) )
      {
        return( FALSE );
      }

      // must NOT be hostile, must NOT have stationary orders OR militia team, must be >= OKLIFE
      if ( pSoldier2->bNeutral && pSoldier2->bLife >= OKLIFE && 
			     pSoldier2->ubCivilianGroup != HICKS_CIV_GROUP && 
			   ( ( pSoldier2->bOrders != STATIONARY || pSoldier2->bTeam == MILITIA_TEAM ) || 
			   ( pSoldier2->sAbsoluteFinalDestination != NOWHERE && pSoldier2->sAbsoluteFinalDestination != pSoldier2->sGridNo ) ) )
      {
        return( TRUE );
      }

		  if ( fShow )
		  {
        if ( pSoldier2->ubProfile == NO_PROFILE )
        {
				  ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, TacticalStr[ REFUSE_EXCHANGE_PLACES ] );
        }
        else
        {
				  ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[3], pSoldier2->name );
        }
		  }

		  // ATE: OK, reduce this guy's next ai counter....
		  pSoldier2->uiAIDelay = 100;

		  return( FALSE );
	  }
	  else
	  {
		  return( FALSE );
	  }
  }
	else
	{
		return( FALSE );
	}
	return( TRUE );
}
Ejemplo n.º 20
0
void DisplayRangeToTarget( SOLDIERTYPE *pSoldier, INT32 sTargetGridNo )
{
	UINT16 usRange=0;
	CHAR16	zOutputString[512];
	UINT8	title = (UsingNewCTHSystem() == true ? DC_MSG__NCTH_GUN_RANGE_INFORMATION : DC_MSG__GUN_RANGE_INFORMATION);

	if( sTargetGridNo == NOWHERE || sTargetGridNo == 0 )
	{
		return;
	}

	{
		UINT8 ubLightLevel = LightTrueLevel(sTargetGridNo, gsInterfaceLevel);
		UINT8 ubBrightness = 100 - 100 * (ubLightLevel-SHADE_MAX)/(SHADE_MIN-SHADE_MAX); // percentage
		
		UINT8 ubTerrainType = NO_TERRAIN; 

		// anv: additional tile properties
		ADDITIONAL_TILE_PROPERTIES_VALUES zGivenTileProperties;
		memset(&zGivenTileProperties,0,sizeof(zGivenTileProperties));
		if(gGameExternalOptions.fAdditionalTileProperties)
		{
			zGivenTileProperties = GetAllAdditonalTilePropertiesForGrid(sTargetGridNo, gsInterfaceLevel);
		}
		else
		{
			ubTerrainType = GetTerrainTypeForGrid(sTargetGridNo, gsInterfaceLevel);
		}

		INT8 ubCover = - GetSightAdjustment(pSoldier, sTargetGridNo, gsInterfaceLevel);

		//display a string with cover value of current selected merc and brightness
		//swprintf( zOutputString, gzDisplayCoverText[DC_MSG__COVER_INFORMATION], ubCover, GetTerrainName(ubTerrainType), ubBrightness );

		//Display the msg
		//ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );

		if(gGameExternalOptions.fAdditionalTileProperties)
		{
			if(!gGameExternalOptions.fCoverTooltipDetailedTileProperties)
			{
				ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE,
					gzDisplayCoverText[DC_MSG__COVER_INFORMATION],
					ubCover, GetDetailedTerrainName(zGivenTileProperties), ubBrightness );
			}
			else
			{
				ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE,
					gzDisplayCoverText[DC_MSG__COVER_INFORMATION_WITH_DETAILED_CAMO],
					ubCover, ubBrightness );

				UINT8 ubApplicableProperties = 0;
				swprintf( zOutputString, L"" );
				if(zGivenTileProperties.bWoodCamoAffinity > 0)
				{
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__WOOD]);
					swprintf( zOutputString + wcslen(zOutputString), L": %d/100", zGivenTileProperties.bWoodCamoAffinity);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bDesertCamoAffinity > 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__DESERT]);
					swprintf( zOutputString + wcslen(zOutputString), L": %d/100", zGivenTileProperties.bDesertCamoAffinity);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bUrbanCamoAffinity > 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__URBAN]);
					swprintf( zOutputString + wcslen(zOutputString), L": %d/100", zGivenTileProperties.bUrbanCamoAffinity);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bSnowCamoAffinity > 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__SNOW]);
					swprintf( zOutputString + wcslen(zOutputString), L": %d/100", zGivenTileProperties.bSnowCamoAffinity);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bSoundModifier != 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__DETAILED_SOUND]);
					if(zGivenTileProperties.bSoundModifier > 0)
						swprintf( zOutputString + wcslen(zOutputString), L": +%d", zGivenTileProperties.bSoundModifier);
					else
						swprintf( zOutputString + wcslen(zOutputString), L": %d", zGivenTileProperties.bSoundModifier);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bStealthDifficultyModifer != 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__DETAILED_STEALTH]);
					if(zGivenTileProperties.bStealthDifficultyModifer > 0)
						swprintf( zOutputString + wcslen(zOutputString), L": +%d/100", zGivenTileProperties.bStealthDifficultyModifer);
					else
						swprintf( zOutputString + wcslen(zOutputString), L": %d/100", zGivenTileProperties.bStealthDifficultyModifer);
					ubApplicableProperties++;
				}
				if(zGivenTileProperties.bTrapBonus != 0)
				{
					if(ubApplicableProperties)
						swprintf( zOutputString + wcslen(zOutputString), L", ");
					swprintf( zOutputString + wcslen(zOutputString), gzDisplayCoverText[DC_TTI__DETAILED_TRAP_LEVEL]);
					if(zGivenTileProperties.bTrapBonus > 0)
						swprintf( zOutputString + wcslen(zOutputString), L": +%d", zGivenTileProperties.bTrapBonus);
					else
						swprintf( zOutputString + wcslen(zOutputString), L": %d", zGivenTileProperties.bTrapBonus);
					ubApplicableProperties++;
				}
				if( wcslen(zOutputString) > 0 )
					ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
			}
		}
		else
		{
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE,
				gzDisplayCoverText[DC_MSG__COVER_INFORMATION],
				ubCover, GetTerrainName(ubTerrainType), ubBrightness );
		}
	}

	//Get the range to the target location
	usRange = GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo, sTargetGridNo );

	//if the soldier has a weapon in hand, display gun range and chance to hit
	if( WeaponInHand( pSoldier ) )
	{
		UINT32 uiHitChance;
		//AXP 30.03.2007: Fix CtH calculation for first shot after changing aim level (roof/ground)
		INT8 bTempTargetLevel = pSoldier->bTargetLevel;
		pSoldier->bTargetLevel = (INT8)gsInterfaceLevel;
		uiHitChance = CalcChanceToHitGun( pSoldier, sTargetGridNo, (INT8)(pSoldier->aiData.bShownAimTime ), pSoldier->bAimShotLocation );
		// HEADROCK HAM B2.7: CTH approximation?
		if (gGameExternalOptions.fApproximateCTH)
		{	
			uiHitChance = ChanceToHitApproximation( pSoldier, uiHitChance );
		}
		pSoldier->bTargetLevel = bTempTargetLevel;

		// HEADROCK HAM 3.6: Calculate Gun Range using formula.
		// Flugente: we might be equipped with an underbarrel gun....
		OBJECTTYPE* pObjhand = pSoldier->GetUsedWeapon(&pSoldier->inv[HANDPOS]);
		UINT16 usGunRange = GunRange(pObjhand, pSoldier ); // SANDRO - added argument

		swprintf( zOutputString, gzDisplayCoverText[title], usRange / 10, usGunRange / 10, uiHitChance );
		//Display the msg
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
	}
	else
	{
		swprintf( zOutputString, gzDisplayCoverText[title], usRange / 10, 0, 0 );

		//Display the msg
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, zOutputString );
	}

	//increment the display gun range counter ( just seeing how many times people use it )
	//gJa25SaveStruct.uiDisplayGunRangeCounter++;
}
Ejemplo n.º 21
0
void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
{
	UINT8 ubHeadMinerIndex = 0;
	UINT16 usHeadMinerProfileId = 0;
	INT8 bQuoteNum = 0;
	UINT8 ubFaceIndex = 0;
	BOOLEAN fForceMapscreen = FALSE;
	INT16 sXPos, sYPos;


	Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) );
	Assert( ubQuoteType < NUM_HEAD_MINER_STRATEGIC_QUOTES );
	Assert( CheckFact( FACT_MINERS_PLACED, 0 ) );

	ubHeadMinerIndex = GetHeadMinerIndexForMine( bMineIndex );
	usHeadMinerProfileId = gHeadMinerData[ ubHeadMinerIndex ].usProfileId;

	// make sure the miner ain't dead
	if (gMercProfiles[ usHeadMinerProfileId ].bLife < OKLIFE)
	{
		// debug message
		ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"Head Miner #%s can't talk (quote #%d)", gMercProfiles[ usHeadMinerProfileId ].zNickname, ubQuoteType);
		return;
	}

	bQuoteNum = gHeadMinerData[ ubHeadMinerIndex ].bQuoteNum[ ubQuoteType ];
	Assert( bQuoteNum != -1 );

	ubFaceIndex = ( UINT8 ) uiExternalStaticNPCFaces[ gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace ];

	// transition to mapscreen is not necessary for "creatures gone" quote - player is IN that mine, so he'll know
	if ( ubQuoteType != HEAD_MINER_STRATEGIC_QUOTE_CREATURES_GONE )
	{
		fForceMapscreen = TRUE;
	}


	// decide where the miner's face and text box should be positioned in order to not obscure the mine he's in as it flashes
	switch ( bMineIndex )
	{
		case MINE_GRUMM:
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = DEFAULT_EXTERN_PANEL_Y_POS;
			break;
		case MINE_CAMBRIA:
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = DEFAULT_EXTERN_PANEL_Y_POS;
			break;
		case MINE_ALMA:
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = DEFAULT_EXTERN_PANEL_Y_POS;
			break;
		case MINE_DRASSEN:
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = 135;
			break;
		case MINE_CHITZENA:
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = 117;
			break;

		// there's no head miner in San Mona, this is an error!
		case MINE_SAN_MONA:
		default:
			Assert( FALSE );
			sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = DEFAULT_EXTERN_PANEL_Y_POS;
			break;
	}

	SetExternMapscreenSpeechPanelXY( sXPos, sYPos );

	// cause this quote to come up for this profile id and an indicator to flash over the mine sector
	HandleMinerEvent( gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace, gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY, (INT16) bQuoteNum, fForceMapscreen );

	// stop time compression with any miner quote - these are important events.
	StopTimeCompression();
}
Ejemplo n.º 22
0
//Because loading and saving the map takes a few seconds, we want to post a message
//on the screen and then update it which requires passing the screen back to the main loop.
//When we come back for the next frame, we then actually save or load the map.  So this
//process takes two full screen cycles.
UINT32 ProcessFileIO()
{
    INT16 usStartX, usStartY;
    UINT8 ubNewFilename[50];
    switch( gbCurrentFileIOStatus )
    {
    case INITIATE_MAP_SAVE:	//draw save message
        StartFrameBufferRender( );
        SaveFontSettings();
        SetFont( HUGEFONT );
        SetFontForeground( FONT_LTKHAKI );
        SetFontShadow( FONT_DKKHAKI );
        SetFontBackground( 0 );
        swprintf( zOrigName, L"Saving map:  %s", gzFilename );
        usStartX = 320 - StringPixLength( zOrigName, LARGEFONT1 ) / 2;
        usStartY = 180 - GetFontHeight( LARGEFONT1 ) / 2;
        mprintf( usStartX, usStartY, zOrigName );

        InvalidateScreen( );
        EndFrameBufferRender( );
        gbCurrentFileIOStatus = SAVING_MAP;
        return LOADSAVE_SCREEN;
    case SAVING_MAP: //save map
        sprintf( ubNewFilename, "%S", gzFilename );
        RaiseWorldLand();
        if( gfShowPits )
            RemoveAllPits();
        OptimizeSchedules();
        if ( !SaveWorld( ubNewFilename ) )
        {
            if( gfErrorCatch )
            {
                InitErrorCatchDialog();
                return EDIT_SCREEN;
            }
            return ERROR_SCREEN;
        }
        if( gfShowPits )
            AddAllPits();

        SetGlobalSectorValues( gzFilename );

        if( gfGlobalSummaryExists )
            UpdateSectorSummary( gzFilename, gfUpdateSummaryInfo );

        iCurrentAction = ACTION_NULL;
        gbCurrentFileIOStatus = IOSTATUS_NONE;
        gfRenderWorld = TRUE;
        gfRenderTaskbar = TRUE;
        fEnteringLoadSaveScreen = TRUE;
        RestoreFontSettings();
        if( gfErrorCatch )
        {
            InitErrorCatchDialog();
            return EDIT_SCREEN;
        }
        if( gMapInformation.ubMapVersion != gubMinorMapVersion )
            ScreenMsg( FONT_MCOLOR_RED, MSG_ERROR, L"Map data has just been corrupted!!!  What did you just do?  KM : 0" );
        return EDIT_SCREEN;
    case INITIATE_MAP_LOAD: //draw load message
        SaveFontSettings();
        gbCurrentFileIOStatus = LOADING_MAP;
        if( gfEditMode && iCurrentTaskbar == TASK_MERCS )
            IndicateSelectedMerc( SELECT_NO_MERC );
        SpecifyItemToEdit( NULL, -1 );
        return LOADSAVE_SCREEN;
    case LOADING_MAP: //load map
        DisableUndo();
        sprintf( ubNewFilename, "%S", gzFilename );

        RemoveMercsInSector( );

        if( !LoadWorld( ubNewFilename ) )
        {   //Want to override crash, so user can do something else.
            EnableUndo();
            SetPendingNewScreen( LOADSAVE_SCREEN );
            gbCurrentFileIOStatus = IOSTATUS_NONE;
            gfGlobalError = FALSE;
            gfLoadError = TRUE;
            //RemoveButton( iTempButton );
            CreateMessageBox( L" Error loading file.  Try another filename?" );
            return LOADSAVE_SCREEN;
        }
        SetGlobalSectorValues( gzFilename );

        RestoreFontSettings();

        //Load successful, update necessary information.

        //ATE: Any current mercs are transfered here...
        //UpdateMercsInSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );

        AddSoldierInitListTeamToWorld( ENEMY_TEAM,		255 );
        AddSoldierInitListTeamToWorld( CREATURE_TEAM, 255 );
        AddSoldierInitListTeamToWorld( MILITIA_TEAM,	255 );
        AddSoldierInitListTeamToWorld( CIV_TEAM,			255 );
        iCurrentAction = ACTION_NULL;
        gbCurrentFileIOStatus = IOSTATUS_NONE;
        if( !gfCaves && !gfBasement )
        {
            gusLightLevel = 12;
            if( ubAmbientLightLevel != 4 )
            {
                ubAmbientLightLevel = 4;
                LightSetBaseLevel( ubAmbientLightLevel );
            }
        }
        else
            gusLightLevel = (UINT16)(EDITOR_LIGHT_MAX - ubAmbientLightLevel );
        gEditorLightColor = gpLightColors[ 0 ];
        gfRenderWorld = TRUE;
        gfRenderTaskbar = TRUE;
        fEnteringLoadSaveScreen = TRUE;
        InitJA2SelectionWindow();
        ShowEntryPoints();
        EnableUndo();
        RemoveAllFromUndoList();
        SetEditorSmoothingMode( gMapInformation.ubEditorSmoothingType );
        if( gMapInformation.ubEditorSmoothingType == SMOOTHING_CAVES )
            AnalyseCaveMapForStructureInfo();

        AddLockedDoorCursors();
        gubCurrRoomNumber = gubMaxRoomNumber;
        UpdateRoofsView();
        UpdateWallsView();
        ShowLightPositionHandles();
        SetMercTeamVisibility( ENEMY_TEAM, gfShowEnemies );
        SetMercTeamVisibility( CREATURE_TEAM, gfShowCreatures );
        SetMercTeamVisibility( MILITIA_TEAM, gfShowRebels );
        SetMercTeamVisibility( CIV_TEAM, gfShowCivilians );
        BuildItemPoolList();
        if( gfShowPits )
            AddAllPits();

        if( iCurrentTaskbar == TASK_MAPINFO )
        {   //We have to temporarily remove the current textinput mode,
            //update the disabled text field values, then restore the current
            //text input fields.
            SaveAndRemoveCurrentTextInputMode();
            UpdateMapInfoFields();
            RestoreSavedTextInputMode();
        }
        return EDIT_SCREEN;
    }
    gbCurrentFileIOStatus = IOSTATUS_NONE;
    return LOADSAVE_SCREEN;
}
Ejemplo n.º 23
0
        void LegacyAIPlan::execute(PlanInputData& environment)
        {
            if(!environment.turn_based())
            {
                if ( (get_npc()->ubProfile != NO_PROFILE) && (gMercProfiles[ get_npc()->ubProfile ].ubMiscFlags3 & PROFILE_MISC_FLAG3_HANDLE_DONE_TRAVERSAL ) )
                {
                    TriggerNPCWithGivenApproach( get_npc()->ubProfile, APPROACH_DONE_TRAVERSAL, FALSE );
                    gMercProfiles[ get_npc()->ubProfile ].ubMiscFlags3 &= (~PROFILE_MISC_FLAG3_HANDLE_DONE_TRAVERSAL);
                    get_npc()->ubQuoteActionID = 0;
                    // wait a tiny bit
                    get_npc()->aiData.usActionData = 100;
                    get_npc()->aiData.bAction =  AI_ACTION_WAIT;
                    return;
                }
                if (get_npc()->bTeam == gbPlayerNum)
                {
                    if (environment.get_tactical_status().fAutoBandageMode)
                    {
                        get_npc()->aiData.bAction = DecideAutoBandage( get_npc() );
                        return;
                    }
                }
            }

            if ( get_npc()->bTeam != MILITIA_TEAM )
            {
                if ( !sniperwarning && get_npc()->aiData.bOrders == SNIPER )
                {
                    ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_WATHCHOUTFORSNIPERS] );
                    sniperwarning = TRUE;
                }

                if (!biggunwarning && FindRocketLauncherOrCannon(get_npc()) != NO_SLOT )
                {
                    biggunwarning = TRUE;
                    //TODO: don't say this again after reloading a savegame
                    SayQuoteFromAnyBodyInSector( QUOTE_WEARY_SLASH_SUSPUCIOUS );
                }
            }
            get_npc()->aiData.fAIFlags &= (~AI_CAUTIOUS); // turn off cautious flag
            // if status override is set, bypass RED/YELLOW and go directly to GREEN!
            if ((get_npc()->aiData.bBypassToGreen) && (get_npc()->aiData.bAlertStatus < STATUS_BLACK))
            {
                get_npc()->aiData.bAction = DecideActionGreen(get_npc());
                if ( !gfTurnBasedAI )
                {
                    // reset bypass now
                    get_npc()->aiData.bBypassToGreen = 0;
                }
            }
            else
            {
                switch (get_npc()->aiData.bAlertStatus)
                {
                    case STATUS_GREEN:
                        get_npc()->aiData.bAction = DecideActionGreen(get_npc());
                        break;
                    case STATUS_YELLOW:
                        get_npc()->aiData.bAction = DecideActionYellow(get_npc());
                        break;
                    case STATUS_RED:
                        get_npc()->aiData.bAction = DecideActionRed(get_npc(),TRUE);
                        break;
                    case STATUS_BLACK:
                        get_npc()->aiData.bAction = DecideActionBlack(get_npc());
                        break;
                }
            }
            DEBUGAIMSG("Deciding for guynum "<<(int)get_npc()->ubID<<" at gridno "<<get_npc()->sGridNo<<", APs "<<get_npc()->bActionPoints<<
                    ", decided action: "<<(int)get_npc()->aiData.bAction<<", data "<<(int)get_npc()->aiData.usActionData);
        }
Ejemplo n.º 24
0
BOOLEAN AddUIPlan( UINT16 sGridNo, UINT8 ubPlanID )
{
	SOLDIERTYPE				*pPlanSoldier;
	INT16							sXPos, sYPos;
	INT16							sAPCost = 0;
	INT8							bDirection;
	INT32							iLoop;
	SOLDIERCREATE_STRUCT		MercCreateStruct;
	UINT8							ubNewIndex;

	// Depeding on stance and direction facing, add guy!
	
	// If we have a planned action here, ignore!


	// If not OK Dest, ignore!
	if ( !NewOKDestination( gpUIPlannedSoldier, sGridNo, FALSE, (INT8)gsInterfaceLevel ) )
	{
		return( FALSE );
	}


	if ( ubPlanID == UIPLAN_ACTION_MOVETO )
	{
		// Calculate cost to move here
		sAPCost = PlotPath( gpUIPlannedSoldier, sGridNo, COPYROUTE, NO_PLOT, TEMPORARY, (UINT16) gpUIPlannedSoldier->usUIMovementMode, NOT_STEALTH, FORWARD,  gpUIPlannedSoldier->bActionPoints );
		// Adjust for running if we are not already running
		if (  gpUIPlannedSoldier->usUIMovementMode == RUNNING )
		{
			sAPCost += AP_START_RUN_COST;
		}

		if ( EnoughPoints( gpUIPlannedSoldier, sAPCost, 0, FALSE ) )
		{
			memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) );
			MercCreateStruct.bTeam				= SOLDIER_CREATE_AUTO_TEAM;
			MercCreateStruct.ubProfile		= NO_PROFILE;
			MercCreateStruct.fPlayerPlan	= TRUE;
			MercCreateStruct.bBodyType		= gpUIPlannedSoldier->ubBodyType;
			MercCreateStruct.sInsertionGridNo		= sGridNo;

			// Get Grid Corrdinates of mouse
			if ( TacticalCreateSoldier( &MercCreateStruct, &ubNewIndex ) )
			{			
				// Get pointer to soldier
				GetSoldier( &pPlanSoldier, (UINT16)ubNewIndex );

				pPlanSoldier->sPlannedTargetX = -1;
				pPlanSoldier->sPlannedTargetY = -1;

				// Compare OPPLISTS!
				// Set ones we don't know about but do now back to old ( ie no new guys )
				for (iLoop = 0; iLoop < MAX_NUM_SOLDIERS; iLoop++ )
				{
					if ( gpUIPlannedSoldier->bOppList[ iLoop ] < 0 )
					{
							pPlanSoldier->bOppList[ iLoop ] = gpUIPlannedSoldier->bOppList[ iLoop ];
					}
				}

				// Get XY from Gridno
				ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos );

				EVENT_SetSoldierPosition( pPlanSoldier, sXPos, sYPos );
				EVENT_SetSoldierDestination( pPlanSoldier, sGridNo );
				pPlanSoldier->bVisible = 1;
				pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode;


				pPlanSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost;

				pPlanSoldier->ubPlannedUIAPCost = (UINT8)pPlanSoldier->bActionPoints;

				// Get direction
				bDirection = (INT8)gpUIPlannedSoldier->usPathingData[ gpUIPlannedSoldier->usPathDataSize - 1 ];

				// Set direction
				pPlanSoldier->bDirection = bDirection;
				pPlanSoldier->bDesiredDirection = bDirection;

				// Set walking animation
				ChangeSoldierState( pPlanSoldier, pPlanSoldier->usUIMovementMode, 0, FALSE );	
				
				// Change selected soldier
				gusSelectedSoldier = (UINT16)pPlanSoldier->ubID;

				// Change global planned mode to this guy!
				gpUIPlannedSoldier = pPlanSoldier;

				gubNumUIPlannedMoves++;

				gfPlotNewMovement    = TRUE;

				ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Adding Merc Move to Plan" );

			}
		}
		else
		{
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Merc will not have enough action points" );
		}
	}
	else if ( ubPlanID == UIPLAN_ACTION_FIRE )
	{
 	  sAPCost = CalcTotalAPsToAttack( gpUIPlannedSoldier, sGridNo, TRUE, (INT8)(gpUIPlannedSoldier->bShownAimTime /2) );

		// Get XY from Gridno
		ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos );


		// If this is a player guy, show message about no APS
		if ( EnoughPoints( gpUIPlannedSoldier, sAPCost, 0, FALSE ) )
		{
			// CHECK IF WE ARE A PLANNED SOLDIER OR NOT< IF SO< CREATE!
			if ( gpUIPlannedSoldier->ubID < MAX_NUM_SOLDIERS )
			{
				memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) );
				MercCreateStruct.bTeam				= SOLDIER_CREATE_AUTO_TEAM;
				MercCreateStruct.ubProfile		= NO_PROFILE;
				MercCreateStruct.fPlayerPlan	= TRUE;
				MercCreateStruct.bBodyType		= gpUIPlannedSoldier->ubBodyType;
				MercCreateStruct.sInsertionGridNo		= sGridNo;

				// Get Grid Corrdinates of mouse
				if ( TacticalCreateSoldier( &MercCreateStruct, &ubNewIndex ) )
				{			
					// Get pointer to soldier
					GetSoldier( &pPlanSoldier, (UINT16)ubNewIndex );

					pPlanSoldier->sPlannedTargetX = -1;
					pPlanSoldier->sPlannedTargetY = -1;

					// Compare OPPLISTS!
					// Set ones we don't know about but do now back to old ( ie no new guys )
					for (iLoop = 0; iLoop < MAX_NUM_SOLDIERS; iLoop++ )
					{
						if ( gpUIPlannedSoldier->bOppList[ iLoop ] < 0 )
						{
								pPlanSoldier->bOppList[ iLoop ] = gpUIPlannedSoldier->bOppList[ iLoop ];
						}
					}

					EVENT_SetSoldierPosition( pPlanSoldier, gpUIPlannedSoldier->dXPos, gpUIPlannedSoldier->dYPos );
					EVENT_SetSoldierDestination( pPlanSoldier, gpUIPlannedSoldier->sGridNo );
					pPlanSoldier->bVisible = 1;
					pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode;


					pPlanSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost;

					pPlanSoldier->ubPlannedUIAPCost = (UINT8)pPlanSoldier->bActionPoints;

					// Get direction
					bDirection = (INT8)gpUIPlannedSoldier->usPathingData[ gpUIPlannedSoldier->usPathDataSize - 1 ];

					// Set direction
					pPlanSoldier->bDirection = bDirection;
					pPlanSoldier->bDesiredDirection = bDirection;

					// Set walking animation
					ChangeSoldierState( pPlanSoldier, pPlanSoldier->usUIMovementMode, 0, FALSE );	
					
					// Change selected soldier
					gusSelectedSoldier = (UINT16)pPlanSoldier->ubID;

					// Change global planned mode to this guy!
					gpUIPlannedSoldier = pPlanSoldier;

					gubNumUIPlannedMoves++;
				}


			}

			gpUIPlannedSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost;

			gpUIPlannedSoldier->ubPlannedUIAPCost = (UINT8)gpUIPlannedSoldier->bActionPoints;

			// Get direction from gridno
			bDirection = (INT8)GetDirectionFromGridNo( sGridNo, gpUIPlannedSoldier );

			// Set direction
			gpUIPlannedSoldier->bDirection = bDirection;
			gpUIPlannedSoldier->bDesiredDirection = bDirection;

			// Set to shooting animation
			SelectPausedFireAnimation( gpUIPlannedSoldier );

			gpUIPlannedSoldier->sPlannedTargetX = sXPos;
			gpUIPlannedSoldier->sPlannedTargetY = sYPos;

			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Adding Merc Shoot to Plan" );

		}
		else
		{
			ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Merc will not have enough action points" );
		}
	}
	return( TRUE );
}
Ejemplo n.º 25
0
INT16 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT16 sDesGrid, INT8 bReserveAPs, INT8 bAction, INT8 fFlags )
{
	INT16 sLoop,sAPCost;
	INT16 sTempDest,sGoToGrid;
	INT16 sOrigin;
	UINT16 usMaxDist;
	UINT8 ubDirection,ubDirsLeft,ubDirChecked[8],fFound = FALSE;
	INT8 bAPsLeft, fPathFlags;
	UINT8 ubRoomRequired = 0, ubTempRoom;

	if ( bReserveAPs == -1 )
	{
		// default reserve points
		if ( CREATURE_OR_BLOODCAT( pSoldier ) )
		{
			bReserveAPs = 0;
		}
		else
		{
			bReserveAPs = MAX_AP_CARRIED;
		}
	}

	sTempDest = -1;

	// obtain maximum roaming distance from soldier's sOrigin
	usMaxDist = RoamingRange(pSoldier,&sOrigin);

	if ( pSoldier->bOrders <= CLOSEPATROL && (pSoldier->bTeam == CIV_TEAM || pSoldier->ubProfile != NO_PROFILE ) )
	{
		if ( InARoom( pSoldier->usPatrolGrid[0], &ubRoomRequired ) )
		{
			// make sure this doesn't interfere with pathing for scripts
			if ( pSoldier->sAbsoluteFinalDestination != NOWHERE )
			{
				ubRoomRequired = 0;
			}
		}
	}

	pSoldier->usUIMovementMode = DetermineMovementMode(pSoldier, bAction );
	if ( pSoldier->usUIMovementMode == RUNNING && fFlags & FLAG_CAUTIOUS )
	{
		pSoldier->usUIMovementMode = WALKING;
	}

#ifdef DEBUGDECISIONS
	sprintf(tempstr,"%s wants to go towards %d (has range %d)",pSoldier->name,sDesGrid,usMaxDist);
	AIPopMessage(tempstr);
#endif

	// if soldier is ALREADY at the desired destination, quit right away
	if (sDesGrid == pSoldier->sGridNo)
	{
		return(NOWHERE);
	}

	// don't try to approach go after noises or enemies actually in water
	// would be too easy to throw rocks in water, etc. & distract the AI
	if (Water(sDesGrid))
	{
		return(NOWHERE);
	}

	fPathFlags = 0;
	if ( CREATURE_OR_BLOODCAT( pSoldier ) )
	{	/*
		if ( PythSpacesAway( pSoldier->sGridNo, sDesGrid ) <= PATH_CLOSE_RADIUS )
		{
			// then do a limited range path search and see if we can get there
			gubNPCDistLimit = 10;
			if ( !LegalNPCDestination( pSoldier, sDesGrid, ENSURE_PATH, NOWATER, fPathFlags) )
			{
				gubNPCDistLimit = 0;
				return( NOWHERE );
			}
			else
			{
				// allow attempt to path without 'good enough' flag on
				gubNPCDistLimit = 0;
			}
		}
		else
		{
		*/
			fPathFlags = PATH_CLOSE_GOOD_ENOUGH;
		//}
	}

	// first step: try to find an OK destination at or near the desired gridno
	if (!LegalNPCDestination(pSoldier,sDesGrid,ENSURE_PATH,NOWATER,fPathFlags))
	{
#ifdef DEBUGDECISIONS
		AIPopMessage("destination Grid # itself not valid, looking around it");
#endif
		if ( CREATURE_OR_BLOODCAT( pSoldier ) )
		{
			// we tried to get close, failed; abort!
			return( NOWHERE );
		}
		else
		{
			// else look at the 8 nearest gridnos to sDesGrid for a valid destination

			// clear ubDirChecked flag for all 8 directions
			for (ubDirection = 0; ubDirection < 8; ubDirection++)
				ubDirChecked[ubDirection] = FALSE;

			ubDirsLeft = 8;

			// examine all 8 spots around 'sDesGrid'
			// keep looking while directions remain and a satisfactory one not found
			for (ubDirsLeft = 8; ubDirsLeft != 0; ubDirsLeft--)
			{
				if (fFound)
				{
					break;
				}
				// randomly select a direction which hasn't been 'checked' yet
				do
				{
					ubDirection = (UINT8) Random(8);
				}
				while (ubDirChecked[ubDirection]);

				ubDirChecked[ubDirection] = TRUE;

				// determine the gridno 1 tile away from current friend in this direction
				sTempDest = NewGridNo(sDesGrid,DirectionInc( (INT16)(ubDirection + 1) ));

				// if that's out of bounds, ignore it & check next direction
				if (sTempDest == sDesGrid)
					continue;

				if (LegalNPCDestination(pSoldier,sTempDest,ENSURE_PATH,NOWATER,0))
				{
					fFound = TRUE;            // found a spot

#ifdef DEBUGDECISIONS
					AINumMessage("Found a spot!  ubDirection = ",ubDirection + 1);
#endif

					break;                   // stop checking in other directions
				}
			}

			if (!fFound)
			{
#ifdef DEBUGDECISIONS
				AINumMessage("Couldn't find OK destination around grid #",sDesGrid);
#endif

				return(NOWHERE);
			}

			// found a good grid #, this becomes our actual desired grid #
			sDesGrid = sTempDest;
		}
	}

 // HAVE FOUND AN OK destination AND PLOTTED A VALID BEST PATH TO IT


#ifdef DEBUGDECISIONS
 AINumMessage("Chosen legal destination is gridno ",sDesGrid);
 AINumMessage("Tracing along path, pathRouteToGo = ",pSoldier->pathRouteToGo);
#endif

 sGoToGrid = pSoldier->sGridNo;      // start back where soldier is standing now
 sAPCost = 0;		      // initialize path cost counter

 // we'll only go as far along the plotted route as is within our
 // permitted roaming range, and we'll stop as soon as we're down to <= 5 APs

 for (sLoop = 0; sLoop < (pSoldier->usPathDataSize - pSoldier->usPathIndex); sLoop++)
  {
   // what is the next gridno in the path?

	 //sTempDest = NewGridNo( sGoToGrid,DirectionInc( (INT16) (pSoldier->usPathingData[sLoop] + 1) ) );
	 sTempDest = NewGridNo( sGoToGrid,DirectionInc( (INT16) (pSoldier->usPathingData[sLoop]) ) );
   //NumMessage("sTempDest = ",sTempDest);

   // this should NEVER be out of bounds
   if (sTempDest == sGoToGrid)
    {
#ifdef BETAVERSION
     sprintf(tempstr,"GoAsFarAsPossibleTowards: ERROR - gridno along valid route is invalid!  guynum %d, sTempDest = %d",pSoldier->ubID,sTempDest);

#ifdef RECORDNET
     fprintf(NetDebugFile,"\n\t%s\n",tempstr);
#endif

     PopMessage(tempstr);
     SaveGame(ERROR_SAVE);
#endif

     break;           // quit here, sGoToGrid is where we are going
    }

   // if this takes us beyond our permitted "roaming range"
   if (SpacesAway(sOrigin,sTempDest) > usMaxDist)
     break;           // quit here, sGoToGrid is where we are going


	 if ( ubRoomRequired )
	 {
		if ( !( InARoom( sTempDest, &ubTempRoom ) && ubTempRoom == ubRoomRequired ) )
		{
		 // quit here, limited by room!
		 break;
		}
	 }

   if ( (fFlags & FLAG_STOPSHORT) && SpacesAway( sDesGrid, sTempDest ) <= STOPSHORTDIST )
	 {
     break;           // quit here, sGoToGrid is where we are going
	 }

   // if this gridno is NOT a legal NPC destination
   // DONT'T test path again - that would replace the traced path! - Ian
   // NOTE: It's OK to go *THROUGH* water to try and get to the destination!
   if (!LegalNPCDestination(pSoldier,sTempDest,IGNORE_PATH,WATEROK,0))
     break;           // quit here, sGoToGrid is where we are going


   // CAN'T CALL PathCost() HERE! IT CALLS findBestPath() and overwrites
   //       pathRouteToGo !!!  Gotta calculate the cost ourselves - Ian
   //
   //ubAPsLeft = pSoldier->bActionPoints - PathCost(pSoldier,sTempDest,FALSE,FALSE,FALSE,FALSE,FALSE);

	 if (gfTurnBasedAI)
	 {
		 // if we're just starting the "costing" process (first gridno)
		 if (sLoop == 0)
			{
			/*
			 // first, add any additional costs - such as intermediate animations, etc.
			 switch(pSoldier->anitype[pSoldier->anim])
				{
				 // in theory, no NPC should ever be in one of these animations as
				 // things stand (they don't medic anyone), but leave it for robustness
				 case START_AID   :
				 case GIVING_AID  : sAnimCost = AP_STOP_FIRST_AID;
					break;

				 case TWISTOMACH  :
				 case COLLAPSED   : sAnimCost = AP_GET_UP;
					break;

				 case TWISTBACK   :
				 case UNCONSCIOUS : sAnimCost = (AP_ROLL_OVER + AP_GET_UP);
					break;

				 default          : sAnimCost = 0;
				}

			 // this is our first cost
			 sAPCost += sAnimCost;
			 */

			 if (pSoldier->usUIMovementMode == RUNNING)
			 {
				sAPCost += AP_START_RUN_COST;
			 }
			}

		 // ATE: Direction here?
		 sAPCost += EstimateActionPointCost( pSoldier, sTempDest, (INT8) pSoldier->usPathingData[sLoop], pSoldier->usUIMovementMode, (INT8) sLoop, (INT8) pSoldier->usPathDataSize );

		 bAPsLeft = pSoldier->bActionPoints - sAPCost;
	 }

	 // if after this, we have <= 5 APs remaining, that's far enough, break out
	 // (the idea is to preserve APs so we can crouch or react if
	 // necessary, and benefit from the carry-over next turn if not needed)
	 // This routine is NOT used by any GREEN AI, so such caution is warranted!

	 if ( gfTurnBasedAI && (bAPsLeft < bReserveAPs) )
		 break;
	 else
		{
		 sGoToGrid = sTempDest;    // we're OK up to here

		 // if exactly 5 APs left, don't bother checking any further
		 if ( gfTurnBasedAI && (bAPsLeft == bReserveAPs) )
			 break;
		}		
  }


 // if it turned out we couldn't go even 1 tile towards the desired gridno
 if (sGoToGrid == pSoldier->sGridNo)
  {
#ifdef DEBUGDECISIONS
   sprintf(tempstr,"%s will go NOWHERE, path doesn't meet criteria",pSoldier->name);
   AIPopMessage(tempstr);
#endif

   return(NOWHERE);             // then go nowhere
  }
 else
  {
   // possible optimization - stored path IS good if we're going all the way
   if (sGoToGrid == sDesGrid)
	 {
     pSoldier->bPathStored = TRUE;
		 pSoldier->sFinalDestination = sGoToGrid;
	 }
	 else if ( pSoldier->usPathIndex == 0 )
	 {
		// we can hack this surely! -- CJC
     pSoldier->bPathStored = TRUE; 
		 pSoldier->sFinalDestination = sGoToGrid;
		 pSoldier->usPathDataSize = sLoop + 1;
	 }

#ifdef DEBUGDECISIONS
		ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"%d to %d with %d APs left", pSoldier->ubID, sGoToGrid, pSoldier->bActionPoints );
 #endif


		return( sGoToGrid );
  }
}
Ejemplo n.º 26
0
void StrategicHandlePlayerTeamMercDeath( SOLDIERTYPE *pSoldier )
{
	SOLDIERTYPE *pKiller = NULL;
	INT16 sSectorX, sSectorY;

	//if the soldier HAS a profile
	if( pSoldier->ubProfile != NO_PROFILE )
	{
		//add to the history log the fact that the merc died and the circumstances
		if( pSoldier->ubAttackerID != NOBODY )
		{
			pKiller = MercPtrs[ pSoldier->ubAttackerID ];
		}

		// CJC Nov 11, 2002
		// Use the soldier's sector location unless impossible
		if (pSoldier->sSectorX != 0 && pSoldier->sSectorY != 0)
		{
			sSectorX = pSoldier->sSectorX;
			sSectorY = pSoldier->sSectorY;
		}
		else
		{
			sSectorX = gWorldSectorX;
			sSectorY = gWorldSectorY;
		}

		if( pKiller && pKiller->bTeam == OUR_TEAM )
		{
			AddHistoryToPlayersLog( HISTORY_MERC_KILLED_CHARACTER, pSoldier->ubProfile, GetWorldTotalMin(), sSectorX, sSectorY );
		}
		else
		{
			AddHistoryToPlayersLog( HISTORY_MERC_KILLED, pSoldier->ubProfile, GetWorldTotalMin(), sSectorX, sSectorY );
		}
	}

	if ( guiCurrentScreen != GAME_SCREEN )
	{
		ScreenMsg( FONT_RED, MSG_INTERFACE, pMercDeadString[ 0 ], pSoldier->name );
	}

	// robot and EPCs don't count against death rate - the mercs back home don't particularly give a damn about locals & machines!
	if ( !AM_AN_EPC( pSoldier ) && !AM_A_ROBOT( pSoldier ) )
	{
		// keep track of how many mercs have died under player's command (for death rate, can't wait until removed from team)
		gStrategicStatus.ubMercDeaths++;
	}
 

	pSoldier->uiStatusFlags |= SOLDIER_DEAD;

	// Set breath to 0!
	pSoldier->bBreathMax = pSoldier->bBreath = 0;

	// not asleep, DEAD!
	pSoldier->fMercAsleep = FALSE;


	//if the merc had life insurance
	if( pSoldier->usLifeInsurance )
	{
		// if he didn't die during auto-resolve
		if( guiCurrentScreen != AUTORESOLVE_SCREEN )
		{
			// check whether this was obviously a suspicious death
			// if killed within an hour of being insured
			if ( pSoldier->uiStartTimeOfInsuranceContract <= GetWorldTotalMin() && GetWorldTotalMin() - pSoldier->uiStartTimeOfInsuranceContract < 60 )
			{
				gMercProfiles[ pSoldier->ubProfile ].ubSuspiciousDeath = VERY_SUSPICIOUS_DEATH;
			}
			// if killed by someone on our team, or while there weren't any opponents around
			else if (Menptr[ pSoldier->ubAttackerID ].bTeam == OUR_TEAM || !gTacticalStatus.fEnemyInSector )
			{
				// cause insurance company to suspect fraud and investigate this claim
				gMercProfiles[ pSoldier->ubProfile ].ubSuspiciousDeath = SUSPICIOUS_DEATH;
			}
		}

		AddLifeInsurancePayout( pSoldier );
	}


	// robot and EPCs don't penalize morale - merc don't care about fighting machines and the lives of locals much
	if ( !AM_AN_EPC( pSoldier ) && !AM_A_ROBOT( pSoldier ) )
	{
		// Change morale of others based on this
		HandleMoraleEvent( pSoldier, MORALE_TEAMMATE_DIED, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
	}

	//if its a MERC merc, record the time of his death
	if( pSoldier->ubWhatKindOfMercAmI == MERC_TYPE__MERC )
	{
		pSoldier->iEndofContractTime = GetWorldTotalMin();

		//set is so Speck can say that a merc is dead
		LaptopSaveInfo.ubSpeckCanSayPlayersLostQuote = 1;
	}

	//Set the fact that the merc is DEAD!!
	gMercProfiles[ pSoldier->ubProfile ].bMercStatus = MERC_IS_DEAD;

	if( pSoldier->bAssignment != ASSIGNMENT_DEAD )
	{
		SetTimeOfAssignmentChangeForMerc( pSoldier );
	}

	// handle strategic level death
	HandleStrategicDeath( pSoldier );
}
Ejemplo n.º 27
0
void InitNPCs( void )
{
	MERCPROFILESTRUCT * pProfile;

	// add the pilot at a random location!
	pProfile = &(gMercProfiles[ SKYRIDER ]);
	switch( Random( 4 ) )
	{
		case 0:
			pProfile->sSectorX = 15;
			pProfile->sSectorY = MAP_ROW_B;
			pProfile->bSectorZ = 0;
			break;
		case 1:
			pProfile->sSectorX = 14;
			pProfile->sSectorY = MAP_ROW_E;
			pProfile->bSectorZ = 0;
			break;
		case 2:
			pProfile->sSectorX = 12;
			pProfile->sSectorY = MAP_ROW_D;
			pProfile->bSectorZ = 0;
			break;
		case 3:
			pProfile->sSectorX = 16;
			pProfile->sSectorY = MAP_ROW_C;
			pProfile->bSectorZ = 0;
			break;
	}

	#ifdef JA2TESTVERSION
		ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"Skyrider in %c %d", 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
	#endif
	// use alternate map, with Skyrider's shack, in this sector
	SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;


	// set up Madlab's secret lab (he'll be added when the meanwhile scene occurs)

	switch( Random( 4 ) )
	{
		case 0:
			// use alternate map in this sector
			SectorInfo[ SECTOR( 7, MAP_ROW_H ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
			break;
		case 1:
			SectorInfo[ SECTOR( 16, MAP_ROW_H ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
			break;
		case 2:
			SectorInfo[ SECTOR( 11, MAP_ROW_I ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
			break;
		case 3:
			SectorInfo[ SECTOR( 4, MAP_ROW_E ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
			break;
	}
	
	// add Micky in random location

	pProfile = &(gMercProfiles[MICKY]);
	switch( Random( 5 ) )
	{
		case 0:
			pProfile->sSectorX = 9;
			pProfile->sSectorY = MAP_ROW_G;
			pProfile->bSectorZ = 0;
			break;
		case 1:
			pProfile->sSectorX = 13;
			pProfile->sSectorY = MAP_ROW_D;
			pProfile->bSectorZ = 0;
			break;
		case 2:
			pProfile->sSectorX = 5;
			pProfile->sSectorY = MAP_ROW_C;
			pProfile->bSectorZ = 0;
			break;
		case 3:
			pProfile->sSectorX = 2;
			pProfile->sSectorY = MAP_ROW_H;
			pProfile->bSectorZ = 0;
			break;
		case 4:
			pProfile->sSectorX = 6;
			pProfile->sSectorY = MAP_ROW_C;
			pProfile->bSectorZ = 0;
			break;
	}

	#ifdef JA2TESTVERSION
		ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s in %c %d", pProfile->zNickname, 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
	#endif

	// use alternate map in this sector
	//SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;

  gfPlayerTeamSawJoey = FALSE;


	if ( gGameOptions.fSciFi )
	{
		// add Bob
		pProfile = &(gMercProfiles[BOB]);
		pProfile->sSectorX = 8;
		pProfile->sSectorY = MAP_ROW_F;
		pProfile->bSectorZ = 0;

		// add Gabby in random location
		pProfile = &(gMercProfiles[GABBY]);
		switch( Random( 2 ) )
		{
			case 0:
				pProfile->sSectorX = 11;
				pProfile->sSectorY = MAP_ROW_H;
				pProfile->bSectorZ = 0;
				break;
			case 1:
				pProfile->sSectorX = 4;
				pProfile->sSectorY = MAP_ROW_I;
				pProfile->bSectorZ = 0;
				break;
		}

		#ifdef JA2TESTVERSION
			ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s in %c %d", pProfile->zNickname, 'A' + pProfile->sSectorY - 1, pProfile->sSectorX );
		#endif

		// use alternate map in this sector
		SectorInfo[ SECTOR( pProfile->sSectorX, pProfile->sSectorY ) ].uiFlags |= SF_USE_ALTERNATE_MAP;
	}
	else
	{ //not scifi, so use alternate map in Tixa's b1 level that doesn't have the stairs going down to the caves.
		UNDERGROUND_SECTORINFO *pSector;
		pSector = FindUnderGroundSector( 9, 10, 1 ); //j9_b1
		if( pSector )
		{
			pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
		}
	}

	// init hospital variables
	giHospitalTempBalance = 0;
	giHospitalRefund = 0;
	gbHospitalPriceModifier = 0;

	// set up Devin so he will be placed ASAP
	gMercProfiles[ DEVIN ].bNPCData = 3;
}
Ejemplo n.º 28
0
//This will automatically update obsolete map versions to the new ones.	This will even
//work in the game itself, but would require conversion to happen every time.	This is completely
//transparent to the rest of the game, but in the editor, obsolete versions will be updated upon
//loading and won't be permanently updated until the map is saved, regardless of changes.
void UpdateOldVersionMap()
{
#if 0 //This code is no longer needed since the major version update from 1.0 to 4.0
    //However, I am keeping it in for reference.
    SOLDIERINITNODE *curr;
    INT32 i;
    LEVELNODE *pStruct;
    //VERSION 0 -- obsolete November 14, 1997
    if( gMapInformation.ubMapVersion == 0 )
    {
        //Soldier information contained two fixable bugs.
        gMapInformation.ubMapVersion++;
        curr = gSoldierInitHead;
        while( curr )
        {
            //Bug #01)	Nodes without detailed slots weren't initialized.
            if( !curr->pBasicPlacement->fDetailedPlacement )
                curr->pDetailedPlacement = NULL;
            //Bug #02)	The attitude variable was accidentally being generated like attributes
            //					which put it completely out of range.
            if( curr->pBasicPlacement->bAttitude > 7 )
                curr->pBasicPlacement->bAttitude = (INT8)Random(8);
            //go to next node
            curr = curr->next;
        }
    }
    //VERSION 1 -- obsolete January 7, 1998
    if( gMapInformation.ubMapVersion == 1 )
    {
        gMapInformation.ubMapVersion++;
        //Bug #03)	Removing all wall decals from map, because of new changes to the slots
        //					as well as certain decals found commonly in illegal places.
        for( i = 0; i < WORLD_MAX; i++ )
        {
            RemoveAllStructsOfTypeRange( i, FIRSTWALLDECAL, LASTWALLDECAL );
            RemoveAllStructsOfTypeRange( i, FIFTHWALLDECAL, SIXTHWALLDECAL );
        }
    }
    //VERSION 2 -- obsolete February 3, 1998
    if( gMapInformation.ubMapVersion == 2 )
    {
        gMapInformation.ubMapVersion++;
        curr = gSoldierInitHead;
        while( curr )
        {
            //Bug #04)	Assign enemy mercs default army color code if applicable
            if( curr->pBasicPlacement->bTeam == ENEMY_TEAM && !curr->pBasicPlacement->ubSoldierClass )
            {
                if( !curr->pDetailedPlacement )
                {
                    curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ARMY;
                }
                else if( curr->pDetailedPlacement && curr->pDetailedPlacement->ubProfile == NO_PROFILE )
                {
                    curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_ARMY;
                    curr->pDetailedPlacement->ubSoldierClass = SOLDIER_CLASS_ARMY;
                }
            }
            curr = curr->next;
        }
    }
    //VERSION 3 -- obsolete February 9, 1998
    if( gMapInformation.ubMapVersion == 3 )
    {
        gMapInformation.ubMapVersion++;
        //Bug #05)	Move entry points down if necessary.
        ValidateEntryPointGridNo( &gMapInformation.sNorthGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sEastGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sSouthGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sWestGridNo );
    }
    //VERSION 4 -- obsolete February 25, 1998
    if( gMapInformation.ubMapVersion == 4 )
    {
        gMapInformation.ubMapVersion++;
        //6)	Change all doors to FIRSTDOOR
        for( i = 0; i < WORLD_MAX; i++ )
        {
            //NOTE:	Here are the index values for the various doors
            //DOOR		OPEN		CLOSED
            //FIRST		916			912
            //SECOND	936		932
            //THIRD		956		952
            //FOURTH	976		972
            pStruct = gpWorldLevelData[ i ].pStructHead;
            while( pStruct )
            {
                //outside topleft
                if( pStruct->usIndex == 932 || pStruct->usIndex == 952 || pStruct->usIndex == 972 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 912 );
                    break;
                }
                else if( pStruct->usIndex == 936 || pStruct->usIndex == 956 || pStruct->usIndex == 976 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 916 );
                    break;
                }
                //outside topright
                else if( pStruct->usIndex == 927 || pStruct->usIndex == 947 || pStruct->usIndex == 967 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 907 );
                    break;
                }
                else if( pStruct->usIndex == 931 || pStruct->usIndex == 951 || pStruct->usIndex == 971 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 911 );
                    break;
                }
                //inside topleft
                else if( pStruct->usIndex == 942 || pStruct->usIndex == 962 || pStruct->usIndex == 982 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 922 );
                    break;
                }
                else if( pStruct->usIndex == 946 || pStruct->usIndex == 966 || pStruct->usIndex == 986 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 926 );
                    break;
                }
                //inside topright
                else if( pStruct->usIndex == 937 || pStruct->usIndex == 957 || pStruct->usIndex == 977 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 917 );
                    break;
                }
                else if( pStruct->usIndex == 941 || pStruct->usIndex == 961 || pStruct->usIndex == 981 )
                {
                    ReplaceStructIndex( i, pStruct->usIndex, 921 );
                    break;
                }
                pStruct = pStruct->pNext;
            }
        }
    }
    //VERSION 5 -- obsolete March 4, 1998
    if( gMapInformation.ubMapVersion == 5 )
    {
        gMapInformation.ubMapVersion++;
        //Bug 7)	Remove all exit grids (the format has changed)
        for( i = 0; i < WORLD_MAX; i++ )
            RemoveExitGridFromWorld( i );
    }
    //VERSION 6 -- obsolete March 9, 1998
    if( gMapInformation.ubMapVersion == 6 )
    {   //Bug 8)	Change droppable status of merc items so that they are all undroppable.
        gMapInformation.ubMapVersion++;
        curr = gSoldierInitHead;
        while( curr )
        {
            //Bug #04)	Assign enemy mercs default army color code if applicable
            if( curr->pDetailedPlacement )
            {
                for( i = 0; i < curr->pDetailedPlacement->Inv.size(); i++ )
                {   //make all items undroppable, even if it is empty.	This will allow for
                    //random item generation, while empty, droppable slots are locked as empty
                    //during random item generation.
                    curr->pDetailedPlacement->Inv[ i ].fFlags |= OBJECT_UNDROPPABLE;
                }
            }
            curr = curr->next;
        }
    }
    //VERSION 7 -- obsolete April 14, 1998
    if( gMapInformation.ubMapVersion == 7 )
    {
        gMapInformation.ubMapVersion++;
        //Bug 9)	Priority placements have been dropped in favor of splitting it into two categories.
        //				The first is Detailed placements, and the second is priority existance.	So, all
        //				current detailed placements will also have priority existance.
        curr = gSoldierInitHead;
        while( curr )
        {
            if( curr->pDetailedPlacement )
            {
                curr->pBasicPlacement->fPriorityExistance = TRUE;
            }
            curr = curr->next;
        }
    }

    if( gMapInformation.ubMapVersion == 14 )
    {   //Toast all of the ambiguous road pieces that ended up wrapping the byte.
        LEVELNODE *pStruct, *pStruct2;
        INT32 i;
        for( i = 0; i < WORLD_MAX; i++ )
        {
            pStruct = gpWorldLevelData[ i ].pObjectHead;
            if( pStruct && pStruct->usIndex == 1078 && i < WORLD_MAX-2 && i >= 320 )
            {   //This is the only detectable road piece that we can repair.
                pStruct2 = gpWorldLevelData[ i+1 ].pObjectHead;
                if( pStruct2 && pStruct2->usIndex == 1081 )
                {
                    RemoveObject( i, pStruct->usIndex );
                    RemoveObject( i+1, pStruct->usIndex+1 );
                    RemoveObject( i+2, pStruct->usIndex+2 );
                    RemoveObject( i-160, pStruct->usIndex-160 );
                    RemoveObject( i-159, pStruct->usIndex-159 );
                    RemoveObject( i-158, pStruct->usIndex-158 );
                    RemoveObject( i-320, pStruct->usIndex-320 );
                    RemoveObject( i-319, pStruct->usIndex-319 );
                    RemoveObject( i-318, pStruct->usIndex-318 );
                    AddObjectToTail( i, 1334 );
                    AddObjectToTail( i-160, 1335 );
                    AddObjectToTail( i-320, 1336 );
                    AddObjectToTail( i+1, 1337 );
                    AddObjectToTail( i-159, 1338 );
                    AddObjectToTail( i-319, 1339 );
                    AddObjectToTail( i+2, 1340 );
                    AddObjectToTail( i-158, 1341 );
                    AddObjectToTail( i-318, 1342 );
                }
            }
            else if( pStruct && pStruct->usIndex >= 1079 && pStruct->usIndex < 1115 )
            {
                RemoveObject( i, pStruct->usIndex );
            }
        }
    }

    if( gMapInformation.ubMapVersion <= 7 )
    {
        if( gfEditMode )
        {
#ifdef JA2TESTVERSION
            ScreenMsg( FONT_MCOLOR_RED, MSG_ERROR, L"Currently loaded map is corrupt!	Allowing the map to load anyway!" );
#endif
        }
        else
        {
            if( gbWorldSectorZ )
            {
                AssertMsg( 0, String( "Currently loaded map (%c%d_b%d.dat) is invalid -- less than the minimum supported version.", gWorldSectorY + 'A' - 1, gWorldSectorX, gbWorldSectorZ ) );
            }
            else if( !gbWorldSectorZ )
            {
                AssertMsg( 0, String( "Currently loaded map (%c%d.dat) is invalid -- less than the minimum supported version.", gWorldSectorY + 'A' - 1, gWorldSectorX ) );
            }
        }
    }
    //VERSION 8 -- obsolete April 18, 1998
    if( gMapInformation.ubMapVersion == 8 )
    {
        gMapInformation.ubMapVersion++;
        //Bug 10) Padding on detailed placements is uninitialized.	Clear all data starting at
        //				fKillSlotIfOwnerDies.
        curr = gSoldierInitHead;
        while( curr )
        {
            if( curr->pDetailedPlacement )
            {
                //The size 120 was hand calculated.	The remaining padding was 118 bytes
                //and there were two one byte fields cleared, fKillSlotIfOwnerDies and ubScheduleID
                memset( &curr->pDetailedPlacement->fKillSlotIfOwnerDies, 0, 120 );
            }
            curr = curr->next;
        }
    }
    //Version 9 -- Kris -- obsolete April 27, 1998
    if( gMapInformation.ubMapVersion == 9 )
    {
        gMapInformation.ubMapVersion++;
        curr = gSoldierInitHead;
        while( curr )
        {
            //Bug 11) Convert all wheelchaired placement bodytypes to cows.	Result of change in the animation database.
            if( curr->pDetailedPlacement && curr->pDetailedPlacement->bBodyType == CRIPPLECIV )
            {
                curr->pDetailedPlacement->bBodyType = COW;
                curr->pBasicPlacement->bBodyType = COW;
            }
            curr = curr->next;
        }
    }
    if( gMapInformation.ubMapVersion < 12 )
    {
        gMapInformation.ubMapVersion = 12;
        gMapInformation.sCenterGridNo = -1;
    }
    if( gMapInformation.ubMapVersion < 13 )
    {   //replace all merc ammo inventory slots status value with the max ammo that the clip can hold.
        INT32 i, cnt;
        OBJECTTYPE *pItem;
        gMapInformation.ubMapVersion++;
        //Bug 10) Padding on detailed placements is uninitialized.	Clear all data starting at
        //				fKillSlotIfOwnerDies.
        curr = gSoldierInitHead;
        while( curr )
        {
            if( curr->pDetailedPlacement )
            {
                for ( i = 0; i < curr->pDetailedPlacement->Inv.size(); i++ )
                {
                    pItem = &curr->pDetailedPlacement->Inv[ i ];
                    if( Item[ pItem->usItem ].usItemClass & IC_AMMO )
                    {
                        for( cnt = 0; cnt < pItem->ubNumberOfObjects; cnt++ )
                        {
                            pItem->shots.ubShotsLeft[ cnt ] = Magazine[ Item[ pItem->usItem ].ubClassIndex ].ubMagSize;
                        }
                    }
                }
            }
            curr = curr->next;
        }
    }
    if( gMapInformation.ubMapVersion < 14 )
    {
        gMapInformation.ubMapVersion++;
        if( !gfCaves && !gfBasement )
        {
            ReplaceObsoleteRoads();
        }
    }
    if( gMapInformation.ubMapVersion < 15 )
    {   //Do nothing.	The object layer was expanded from 1 byte to 2 bytes, effecting the
        //size of the maps.	This was due to the fact that the ROADPIECES tileset contains
        //over 300 pieces, hence requiring a size increase of the tileset subindex for this
        //layer only.
    }
#endif //end of MAJOR VERSION 3.0 obsolete code
    if( gMapInformation.ubMapVersion < 15 )
    {
        AssertMsg( 0, "Map is less than minimum supported version." );
    }
    if( gMapInformation.ubMapVersion < 16 )
    {
        gMapInformation.ubMapVersion = 16;
        gMapInformation.sIsolatedGridNo = -1;
    }
    if( gMapInformation.ubMapVersion < 17 )
    {
        gMapInformation.ubMapVersion = 17;
        //EliminateObjectLayerRedundancy();
    }
    if( gMapInformation.ubMapVersion < 18 )
    {
        // replace useless crowbars with proper ones
        UINT32 i;
        gMapInformation.ubMapVersion = 18;
        for ( i = 0; i < guiNumWorldItems; i++ )
        {
            if ( gWorldItems[ i ].object.usItem == JAR_ELIXIR )
            {
                gWorldItems[ i ].object.usItem = CROWBAR;
            }
        }
    }
    if( gMapInformation.ubMapVersion < 19 )
    {
        //Do nothing, this is used to force regenerate the map edgepoints in map edgepoints.c
        gMapInformation.ubMapVersion = 19;
    }
    if( gMapInformation.ubMapVersion < 20 )
    {
        //validate the map entry points as the world boundaries have changed.
        gMapInformation.ubMapVersion = 20;
        ValidateEntryPointGridNo( &gMapInformation.sNorthGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sEastGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sSouthGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sWestGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sCenterGridNo );
        ValidateEntryPointGridNo( &gMapInformation.sIsolatedGridNo );
    }
    if( gMapInformation.ubMapVersion < 21 )
    {
        SOLDIERINITNODE *curr;
        //override any item slots being locked if there is no item in that slot.
        //Laymen terms:	If any items slots are locked to be empty, make them empty but available
        //for random item generation.
        gMapInformation.ubMapVersion = 21;
        curr = gSoldierInitHead;
        while( curr )
        {
            if( curr->pDetailedPlacement )
            {
                for( UINT32 i = 0; i < curr->pDetailedPlacement->Inv.size(); i++ )
                {
                    if( !curr->pDetailedPlacement->Inv[ i ].usItem )
                    {
                        if( curr->pDetailedPlacement->Inv[ i ].fFlags & OBJECT_UNDROPPABLE )
                        {
                            if( curr->pDetailedPlacement->Inv[ i ].fFlags & OBJECT_NO_OVERWRITE )
                            {
                                curr->pDetailedPlacement->Inv[ i ].fFlags &= ~OBJECT_NO_OVERWRITE;
                            }
                        }
                    }
                }
            }
            curr = curr->next;
        }
    }
    if( gMapInformation.ubMapVersion < 22 )
    {   //Allow map edgepoints to be regenerated as new system has been reenabled.
        gMapInformation.ubMapVersion = 22;
    }
    if( gMapInformation.ubMapVersion < 23 )
    {   //Allow map edgepoints to be regenerated as new system has been reenabled.
        SOLDIERINITNODE *curr;
        gMapInformation.ubMapVersion = 23;
        if( giCurrentTilesetID == 1 ) //cave/mine tileset only
        {   //convert all civilians to miners which use uniforms and more masculine body types.
            curr = gSoldierInitHead;
            while( curr )
            {
                if( curr->pBasicPlacement->bTeam == CIV_TEAM && !curr->pDetailedPlacement )
                {
                    curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_MINER;
                    curr->pBasicPlacement->bBodyType = -1;
                }
                curr = curr->next;
            }
        }
    }
    if( gMapInformation.ubMapVersion < 25 )
    {
        gMapInformation.ubMapVersion = 25;
        if( gfCaves )
        {
            LightSetBaseLevel( 13 );
        }
    }
    if( gMapInformation.ubMapVersion < 26 )
    {   //Allow map edgepoints to be regenerated as new system has been reenabled.
        gMapInformation.ubMapVersion = 26;
    }
    if( gMapInformation.ubMapVersion < 27 )
    {   //Allow map edgepoints to be regenerated as new system has been reenabled.
        gMapInformation.ubMapVersion = 27;
    }
    if( gMapInformation.ubMapVersion < 29 )
    {
        gMapInformation.ubMapVersion = 29;
    }
}
Ejemplo n.º 29
0
INT32 AddItemToWorld( INT32 sGridNo, OBJECTTYPE *pObject, UINT8 ubLevel, UINT16 usFlags, INT8 bRenderZHeightAboveLevel, INT8 bVisible, INT8 soldierID )
{
    UINT32	iItemIndex;
    INT32		iReturn;

    // ATE: Check if the gridno is OK
    if ( TileIsOutOfBounds(sGridNo))
    {
        // Display warning.....
#ifdef JA2BETAVERSION
        ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_BETAVERSION, L"Error: Item %d was given invalid grid location %d. Please report", pObject->usItem, sGridNo);
#endif
        return( -1 );
    }

    iItemIndex = GetFreeWorldItemIndex( );

    //Add the new world item to the table.
    gWorldItems[ iItemIndex ].fExists										= TRUE;
    gWorldItems[ iItemIndex ].sGridNo										= sGridNo;
    gWorldItems[ iItemIndex ].ubLevel										= ubLevel;
    gWorldItems[ iItemIndex ].usFlags										= usFlags;
    gWorldItems[ iItemIndex ].bVisible									= bVisible;
    gWorldItems[ iItemIndex ].bRenderZHeightAboveLevel	= bRenderZHeightAboveLevel;
    gWorldItems[ iItemIndex ].soldierID										= soldierID;

    gWorldItems[ iItemIndex ].object = *pObject;

    // Add a bomb reference if needed
    // Flugente: we can arm bombs in our inventory and then throw them out, which will cause them to be added to the world. Only way to identify those items is via a check for their bDetonatorType
    if (usFlags & WORLD_ITEM_ARMED_BOMB || ( (Item[pObject->usItem].usItemClass & (IC_BOMB)) && ( ( (*pObject)[0]->data.misc.bDetonatorType == BOMB_TIMED ) || ( (*pObject)[0]->data.misc.bDetonatorType == BOMB_REMOTE ) ) ) )
    {
        // sevenfm: added flag WORLD_ITEM_ARMED_BOMB
        // this fixes bug with remote explosives not being removed after activation, if they were armed in inventory and thrown afterwards
        gWorldItems[ iItemIndex ].usFlags |= WORLD_ITEM_ARMED_BOMB;

        iReturn = AddBombToWorld( iItemIndex );
        if (iReturn == -1)
        {
            return( -1 );
        }
        else
        {
            // OJW - 20091002 - Explosives
            if (is_networked && is_client)
            {
                SOLDIERTYPE* pSoldier = NULL;

                if (soldierID == -1)
                {
                    if (gWorldItems[ iItemIndex ].object[0]->data.misc.ubBombOwner > 1)
                    {
                        soldierID = gWorldItems[ iItemIndex ].object[0]->data.misc.ubBombOwner - 2; // undo the hack
                        pSoldier = MercPtrs[ soldierID ];
                    }
                }

                if (pSoldier != NULL)
                {
                    // if soldier is on our team, or is AI and we are the server
                    if (pSoldier->bTeam == 0 || (pSoldier->bTeam == 1 && is_server))
                    {
                        // this is a local bomb, so init it that way
                        gWorldBombs[iReturn].iMPWorldItemIndex = 0;
                        gWorldBombs[iReturn].ubMPTeamIndex = pSoldier->bTeam;
                        gWorldBombs[iReturn].bIsFromRemotePlayer = false;
                        // <TODO> the 99 is a hack..though probably doesnt matter
                        send_plant_explosive(soldierID , pObject->usItem , 99 , usFlags , sGridNo , ubLevel , iItemIndex );
                    }
                }
            }
        }
    }

    return ( iItemIndex );
}