1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480 |
- #ifdef PRECOMPILEDHEADERS
- #include "Tactical All.h"
- #else
- #include <stdio.h>
- #include <string.h>
- #include "wcheck.h"
- #include "stdlib.h"
- #include "debug.h"
- #include "math.h"
- #include "worlddef.h"
- #include "worldman.h"
- #include "renderworld.h"
- #include "Soldier Control.h"
- #include "Animation Control.h"
- #include "Animation Data.h"
- #include "Isometric Utils.h"
- #include "Event Pump.h"
- #include "Timer Control.h"
- #include "Render Fun.h"
- #include "Render Dirty.h"
- #include "mousesystem.h"
- #include "interface.h"
- #include "sysutil.h"
- #include "FileMan.h"
- #include "points.h"
- #include "Random.h"
- #include "ai.h"
- #include "Interactive Tiles.h"
- #include "soldier ani.h"
- #include "english.h"
- #include "overhead.h"
- #include "Soldier Profile.h"
- #include "Game Clock.h"
- #include "assignments.h"
- #include "Dialogue Control.h"
- #include "soldier create.h"
- #include "soldier add.h"
- #include "opplist.h"
- #include "weapons.h"
- #include "Strategic Town Loyalty.h"
- #include "squads.h"
- #include "Tactical Save.h"
- #include "Quests.h"
- #include "aim.h"
- #include "Interface Dialogue.h"
- #include "GameSettings.h"
- #include "strategic town reputation.h"
- #endif
- #ifdef JA2EDITOR
- extern BOOLEAN gfProfileDataLoaded;
- #endif
- BOOLEAN gfPotentialTeamChangeDuringDeath = FALSE;
- #define MIN_BLINK_FREQ 3000
- #define MIN_EXPRESSION_FREQ 2000
- #define SET_PROFILE_GAINS2 500, 500, 500, 500, 500, 500, 500, 500, 500
- MERCPROFILESTRUCT gMercProfiles[ NUM_PROFILES ];
- INT8 gbSkillTraitBonus[NUM_SKILLTRAITS] =
- {
- 0, //NO_SKILLTRAIT
- 25, //LOCKPICKING
- 15, //HANDTOHAND
- 15, //ELECTRONICS
- 15, //NIGHTOPS
- 12, //THROWING
- 15, //TEACHING
- 15, //HEAVY_WEAPS
- 0, //AUTO_WEAPS
- 15, //STEALTHY
- 0, //AMBIDEXT
- 0, //THIEF // UNUSED!
- 30, //MARTIALARTS
- 30, //KNIFING
- 15, //ONROOF
- 0, //CAMOUFLAGED
- };
- UINT8 gubBasicInventoryPositions[] = {
- HELMETPOS,
- VESTPOS,
- LEGPOS,
- HANDPOS,
- BIGPOCK1POS,
- BIGPOCK2POS,
- BIGPOCK3POS,
- BIGPOCK4POS
- };
- #define NUM_TERRORISTS 6
- UINT8 gubTerrorists[NUM_TERRORISTS + 1] =
- {
- DRUGGIST,
- SLAY,
- ANNIE,
- CHRIS,
- TIFFANY,
- T_REX,
- 0
- };
- UINT8 gubNumTerrorists = 0;
- #define NUM_TERRORIST_POSSIBLE_LOCATIONS 5
- INT16 gsTerroristSector[NUM_TERRORISTS][NUM_TERRORIST_POSSIBLE_LOCATIONS][2] =
- {
- // Elgin... preplaced
- {
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 },
- { 0, 0 }
- },
- // Slay
- {
- { 9, MAP_ROW_F },
- { 14, MAP_ROW_I },
- { 1, MAP_ROW_G },
- { 2, MAP_ROW_G },
- { 8, MAP_ROW_G }
- },
- // Matron
- {
- { 14, MAP_ROW_I },
- { 6, MAP_ROW_C },
- { 2, MAP_ROW_B },
- { 11, MAP_ROW_L },
- { 8, MAP_ROW_G }
- },
- // Imposter
- {
- { 1, MAP_ROW_G },
- { 9, MAP_ROW_F },
- { 11, MAP_ROW_L },
- { 8, MAP_ROW_G },
- { 2, MAP_ROW_G }
- },
- // Tiffany
- {
- { 14, MAP_ROW_I },
- { 2, MAP_ROW_G },
- { 14, MAP_ROW_H },
- { 6, MAP_ROW_C },
- { 2, MAP_ROW_B }
- },
- // Rexall
- {
- { 9, MAP_ROW_F },
- { 14, MAP_ROW_H },
- { 2, MAP_ROW_H },
- { 1, MAP_ROW_G },
- { 2, MAP_ROW_B }
- }
- };
- INT16 gsRobotGridNo;
- #define NUM_ASSASSINS 6
- UINT8 gubAssassins[NUM_ASSASSINS] =
- {
- JIM,
- JACK,
- OLAF,
- RAY,
- OLGA,
- TYRONE
- };
- #define NUM_ASSASSIN_POSSIBLE_TOWNS 5
- INT8 gbAssassinTown[NUM_ASSASSINS][NUM_ASSASSIN_POSSIBLE_TOWNS] =
- {
- // Jim
- { CAMBRIA, DRASSEN, ALMA, BALIME, GRUMM },
- // Jack
- { CHITZENA, ESTONI, ALMA, BALIME, GRUMM },
- // Olaf
- { DRASSEN, ESTONI, ALMA, CAMBRIA, BALIME },
- // Ray
- { CAMBRIA, OMERTA, BALIME, GRUMM, DRASSEN },
- // Olga
- { CHITZENA, OMERTA, CAMBRIA, ALMA, GRUMM },
- // Tyrone
- { CAMBRIA, BALIME, ALMA, GRUMM, DRASSEN },
- };
- UINT16 CalcCompetence( MERCPROFILESTRUCT * pProfile );
- INT16 CalcMedicalDeposit( MERCPROFILESTRUCT * pProfile );
- extern void HandleEndDemoInCreatureLevel( );
- void DecideActiveTerrorists( void );
- extern SOLDIERTYPE *gpSMCurrentMerc;
- extern BOOLEAN gfRerenderInterfaceFromHelpText;
- BOOLEAN LoadMercProfiles(void)
- {
- // FILE *fptr;
- HWFILE fptr;
- char *pFileName = "BINARYDATA\\Prof.dat";
- UINT32 uiLoop, uiLoop2, uiLoop3;
- UINT16 usItem, usNewGun, usAmmo, usNewAmmo;
- UINT32 uiNumBytesRead;
- fptr = FileOpen(pFileName, FILE_ACCESS_READ, FALSE );
- if( !fptr )
- {
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to LoadMercProfiles from file %s", pFileName) );
- return(FALSE);
- }
- for(uiLoop=0; uiLoop< NUM_PROFILES; uiLoop++)
- {
- if( JA2EncryptedFileRead( fptr, &gMercProfiles[uiLoop], sizeof( MERCPROFILESTRUCT ), &uiNumBytesRead ) != 1)
- {
- DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("FAILED to Read Merc Profiles from File %d %s",uiLoop, pFileName) );
- FileClose( fptr );
- return(FALSE);
- }
-
- //if the Dialogue exists for the merc, allow the merc to be hired
- if( DialogueDataFileExistsForProfile( (UINT8)uiLoop, 0, FALSE, NULL ) )
- {
- gMercProfiles[uiLoop].bMercStatus = 0;
- }
- else
- gMercProfiles[uiLoop].bMercStatus = MERC_HAS_NO_TEXT_FILE;
- // if the merc has a medical deposit
- if( gMercProfiles[ uiLoop ].bMedicalDeposit )
- {
- gMercProfiles[uiLoop].sMedicalDepositAmount = CalcMedicalDeposit( &gMercProfiles[uiLoop]);
- }
- else
- gMercProfiles[uiLoop].sMedicalDepositAmount = 0;
- // ATE: New, face display indipendent of ID num now
- // Setup face index value
- // Default is the ubCharNum
- gMercProfiles[uiLoop].ubFaceIndex = (UINT8)uiLoop;
- #ifndef JA2DEMO
- if ( !gGameOptions.fGunNut )
- {
- // CJC: replace guns in profile if they aren't available
- for ( uiLoop2 = 0; uiLoop2 < NUM_INV_SLOTS; uiLoop2++ )
- {
- usItem = gMercProfiles[uiLoop].inv[ uiLoop2 ];
- if ( ( Item[ usItem ].usItemClass & IC_GUN ) && ExtendedGunListGun( usItem ) )
- {
- usNewGun = StandardGunListReplacement( usItem );
- if ( usNewGun != NOTHING )
- {
- gMercProfiles[uiLoop].inv[ uiLoop2 ] = usNewGun;
- // must search through inventory and replace ammo accordingly
- for ( uiLoop3 = 0; uiLoop3 < NUM_INV_SLOTS; uiLoop3++ )
- {
- usAmmo = gMercProfiles[ uiLoop ].inv[ uiLoop3 ];
- if ( (Item[ usAmmo ].usItemClass & IC_AMMO) )
- {
- usNewAmmo = FindReplacementMagazineIfNecessary( usItem, usAmmo, usNewGun );
- if (usNewAmmo != NOTHING );
- {
- // found a new magazine, replace...
- gMercProfiles[ uiLoop ].inv[ uiLoop3 ] = usNewAmmo;
- }
- }
- }
- }
- }
- }
- } // end of if not gun nut
- #endif
- //ATE: Calculate some inital attractiveness values for buddy's inital equipment...
- // Look for gun and armour
- gMercProfiles[uiLoop].bMainGunAttractiveness = -1;
- gMercProfiles[uiLoop].bArmourAttractiveness = -1;
- for ( uiLoop2 = 0; uiLoop2 < NUM_INV_SLOTS; uiLoop2++ )
- {
- usItem = gMercProfiles[uiLoop].inv[ uiLoop2 ];
- if ( usItem != NOTHING )
- {
- // Check if it's a gun
- if ( Item[ usItem ].usItemClass & IC_GUN )
- {
- gMercProfiles[uiLoop].bMainGunAttractiveness = Weapon[ usItem ].ubDeadliness;
- }
- // If it's armour
- if ( Item[ usItem ].usItemClass & IC_ARMOUR )
- {
- gMercProfiles[uiLoop].bArmourAttractiveness = Armour[ Item[ usItem ].ubClassIndex ].ubProtection;
- }
- }
- }
- // OK, if we are a created slot, this will get overriden at some time..
- //add up the items the merc has for the usOptionalGearCost
- gMercProfiles[ uiLoop ].usOptionalGearCost = 0;
- for ( uiLoop2 = 0; uiLoop2< NUM_INV_SLOTS; uiLoop2++ )
- {
- if ( gMercProfiles[ uiLoop ].inv[ uiLoop2 ] != NOTHING )
- {
- //get the item
- usItem = gMercProfiles[ uiLoop ].inv[ uiLoop2 ];
-
- //add the cost
- gMercProfiles[ uiLoop ].usOptionalGearCost += Item[ usItem ].usPrice;
- }
- }
- //These variables to get loaded in
- gMercProfiles[ uiLoop ].fUseProfileInsertionInfo = FALSE;
- gMercProfiles[ uiLoop ].sGridNo = 0;
- // ARM: this is also being done inside the profile editor, but put it here too, so this project's code makes sense
- gMercProfiles[ uiLoop ].bHatedCount[0] = gMercProfiles[ uiLoop ].bHatedTime[0];
- gMercProfiles[ uiLoop ].bHatedCount[1] = gMercProfiles[ uiLoop ].bHatedTime[1];
- gMercProfiles[ uiLoop ].bLearnToHateCount = gMercProfiles[ uiLoop ].bLearnToHateTime;
- gMercProfiles[ uiLoop ].bLearnToLikeCount = gMercProfiles[ uiLoop ].bLearnToLikeTime;
- }
- // SET SOME DEFAULT LOCATIONS FOR STARTING NPCS
- FileClose( fptr );
- // decide which terrorists are active
- #ifndef JA2DEMO
- DecideActiveTerrorists();
- #endif
- // initialize mercs' status
- StartSomeMercsOnAssignment( );
- // initial recruitable mercs' reputation in each town
- InitializeProfilesForTownReputation( );
- #ifdef JA2EDITOR
- gfProfileDataLoaded = TRUE;
- #endif
- // no better place..heh?.. will load faces for profiles that are 'extern'.....won't have soldiertype instances
- InitalizeStaticExternalNPCFaces( );
- // car portrait values
- LoadCarPortraitValues( );
- return(TRUE);
- }
- #define MAX_ADDITIONAL_TERRORISTS 4
- void DecideActiveTerrorists( void )
- {
- UINT8 ubLoop, ubLoop2;
- UINT8 ubTerrorist;
- UINT8 ubNumAdditionalTerrorists, ubNumTerroristsAdded = 0;
- UINT32 uiChance, uiLocationChoice;
- BOOLEAN fFoundSpot;
- INT16 sTerroristPlacement[MAX_ADDITIONAL_TERRORISTS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
-
- #ifdef CRIPPLED_VERSION
- return;
- #endif
- // one terrorist will always be Elgin
- // determine how many more terrorists - 2 to 4 more
- // using this stochastic process(!), the chances for terrorists are:
- // EASY: 3, 9% 4, 42% 5, 49%
- // MEDIUM: 3, 25% 4, 50% 5, 25%
- // HARD: 3, 49% 4, 42% 5, 9%
- switch( gGameOptions.ubDifficultyLevel )
- {
- case DIF_LEVEL_EASY:
- uiChance = 70;
- break;
- case DIF_LEVEL_HARD:
- uiChance = 30;
- break;
- default:
- uiChance = 50;
- break;
- }
- // add at least 2 more
- ubNumAdditionalTerrorists = 2;
- for (ubLoop = 0; ubLoop < (MAX_ADDITIONAL_TERRORISTS - 2); ubLoop++)
- {
- if (Random( 100 ) < uiChance)
- {
- ubNumAdditionalTerrorists++;
- }
- }
- // ifdefs added by CJC
- #ifdef JA2TESTVERSION
- ubNumAdditionalTerrorists = 4;
- #endif
- while ( ubNumTerroristsAdded < ubNumAdditionalTerrorists )
- {
- ubLoop = 1; // start at beginning of array (well, after Elgin)
- // NB terrorist ID of 0 indicates end of array
- while ( ubNumTerroristsAdded < ubNumAdditionalTerrorists && gubTerrorists[ ubLoop ] != 0 )
- {
- ubTerrorist = gubTerrorists[ ubLoop ];
- // random 40% chance of adding this terrorist if not yet placed
- if ( ( gMercProfiles[ ubTerrorist ].sSectorX == 0 ) && ( Random( 100 ) < 40 ) )
- {
- fFoundSpot = FALSE;
- // Since there are 5 spots per terrorist and a maximum of 5 terrorists, we
- // are guaranteed to be able to find a spot for each terrorist since there
- // aren't enough other terrorists to use up all the spots for any one
- // terrorist
- do
- {
- // pick a random spot, see if it's already been used by another terrorist
- uiLocationChoice = Random( NUM_TERRORIST_POSSIBLE_LOCATIONS );
- for (ubLoop2 = 0; ubLoop2 < ubNumTerroristsAdded; ubLoop2++)
- {
- if (sTerroristPlacement[ubLoop2][0] == gsTerroristSector[ubLoop][uiLocationChoice][0] )
- {
- if (sTerroristPlacement[ubLoop2][1] == gsTerroristSector[ubLoop][uiLocationChoice][1] )
- {
- continue;
- }
- }
- }
- fFoundSpot = TRUE;
- } while( !fFoundSpot );
- // place terrorist!
- gMercProfiles[ ubTerrorist ].sSectorX = gsTerroristSector[ ubLoop ][ uiLocationChoice ][ 0 ];
- gMercProfiles[ ubTerrorist ].sSectorY = gsTerroristSector[ ubLoop ][ uiLocationChoice ][ 1 ];
- gMercProfiles[ ubTerrorist ].bSectorZ = 0;
- sTerroristPlacement[ ubNumTerroristsAdded ][ 0 ] = gMercProfiles[ ubTerrorist ].sSectorX;
- sTerroristPlacement[ ubNumTerroristsAdded ][ 1 ] = gMercProfiles[ ubTerrorist ].sSectorY;
- ubNumTerroristsAdded++;
- }
- ubLoop++;
- }
- // start over if necessary
- }
- // set total terrorists outstanding in Carmen's info byte
- gMercProfiles[ 78 ].bNPCData = 1 + ubNumAdditionalTerrorists;
- // store total terrorists
- gubNumTerrorists = 1 + ubNumAdditionalTerrorists;
- }
- void MakeRemainingTerroristsTougher( void )
- {
- UINT8 ubRemainingTerrorists = 0, ubLoop;
- UINT16 usNewItem, usOldItem;
- OBJECTTYPE Object;
- UINT8 ubRemainingDifficulty;
- for ( ubLoop = 0; ubLoop < NUM_TERRORISTS; ubLoop++ )
- {
- if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
- {
- if ( gubTerrorists[ ubLoop ] == SLAY )
- {
- if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
- {
- // Slay on player's team, doesn't count towards remaining terrorists
- continue;
- }
- }
- ubRemainingTerrorists++;
- }
- }
- ubRemainingDifficulty = (60 / gubNumTerrorists) * (gubNumTerrorists - ubRemainingTerrorists);
- switch( gGameOptions.ubDifficultyLevel )
- {
- case DIF_LEVEL_MEDIUM:
- ubRemainingDifficulty = (ubRemainingDifficulty * 13) / 10;
- break;
- case DIF_LEVEL_HARD:
- ubRemainingDifficulty = (ubRemainingDifficulty * 16) / 10;
- break;
- default:
- break;
- }
- if ( ubRemainingDifficulty < 14 )
- {
- // nothing
- return;
- }
- else if ( ubRemainingDifficulty < 28 )
- {
- // mini grenade
- usOldItem = NOTHING;
- usNewItem = MINI_GRENADE;
- }
- else if ( ubRemainingDifficulty < 42)
- {
- // hand grenade
- usOldItem = MINI_GRENADE;
- usNewItem = HAND_GRENADE;
- }
- else if ( ubRemainingDifficulty < 56)
- {
- // mustard
- usOldItem = HAND_GRENADE;
- usNewItem = MUSTARD_GRENADE;
- }
- else if ( ubRemainingDifficulty < 70)
- {
- // LAW
- usOldItem = MUSTARD_GRENADE;
- usNewItem = ROCKET_LAUNCHER;
- }
- else
- {
- // LAW and hand grenade
- usOldItem = NOTHING;
- usNewItem = HAND_GRENADE;
- }
- DeleteObj( &Object );
- Object.usItem = usNewItem;
- Object.bStatus[ 0 ] = 100;
- for ( ubLoop = 0; ubLoop < NUM_TERRORISTS; ubLoop++ )
- {
- if ( gMercProfiles[ gubTerrorists[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorX != 0 && gMercProfiles[ gubTerrorists[ ubLoop ] ].sSectorY != 0 )
- {
- if ( gubTerrorists[ ubLoop ] == SLAY )
- {
- if ( FindSoldierByProfileID( SLAY, TRUE ) != NULL )
- {
- // Slay on player's team, doesn't count towards remaining terrorists
- continue;
- }
- }
- if ( usOldItem != NOTHING )
- {
- RemoveObjectFromSoldierProfile( gubTerrorists[ ubLoop ], usOldItem );
- }
- PlaceObjectInSoldierProfile( gubTerrorists[ ubLoop ], &Object );
- }
- }
- }
- void DecideOnAssassin( void )
- {
- UINT8 ubAssassinPossibility[NUM_ASSASSINS] = { NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE, NO_PROFILE };
- UINT8 ubAssassinsPossible = 0;
- UINT8 ubLoop, ubLoop2;
- UINT8 ubTown;
- #ifdef CRIPPLED_VERSION
- return;
- #endif
- ubTown = GetTownIdForSector( gWorldSectorX, gWorldSectorY );
- for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
- {
- // make sure alive and not placed already
- if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD && gMercProfiles[ gubAssassins[ ubLoop ] ].sSectorX == 0 && gMercProfiles[ gubAssassins[ ubLoop ] ].sSectorY == 0 )
- {
- // check this merc to see if the town is a possibility
- for ( ubLoop2 = 0; ubLoop2 < NUM_ASSASSIN_POSSIBLE_TOWNS; ubLoop2++ )
- {
- if ( gbAssassinTown[ ubLoop ][ ubLoop2 ] == ubTown )
- {
- ubAssassinPossibility[ ubAssassinsPossible ] = gubAssassins[ ubLoop ];
- ubAssassinsPossible++;
- }
- }
- }
- }
- if ( ubAssassinsPossible != 0 )
- {
- ubLoop = ubAssassinPossibility[ Random( ubAssassinsPossible ) ];
- gMercProfiles[ ubLoop ].sSectorX = gWorldSectorX;
- gMercProfiles[ ubLoop ].sSectorY = gWorldSectorY;
- AddStrategicEvent( EVENT_REMOVE_ASSASSIN, GetWorldTotalMin() + 60 * ( 3 + Random( 3 ) ), ubLoop );
- }
-
- }
- void MakeRemainingAssassinsTougher( void )
- {
- UINT8 ubRemainingAssassins = 0, ubLoop;
- UINT16 usNewItem, usOldItem;
- OBJECTTYPE Object;
- UINT8 ubRemainingDifficulty;
- for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
- {
- if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD )
- {
- ubRemainingAssassins++;
- }
- }
- ubRemainingDifficulty = (60 / NUM_ASSASSINS) * (NUM_ASSASSINS - ubRemainingAssassins);
- switch( gGameOptions.ubDifficultyLevel )
- {
- case DIF_LEVEL_MEDIUM:
- ubRemainingDifficulty = (ubRemainingDifficulty * 13) / 10;
- break;
- case DIF_LEVEL_HARD:
- ubRemainingDifficulty = (ubRemainingDifficulty * 16) / 10;
- break;
- default:
- break;
- }
- if ( ubRemainingDifficulty < 14 )
- {
- // nothing
- return;
- }
- else if ( ubRemainingDifficulty < 28 )
- {
- // mini grenade
- usOldItem = NOTHING;
- usNewItem = MINI_GRENADE;
- }
- else if ( ubRemainingDifficulty < 42)
- {
- // hand grenade
- usOldItem = MINI_GRENADE;
- usNewItem = HAND_GRENADE;
- }
- else if ( ubRemainingDifficulty < 56)
- {
- // mustard
- usOldItem = HAND_GRENADE;
- usNewItem = MUSTARD_GRENADE;
- }
- else if ( ubRemainingDifficulty < 70)
- {
- // LAW
- usOldItem = MUSTARD_GRENADE;
- usNewItem = ROCKET_LAUNCHER;
- }
- else
- {
- // LAW and hand grenade
- usOldItem = NOTHING;
- usNewItem = HAND_GRENADE;
- }
- DeleteObj( &Object );
- Object.usItem = usNewItem;
- Object.bStatus[ 0 ] = 100;
- for ( ubLoop = 0; ubLoop < NUM_ASSASSINS; ubLoop++ )
- {
- if ( gMercProfiles[ gubAssassins[ ubLoop ] ].bMercStatus != MERC_IS_DEAD )
- {
- if ( usOldItem != NOTHING )
- {
- RemoveObjectFromSoldierProfile( gubAssassins[ ubLoop ], usOldItem );
- }
- PlaceObjectInSoldierProfile( gubAssassins[ ubLoop ], &Object );
- }
- }
- }
- void StartSomeMercsOnAssignment(void)
- {
- UINT32 uiCnt;
- MERCPROFILESTRUCT *pProfile;
- UINT32 uiChance;
- // some randomly picked A.I.M. mercs will start off "on assignment" at the beginning of each new game
- for( uiCnt = 0; uiCnt < AIM_AND_MERC_MERCS; uiCnt++)
- {
- pProfile = &(gMercProfiles[ uiCnt ]);
- // calc chance to start on assignment
- uiChance = 5 * pProfile->bExpLevel;
- if (Random(100) < uiChance)
- {
- pProfile->bMercStatus = MERC_WORKING_ELSEWHERE;
- pProfile->uiDayBecomesAvailable = 1 + Random(6 + (pProfile->bExpLevel / 2) ); // 1-(6 to 11) days
- }
- else
- {
- pProfile->bMercStatus = MERC_OK;
- pProfile->uiDayBecomesAvailable = 0;
- }
- pProfile->uiPrecedentQuoteSaid = 0;
- pProfile->ubDaysOfMoraleHangover = 0;
- }
- }
- void SetProfileFaceData( UINT8 ubCharNum, UINT8 ubFaceIndex, UINT16 usEyesX, UINT16 usEyesY, UINT16 usMouthX, UINT16 usMouthY )
- {
- gMercProfiles[ ubCharNum ].ubFaceIndex = ubFaceIndex;
- gMercProfiles[ ubCharNum ].usEyesX = usEyesX;
- gMercProfiles[ ubCharNum ].usEyesY = usEyesY;
- gMercProfiles[ ubCharNum ].usMouthX = usMouthX;
- gMercProfiles[ ubCharNum ].usMouthY = usMouthY;
- }
- UINT16 CalcCompetence( MERCPROFILESTRUCT * pProfile )
- {
- UINT32 uiStats, uiSkills, uiActionPoints, uiSpecialSkills;
- UINT16 usCompetence;
- // count life twice 'cause it's also hit points
- // mental skills are halved 'cause they're actually not that important within the game
- uiStats = ((2 * pProfile->bLifeMax) + pProfile->bStrength + pProfile->bAgility + pProfile->bDexterity + ((pProfile->bLeadership + pProfile->bWisdom) / 2)) / 3;
- // marksmanship is very important, count it double
- uiSkills = (UINT32) ((2 * (pow(pProfile->bMarksmanship, 3) / 10000)) +
- 1.5 * (pow(pProfile->bMedical, 3) / 10000) +
- (pow(pProfile->bMechanical, 3) / 10000) +
- (pow(pProfile->bExplosive, 3) / 10000));
- // action points
- uiActionPoints = 5 + (((10 * pProfile->bExpLevel +
- 3 * pProfile->bAgility +
- 2 * pProfile->bLifeMax +
- 2 * pProfile->bDexterity) + 20) / 40);
- // count how many he has, don't care what they are
- uiSpecialSkills = ((pProfile->bSkillTrait != 0) ? 1 : 0) + ((pProfile->bSkillTrait2 != 0) ? 1 : 0);
- usCompetence = (UINT16) ((pow(pProfile->bExpLevel, 0.2) * uiStats * uiSkills * (uiActionPoints - 6) * (1 + (0.05 * (FLOAT)uiSpecialSkills))) / 1000);
- // this currently varies from about 10 (Flo) to 1200 (Gus)
- return(usCompetence);
- }
- INT16 CalcMedicalDeposit( MERCPROFILESTRUCT * pProfile )
- {
- UINT16 usDeposit;
- // this rounds off to the nearest hundred
- usDeposit = (((5 * CalcCompetence(pProfile)) + 50) / 100) * 100;
- return(usDeposit);
- }
- SOLDIERTYPE * FindSoldierByProfileID( UINT8 ubProfileID, BOOLEAN fPlayerMercsOnly )
- {
- UINT8 ubLoop, ubLoopLimit;
- SOLDIERTYPE * pSoldier;
- if (fPlayerMercsOnly)
- {
- ubLoopLimit = gTacticalStatus.Team[0].bLastID;
- }
- else
- {
- ubLoopLimit = MAX_NUM_SOLDIERS;
- }
- for (ubLoop = 0, pSoldier = MercPtrs[0]; ubLoop < ubLoopLimit; ubLoop++, pSoldier++)
- {
- if (pSoldier->bActive && pSoldier->ubProfile == ubProfileID)
- {
- return( pSoldier );
- }
- }
- return( NULL );
- }
- SOLDIERTYPE *ChangeSoldierTeam( SOLDIERTYPE *pSoldier, UINT8 ubTeam )
- {
- UINT8 ubID;
- SOLDIERTYPE *pNewSoldier = NULL;
- SOLDIERCREATE_STRUCT MercCreateStruct;
- UINT32 cnt;
- INT16 sOldGridNo;
- UINT8 ubOldID;
- UINT32 uiOldUniqueId;
- UINT32 uiSlot;
- SOLDIERTYPE *pGroupMember;
- if (gfInTalkPanel)
- {
- DeleteTalkingMenu();
- }
- // Save merc id for this guy...
- ubID = pSoldier->ubID;
- ubOldID = ubID;
- uiOldUniqueId = pSoldier->uiUniqueSoldierIdValue;
- sOldGridNo = pSoldier->sGridNo;
- // Remove him from the game!
- InternalTacticalRemoveSoldier( ubID, FALSE );
- // Create a new one!
- memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) );
- MercCreateStruct.bTeam = ubTeam;
- MercCreateStruct.ubProfile = pSoldier->ubProfile;
- MercCreateStruct.bBodyType = pSoldier->ubBodyType;
- MercCreateStruct.sSectorX = pSoldier->sSectorX;
- MercCreateStruct.sSectorY = pSoldier->sSectorY;
- MercCreateStruct.bSectorZ = pSoldier->bSectorZ;
- MercCreateStruct.sInsertionGridNo = pSoldier->sGridNo;
- MercCreateStruct.bDirection = pSoldier->bDirection;
- if ( pSoldier->uiStatusFlags & SOLDIER_VEHICLE )
- {
- MercCreateStruct.ubProfile = NO_PROFILE;
- MercCreateStruct.fUseGivenVehicle = TRUE;
- MercCreateStruct.bUseGivenVehicleID = pSoldier->bVehicleID;
- }
- if ( ubTeam == gbPlayerNum )
- {
- MercCreateStruct.fPlayerMerc = TRUE;
- }
- if ( TacticalCreateSoldier( &MercCreateStruct, &ubID ) )
- {
- pNewSoldier = MercPtrs[ ubID ];
- // Copy vital stats back!
- pNewSoldier->bLife = pSoldier->bLife;
- pNewSoldier->bLifeMax = pSoldier->bLifeMax;
- pNewSoldier->bAgility = pSoldier->bAgility;
- pNewSoldier->bLeadership = pSoldier->bLeadership;
- pNewSoldier->bDexterity = pSoldier->bDexterity;
- pNewSoldier->bStrength = pSoldier->bStrength;
- pNewSoldier->bWisdom = pSoldier->bWisdom;
- pNewSoldier->bExpLevel = pSoldier->bExpLevel;
- pNewSoldier->bMarksmanship = pSoldier->bMarksmanship;
- pNewSoldier->bMedical = pSoldier->bMedical;
- pNewSoldier->bMechanical = pSoldier->bMechanical;
- pNewSoldier->bExplosive = pSoldier->bExplosive;
- pNewSoldier->bScientific = pSoldier->bScientific;
- pNewSoldier->bLastRenderVisibleValue = pSoldier->bLastRenderVisibleValue;
- pNewSoldier->bVisible = pSoldier->bVisible;
- if ( ubTeam == gbPlayerNum )
- {
- pNewSoldier->bVisible = 1;
- }
- // Copy over any items....
- for ( cnt = 0; cnt < NUM_INV_SLOTS; cnt++ )
- {
- pNewSoldier->inv[ cnt ] = pSoldier->inv[ cnt ];
- }
- // OK, loop through all active merc slots, change
- // Change ANY attacker's target if they were once on this guy.....
- for ( uiSlot = 0; uiSlot < guiNumMercSlots; uiSlot++ )
- {
- pGroupMember = MercSlots[ uiSlot ];
- if ( pGroupMember != NULL )
- {
- if ( pGroupMember->ubTargetID == pSoldier->ubID )
- {
- pGroupMember->ubTargetID = pNewSoldier->ubID;
- }
- }
- }
-
- // Set insertion gridNo
- pNewSoldier->sInsertionGridNo = sOldGridNo;
- if ( gfPotentialTeamChangeDuringDeath )
- {
- HandleCheckForDeathCommonCode( pSoldier );
- }
- if ( gfWorldLoaded && pSoldier->bInSector
- //pSoldier->sSectorX == gWorldSectorX && pSoldier->sSectorY == gWorldSectorY && pSoldier->bSectorZ == gbWorldSectorZ
- )
- {
- AddSoldierToSectorNoCalculateDirectionUseAnimation( ubID, pSoldier->usAnimState, pSoldier->usAniCode );
- HandleSight(pNewSoldier, SIGHT_LOOK | SIGHT_RADIO);
- }
- // fix up the event queue...
- // ChangeSoldierIDInQueuedEvents( ubOldID, uiOldUniqueId, pNewSoldier->ubID, pNewSoldier->uiUniqueSoldierIdValue );
- if ( pNewSoldier->ubProfile != NO_PROFILE )
- {
- if ( ubTeam == gbPlayerNum )
- {
- gMercProfiles[ pNewSoldier->ubProfile ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
- }
- else
- {
- gMercProfiles[ pNewSoldier->ubProfile ].ubMiscFlags &= (~PROFILE_MISC_FLAG_RECRUITED);
- }
- }
- }
- // AT the low level check if this poor guy is in inv panel, else
- // remove....
- if ( gsCurInterfacePanel == SM_PANEL && gpSMCurrentMerc == pSoldier )
- {
- // Switch....
- SetCurrentInterfacePanel( TEAM_PANEL );
- }
- return( pNewSoldier );
- }
- BOOLEAN RecruitRPC( UINT8 ubCharNum )
- {
- SOLDIERTYPE *pSoldier, *pNewSoldier;
- // Get soldier pointer
- pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
- if (!pSoldier)
- {
- return( FALSE );
- }
- // OK, set recruit flag..
- gMercProfiles[ ubCharNum ].ubMiscFlags |= PROFILE_MISC_FLAG_RECRUITED;
- // Add this guy to our team!
- pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum );
- // handle set up any RPC's that will leave us in time
- if ( ubCharNum == SLAY )
- {
- // slay will leave in a week
- pNewSoldier->iEndofContractTime = GetWorldTotalMin() + ( 7 * 24 * 60 );
- KickOutWheelchair( pNewSoldier );
- }
- else if ( ubCharNum == DYNAMO && gubQuest[ QUEST_FREE_DYNAMO ] == QUESTINPROGRESS )
- {
- EndQuest( QUEST_FREE_DYNAMO, pSoldier->sSectorX, pSoldier->sSectorY );
- }
- // handle town loyalty adjustment
- HandleTownLoyaltyForNPCRecruitment( pNewSoldier );
- // Try putting them into the current squad
- if ( AddCharacterToSquad( pNewSoldier, (INT8)CurrentSquad( ) ) == FALSE )
- {
- AddCharacterToAnySquad( pNewSoldier );
- }
- ResetDeadSquadMemberList( pNewSoldier->bAssignment );
- DirtyMercPanelInterface( pNewSoldier, DIRTYLEVEL2 );
- if ( pNewSoldier->inv[ HANDPOS ].usItem == NOTHING )
- {
- // empty handed - swap in first available weapon
- INT8 bSlot;
- bSlot = FindObjClass( pNewSoldier, IC_WEAPON );
- if ( bSlot != NO_SLOT )
- {
- if ( Item[ pNewSoldier->inv[ bSlot ].usItem ].fFlags & ITEM_TWO_HANDED )
- {
- if ( bSlot != SECONDHANDPOS && pNewSoldier->inv[ SECONDHANDPOS ].usItem != NOTHING )
- {
- // need to move second hand item out first
- AutoPlaceObject( pNewSoldier, &(pNewSoldier->inv[ SECONDHANDPOS ]), FALSE );
- }
- }
- // swap item to hand
- SwapObjs( &(pNewSoldier->inv[ bSlot ]), &(pNewSoldier->inv[ HANDPOS ]) );
- }
- }
- #ifdef JA2DEMO
- HandleEndDemoInCreatureLevel( );
- #endif
- if ( ubCharNum == IRA )
- {
- // trigger 0th PCscript line
- TriggerNPCRecord( IRA, 0 );
- }
- // Set whatkind of merc am i
- pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__NPC;
- //
- //add a history log that tells the user that a npc has joined the team
- //
- // ( pass in pNewSoldier->sSectorX cause if its invalid, -1, n/a will appear as the sector in the history log )
- AddHistoryToPlayersLog( HISTORY_RPC_JOINED_TEAM, pNewSoldier->ubProfile, GetWorldTotalMin(), pNewSoldier->sSectorX, pNewSoldier->sSectorY );
- //remove the merc from the Personnel screens departed list ( if they have never been hired before, its ok to call it )
- RemoveNewlyHiredMercFromPersonnelDepartedList( pSoldier->ubProfile );
- return( TRUE );
- }
- BOOLEAN RecruitEPC( UINT8 ubCharNum )
- {
- SOLDIERTYPE *pSoldier, *pNewSoldier;
- // Get soldier pointer
- pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
- if (!pSoldier)
- {
- return( FALSE );
- }
- // OK, set recruit flag..
- gMercProfiles[ ubCharNum ].ubMiscFlags |= PROFILE_MISC_FLAG_EPCACTIVE;
- gMercProfiles[ ubCharNum ].ubMiscFlags3 &= ~PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE;
- // Add this guy to our team!
- pNewSoldier = ChangeSoldierTeam( pSoldier, gbPlayerNum );
- pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__EPC;
- // Try putting them into the current squad
- if ( AddCharacterToSquad( pNewSoldier, (INT8)CurrentSquad( ) ) == FALSE )
- {
- AddCharacterToAnySquad( pNewSoldier );
- }
- ResetDeadSquadMemberList( pNewSoldier->bAssignment );
- DirtyMercPanelInterface( pNewSoldier, DIRTYLEVEL2 );
- // Make the interface panel dirty..
- // This will dirty the panel next frame...
- gfRerenderInterfaceFromHelpText = TRUE;
- // If we are a robot, look to update controller....
- if ( pNewSoldier->uiStatusFlags & SOLDIER_ROBOT )
- {
- UpdateRobotControllerGivenRobot( pNewSoldier );
- }
- // Set whatkind of merc am i
- pNewSoldier->ubWhatKindOfMercAmI = MERC_TYPE__EPC;
- UpdateTeamPanelAssignments( );
- return( TRUE );
- }
- BOOLEAN UnRecruitEPC( UINT8 ubCharNum )
- {
- SOLDIERTYPE *pSoldier, *pNewSoldier;
- // Get soldier pointer
- pSoldier = FindSoldierByProfileID( ubCharNum, FALSE );
- if (!pSoldier)
- {
- return( FALSE );
- }
- if (pSoldier->ubWhatKindOfMercAmI != MERC_TYPE__EPC)
- {
- return( FALSE );
- }
- if ( pSoldier->bAssignment < ON_DUTY )
- {
- ResetDeadSquadMemberList( pSoldier->bAssignment );
- }
- // Rmeove from squad....
- RemoveCharacterFromSquads( pSoldier );
- // O< check if this is the only guy in the sector....
- if ( gusSelectedSoldier == pSoldier->ubID )
- {
- gusSelectedSoldier = NOBODY;
- }
- // OK, UN set recruit flag..
- gMercProfiles[ ubCharNum ].ubMiscFlags &= (~PROFILE_MISC_FLAG_EPCACTIVE);
- // update sector values to current
- // check to see if this person should disappear from the map after this
- if ( (ubCharNum == JOHN || ubCharNum == MARY) && pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_B && pSoldier->bSectorZ == 0 )
- {
- gMercProfiles[ ubCharNum ].sSectorX = 0;
- gMercProfiles[ ubCharNum ].sSectorY = 0;
- gMercProfiles[ ubCharNum ].bSectorZ = 0;
- }
- else
- {
- gMercProfiles[ ubCharNum ].sSectorX = pSoldier->sSectorX;
- gMercProfiles[ ubCharNum ].sSectorY = pSoldier->sSectorY;
- gMercProfiles[ ubCharNum ].bSectorZ = pSoldier->bSectorZ;
- }
- // how do we decide whether or not to set this?
- gMercProfiles[ ubCharNum ].fUseProfileInsertionInfo = TRUE;
- gMercProfiles[ ubCharNum ].ubMiscFlags3 |= PROFILE_MISC_FLAG3_PERMANENT_INSERTION_CODE;
- // Add this guy to CIV team!
- pNewSoldier = ChangeSoldierTeam( pSoldier, CIV_TEAM );
- UpdateTeamPanelAssignments( );
- return( TRUE );
- }
- INT8 WhichBuddy( UINT8 ubCharNum, UINT8 ubBuddy )
- {
- MERCPROFILESTRUCT * pProfile;
- INT8 bLoop;
- pProfile = &( gMercProfiles[ ubCharNum ] );
- for (bLoop = 0; bLoop < 3; bLoop++)
- {
- if ( pProfile->bBuddy[bLoop] == ubBuddy )
- {
- return( bLoop );
- }
- }
- return( -1 );
- }
- INT8 WhichHated( UINT8 ubCharNum, UINT8 ubHated )
- {
- MERCPROFILESTRUCT * pProfile;
- INT8 bLoop;
- pProfile = &( gMercProfiles[ ubCharNum ] );
- for (bLoop = 0; bLoop < 3; bLoop++)
- {
- if ( pProfile->bHated[bLoop] == ubHated )
- {
- return( bLoop );
- }
- }
- return( -1 );
- }
- BOOLEAN IsProfileATerrorist( UINT8 ubProfile )
- {
- if ( ubProfile == 83 || ubProfile == 111 ||
- ubProfile == 64 || ubProfile == 112 ||
- ubProfile == 82 || ubProfile == 110 )
- {
- return( TRUE );
- }
- else
- {
- return( FALSE );
- }
- }
- BOOLEAN IsProfileAHeadMiner( UINT8 ubProfile )
- {
- if ( ubProfile == 106 || ubProfile == 148 ||
- ubProfile == 156 || ubProfile == 157 ||
- ubProfile == 158 )
- {
- return( TRUE );
- }
- else
- {
- return( FALSE );
- }
- }
- void UpdateSoldierPointerDataIntoProfile( BOOLEAN fPlayerMercs )
- {
- UINT32 uiCount;
- SOLDIERTYPE *pSoldier = NULL;
- MERCPROFILESTRUCT * pProfile;
- BOOLEAN fDoCopy = FALSE;
- for( uiCount=0; uiCount < guiNumMercSlots; uiCount++)
- {
- pSoldier = MercSlots[ uiCount ];
- if ( pSoldier != NULL )
- {
- if ( pSoldier->ubProfile != NO_PROFILE )
- {
- fDoCopy = FALSE;
- // If we are above player mercs
- if ( fPlayerMercs )
- {
- if ( pSoldier->ubProfile < FIRST_RPC )
- {
- fDoCopy = TRUE;
- }
- }
- else
- {
- if ( pSoldier->ubProfile >= FIRST_RPC )
- {
- fDoCopy = TRUE;
- }
- }
- if ( fDoCopy )
- {
- // get profile...
- pProfile = &( gMercProfiles[ pSoldier->ubProfile ] );
- // Copy....
- pProfile->bLife = pSoldier->bLife;
- pProfile->bLifeMax = pSoldier->bLifeMax;
- pProfile->bAgility = pSoldier->bAgility;
- pProfile->bLeadership = pSoldier->bLeadership;
- pProfile->bDexterity = pSoldier->bDexterity;
- pProfile->bStrength = pSoldier->bStrength;
- pProfile->bWisdom = pSoldier->bWisdom;
- pProfile->bExpLevel = pSoldier->bExpLevel;
- pProfile->bMarksmanship = pSoldier->bMarksmanship;
- pProfile->bMedical = pSoldier->bMedical;
- pProfile->bMechanical = pSoldier->bMechanical;
- pProfile->bExplosive = pSoldier->bExplosive;
- pProfile->bScientific = pSoldier->bScientific;
- }
- }
- }
- }
- }
- BOOLEAN DoesMercHaveABuddyOnTheTeam( UINT8 ubMercID )
- {
- UINT8 ubCnt;
- INT8 bBuddyID;
- // loop through the list of people the merc is buddies with
- for(ubCnt=0; ubCnt< 3; ubCnt++)
- {
- //see if the merc has a buddy on the team
- bBuddyID = gMercProfiles[ ubMercID ].bBuddy[ubCnt];
- //If its not a valid 'buddy'
- if( bBuddyID < 0 )
- continue;
- if( IsMercOnTeam( bBuddyID ) )
- {
- if( !IsMercDead( bBuddyID ) )
- {
- return( TRUE );
- }
- }
- }
- return( FALSE );
- }
- BOOLEAN MercIsHot( SOLDIERTYPE * pSoldier )
- {
- if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait == HEAT_INTOLERANT )
- {
- if ( SectorTemperature( GetWorldMinutesInDay(), pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ) > 0 )
- {
- return( TRUE );
- }
- }
- return( FALSE );
- }
- SOLDIERTYPE * SwapLarrysProfiles( SOLDIERTYPE * pSoldier )
- {
- UINT8 ubSrcProfile;
- UINT8 ubDestProfile;
- MERCPROFILESTRUCT * pNewProfile;
- ubSrcProfile = pSoldier->ubProfile;
- if ( ubSrcProfile == LARRY_NORMAL)
- {
- ubDestProfile = LARRY_DRUNK;
- }
- else if ( ubSrcProfile == LARRY_DRUNK )
- {
- ubDestProfile = LARRY_NORMAL;
- }
- else
- {
- // I don't think so!
- return( pSoldier );
- }
-
- pNewProfile = &gMercProfiles[ ubDestProfile ];
- pNewProfile->ubMiscFlags2 = gMercProfiles[ ubSrcProfile ].ubMiscFlags2;
- pNewProfile->ubMiscFlags = gMercProfiles[ ubSrcProfile ].ubMiscFlags;
- pNewProfile->sSectorX = gMercProfiles[ ubSrcProfile ].sSectorX;
- pNewProfile->sSectorY = gMercProfiles[ ubSrcProfile ].sSectorY;
- pNewProfile->uiDayBecomesAvailable = gMercProfiles[ ubSrcProfile ].uiDayBecomesAvailable;
- pNewProfile->usKills = gMercProfiles[ ubSrcProfile ].usKills;
- pNewProfile->usAssists = gMercProfiles[ ubSrcProfile ].usAssists;
- pNewProfile->usShotsFired = gMercProfiles[ ubSrcProfile ].usShotsFired;
- pNewProfile->usShotsHit = gMercProfiles[ ubSrcProfile ].usShotsHit;
- pNewProfile->usBattlesFought = gMercProfiles[ ubSrcProfile ].usBattlesFought;
- pNewProfile->usTimesWounded = gMercProfiles[ ubSrcProfile ].usTimesWounded;
- pNewProfile->usTotalDaysServed = gMercProfiles[ ubSrcProfile ].usTotalDaysServed;
- pNewProfile->bResigned = gMercProfiles[ ubSrcProfile ].bResigned;
- pNewProfile->bActive = gMercProfiles[ ubSrcProfile ].bActive;
- pNewProfile->fUseProfileInsertionInfo = gMercProfiles[ ubSrcProfile ].fUseProfileInsertionInfo;
- pNewProfile->sGridNo = gMercProfiles[ ubSrcProfile ].sGridNo;
- pNewProfile->ubQuoteActionID = gMercProfiles[ ubSrcProfile ].ubQuoteActionID;
- pNewProfile->ubLastQuoteSaid = gMercProfiles[ ubSrcProfile ].ubLastQuoteSaid;
- pNewProfile->ubStrategicInsertionCode = gMercProfiles[ ubSrcProfile ].ubStrategicInsertionCode;
- pNewProfile->bMercStatus = gMercProfiles[ ubSrcProfile ].bMercStatus;
- pNewProfile->bSectorZ = gMercProfiles[ ubSrcProfile ].bSectorZ;
- pNewProfile->usStrategicInsertionData = gMercProfiles[ ubSrcProfile ].usStrategicInsertionData;
- pNewProfile->sTrueSalary = gMercProfiles[ ubSrcProfile ].sTrueSalary;
- pNewProfile->ubMiscFlags3 = gMercProfiles[ ubSrcProfile ].ubMiscFlags3;
- pNewProfile->ubDaysOfMoraleHangover = gMercProfiles[ ubSrcProfile ].ubDaysOfMoraleHangover;
- pNewProfile->ubNumTimesDrugUseInLifetime = gMercProfiles[ ubSrcProfile ].ubNumTimesDrugUseInLifetime;
- pNewProfile->uiPrecedentQuoteSaid = gMercProfiles[ ubSrcProfile ].uiPrecedentQuoteSaid;
- pNewProfile->sPreCombatGridNo = gMercProfiles[ ubSrcProfile ].sPreCombatGridNo;
- // CJC: this is causing problems so just skip the transfer of exp...
- /*
- pNewProfile->sLifeGain = gMercProfiles[ ubSrcProfile ].sLifeGain;
- pNewProfile->sAgilityGain = gMercProfiles[ ubSrcProfile ].sAgilityGain;
- pNewProfile->sDexterityGain = gMercProfiles[ ubSrcProfile ].sDexterityGain;
- pNewProfile->sStrengthGain = gMercProfiles[ ubSrcProfile ].sStrengthGain;
- pNewProfile->sLeadershipGain = gMercProfiles[ ubSrcProfile ].sLeadershipGain;
- pNewProfile->sWisdomGain = gMercProfiles[ ubSrcProfile ].sWisdomGain;
- pNewProfile->sExpLevelGain = gMercProfiles[ ubSrcProfile ].sExpLevelGain;
- pNewProfile->sMarksmanshipGain = gMercProfiles[ ubSrcProfile ].sMarksmanshipGain;
- pNewProfile->sMedicalGain = gMercProfiles[ ubSrcProfile ].sMedicalGain;
- pNewProfile->sMechanicGain = gMercProfiles[ ubSrcProfile ].sMechanicGain;
- pNewProfile->sExplosivesGain = gMercProfiles[ ubSrcProfile ].sExplosivesGain;
- pNewProfile->bLifeDelta = gMercProfiles[ ubSrcProfile ].bLifeDelta;
- pNewProfile->bAgilityDelta = gMercProfiles[ ubSrcProfile ].bAgilityDelta;
- pNewProfile->bDexterityDelta = gMercProfiles[ ubSrcProfile ].bDexterityDelta;
- pNewProfile->bStrengthDelta = gMercProfiles[ ubSrcProfile ].bStrengthDelta;
- pNewProfile->bLeadershipDelta = gMercProfiles[ ubSrcProfile ].bLeadershipDelta;
- pNewProfile->bWisdomDelta = gMercProfiles[ ubSrcProfile ].bWisdomDelta;
- pNewProfile->bExpLevelDelta = gMercProfiles[ ubSrcProfile ].bExpLevelDelta;
- pNewProfile->bMarksmanshipDelta = gMercProfiles[ ubSrcProfile ].bMarksmanshipDelta;
- pNewProfile->bMedicalDelta = gMercProfiles[ ubSrcProfile ].bMedicalDelta;
- pNewProfile->bMechanicDelta = gMercProfiles[ ubSrcProfile ].bMechanicDelta;
- pNewProfile->bExplosivesDelta = gMercProfiles[ ubSrcProfile ].bExplosivesDelta;
- */
- memcpy( pNewProfile->bInvStatus, gMercProfiles[ ubSrcProfile ].bInvStatus , sizeof( UINT8) * 19 );
- memcpy( pNewProfile->bInvStatus, gMercProfiles[ ubSrcProfile ].bInvStatus , sizeof( UINT8) * 19 );
- memcpy( pNewProfile->inv , gMercProfiles[ ubSrcProfile ].inv , sizeof( UINT16 ) * 19 );
- memcpy( pNewProfile->bMercTownReputation , gMercProfiles[ ubSrcProfile ].bMercTownReputation , sizeof( UINT8 ) * 20 );
- // remove face
- DeleteSoldierFace( pSoldier );
- pSoldier->ubProfile = ubDestProfile;
- // create new face
- pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
-
- // replace profile in group
- ReplaceSoldierProfileInPlayerGroup( pSoldier->ubGroupID, ubSrcProfile, ubDestProfile );
- pSoldier->bStrength = pNewProfile->bStrength + pNewProfile->bStrengthDelta;
- pSoldier->bDexterity = pNewProfile->bDexterity + pNewProfile->bDexterityDelta;
- pSoldier->bAgility = pNewProfile->bAgility + pNewProfile->bAgilityDelta;
- pSoldier->bWisdom = pNewProfile->bWisdom + pNewProfile->bWisdomDelta;
- pSoldier->bExpLevel = pNewProfile->bExpLevel + pNewProfile->bExpLevelDelta;
- pSoldier->bLeadership = pNewProfile->bLeadership + pNewProfile->bLeadershipDelta;
- pSoldier->bMarksmanship = pNewProfile->bMarksmanship + pNewProfile->bMarksmanshipDelta;
- pSoldier->bMechanical = pNewProfile->bMechanical + pNewProfile->bMechanicDelta;
- pSoldier->bMedical = pNewProfile->bMedical + pNewProfile->bMedicalDelta;
- pSoldier->bExplosive = pNewProfile->bExplosive + pNewProfile->bExplosivesDelta;
- if ( pSoldier->ubProfile == LARRY_DRUNK )
- {
- SetFactTrue( FACT_LARRY_CHANGED );
- }
- else
- {
- SetFactFalse( FACT_LARRY_CHANGED );
- }
- DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
- return( pSoldier );
- }
- BOOLEAN DoesNPCOwnBuilding( SOLDIERTYPE *pSoldier, INT16 sGridNo )
- {
- UINT8 ubRoomInfo;
- // Get room info
- ubRoomInfo = gubWorldRoomInfo[ sGridNo ];
- if ( ubRoomInfo == NO_ROOM )
- {
- return( FALSE );
- }
- // Are we an NPC?
- if ( pSoldier->bTeam != CIV_TEAM )
- {
- return( FALSE );
- }
- // OK, check both ranges
- if ( ubRoomInfo >= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeStart[ 0 ] &&
- ubRoomInfo <= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeEnd[ 0 ] )
- {
- return( TRUE );
- }
- if ( ubRoomInfo >= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeStart[ 1 ] &&
- ubRoomInfo <= gMercProfiles[ pSoldier->ubProfile ].ubRoomRangeEnd[ 1 ] )
- {
- return( TRUE );
- }
- return( FALSE );
- }
|