mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added missing #includes Added LUA scripting and console Changed the way tracers are visualized, so they work more like real tracers instead of a light fountain Fixed signedness of many grid variables used in GetMouseMapPos calls Fixed enemy weapon choosing: Sometimes a mortar is chosen but later rejected, but the grenade class was not reset. Caused assertion failure Added checks so enemies don't try to chuck RPG grenades with their hands Now possible to shoot a someone in the head if he's in water Fixed InitSightArrays to also clear soldier interrupt duel points. This was causing an assertion failure elsewhere in the code because the interrupt list still had soldiers on it sometimes when this function was called. Soldiers are much less willing to forfeit their turn over an attempt to use more APs than they have Removed early setting of muzzle flash. This would allow enemies to get an interrupt before you even fired. Fixed item dropping by AI. If AI tried to drop something while standing it would cause deadlock Change to greatly speed up closing the sector inventory window in an unloaded sector Added conditional compile flag to always give robot weapon ready advantage, even for 360 degree sighting Check builddefines.h for the conditional flags. Of greatest interest might be LUA_CONSOLE. This will cause the game to bring up a command console when run. However this console is severely lacking in many areas. If anybody knows of an open-source terminal/console that could be used instead, it would be appreciated. The existing console does bad things when you try to close it, and since it counts as a separate app, it pauses the game while it has focus. LUA scripting is very limited, basically just proof of concept. There is one global variable, the Soldiers array. An array index gives you the soldier in that slot in the currently loaded sector. The soldier has a few things that can be accessed: name (short name); fullname (long name); grid (current grid #, can be changed); walkto(grid) (function to walk to another grid); runto(grid) (function to run to another grid) git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@924 3b4a5df2-a311-0410-b5c6-a8a6f20db521
1002 lines
24 KiB
C++
1002 lines
24 KiB
C++
#ifdef PRECOMPILEDHEADERS
|
|
#include "Laptop All.h"
|
|
#include "IMP Skill Trait.h"
|
|
#include "GameSettings.h"
|
|
#else
|
|
#include "laptop.h"
|
|
#include "CharProfile.h"
|
|
#include "Utilities.h"
|
|
#include "WCheck.h"
|
|
#include "Debug.h"
|
|
#include "WordWrap.h"
|
|
#include "Render Dirty.h"
|
|
#include "Encrypted File.h"
|
|
#include "cursors.h"
|
|
#include "GameSettings.h"
|
|
#include "IMP HomePage.h"
|
|
#include "IMPVideoObjects.h"
|
|
#include "IMP AboutUs.h"
|
|
#include "IMP MainPage.h"
|
|
#include "IMP Begin Screen.h"
|
|
#include "IMP Personality Entrance.h"
|
|
#include "IMP Personality Quiz.h"
|
|
#include "IMP Personality Finish.h"
|
|
#include "IMP Skill Trait.h"
|
|
#include "IMP Attribute Entrance.h"
|
|
#include "IMP Attribute Selection.h"
|
|
#include "IMP Attribute Finish.h"
|
|
#include "IMP Portraits.h"
|
|
#include "IMP Compile Character.h"
|
|
#include "IMP Voices.h"
|
|
#include "IMP Finish.h"
|
|
#include "Soldier Profile Type.h"
|
|
#include "Soldier Profile.h"
|
|
#include "Animation Data.h"
|
|
#include "random.h"
|
|
#include "LaptopSave.h"
|
|
#endif
|
|
|
|
// how many times should a 'die' be rolled for skills of the same type?
|
|
|
|
#define HOW_MANY_ROLLS_FOR_SAME_SKILL_CHECK 20
|
|
|
|
INT32 AttitudeList[ ATTITUDE_LIST_SIZE ];
|
|
INT32 iLastElementInAttitudeList = 0;
|
|
|
|
INT32 SkillsList[ ATTITUDE_LIST_SIZE ];
|
|
INT32 BackupSkillsList[ ATTITUDE_LIST_SIZE ];
|
|
INT32 iLastElementInSkillsList = 0;
|
|
|
|
INT32 PersonalityList[ ATTITUDE_LIST_SIZE ];
|
|
INT32 iLastElementInPersonalityList = 0;
|
|
|
|
extern BOOLEAN fLoadingCharacterForPreviousImpProfile;
|
|
|
|
// positions of the face x and y for eyes and mouth for the 10 portraits
|
|
INT16 sFacePositions[ NUMBER_OF_PLAYER_PORTRAITS ][ 4 ]=
|
|
{
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
{0,0,0,0},
|
|
};
|
|
|
|
STR8 pPlayerSelectedFaceFileNames[ NUMBER_OF_PLAYER_PORTRAITS ]=
|
|
{
|
|
"Faces\\200.sti",
|
|
"Faces\\201.sti",
|
|
"Faces\\202.sti",
|
|
"Faces\\203.sti",
|
|
"Faces\\204.sti",
|
|
"Faces\\205.sti",
|
|
"Faces\\206.sti",
|
|
"Faces\\207.sti",
|
|
"Faces\\208.sti",
|
|
"Faces\\209.sti",
|
|
"Faces\\210.sti",
|
|
"Faces\\211.sti",
|
|
"Faces\\212.sti",
|
|
"Faces\\213.sti",
|
|
"Faces\\214.sti",
|
|
"Faces\\215.sti",
|
|
};
|
|
|
|
STR8 pPlayerSelectedBigFaceFileNames[ NUMBER_OF_PLAYER_PORTRAITS ]=
|
|
{
|
|
"Faces\\BigFaces\\200.sti",
|
|
"Faces\\BigFaces\\201.sti",
|
|
"Faces\\BigFaces\\202.sti",
|
|
"Faces\\BigFaces\\203.sti",
|
|
"Faces\\BigFaces\\204.sti",
|
|
"Faces\\BigFaces\\205.sti",
|
|
"Faces\\BigFaces\\206.sti",
|
|
"Faces\\BigFaces\\207.sti",
|
|
"Faces\\BigFaces\\208.sti",
|
|
"Faces\\BigFaces\\209.sti",
|
|
"Faces\\BigFaces\\210.sti",
|
|
"Faces\\BigFaces\\211.sti",
|
|
"Faces\\BigFaces\\212.sti",
|
|
"Faces\\BigFaces\\213.sti",
|
|
"Faces\\BigFaces\\214.sti",
|
|
"Faces\\BigFaces\\215.sti",
|
|
};
|
|
|
|
|
|
// function declarations
|
|
void SelectMercFace( void );
|
|
void SetMercSkinAndHairColors( void );
|
|
BOOLEAN ShouldThisMercHaveABigBody( void );
|
|
|
|
|
|
|
|
|
|
|
|
void CreateACharacterFromPlayerEnteredStats( void )
|
|
{
|
|
|
|
// Kaiden: Seems like as good a place as any to stash this function call to
|
|
// ensure that these lists don't get overwritten or Nulled due to the amount
|
|
// of changes and revisions that have been made to personalities and attitudes.
|
|
CreatePlayersPersonalitySkillsAndAttitude();
|
|
|
|
|
|
|
|
// copy over full name
|
|
wcscpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].zName, pFullName );
|
|
|
|
// the nickname
|
|
wcscpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].zNickname, pNickName );
|
|
|
|
// gender
|
|
if ( fCharacterIsMale == TRUE )
|
|
{
|
|
// male
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = MALE;
|
|
}
|
|
else
|
|
{
|
|
// female
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSex = FEMALE;
|
|
}
|
|
|
|
|
|
// attributes
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bLifeMax = ( INT8 )iHealth;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bLife = ( INT8 )iHealth;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bAgility = ( INT8 )iAgility;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bStrength = ( INT8 )iStrength;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bDexterity = ( INT8 )iDexterity;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bWisdom = ( INT8 )iWisdom;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bLeadership = ( INT8 )iLeadership;
|
|
|
|
|
|
// skills
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMarksmanship = ( INT8 )iMarksmanship;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMedical = ( INT8 )iMedical;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMechanical = ( INT8 )iMechanical;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bExplosive = ( INT8 )iExplosives;
|
|
|
|
|
|
// personality
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bPersonalityTrait = ( INT8 )iPersonality;
|
|
|
|
// attitude
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bAttitude = ( INT8 )iAttitude;
|
|
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bExpLevel = 1;
|
|
|
|
// set time away
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bMercStatus = 0;
|
|
|
|
|
|
|
|
// face
|
|
SelectMercFace( );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
BOOLEAN DoesCharacterHaveAnAttitude( void )
|
|
{
|
|
|
|
// simply checks if caracter has an attitude other than normal
|
|
switch( iAttitude )
|
|
{
|
|
case ATT_LONER:
|
|
case ATT_PESSIMIST:
|
|
case ATT_ARROGANT:
|
|
case ATT_BIG_SHOT:
|
|
case ATT_ASSHOLE:
|
|
case ATT_COWARD:
|
|
return( TRUE );
|
|
default:
|
|
return( FALSE );
|
|
}
|
|
}
|
|
|
|
|
|
BOOLEAN DoesCharacterHaveAPersoanlity( void )
|
|
{
|
|
|
|
|
|
if( iPersonality != NO_PERSONALITYTRAIT )
|
|
{
|
|
// yep
|
|
return ( TRUE );
|
|
}
|
|
else
|
|
{
|
|
// nope
|
|
return ( FALSE );
|
|
}
|
|
|
|
|
|
// Kaiden: Following is the original UB section:
|
|
// The fist return( FALSE ); Statement was the only
|
|
// thing uncommented.
|
|
/*
|
|
// only one we can get is PSYCHO, and that is not much of a penalty
|
|
return( FALSE );
|
|
|
|
// simply checks if caracter has a personality other than normal
|
|
if( iPersonality != NO_PERSONALITYTRAIT )
|
|
{
|
|
// yep
|
|
return ( TRUE );
|
|
}
|
|
else
|
|
{
|
|
// nope
|
|
return ( FALSE );
|
|
}
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
void CreatePlayerAttitude( void )
|
|
{
|
|
|
|
if(gGameSettings.fOptions[TOPTION_USE_RANDOM_PERSONALITY] == TRUE)
|
|
{
|
|
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 );
|
|
|
|
// 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 )
|
|
{
|
|
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 )
|
|
{
|
|
iHighestHits = __max( iHighestHits, iAttitudeHits[ iCounter ] );
|
|
iNumAttitudesWithHighestHits = 1;
|
|
}
|
|
else if ( iAttitudeHits[ iCounter ] == iHighestHits )
|
|
{
|
|
iNumAttitudesWithHighestHits++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// roll dice
|
|
iDiceValue = Random( iNumAttitudesWithHighestHits + 1 );
|
|
|
|
// find attitude
|
|
for ( iCounter = 0; iCounter < NUM_ATTITUDES; iCounter++ )
|
|
{
|
|
if ( iAttitudeHits[ iCounter ] == iHighestHits )
|
|
{
|
|
if ( iCounter2 == iDiceValue )
|
|
{
|
|
// this is it!
|
|
iAttitude = iCounter2;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
// one of the next attitudes...
|
|
iCounter2++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iAttitude = gGameExternalOptions.iCustomAttitude;
|
|
}
|
|
}
|
|
|
|
|
|
void AddAnAttitudeToAttitudeList( INT8 bAttitude )
|
|
{
|
|
// adds an attitude to attitude list
|
|
|
|
if( iLastElementInAttitudeList < ATTITUDE_LIST_SIZE)
|
|
{
|
|
// add element
|
|
AttitudeList[ iLastElementInAttitudeList ] = ( INT32 )bAttitude;
|
|
|
|
// increment attitude list counter
|
|
iLastElementInAttitudeList++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void AddSkillToSkillList( INT8 bSkill )
|
|
{
|
|
// adds a skill to skills list
|
|
|
|
if( iLastElementInSkillsList < ATTITUDE_LIST_SIZE)
|
|
{
|
|
// add element
|
|
SkillsList[ iLastElementInSkillsList ] = ( INT32 )bSkill;
|
|
|
|
// increment attitude list counter
|
|
iLastElementInSkillsList++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Kaiden : Added to clear the list when first visiting the IMP homepage,
|
|
// Or for each visit there after.
|
|
void ClearAllSkillsList( void )
|
|
{
|
|
INT32 iLoop;
|
|
|
|
for ( iLoop = 0; iLoop < iLastElementInSkillsList; iLoop++ )
|
|
{
|
|
SkillsList[ iLoop ] = 0;
|
|
}
|
|
iLastElementInSkillsList = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void RemoveSkillFromSkillsList( INT32 iIndex )
|
|
{
|
|
INT32 iLoop;
|
|
|
|
// remove a skill from the index given and shorten the list
|
|
if ( iIndex < iLastElementInSkillsList )
|
|
{
|
|
memset( BackupSkillsList, 0, ATTITUDE_LIST_SIZE * sizeof( INT32 ) );
|
|
|
|
// use the backup array to create a version of the array without
|
|
// this index
|
|
for ( iLoop = 0; iLoop < iIndex; iLoop++ )
|
|
{
|
|
BackupSkillsList[ iLoop ] = SkillsList[ iLoop ];
|
|
}
|
|
for ( iLoop = iIndex + 1; iLoop < iLastElementInSkillsList; iLoop++ )
|
|
{
|
|
BackupSkillsList[ iLoop - 1 ] = SkillsList[ iLoop ];
|
|
}
|
|
// now copy this over to the skills list
|
|
memcpy( SkillsList, BackupSkillsList, ATTITUDE_LIST_SIZE * sizeof( INT32 ) );
|
|
|
|
// reduce recorded size by 1
|
|
iLastElementInSkillsList--;
|
|
}
|
|
}
|
|
|
|
INT32 FindSkillInSkillsList( INT32 iSkill )
|
|
{
|
|
INT32 iLoop;
|
|
|
|
for ( iLoop = 0; iLoop < iLastElementInSkillsList; iLoop++ )
|
|
{
|
|
if ( SkillsList[ iLoop ] == iSkill )
|
|
{
|
|
return( iLoop );
|
|
}
|
|
}
|
|
|
|
return( -1 );
|
|
}
|
|
|
|
void ValidateSkillsList( void )
|
|
{
|
|
INT32 iIndex;//, iValue;
|
|
MERCPROFILESTRUCT * pProfile;
|
|
|
|
// remove from the generated traits list any traits that don't match
|
|
// the character's skills
|
|
pProfile = &(gMercProfiles[ LaptopSaveInfo.iIMPIndex ]);
|
|
if ( pProfile->bMechanical == 0 )
|
|
{
|
|
// without mechanical, electronics is useless
|
|
iIndex = FindSkillInSkillsList( ELECTRONICS );
|
|
if ( iIndex != -1 )
|
|
{
|
|
pProfile->bMechanical = 1;
|
|
}
|
|
}
|
|
|
|
// Kaiden using UB's code, lockpicking can't be removed from the list "yet".
|
|
// special check for lockpicking
|
|
//iValue = pProfile->bMechanical;
|
|
//iValue = ( iValue * pProfile->bWisdom ) / 100;
|
|
//iValue = ( iValue * pProfile->bDexterity ) / 100;
|
|
//if ( iValue + gbSkillTraitBonus[ LOCKPICKING ] < 50 )
|
|
//{
|
|
// // not good enough for lockpicking!
|
|
//
|
|
// // so is lockpicking
|
|
// iIndex = FindSkillInSkillsList( LOCKPICKING );
|
|
// while ( iIndex != -1 )
|
|
// {
|
|
// RemoveSkillFromSkillsList( iIndex );
|
|
// iIndex = FindSkillInSkillsList( LOCKPICKING );
|
|
// }
|
|
//}
|
|
|
|
if ( pProfile->bMarksmanship == 0 )
|
|
{
|
|
// without marksmanship, the following traits are useless:
|
|
// auto weapons, heavy weapons
|
|
iIndex = FindSkillInSkillsList( AUTO_WEAPS );
|
|
if( iIndex != -1 )
|
|
{
|
|
//RemoveSkillFromSkillsList( iIndex );
|
|
//iIndex = FindSkillInSkillsList( AUTO_WEAPS );
|
|
pProfile->bMarksmanship = 1;
|
|
}
|
|
// so is lockpicking
|
|
iIndex = FindSkillInSkillsList( HEAVY_WEAPS );
|
|
if( iIndex != -1 )
|
|
{
|
|
//RemoveSkillFromSkillsList( iIndex );
|
|
//iIndex = FindSkillInSkillsList( HEAVY_WEAPS );
|
|
pProfile->bMarksmanship = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreatePlayerSkills( void )
|
|
{
|
|
|
|
// this function will 'roll a die' and decide if any attitude does exists
|
|
INT32 iDiceValue = 0;
|
|
INT32 iCounter = 0;
|
|
|
|
ValidateSkillsList();
|
|
/* Kaiden - Commented out in UB to skip the whole random skill thing
|
|
// roll dice
|
|
iDiceValue = Random( iLastElementInSkillsList );
|
|
|
|
// set attitude
|
|
iSkillA = SkillsList[ iDiceValue ];
|
|
|
|
// second dice value
|
|
iDiceValue = Random( iLastElementInSkillsList );
|
|
|
|
iSkillB = SkillsList[ iDiceValue ];
|
|
*/
|
|
|
|
// Kaiden: This section was added in it's place:
|
|
if( iLastElementInSkillsList > 0 )
|
|
{
|
|
// set attitude
|
|
iSkillA = SkillsList[ 0 ];
|
|
}
|
|
|
|
if( iLastElementInSkillsList > 1 )
|
|
{
|
|
iSkillB = SkillsList[ 1 ];
|
|
}
|
|
else
|
|
{
|
|
iSkillB = SkillsList[ 0 ];
|
|
}
|
|
|
|
// allow expert level for generated merc so you CAN have two of the same
|
|
// but there is no such thing as expert level for electronics
|
|
|
|
|
|
while ( iSkillA == iSkillB && ( iSkillB == ELECTRONICS || iSkillB == AMBIDEXT ) )
|
|
{
|
|
// remove electronics as an option and roll again
|
|
RemoveSkillFromSkillsList( iDiceValue );
|
|
if ( iLastElementInSkillsList == 0 )
|
|
{
|
|
// ok, only one trait!
|
|
iSkillB = NO_SKILLTRAIT;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
iDiceValue = Random( iLastElementInSkillsList );
|
|
iSkillB = SkillsList[ iDiceValue ];
|
|
}
|
|
}
|
|
|
|
/*
|
|
// are the same,
|
|
// reroll until different, or until ATTITUDE_LIST_SIZE times
|
|
iSkillB = Random( iLastElementInSkillsList + 1 );
|
|
|
|
while( (iSkillA == iSkillB ) && ( iCounter < HOW_MANY_ROLLS_FOR_SAME_SKILL_CHECK ) )
|
|
{
|
|
// increment counter
|
|
iCounter++;
|
|
|
|
// next random
|
|
iSkillB = Random( iLastElementInSkillsList + 1 );
|
|
|
|
}
|
|
if( iCounter == ATTITUDE_LIST_SIZE )
|
|
{
|
|
iSkillB = NO_SKILLTRAIT;
|
|
}
|
|
return;
|
|
|
|
|
|
*/
|
|
}
|
|
|
|
|
|
void AddAPersonalityToPersonalityList( INT8 bPersonlity )
|
|
{
|
|
// CJC, Oct 26 98: prevent personality list from being generated
|
|
// because no dialogue was written to support PC personality quotes
|
|
|
|
// BUT we can manage this for PSYCHO okay
|
|
|
|
//Kaiden: But we're going to try it anyway screw dialoge.
|
|
// Commenting out the below if test
|
|
|
|
//if ( bPersonlity != PSYCHO )
|
|
//{
|
|
// return;
|
|
//}
|
|
|
|
// will add a persoanlity to persoanlity list
|
|
if( iLastElementInPersonalityList < ATTITUDE_LIST_SIZE)
|
|
{
|
|
// add element
|
|
PersonalityList[ iLastElementInPersonalityList ] = ( INT32 )bPersonlity;
|
|
|
|
// increment attitude list counter
|
|
iLastElementInPersonalityList++;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void CreatePlayerPersonality( void )
|
|
{
|
|
|
|
// Kaiden: Added for optional Mercenary personalities and attitudes
|
|
|
|
if(gGameSettings.fOptions[TOPTION_USE_RANDOM_PERSONALITY] == TRUE)
|
|
{
|
|
// 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 );
|
|
|
|
|
|
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.
|
|
for (iCounter2 = 0; iCounter2 < 20; iCounter2++)
|
|
{
|
|
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;
|
|
}
|
|
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( );
|
|
|
|
// attitude
|
|
CreatePlayerAttitude( );
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void ResetSkillsAttributesAndPersonality( void )
|
|
{
|
|
|
|
// reset count of skills attributes and personality
|
|
|
|
iLastElementInPersonalityList = 0;
|
|
|
|
iLastElementInSkillsList = 0;
|
|
|
|
iLastElementInAttitudeList = 0;
|
|
|
|
}
|
|
|
|
|
|
void ResetIncrementCharacterAttributes( void )
|
|
{
|
|
// this resets any increments due to character generation
|
|
|
|
// attributes
|
|
iAddStrength = 0;
|
|
iAddDexterity = 0;
|
|
iAddWisdom = 0;
|
|
iAddAgility = 0;
|
|
iAddHealth = 0;
|
|
iAddLeadership = 0;
|
|
|
|
// skills
|
|
iAddMarksmanship = 0;
|
|
iAddExplosives = 0;
|
|
iAddMedical = 0;
|
|
iAddMechanical = 0;
|
|
|
|
}
|
|
|
|
void SelectMercFace( void )
|
|
{
|
|
// this procedure will select the approriate face for the merc and save offsets
|
|
|
|
// grab face filename
|
|
// strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubUnusedFaceFileName , pPlayerSelectedFaceFileNames[ iPortraitNumber ]);
|
|
|
|
// now the offsets
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubFaceIndex = 200 + ( UINT8 )iPortraitNumber;
|
|
|
|
// eyes
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesX = sFacePositions[ iPortraitNumber ][ 0 ];
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usEyesY = sFacePositions[ iPortraitNumber ][ 1 ];
|
|
|
|
// mouth
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthX = sFacePositions[ iPortraitNumber ][ 2 ];
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].usMouthY = sFacePositions[ iPortraitNumber ][ 3 ];
|
|
|
|
// set merc skins and hair color
|
|
SetMercSkinAndHairColors( );
|
|
return;
|
|
}
|
|
|
|
void SetMercSkinAndHairColors( void )
|
|
{
|
|
enum{ PINKSKIN, TANSKIN, DARKSKIN, BLACKSKIN, NUMSKINS };
|
|
enum{ BROWNHEAD, BLACKHEAD, //black skin (only this line )
|
|
WHITEHEAD, //dark skin (this line plus all above)
|
|
BLONDHEAD, REDHEAD, //pink/tan skin (this line plus all above )
|
|
NUMHEADS
|
|
};
|
|
|
|
enum
|
|
{
|
|
WHITEVEST,
|
|
GYELLOWSHIRT,
|
|
YELLOWVEST,
|
|
GREYVEST,
|
|
BROWNVEST,
|
|
PURPLESHIRT,
|
|
BLUEVEST,
|
|
JEANVEST,
|
|
GREENVEST,
|
|
REDVEST,
|
|
BLACKSHIRT,
|
|
NUMSHIRTS
|
|
};//shirts
|
|
|
|
enum
|
|
{
|
|
BLUEPANTS,
|
|
BLACKPANTS,
|
|
JEANPANTS,
|
|
TANPANTS,
|
|
BEIGEPANTS,
|
|
GREENPANTS,
|
|
NUMPANTS
|
|
};//pants
|
|
|
|
// skin strings
|
|
STR sSkinStrings[]={
|
|
"PINKSKIN",
|
|
"TANSKIN",
|
|
"DARKSKIN",
|
|
"BLACKSKIN",
|
|
};
|
|
|
|
// the hair colors
|
|
STR sHairStrings[]={
|
|
"BROWNHEAD",
|
|
"BLACKHEAD",
|
|
"WHITEHEAD",
|
|
"BLONDHEAD",
|
|
"REDHEAD",
|
|
};
|
|
|
|
// shirts
|
|
STR sShirtStrings[]={
|
|
"WHITEVEST",
|
|
"GYELLOWSHIRT",
|
|
"YELLOWVEST",
|
|
"greyVEST",
|
|
"BROWNVEST",
|
|
"PURPLESHIRT",
|
|
"BLUEVEST",
|
|
"JEANVEST",
|
|
"GREENVEST",
|
|
"REDVEST",
|
|
"BLACKSHIRT",
|
|
};//shirts
|
|
|
|
|
|
// shirts
|
|
STR sPantStrings[]={
|
|
"BLUEPANTS",
|
|
"BLACKPANTS",
|
|
"JEANPANTS",
|
|
"TANPANTS",
|
|
"BEIGEPANTS",
|
|
"GREENPANTS",
|
|
};//pants
|
|
|
|
// given the portrait number, set the merc's skin and hair color
|
|
INT16 sSkinColor = 0, sHairColor = 0, sShirtColor, sPantColor;
|
|
|
|
switch( iPortraitNumber )
|
|
{
|
|
case( 0 ):
|
|
sSkinColor = BLACKSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = JEANVEST;
|
|
sPantColor = JEANPANTS;
|
|
break;
|
|
case( 1 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = TANPANTS;
|
|
break;
|
|
case( 2 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = WHITEVEST;
|
|
sPantColor = BLUEPANTS;
|
|
break;
|
|
case( 3 ):
|
|
sSkinColor = DARKSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = WHITEVEST;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 4 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = GREYVEST;
|
|
sPantColor = GREENPANTS;
|
|
break;
|
|
case( 5 ):
|
|
sSkinColor = DARKSKIN;
|
|
sHairColor = BLACKHEAD;
|
|
sShirtColor = GREYVEST;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 6 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = BLUEPANTS;
|
|
break;
|
|
case( 7 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = BLACKSHIRT;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 8 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = TANPANTS;
|
|
break;
|
|
case( 9 ):
|
|
sSkinColor = PINKSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = BEIGEPANTS;
|
|
break;
|
|
case( 10 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BLACKHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 11 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BLACKHEAD;
|
|
sShirtColor = BLACKSHIRT;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 12 ):
|
|
sSkinColor = PINKSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = WHITEVEST;
|
|
sPantColor = GREENPANTS;
|
|
break;
|
|
case( 13 ):
|
|
sSkinColor = BLACKSKIN;
|
|
sHairColor = BROWNHEAD;
|
|
sShirtColor = GREYVEST;
|
|
sPantColor = BLACKPANTS;
|
|
break;
|
|
case( 14 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = REDHEAD;
|
|
sShirtColor = WHITEVEST;
|
|
sPantColor = JEANPANTS;
|
|
break;
|
|
case( 15 ):
|
|
sSkinColor = TANSKIN;
|
|
sHairColor = BLONDHEAD;
|
|
sShirtColor = BROWNVEST;
|
|
sPantColor = GREENPANTS;
|
|
break;
|
|
}
|
|
|
|
// now set them
|
|
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].HAIR, sHairStrings[ sHairColor ] );
|
|
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].SKIN, sSkinStrings[ sSkinColor ] );
|
|
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].PANTS, sPantStrings[ sPantColor ] );
|
|
strcpy( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].VEST, sShirtStrings[ sShirtColor ] );
|
|
|
|
}
|
|
|
|
|
|
void HandleMercStatsForChangesInFace( )
|
|
{
|
|
if ( fLoadingCharacterForPreviousImpProfile )
|
|
{
|
|
return;
|
|
}
|
|
|
|
//add the skills to the skills list
|
|
AddSelectedSkillsToSkillsList();
|
|
|
|
// now figure out skills
|
|
CreatePlayerSkills();
|
|
|
|
// body type
|
|
if ( fCharacterIsMale )
|
|
{
|
|
// male
|
|
// big or regular
|
|
// Madd - don't override the skills - override the body type instead
|
|
if( ShouldThisMercHaveABigBody() && iSkillA != MARTIALARTS && iSkillB != MARTIALARTS )
|
|
{
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = BIGMALE;
|
|
|
|
//if( iSkillA == MARTIALARTS )
|
|
//{
|
|
// iSkillA = HANDTOHAND;
|
|
//}
|
|
//if( iSkillB == MARTIALARTS )
|
|
//{
|
|
// iSkillB = HANDTOHAND;
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGMALE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// female
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].ubBodyType = REGFEMALE;
|
|
|
|
if( iSkillA == MARTIALARTS )
|
|
{
|
|
iSkillA = HANDTOHAND;
|
|
}
|
|
if( iSkillB == MARTIALARTS )
|
|
{
|
|
iSkillB = HANDTOHAND;
|
|
}
|
|
}
|
|
|
|
|
|
// skill trait
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTrait = ( INT8 )iSkillA;
|
|
gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bSkillTrait2 = ( INT8 )iSkillB;
|
|
|
|
}
|
|
|
|
BOOLEAN ShouldThisMercHaveABigBody( void )
|
|
{
|
|
// should this merc be a big body type
|
|
// Madd - don't limit it by portrait
|
|
//if ( ( iPortraitNumber == 0 ) || ( iPortraitNumber == 6 ) || ( iPortraitNumber == 7 ) )
|
|
//{
|
|
if ( gMercProfiles[ LaptopSaveInfo.iIMPIndex ].bStrength >= 75 )
|
|
{
|
|
return( TRUE );
|
|
}
|
|
//}
|
|
|
|
return( FALSE );
|
|
} |