- bugfix: Getting incorrect data & CTDs when using multiple IMP characters with same voices. Now it is possible to have up to 6 merc with the same voice without getting incorrect data. No more need to use different voices! (IF YOU PLAY WITH MULTIPLE IMPS, YOU SHOULD START A NEW GAME, BECAUSE THE IMP CHARACTERS GAME DATA IS INCORRECT!)

- bugfix: CTD when using Random personality in I.M.P creation
- moved Random personality flag from INI to option screen
- added MAX_IMP_CHARACTERS entry in the ja2_options.ini (Range: 0 - 6)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@528 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2006-09-17 07:31:34 +00:00
parent c975007d4d
commit 18a1d0e519
17 changed files with 264 additions and 178 deletions
+3
View File
@@ -362,10 +362,13 @@ void BtnIMPBeginScreenDoneCallback(GUI_BUTTON *btn,INT32 reason)
}
else
{
// WANNE:
/*
if( CheckCharacterInputForEgg( ) )
{
fEggOnYouFace = TRUE;
}
*/
}
+120 -121
View File
@@ -249,84 +249,85 @@ BOOLEAN DoesCharacterHaveAPersoanlity( void )
void CreatePlayerAttitude( void )
{
// WANNE
if (gGameSettings.fOptions[ TOPTION_USE_RANDOM_PERSONALITY ] == TRUE)
//if(gGameExternalOptions.fPers_att)
{
AddAnAttitudeToAttitudeList( ATT_OPTIMIST );
AddAnAttitudeToAttitudeList( ATT_LONER );
AddAnAttitudeToAttitudeList( ATT_FRIENDLY );
AddAnAttitudeToAttitudeList( ATT_ARROGANT );
AddAnAttitudeToAttitudeList( ATT_NORMAL );
AddAnAttitudeToAttitudeList( ATT_ASSHOLE );
AddAnAttitudeToAttitudeList( ATT_COWARD );
AddAnAttitudeToAttitudeList( ATT_AGGRESSIVE );
AddAnAttitudeToAttitudeList( ATT_PESSIMIST );
AddAnAttitudeToAttitudeList( ATT_BIG_SHOT );
if(gGameExternalOptions.fPers_att)
// this function will 'roll a die' and decide if any attitude does exists
INT32 iDiceValue = 0;
INT32 iCounter = 0, iCounter2 = 0;
INT32 iAttitudeHits[NUM_ATTITUDES] = { 0 };
INT32 iHighestHits = 0;
INT32 iNumAttitudesWithHighestHits = 0;
iAttitude = ATT_NORMAL;
if ( iLastElementInAttitudeList == 0 )
{
AddAnAttitudeToAttitudeList( ATT_OPTIMIST );
AddAnAttitudeToAttitudeList( ATT_LONER );
AddAnAttitudeToAttitudeList( ATT_FRIENDLY );
AddAnAttitudeToAttitudeList( ATT_ARROGANT );
AddAnAttitudeToAttitudeList( ATT_NORMAL );
AddAnAttitudeToAttitudeList( ATT_ASSHOLE );
AddAnAttitudeToAttitudeList( ATT_COWARD );
AddAnAttitudeToAttitudeList( ATT_AGGRESSIVE );
AddAnAttitudeToAttitudeList( ATT_PESSIMIST );
AddAnAttitudeToAttitudeList( ATT_BIG_SHOT );
return;
}
// this function will 'roll a die' and decide if any attitude does exists
INT32 iDiceValue = 0;
INT32 iCounter = 0, iCounter2 = 0;
// count # of hits for each attitude
for ( iCounter = 0; iCounter < iLastElementInAttitudeList; iCounter++ )
{
iAttitudeHits[ AttitudeList[ iCounter ] ]++;
}
INT32 iAttitudeHits[NUM_ATTITUDES] = { 0 };
INT32 iHighestHits = 0;
INT32 iNumAttitudesWithHighestHits = 0;
iAttitude = ATT_NORMAL;
if ( iLastElementInAttitudeList == 0 )
// find highest # of hits for any attitude
for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
{
if ( iAttitudeHits[ iCounter ] )
{
return;
}
// count # of hits for each attitude
for ( iCounter = 0; iCounter < iLastElementInAttitudeList; iCounter++ )
{
iAttitudeHits[ AttitudeList[ iCounter ] ]++;
}
// find highest # of hits for any attitude
for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
{
if ( iAttitudeHits[ iCounter ] )
if ( iAttitudeHits[ iCounter ] > iHighestHits )
{
if ( iAttitudeHits[ iCounter ] > iHighestHits )
{
iHighestHits = __max( iHighestHits, iAttitudeHits[ iCounter ] );
iNumAttitudesWithHighestHits = 1;
}
else if ( iAttitudeHits[ iCounter ] == iHighestHits )
{
iNumAttitudesWithHighestHits++;
}
iHighestHits = __max( iHighestHits, iAttitudeHits[ iCounter ] );
iNumAttitudesWithHighestHits = 1;
}
}
// roll dice
iDiceValue = Random( iNumAttitudesWithHighestHits + 1 );
// find attitude
for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
{
if ( iAttitudeHits[ iCounter ] == iHighestHits )
else if ( iAttitudeHits[ iCounter ] == iHighestHits )
{
if ( iCounter2 == iDiceValue )
{
// this is it!
iAttitude = iCounter2;
break;
}
else
{
// one of the next attitudes...
iCounter2++;
}
iNumAttitudesWithHighestHits++;
}
}
}
else
// roll dice
iDiceValue = Random( iNumAttitudesWithHighestHits + 1 );
// find attitude
for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
{
iAttitude = gGameExternalOptions.iCustomAttitude;
if ( iAttitudeHits[ iCounter ] == iHighestHits )
{
if ( iCounter2 == iDiceValue )
{
// this is it!
iAttitude = iCounter2;
break;
}
else
{
// one of the next attitudes...
iCounter2++;
}
}
}
}
else
{
iAttitude = gGameExternalOptions.iCustomAttitude;
}
}
@@ -592,84 +593,82 @@ void AddAPersonalityToPersonalityList( INT8 bPersonlity )
void CreatePlayerPersonality( void )
{
// WANNE
if (gGameSettings.fOptions[ TOPTION_USE_RANDOM_PERSONALITY ] == TRUE)
// Kaiden: Added for optional Mercenary personalities and attitudes
//if(gGameExternalOptions.fPers_att)
{
// Kaiden: More chances for Psycho and Normal.
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( FORGETFUL );
AddAPersonalityToPersonalityList( NERVOUS );
AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
AddAPersonalityToPersonalityList( NONSWIMMER );
AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( FORGETFUL );
AddAPersonalityToPersonalityList( NERVOUS );
AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
AddAPersonalityToPersonalityList( NONSWIMMER );
AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
if(gGameExternalOptions.fPers_att)
INT32 iDiceValue = 0;
INT32 iCounter = 0;
INT32 iCounter2 = 0;
// Kaiden: Roll dice 20 times just to be on the safe side
// was getting too many repeats. Will end up scrapping
// rand() later anyway so will worry about fixing it then.
// WANNE: No need to make a 20 times repeat
/*for (iCounter2 = 0; iCounter2 < 20; iCounter2++)
{
// Kaiden: More chances for Psycho and Normal.
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( FORGETFUL );
AddAPersonalityToPersonalityList( NERVOUS );
AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
AddAPersonalityToPersonalityList( NONSWIMMER );
AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( FORGETFUL );
AddAPersonalityToPersonalityList( NERVOUS );
AddAPersonalityToPersonalityList( HEAT_INTOLERANT );
AddAPersonalityToPersonalityList( NO_PERSONALITYTRAIT );
AddAPersonalityToPersonalityList( PSYCHO );
AddAPersonalityToPersonalityList( CLAUSTROPHOBIC );
AddAPersonalityToPersonalityList( NONSWIMMER );
AddAPersonalityToPersonalityList( FEAR_OF_INSECTS );
iDiceValue = Random( iLastElementInPersonalityList + 1 );
}*/
iDiceValue = Random( iLastElementInPersonalityList + 1 );
INT32 iDiceValue = 0;
INT32 iCounter = 0;
INT32 iCounter2 = 0;
// Kaiden two chances to avoid a normal personality. As IMP
// says, They check it twice just to make sure :p
for( iCounter = 0; iCounter < iLastElementInPersonalityList; iCounter++ )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("iDiceValue = %d",iDiceValue));
// Kaiden: Roll dice 20 times just to be on the safe side
// was getting too many repeats. Will end up scrapping
// rand() later anyway so will worry about fixing it then.
for (iCounter2 = 0; iCounter < 20; iCounter2++)
if( PersonalityList[ iDiceValue ] == NO_PERSONALITYTRAIT )
{
//Kaiden: Roll one more time for good measure:
iDiceValue = Random( iLastElementInPersonalityList + 1 );
}
// Kaiden two chances to avoid a normal personality. As IMP
// says, They check it twice just to make sure :p
for( iCounter = 0; iCounter < iLastElementInPersonalityList; iCounter++ )
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("iDiceValue = %d",iDiceValue));
if( PersonalityList[ iDiceValue ] = NO_PERSONALITYTRAIT )
{
//Kaiden: Roll one more time for good measure:
iDiceValue = Random( iLastElementInPersonalityList + 1 );
}
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("And our Personality is... = %d",PersonalityList[ iDiceValue ]));
iPersonality = PersonalityList[ iDiceValue ];
}
else
{
iPersonality = gGameExternalOptions.iCustomPersonality;
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("And our Personality is... = %d",PersonalityList[ iDiceValue ]));
iPersonality = PersonalityList[ iDiceValue ];
}
else
{
iPersonality = gGameExternalOptions.iCustomPersonality;
}
return;
}
void CreatePlayersPersonalitySkillsAndAttitude( void )
{
// creates personality, skills and attitudes from curretly built list
// personality
CreatePlayerPersonality( );
// skills are now created later after stats have been chosen
//CreatePlayerSkills( );
//CreatePlayerSkills( );
// attitude
CreatePlayerAttitude( );
@@ -933,7 +932,7 @@ void HandleMercStatsForChangesInFace( )
return;
}
//add the skills to the skills list
//add the skills to the skills listgMercProfiles
AddSelectedSkillsToSkillsList();
// now figure out skills
+48 -4
View File
@@ -210,11 +210,46 @@ void DestroyConfirmButtons( void )
return;
}
INT32 GetCurrentIMPSlot( void )
{
INT16 iFilledSlot = PLAYER_GENERATED_CHARACTER_ID;
INT16 i;
for (i = PLAYER_GENERATED_CHARACTER_ID + gGameExternalOptions.iMaxIMPCharacters - 1; i >= PLAYER_GENERATED_CHARACTER_ID; i--)
{
// We found the current imp
if (wcscmp( gMercProfiles[i].zName, L"") != 0)
{
iFilledSlot = i;
break;
}
}
return iFilledSlot;
}
// WANNE 10:
INT32 GetNextFreeIMPSlot( void )
{
INT16 iFreeSlot = -1;
INT16 i;
for (i = PLAYER_GENERATED_CHARACTER_ID; i < PLAYER_GENERATED_CHARACTER_ID + gGameExternalOptions.iMaxIMPCharacters; i++)
{
if (wcscmp( gMercProfiles[i].zName, L"") == 0)
{
iFreeSlot = i;
break;
}
}
return iFreeSlot;
}
BOOLEAN AddCharacterToPlayersTeam( void )
{
INT32 iFreeIMPSlot = 0;
MERC_HIRE_STRUCT HireMercStruct;
@@ -225,7 +260,10 @@ BOOLEAN AddCharacterToPlayersTeam( void )
memset(&HireMercStruct, 0, sizeof(MERC_HIRE_STRUCT));
HireMercStruct.ubProfileID = ( UINT8 )( PLAYER_GENERATED_CHARACTER_ID + LaptopSaveInfo.iVoiceId ) ;
//HireMercStruct.ubProfileID = ( UINT8 )( PLAYER_GENERATED_CHARACTER_ID + LaptopSaveInfo.iVoiceId ) ;
// Get the current imp slot (imp is already stored)
HireMercStruct.ubProfileID = GetCurrentIMPSlot();
if( fLoadingCharacterForPreviousImpProfile == FALSE )
{
@@ -755,6 +793,9 @@ void LoadImpCharacter( STR nickName )
return;
}
// WANNE 10: set the next free profile id for the new imp
iProfileId = GetNextFreeIMPSlot();
// read in the profile
if (!FileRead(hFile, &gMercProfiles[ iProfileId ] ,sizeof( MERCPROFILESTRUCT ), &uiBytesRead))
{
@@ -777,8 +818,11 @@ void LoadImpCharacter( STR nickName )
fLoadingCharacterForPreviousImpProfile = TRUE;
AddTransactionToPlayersBook(IMP_PROFILE,0, GetWorldTotalMin( ), - ( COST_OF_PROFILE ) );
AddHistoryToPlayersLog( HISTORY_CHARACTER_GENERATED, 0,GetWorldTotalMin( ), -1, -1 );
LaptopSaveInfo.iVoiceId = iProfileId - PLAYER_GENERATED_CHARACTER_ID;
AddCharacterToPlayersTeam( );
LaptopSaveInfo.iVoiceId = iProfileId - PLAYER_GENERATED_CHARACTER_ID;
AddCharacterToPlayersTeam( );
AddFutureDayStrategicEvent( EVENT_DAY2_ADD_EMAIL_FROM_IMP, 60 * 7, 0, 2 );
LaptopSaveInfo.fIMPCompletedFlag = TRUE;
fPausedReDrawScreenFlag = TRUE;
+4
View File
@@ -15,5 +15,9 @@ void ResetIMPCharactersEyesAndMouthOffsets( UINT8 ubMercProfileID );
BOOLEAN ImpExists ( STR fileName );
// WANNE 10:
INT32 GetNextFreeIMPSlot( void );
INT32 GetCurrentIMPSlot( void );
#endif
+38 -28
View File
@@ -382,6 +382,8 @@ void HandleTextEvent( UINT32 uiKey )
void ProcessPlayerInputActivationString( void )
{
INT16 iNextSlot = -1;
// prcess string to see if it matches activation string
if( NumberOfMercsOnPlayerTeam() >= 18 )
@@ -390,39 +392,47 @@ void ProcessPlayerInputActivationString( void )
char charPlayerActivationString[32];
wcstombs(charPlayerActivationString,pPlayerActivationString,32);
//Madd multiple imps if( ( ( wcscmp(pPlayerActivationString, L"XEP624") == 0 ) || ( wcscmp(pPlayerActivationString, L"xep624") == 0 ) )&&( LaptopSaveInfo.fIMPCompletedFlag == FALSE ) &&( LaptopSaveInfo.gfNewGameLaptop < 2 ) )
if( ( ( wcscmp(pPlayerActivationString, L"XEP624") == 0 ) || ( wcscmp(pPlayerActivationString, L"xep624") == 0 ) ) &&( LaptopSaveInfo.gfNewGameLaptop < 2 ) )
iNextSlot = GetNextFreeIMPSlot();
// We have at least one more free slot for a imp character
if (iNextSlot != -1)
{
// Kaiden: Need to reset skills, attributes and personalities with the new UB Method.
ResetSkillsAttributesAndPersonality( );
ClearAllSkillsList( );
iCurrentImpPage = IMP_MAIN_PAGE;
//Madd multiple imps if( ( ( wcscmp(pPlayerActivationString, L"XEP624") == 0 ) || ( wcscmp(pPlayerActivationString, L"xep624") == 0 ) )&&( LaptopSaveInfo.fIMPCompletedFlag == FALSE ) &&( LaptopSaveInfo.gfNewGameLaptop < 2 ) )
if( ( ( wcscmp(pPlayerActivationString, L"XEP624") == 0 ) || ( wcscmp(pPlayerActivationString, L"xep624") == 0 ) ) &&( LaptopSaveInfo.gfNewGameLaptop < 2 ) )
{
// Kaiden: Need to reset skills, attributes and personalities with the new UB Method.
ResetSkillsAttributesAndPersonality( );
ClearAllSkillsList( );
iCurrentImpPage = IMP_MAIN_PAGE;
}
//Madd multiple imps else if( ( wcscmp(pPlayerActivationString, L"90210") == 0 ) && ( LaptopSaveInfo.fIMPCompletedFlag == FALSE ) )
else if( wcscmp(pPlayerActivationString, L"90210") == 0 )
{
LoadImpCharacter( IMP_MERC_FILENAME );
}
// Madd: load characters by name
else if ( ImpExists( charPlayerActivationString ) )
{
LoadImpCharacter( charPlayerActivationString );
}
else
{
if( ( ( wcscmp(pPlayerActivationString, L"XEP624") != 0 ) && ( wcscmp(pPlayerActivationString, L"xep624") != 0 ) ) )
{
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 0 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
}
else if( LaptopSaveInfo.fIMPCompletedFlag == TRUE )
{
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 6 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
}
}
}
//Madd multiple imps else if( ( wcscmp(pPlayerActivationString, L"90210") == 0 ) && ( LaptopSaveInfo.fIMPCompletedFlag == FALSE ) )
else if( wcscmp(pPlayerActivationString, L"90210") == 0 )
else
{
LoadImpCharacter( IMP_MERC_FILENAME );
}
// Madd: load characters by name
else if ( ImpExists( charPlayerActivationString ) )
{
LoadImpCharacter( charPlayerActivationString );
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 7 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
}
else
{
if( ( ( wcscmp(pPlayerActivationString, L"XEP624") != 0 ) && ( wcscmp(pPlayerActivationString, L"xep624") != 0 ) ) )
{
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 0 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
}
else if( LaptopSaveInfo.fIMPCompletedFlag == TRUE )
{
DoLapTopMessageBox( MSG_BOX_IMP_STYLE, pImpPopUpStrings[ 6 ], LAPTOP_SCREEN, MSG_BOX_FLAG_OK, NULL);
}
}
return;
}
+15 -8
View File
@@ -2,6 +2,7 @@
#include "Laptop All.h"
#else
#include "CharProfile.h"
#include "IMP Confirm.h"
#include "IMP Voices.h"
#include "IMP MainPage.h"
#include "IMP HomePage.h"
@@ -383,14 +384,20 @@ void BtnIMPVoicesDoneCallback(GUI_BUTTON *btn,INT32 reason)
}
*/
// set voice id, to grab character slot
if( fCharacterIsMale == TRUE )
{
LaptopSaveInfo.iVoiceId = iCurrentVoices;
}
else
{
LaptopSaveInfo.iVoiceId = iCurrentVoices + 3;
}
// WANNE 10:
//if( fCharacterIsMale == TRUE )
//{
// LaptopSaveInfo.iVoiceId = iCurrentVoices;
//}
//else
//{
// LaptopSaveInfo.iVoiceId = iCurrentVoices + 3;
//}
// Get the next free imp slot
LaptopSaveInfo.iVoiceId = GetNextFreeIMPSlot() - PLAYER_GENERATED_CHARACTER_ID;
// set button up image pending
fButtonPendingFlag = TRUE;
+4 -3
View File
@@ -98,18 +98,19 @@ void RenderProfileBackGround( void )
// get the video object
GetVideoObject(&hHandle, guiBACKGROUND);
// WANNE
// render each row 5 times wide, 5 tiles high
for(iCounter = 0; iCounter < 4; iCounter++)
{
// blt background to screen from left to right
BltVideoObject(FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X + 0 * CHAR_PROFILE_BACKGROUND_TILE_WIDTH, LAPTOP_SCREEN_WEB_UL_Y + iCounter * CHAR_PROFILE_BACKGROUND_TILE_HEIGHT, VO_BLT_SRCTRANSPARENCY,NULL);
BltVideoObject(FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X + 1 * CHAR_PROFILE_BACKGROUND_TILE_WIDTH, LAPTOP_SCREEN_WEB_UL_Y + iCounter * CHAR_PROFILE_BACKGROUND_TILE_HEIGHT, VO_BLT_SRCTRANSPARENCY,NULL);
BltVideoObject(FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X + 1 * CHAR_PROFILE_BACKGROUND_TILE_WIDTH, LAPTOP_SCREEN_WEB_UL_Y + iCounter * CHAR_PROFILE_BACKGROUND_TILE_HEIGHT, VO_BLT_SRCTRANSPARENCY,NULL);
BltVideoObject(FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X + 2 * CHAR_PROFILE_BACKGROUND_TILE_WIDTH, LAPTOP_SCREEN_WEB_UL_Y + iCounter * CHAR_PROFILE_BACKGROUND_TILE_HEIGHT, VO_BLT_SRCTRANSPARENCY,NULL);
BltVideoObject(FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X + 3 * CHAR_PROFILE_BACKGROUND_TILE_WIDTH, LAPTOP_SCREEN_WEB_UL_Y + iCounter * CHAR_PROFILE_BACKGROUND_TILE_HEIGHT, VO_BLT_SRCTRANSPARENCY,NULL);
}
// dirty buttons
MarkButtonsDirty( );