mirror of
https://github.com/1dot13/source.git
synced 2026-09-02 14:36:06 +02:00
New feature: bloodcat/zombie/bandit raids on player-controlled sectors
For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=23711&goto=353154&#msg_353154 Requires GameDir >= r2420 git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8554 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -316,6 +316,11 @@ INT8 GetCivType( SOLDIERTYPE *pCiv )
|
||||
return( CIV_TYPE_ENEMY );
|
||||
}
|
||||
|
||||
if ( pCiv->bTeam == CREATURE_TEAM && pCiv->ubSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
return( CIV_TYPE_ENEMY );
|
||||
}
|
||||
|
||||
if ( pCiv->bTeam != CIV_TEAM && pCiv->bTeam != MILITIA_TEAM )
|
||||
{
|
||||
return( CIV_TYPE_NA );
|
||||
@@ -1627,6 +1632,7 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar
|
||||
switch( pCiv->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
if( !(zTaunt[ i ].uiFlags2 & TAUNT_C_ADMIN) )
|
||||
continue;
|
||||
if( (zTaunt[ i ].value[TAUNT_PROFILE_ADMIN] != -1 ) && !(zTaunt[ i ].value[TAUNT_PROFILE_ADMIN] == pCiv->usSoldierProfile ) )
|
||||
|
||||
@@ -333,10 +333,11 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
|
||||
// handled differently than for enemies.
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_GREEN_MILITIA:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
bRating = BAD_ADMINISTRATOR_EQUIPMENT_RATING + bEquipmentModifier;
|
||||
|
||||
// Equipment quality modifier
|
||||
if ( bSoldierClass == SOLDIER_CLASS_ADMINISTRATOR )
|
||||
if ( bSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || bSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
if ( gGameExternalOptions.sEnemyAdminEquipmentQualityModifier != 0 )
|
||||
bRating += gGameExternalOptions.sEnemyAdminEquipmentQualityModifier;
|
||||
@@ -360,7 +361,7 @@ void GenerateRandomEquipment( SOLDIERCREATE_STRUCT *pp, INT8 bSoldierClass, INT8
|
||||
bHelmetClass = bRating;
|
||||
// no leggings
|
||||
|
||||
if ( bSoldierClass == SOLDIER_CLASS_ADMINISTRATOR )
|
||||
if ( bSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || bSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
if ( Chance( 30 ) )
|
||||
bKnifeClass = bRating;
|
||||
@@ -919,6 +920,7 @@ void ChooseWeaponForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bWeaponC
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
case SOLDIER_CLASS_GREEN_MILITIA:
|
||||
case SOLDIER_CLASS_REG_MILITIA:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
//Admins/Troops: 60-75% + 1% every 4% progress
|
||||
bStatus = (INT8)(60 + Random( 16 ));
|
||||
bStatus += (INT8)(HighestPlayerProgressPercentage() / 4);
|
||||
@@ -1987,13 +1989,12 @@ void ChooseFaceGearForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp )
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_GREEN_MILITIA:
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ChooseKitsForSoldierCreateStruct( SOLDIERCREATE_STRUCT *pp, INT8 bKitClass )
|
||||
{
|
||||
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"ChooseKitsForSoldierCreateStruct");
|
||||
|
||||
@@ -494,6 +494,10 @@ OBJECTTYPE* GetExternalFeedingObject(SOLDIERTYPE* pSoldier, OBJECTTYPE * pObject
|
||||
|
||||
BOOLEAN DeductBulletViaExternalFeeding(SOLDIERTYPE* pSoldier, OBJECTTYPE * pObject);
|
||||
|
||||
#define SECTORFLAG_RAIDPOSSIBLE_BLOODCAT 0x00000001 // bloodcats can attack this sector
|
||||
#define SECTORFLAG_RAIDPOSSIBLE_ZOMBIE 0x00000002 // zombies can attack this sector
|
||||
#define SECTORFLAG_RAIDPOSSIBLE_BANDIT 0x00000004 // bandits can attack this sector
|
||||
|
||||
// Flugente: additional xml data for sectors
|
||||
typedef struct
|
||||
{
|
||||
@@ -515,6 +519,8 @@ typedef struct
|
||||
|
||||
UINT8 maxworkers; // maximum number of workers in this sector;
|
||||
|
||||
UINT32 usSectorFlagMask; // various flags
|
||||
|
||||
} SECTOR_EXT_DATA;
|
||||
|
||||
// get dirt increase for object with attachments, fConsiderAmmo: with ammo
|
||||
|
||||
+28
-34
@@ -6856,7 +6856,8 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
{
|
||||
switch ( pTeamSoldier->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR: ++sNumPrisoner[PRISONER_ADMIN]; break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT: ++sNumPrisoner[PRISONER_ADMIN]; break;
|
||||
case SOLDIER_CLASS_ARMY: ++sNumPrisoner[PRISONER_REGULAR]; break;
|
||||
case SOLDIER_CLASS_ELITE: ++sNumPrisoner[PRISONER_ELITE]; break;
|
||||
default:
|
||||
@@ -6865,7 +6866,11 @@ void RemoveCapturedEnemiesFromSectorInfo( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //if ( pTeamSoldier->bTeam == CIV_TEAM )
|
||||
else if ( pTeamSoldier->bTeam == CREATURE_TEAM && pTeamSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
++sNumPrisoner[PRISONER_ADMIN];
|
||||
}
|
||||
else
|
||||
{
|
||||
++sNumPrisoner[PRISONER_CIVILIAN];
|
||||
}
|
||||
@@ -10508,9 +10513,9 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// We justify this storywise by these soldiers being very determined leaders who don't allow surrender categorically.
|
||||
BOOLEAN fNoSurrender = FALSE;
|
||||
|
||||
// enemy team
|
||||
// enemy team and creature team (bandits can be captured)
|
||||
firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
lastid = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
|
||||
lastid = gTacticalStatus.Team[CREATURE_TEAM].bLastID;
|
||||
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
|
||||
{
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
@@ -10558,7 +10563,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
{
|
||||
// it is enough to simply set all soldiers to captured
|
||||
firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
lastid = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID;
|
||||
lastid = gTacticalStatus.Team[ CIV_TEAM ].bLastID;
|
||||
for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier)
|
||||
{
|
||||
if( pSoldier->bActive && ( pSoldier->sSectorX == gWorldSectorX ) && ( pSoldier->sSectorY == gWorldSectorY ) && ( pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
@@ -10577,28 +10582,7 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
firstid = gTacticalStatus.Team[CIV_TEAM].bFirstID;
|
||||
lastid = gTacticalStatus.Team[CIV_TEAM].bLastID;
|
||||
for ( uiCnt = firstid, pSoldier = MercPtrs[uiCnt]; uiCnt <= lastid; ++uiCnt, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->bActive && (pSoldier->sSectorX == gWorldSectorX) && (pSoldier->sSectorY == gWorldSectorY) && (pSoldier->bSectorZ == gbWorldSectorZ) )
|
||||
{
|
||||
// can this guy be captured?
|
||||
if ( !pSoldier->CanBeCaptured() )
|
||||
continue;
|
||||
|
||||
// only if not dying
|
||||
if ( pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
pSoldier->usSoldierFlagMask |= SOLDIER_POW;
|
||||
|
||||
// Remove as target
|
||||
RemoveManAsTarget( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// dynamic opinion: a merc caused the remaining enemies to give up
|
||||
if ( gusSelectedSoldier != NOBODY )
|
||||
HandleDynamicOpinionChange( MercPtrs[gusSelectedSoldier], OPINIONEVENT_BATTLE_TOOK_PRISONER, TRUE, TRUE );
|
||||
@@ -10626,6 +10610,14 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
// we offered to surrender OURSELVES TO the enemy
|
||||
else if ( ubExitValue == 2 )
|
||||
{
|
||||
// we cannot surrender to bandits, talk instead
|
||||
if ( MercPtrs[prisonerdialoguetargetID]->bTeam != CREATURE_TEAM )
|
||||
{
|
||||
// normal dialog
|
||||
StartCivQuote( MercPtrs[prisonerdialoguetargetID] );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !gGameExternalOptions.fPlayerCanAsktoSurrender )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szPrisonerTextStr[ SRT_PRISONER_INI_SETTING_OFF ] );
|
||||
@@ -10763,14 +10755,16 @@ void HandleSurrenderOffer( SOLDIERTYPE* pSoldier )
|
||||
|
||||
// open a dialogue box and see wether we really want to offer this, or just talk
|
||||
wcscpy( gzUserDefinedButton[0], TacticalStr[ PRISONER_DEMAND_SURRENDER_STR ] );
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[ PRISONER_OFFER_SURRENDER_STR ] );
|
||||
|
||||
SOLDIERTYPE* pTargetSoldier = NULL;
|
||||
if ( GetSoldier( &pTargetSoldier, prisonerdialoguetargetID ) &&
|
||||
pTargetSoldier->bTeam == ENEMY_TEAM &&
|
||||
pTargetSoldier->ubProfile == NO_PROFILE &&
|
||||
pTargetSoldier->aiData.bAlertStatus < STATUS_RED &&
|
||||
!pTargetSoldier->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
if ( pSoldier->bTeam != CREATURE_TEAM )
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[ PRISONER_OFFER_SURRENDER_STR ] );
|
||||
else
|
||||
wcscpy( gzUserDefinedButton[1], TacticalStr[PRISONER_TALK_STR] );
|
||||
|
||||
if ( pSoldier->bTeam == ENEMY_TEAM &&
|
||||
pSoldier->ubProfile == NO_PROFILE &&
|
||||
pSoldier->aiData.bAlertStatus < STATUS_RED &&
|
||||
!pSoldier->RecognizeAsCombatant( gusSelectedSoldier ) )
|
||||
{
|
||||
wcscpy( gzUserDefinedButton[2], TacticalStr[PRISONER_DISTRACT_STR] );
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#include "Campaign Types.h"
|
||||
#include "text.h" // added by Flugente
|
||||
#include "Vehicles.h" // added by silversurfer
|
||||
#include "ai.h" // added by Flugente
|
||||
#include "PreBattle Interface.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Animation Control.h"
|
||||
@@ -2632,7 +2634,7 @@ void RaiseZombies( void )
|
||||
|
||||
for ( INT32 cnt = giNumRottingCorpse - 1; cnt >= 0; --cnt )
|
||||
{
|
||||
if ( pSector->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures ) // ... if there is still room for more zombies (zombies count as creatures until a separate ZOMBIE_TEAM is implemented)...
|
||||
if ( pSector && pSector->ubNumCreatures < gGameExternalOptions.ubGameMaximumNumberOfCreatures ) // ... if there is still room for more zombies (zombies count as creatures until a separate ZOMBIE_TEAM is implemented)...
|
||||
{
|
||||
pCorpse = &(gRottingCorpse[ cnt ] );
|
||||
|
||||
@@ -2652,8 +2654,8 @@ void RaiseZombies( void )
|
||||
zombieshaverisen = TRUE;
|
||||
CreateZombiefromCorpse( pCorpse, recanimstate );
|
||||
|
||||
//++pSector->ubNumZombies;
|
||||
//++pSector->ubZombiesInBattle;
|
||||
pSector->ubNumCreatures++;
|
||||
pSector->ubCreaturesInBattle++;
|
||||
|
||||
RemoveCorpse( cnt );
|
||||
}
|
||||
@@ -2680,13 +2682,32 @@ void RaiseZombies( void )
|
||||
PlayJA2SampleFromFile( "Sounds\\zombie1.wav", RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
|
||||
|
||||
UseCreatureMusic(TRUE); // Madd: music when zombies rise
|
||||
#ifdef NEWMUSIC
|
||||
#ifdef NEWMUSIC
|
||||
GlobalSoundID = MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalTensor[gbWorldSectorZ];
|
||||
if ( MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalTensor[gbWorldSectorZ] != -1 )
|
||||
SetMusicModeID( MUSIC_TACTICAL_ENEMYPRESENT, MusicSoundValues[ SECTOR( gWorldSectorX, gWorldSectorY ) ].SoundTacticalTensor[gbWorldSectorZ] );
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
SetMusicMode( MUSIC_TACTICAL_ENEMYPRESENT );
|
||||
|
||||
// alert the creatures
|
||||
HandleInitialRedAlert( CREATURE_TEAM, FALSE );
|
||||
|
||||
// we need this so that the battle is properly recognized in strategic
|
||||
{
|
||||
//Set up the location as well as turning on the blit flag.
|
||||
gubPBSectorX = (UINT8)gWorldSectorX;
|
||||
gubPBSectorY = (UINT8)gWorldSectorY;
|
||||
gubPBSectorZ = (UINT8)gbWorldSectorZ;
|
||||
gfBlitBattleSectorLocator = TRUE;
|
||||
}
|
||||
|
||||
if ( GetEnemyEncounterCode() == NO_ENCOUNTER_CODE )
|
||||
SetEnemyEncounterCode( ZOMBIE_ATTACK_CODE );
|
||||
|
||||
// idea... potentially scrap this part and use a simplified form of void CreatureAttackTown_OtherCreatures(...) ?
|
||||
|
||||
//gubSectorIDOfCreatureAttack = SECTOR( gWorldSectorX, gWorldSectorY );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
#include "CampaignStats.h" // added by Flugente
|
||||
#include "DynamicDialogue.h" // added by Flugente
|
||||
#include "MilitiaIndividual.h" // added by Flugente
|
||||
#include "Town Militia.h" // added by Flugente
|
||||
#include "PreBattle Interface.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
// anv: for enemy taunts
|
||||
@@ -3945,6 +3947,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
|
||||
case SOLDIER_CLASS_ZOMBIE :
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsZombies++;
|
||||
break;
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
gMercProfiles[MercPtrs[ubAttacker]->ubProfile].records.usKillsOthers++;
|
||||
break;
|
||||
default :
|
||||
if ( CREATURE_OR_BLOODCAT( pSoldier ) )
|
||||
gMercProfiles[ MercPtrs[ ubAttacker ]->ubProfile ].records.usKillsCreatures++;
|
||||
@@ -4049,6 +4054,14 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse )
|
||||
// Flugente: campaign stats
|
||||
gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_KILL );
|
||||
|
||||
// Flugente: for raids, we need to keep track of killed forces
|
||||
if ( GetEnemyEncounterCode() == BLOODCAT_ATTACK_CODE ||
|
||||
GetEnemyEncounterCode() == ZOMBIE_ATTACK_CODE ||
|
||||
GetEnemyEncounterCode() == BANDIT_ATTACK_CODE )
|
||||
{
|
||||
AddRaidPersonnel( -( pSoldier->ubBodyType == BLOODCAT ), -( pSoldier->ubSoldierClass == SOLDIER_CLASS_ZOMBIE ), -( pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT ) );
|
||||
}
|
||||
|
||||
// Flugente: individual militia
|
||||
MILITIA militia;
|
||||
if ( GetMilitia( pSoldier->usIndividualMilitiaID, &militia ) && !(militia.flagmask & MILITIAFLAG_DEAD) )
|
||||
|
||||
@@ -14723,7 +14723,7 @@ INT32 SOLDIERTYPE::GetDamageResistance( BOOLEAN fAutoResolve, BOOLEAN fCalcBreat
|
||||
else if ( this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0 )
|
||||
resistance += (INT32)(gGameExternalOptions.bVeteranMilitiaDamageResistance / breathmodifiermilitia);
|
||||
// bonus for enemy too
|
||||
else if ( this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0 )
|
||||
else if ( (this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || this->ubSoldierClass == SOLDIER_CLASS_BANDIT ) && gGameExternalOptions.sEnemyAdminDamageResistance != 0 )
|
||||
resistance += gGameExternalOptions.sEnemyAdminDamageResistance;
|
||||
else if ( this->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0 )
|
||||
resistance += gGameExternalOptions.sEnemyRegularDamageResistance;
|
||||
@@ -16211,7 +16211,7 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength( )
|
||||
// adjust for type of soldier
|
||||
if ( this->ubSoldierClass == SOLDIER_CLASS_ELITE || this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA )
|
||||
value *= 1.5f;
|
||||
else if ( this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA || this->ubSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
value *= 0.75f;
|
||||
|
||||
// tanks won't surrender that easy
|
||||
@@ -16267,6 +16267,10 @@ BOOLEAN SOLDIERTYPE::CanBeCaptured( )
|
||||
if ( this->bTeam == ENEMY_TEAM )
|
||||
return TRUE;
|
||||
|
||||
// bandits can be captured
|
||||
if ( this->bTeam == CREATURE_TEAM && this->ubSoldierClass == SOLDIER_CLASS_BANDIT )
|
||||
return TRUE;
|
||||
|
||||
// civilians can be captured if their faction can, and if they are hostile
|
||||
if ( this->bTeam == CIV_TEAM && zCivGroupName[this->ubCivilianGroup].fCanBeCaptured )
|
||||
{
|
||||
|
||||
@@ -331,6 +331,7 @@ enum
|
||||
SOLDIER_CLASS_ZOMBIE,
|
||||
SOLDIER_CLASS_TANK,
|
||||
SOLDIER_CLASS_JEEP,
|
||||
SOLDIER_CLASS_BANDIT,
|
||||
SOLDIER_CLASS_MAX,
|
||||
};
|
||||
|
||||
|
||||
+156
-93
@@ -1799,7 +1799,7 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Added by SANDRO - the enemy/militia has a decent chance to have some traits
|
||||
if ( gGameExternalOptions.fAssignTraitsToEnemy && SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) )
|
||||
if ( gGameExternalOptions.fAssignTraitsToEnemy && (SOLDIER_CLASS_ENEMY( pSoldier->ubSoldierClass ) || pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT) )
|
||||
AssignTraitsToSoldier( pSoldier, pCreateStruct );
|
||||
if ( gGameExternalOptions.fAssignTraitsToMilitia && SOLDIER_CLASS_MILITIA( pSoldier->ubSoldierClass ) )
|
||||
AssignTraitsToSoldier( pSoldier, pCreateStruct );
|
||||
@@ -2010,7 +2010,7 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
}
|
||||
break;
|
||||
case CREATURE_TEAM:
|
||||
if( pSoldier->ubBodyType == BLOODCAT )
|
||||
if ( pSoldier->ubBodyType == BLOODCAT )
|
||||
{
|
||||
swprintf( pSoldier->name, gzLateLocalizedString[ 36 ] );
|
||||
}
|
||||
@@ -2018,9 +2018,13 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] );
|
||||
}
|
||||
else if ( pSoldier->ubBodyType >= ADULTFEMALEMONSTER && pSoldier->ubBodyType <= QUEENMONSTER )
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[CREATURE_TEAM_MERC_NAME] ); break;
|
||||
}
|
||||
else
|
||||
{
|
||||
swprintf( pSoldier->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ] ); break;
|
||||
swprintf( pSoldier->name, gpStrategicString[STR_PB_BANDIT] ); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2296,7 +2300,6 @@ INT8 CalcDifficultyModifier( UINT8 ubSoldierClass )
|
||||
return(bDiffModifier);
|
||||
}
|
||||
|
||||
|
||||
//When the editor modifies the soldier's relative attribute level,
|
||||
//this function is called to update that information.
|
||||
//Used to generate a detailed placement from a basic placement. This assumes that the detailed placement
|
||||
@@ -2397,8 +2400,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
pp->bOrders = bp->bOrders;
|
||||
pp->bAttitude = bp->bAttitude;
|
||||
pp->ubDirection = bp->ubDirection;
|
||||
|
||||
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: determine soldier's class"));
|
||||
// determine this soldier's soldier class
|
||||
if( bp->bTeam == CREATURE_TEAM )
|
||||
@@ -2411,8 +2413,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
}
|
||||
|
||||
ubDiffFactor = CalcDifficultyModifier( ubSoldierClass );
|
||||
|
||||
|
||||
|
||||
// experience level is modified by game difficulty, player's progress, & proximity to Queen's Palace, etc.
|
||||
// This formula gives the following results:
|
||||
// DIFFICULTY FACTOR EXP. LEVEL MODIFIER LEVEL OF AVG REGULAR TROOP
|
||||
@@ -2457,6 +2458,19 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
break;
|
||||
}
|
||||
|
||||
UINT8 DiffLevel;
|
||||
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
|
||||
DiffLevel = 1;
|
||||
else if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
|
||||
DiffLevel = 2;
|
||||
else if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
|
||||
DiffLevel = 3;
|
||||
else if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
DiffLevel = 4;
|
||||
else
|
||||
{
|
||||
DiffLevel = 1 + Random ( 4 );
|
||||
}
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: set level based on soldier class"));
|
||||
//Set the experience level based on the soldier class and exp level modifier or relative attribute level
|
||||
@@ -2464,6 +2478,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_ZOMBIE:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pp->bExpLevel = (INT8) 2 + bExpLevelModifier;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
@@ -2512,23 +2527,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
UINT8 PlacementType = gBloodcatPlacements[ SECTOR(gWorldSectorX, gWorldSectorY) ][0].PlacementType;
|
||||
if( PlacementType == BLOODCAT_PLACEMENT_LAIR )
|
||||
{
|
||||
|
||||
UINT8 DiffLevel;
|
||||
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
|
||||
DiffLevel = 1;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
|
||||
DiffLevel = 2;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
|
||||
DiffLevel = 3;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
DiffLevel = 4;
|
||||
else
|
||||
{
|
||||
DiffLevel = Random (4);
|
||||
if (DiffLevel == 0) DiffLevel = 1;
|
||||
}
|
||||
pp->bExpLevel += DiffLevel;
|
||||
//pp->bExpLevel += gGameOptions.ubDifficultyLevel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2546,8 +2545,8 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
}
|
||||
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: set exp. level"));
|
||||
pp->bExpLevel = max( gGameOptions.ubDifficultyLevel, pp->bExpLevel ); //minimum exp. level of 1 -- madd->= dif level
|
||||
|
||||
pp->bExpLevel = max( DiffLevel, pp->bExpLevel ); //minimum exp. level of 1 -- madd->= dif level
|
||||
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
pp->bExpLevel = max( 6, pp->bExpLevel ); //minimum exp. level of 6 in insane - madd
|
||||
|
||||
@@ -2555,23 +2554,7 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
|
||||
ubStatsLevel = pp->bExpLevel + bStatsModifier;
|
||||
|
||||
UINT8 DiffLevel;
|
||||
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
|
||||
DiffLevel = 1;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
|
||||
DiffLevel = 2;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
|
||||
DiffLevel = 3;
|
||||
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
DiffLevel = 4;
|
||||
else
|
||||
{
|
||||
DiffLevel = Random (4);
|
||||
if (DiffLevel == 0) DiffLevel = 1;
|
||||
}
|
||||
ubStatsLevel = max( DiffLevel, ubStatsLevel ); //minimum stats level of 0 -- madd->= dif level
|
||||
//ubStatsLevel = max( gGameOptions.ubDifficultyLevel, ubStatsLevel ); //minimum stats level of 0 -- madd->= dif level
|
||||
|
||||
ubStatsLevel = max( DiffLevel, ubStatsLevel ); //minimum stats level of 0 -- madd->= dif level
|
||||
if ( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
|
||||
ubStatsLevel = max( 6, ubStatsLevel ); //minimum stats level of 6 in insane
|
||||
|
||||
@@ -2618,7 +2601,11 @@ void CreateDetailedPlacementGivenBasicPlacementInfo( SOLDIERCREATE_STRUCT *pp, B
|
||||
//own equipment.
|
||||
DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("CreateDetailedPlacementGivenBasicPlacementInfo: generate random equipment"));
|
||||
|
||||
if( !bp->fDetailedPlacement && ubSoldierClass != SOLDIER_CLASS_NONE && ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_MINER && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
if( !bp->fDetailedPlacement &&
|
||||
ubSoldierClass != SOLDIER_CLASS_NONE &&
|
||||
ubSoldierClass != SOLDIER_CLASS_CREATURE &&
|
||||
ubSoldierClass != SOLDIER_CLASS_MINER &&
|
||||
ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
{
|
||||
GenerateRandomEquipment( pp, ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
|
||||
@@ -2800,7 +2787,10 @@ void CreateDetailedPlacementGivenStaticDetailedPlacementAndBasicPlacementInfo(
|
||||
// ReplaceExtendedGuns( pp, bp->ubSoldierClass );
|
||||
//}
|
||||
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE && bp->ubSoldierClass != SOLDIER_CLASS_CREATURE && bp->ubSoldierClass != SOLDIER_CLASS_MINER && bp->ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
if( bp->ubSoldierClass != SOLDIER_CLASS_NONE &&
|
||||
bp->ubSoldierClass != SOLDIER_CLASS_CREATURE &&
|
||||
bp->ubSoldierClass != SOLDIER_CLASS_MINER &&
|
||||
bp->ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
{
|
||||
GenerateRandomEquipment( pp, bp->ubSoldierClass, bp->bRelativeEquipmentLevel);
|
||||
|
||||
@@ -2841,6 +2831,7 @@ void UpdateSoldierWithStaticDetailedInformation( SOLDIERTYPE *s, SOLDIERCREATE_S
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
case SOLDIER_CLASS_ELITE:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
GeneratePaletteForSoldier( s, spp->ubSoldierClass, spp->bTeam );
|
||||
break;
|
||||
}
|
||||
@@ -3003,7 +2994,7 @@ SOLDIERTYPE* ReserveTacticalSoldierForAutoresolve( UINT8 ubSoldierClass )
|
||||
//returns the pointer to that soldier. This is used when copying the exact status of
|
||||
//all remaining enemy troops (or creatures) to finish the battle in autoresolve. To
|
||||
//signify that the troop has already been reserved, we simply set their gridno to NOWHERE.
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_ZOMBIE )
|
||||
if( ubSoldierClass != SOLDIER_CLASS_CREATURE && ubSoldierClass != SOLDIER_CLASS_ZOMBIE && ubSoldierClass != SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
//use the enemy team
|
||||
iStart = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
@@ -3244,12 +3235,16 @@ SOLDIERTYPE* TacticalCreateZombie()
|
||||
memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ZOMBIE );
|
||||
bp.bTeam = CREATURE_TEAM;//ZOMBIE_TEAM;
|
||||
bp.bTeam = CREATURE_TEAM;
|
||||
bp.bOrders = SEEKENEMY;
|
||||
bp.bAttitude = AGGRESSIVE;
|
||||
bp.ubBodyType = -1;
|
||||
bp.ubBodyType = Random( ADULTFEMALEMONSTER );
|
||||
bp.ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
|
||||
|
||||
// need to properly set this here
|
||||
pp.ubSoldierClass = SOLDIER_CLASS_ZOMBIE;
|
||||
|
||||
pSoldier = TacticalCreateSoldier( &pp, &ubID );
|
||||
if ( pSoldier )
|
||||
{
|
||||
@@ -3398,10 +3393,13 @@ SOLDIERTYPE* TacticalCreateArmedCivilian( UINT8 usSoldierClass )
|
||||
pSoldier->aiData.sNoiseGridno = (CENTRAL_GRIDNO + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) + (Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS) * WORLD_COLS);
|
||||
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
|
||||
|
||||
// random clothes
|
||||
SetClothes( pSoldier, Random( NUMSHIRTS ), Random( NUMPANTS ) );
|
||||
if ( guiCurrentScreen != AUTORESOLVE_SCREEN )
|
||||
{
|
||||
// random clothes
|
||||
SetClothes( pSoldier, Random( NUMSHIRTS ), Random( NUMPANTS ) );
|
||||
|
||||
pSoldier->CreateSoldierPalettes( );
|
||||
pSoldier->CreateSoldierPalettes();
|
||||
}
|
||||
}
|
||||
|
||||
return(pSoldier);
|
||||
@@ -3481,25 +3479,28 @@ SOLDIERTYPE* TacticalCreateCivilian( INT32 sGridNo, UINT8 usCivilianGroup, INT8
|
||||
pSoldier->aiData.bOrders = ONGUARD;
|
||||
}
|
||||
|
||||
// make him wear administrator uniform
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
if ( guiCurrentScreen != AUTORESOLVE_SCREEN )
|
||||
{
|
||||
SetClothes( pSoldier, aVest, aPants, aHair, aSkin );
|
||||
// make him wear administrator uniform
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof(pSoldier->p8BPPPalette) * 256 );
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
SetClothes( pSoldier, aVest, aPants, aHair, aSkin );
|
||||
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof( pSoldier->p8BPPPalette ) * 256 );
|
||||
|
||||
pSoldier->CreateSoldierPalettes( );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
|
||||
|
||||
// Dirty
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
pSoldier->CreateSoldierPalettes();
|
||||
|
||||
// Dirty
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3572,6 +3573,65 @@ SOLDIERTYPE* TacticalCreateEnemyAssassin(UINT8 disguisetype)
|
||||
return( pSoldier );
|
||||
}
|
||||
|
||||
SOLDIERTYPE* TacticalCreateBandit()
|
||||
{
|
||||
BASIC_SOLDIERCREATE_STRUCT bp;
|
||||
SOLDIERCREATE_STRUCT pp;
|
||||
UINT8 ubID;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
if ( guiCurrentScreen == AUTORESOLVE_SCREEN && !gfPersistantPBI )
|
||||
{
|
||||
pSoldier = ReserveTacticalSoldierForAutoresolve( SOLDIER_CLASS_BANDIT );
|
||||
if ( pSoldier ) return pSoldier;
|
||||
}
|
||||
|
||||
memset( &bp, 0, sizeof( BASIC_SOLDIERCREATE_STRUCT ) );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeAttributeLevel ), SOLDIER_CLASS_ADMINISTRATOR );
|
||||
RandomizeRelativeLevel( &( bp.bRelativeEquipmentLevel ), SOLDIER_CLASS_ADMINISTRATOR );
|
||||
bp.bTeam = ENEMY_TEAM; // set wrong team here, otherwise no bodytype/equipment will be set
|
||||
bp.bOrders = SEEKENEMY;
|
||||
bp.bAttitude = (INT8)Random( MAXATTITUDES );
|
||||
bp.ubBodyType = -1;
|
||||
bp.ubSoldierClass = SOLDIER_CLASS_ADMINISTRATOR;
|
||||
CreateDetailedPlacementGivenBasicPlacementInfo( &pp, &bp );
|
||||
|
||||
// need to properly set this here
|
||||
pp.bTeam = CREATURE_TEAM;
|
||||
pp.ubSoldierClass = SOLDIER_CLASS_BANDIT;
|
||||
|
||||
pSoldier = TacticalCreateSoldier( &pp, &ubID );
|
||||
if ( pSoldier )
|
||||
{
|
||||
// send soldier to centre of map, roughly
|
||||
pSoldier->aiData.sNoiseGridno = ( CENTRAL_GRIDNO + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) + ( Random( CENTRAL_RADIUS * 2 + 1 ) - CENTRAL_RADIUS ) * WORLD_COLS );
|
||||
pSoldier->aiData.ubNoiseVolume = MAX_MISC_NOISE_DURATION;
|
||||
|
||||
if ( guiCurrentScreen != AUTORESOLVE_SCREEN )
|
||||
{
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
// random clothes
|
||||
SetClothes( pSoldier, Random( NUMSHIRTS ), Random( NUMPANTS ) );
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof( pSoldier->p8BPPPalette ) * 256 );
|
||||
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
|
||||
|
||||
pSoldier->CreateSoldierPalettes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return( pSoldier );
|
||||
}
|
||||
|
||||
void CreateAssassin(UINT8 disguisetype)
|
||||
{
|
||||
SOLDIERTYPE* pSoldier = TacticalCreateEnemyAssassin( disguisetype );
|
||||
@@ -3742,26 +3802,29 @@ void CreatePrisonerOfWar()
|
||||
|
||||
swprintf( pSoldier->name, TacticalStr[ POW_TEAM_MERC_NAME ] );
|
||||
|
||||
// make him wear 'prisoner garb' (just what Shank and Dynamo are wearing)
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
||||
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
if ( guiCurrentScreen != AUTORESOLVE_SCREEN )
|
||||
{
|
||||
SET_PALETTEREP_ID( pSoldier->VestPal, "greyVEST" );
|
||||
SET_PALETTEREP_ID( pSoldier->PantsPal, "BLACKPANTS" );
|
||||
// make him wear 'prisoner garb' (just what Shank and Dynamo are wearing)
|
||||
UINT16 usPaletteAnimSurface = LoadSoldierAnimationSurface( pSoldier, pSoldier->usAnimState );
|
||||
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof(pSoldier->p8BPPPalette) * 256 );
|
||||
if ( usPaletteAnimSurface != INVALID_ANIMATION_SURFACE )
|
||||
{
|
||||
SET_PALETTEREP_ID( pSoldier->VestPal, "greyVEST" );
|
||||
SET_PALETTEREP_ID( pSoldier->PantsPal, "BLACKPANTS" );
|
||||
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
|
||||
// Use palette from HVOBJECT, then use substitution for pants, etc
|
||||
memcpy( pSoldier->p8BPPPalette, gAnimSurfaceDatabase[usPaletteAnimSurface].hVideoObject->pPaletteEntry, sizeof( pSoldier->p8BPPPalette ) * 256 );
|
||||
|
||||
pSoldier->CreateSoldierPalettes( );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->HeadPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->VestPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->PantsPal );
|
||||
SetPaletteReplacement( pSoldier->p8BPPPalette, pSoldier->SkinPal );
|
||||
|
||||
// Dirty
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
pSoldier->CreateSoldierPalettes();
|
||||
|
||||
// Dirty
|
||||
fInterfacePanelDirty = DIRTYLEVEL2;
|
||||
}
|
||||
}
|
||||
|
||||
// So we can see them!
|
||||
@@ -4696,7 +4759,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
// 30-80%
|
||||
iChance = 30 + ubProgress / 2;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
// 15-65%
|
||||
iChance = 15 + ubProgress / 2;
|
||||
@@ -4757,7 +4820,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
// 30-80%
|
||||
iChance = 30 + ubProgress / 2;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
// 15-65%
|
||||
iChance = 15 + ubProgress / 2;
|
||||
@@ -4819,7 +4882,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
// 25-75%
|
||||
iChance = 25 + ubProgress / 2;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
// 10-60%
|
||||
iChance = 10 + ubProgress / 2;
|
||||
@@ -4888,7 +4951,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
// 25-75%
|
||||
iChance = 25 + ubProgress / 2;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
// 10-60%
|
||||
iChance = 10 + ubProgress / 2;
|
||||
@@ -4993,7 +5056,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
// 25-75%
|
||||
iChance = 25 + ubProgress / 2;
|
||||
}
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
{
|
||||
// 10-60%
|
||||
iChance = 10 + ubProgress / 2;
|
||||
@@ -5177,7 +5240,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 45 + ubProgress / 2; // 45-95% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 30 + ubProgress / 2; // 30-80% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = 15 + ubProgress / 2; // 15-65% chance
|
||||
|
||||
// adust the chance by the type of heavy weapon
|
||||
@@ -5239,7 +5302,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 20 + ubProgress / 4; // 20-45% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 10 + ubProgress / 4; // 10-35% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = ubProgress / 4; // 0-25% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
@@ -5284,7 +5347,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 40 + ubProgress * 2 / 5; // 40-80% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 25 + ubProgress * 2 / 5; // 25-65% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = 10 + ubProgress * 2 / 5; // 10-50% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ZOMBIE )
|
||||
iChance = 100; // 100% chance
|
||||
@@ -5348,7 +5411,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 30 + ubProgress / 3 + 30; // 60-92% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 15 + ubProgress / 3 + 25; // 40-73% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = ubProgress / 3 + 20; // 20-53% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
@@ -5411,7 +5474,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 20 + ubProgress / 3; // 20-53% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 10 + ubProgress / 3; // 10-43% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = ubProgress / 3; // 0-33% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
@@ -5451,7 +5514,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 50 + ubProgress * 2 / 5; // 50-90% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 35 + ubProgress * 2 / 5; // 35-75% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = 15 + ubProgress * 2 / 5; // 15-55% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
@@ -5514,7 +5577,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 40 + ubProgress * 2 / 5; // 40-80% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 25 + ubProgress * 2 / 5; // 25-65% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = 10 + ubProgress * 2 / 5; // 10-50% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
@@ -5556,7 +5619,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 10 + ubProgress / 4; // 10-35% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = ubProgress / 5; // 0-20% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = 0; // 0% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
@@ -5598,7 +5661,7 @@ BOOLEAN AssignTraitsToSoldier( SOLDIERTYPE *pSoldier, SOLDIERCREATE_STRUCT *pCre
|
||||
iChance = 30 + ubProgress / 2; // 30-90% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ARMY || ubSolClass == SOLDIER_CLASS_REG_MILITIA )
|
||||
iChance = 10 + ubProgress / 2; // 10-60% chance
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA )
|
||||
else if ( ubSolClass == SOLDIER_CLASS_ADMINISTRATOR || ubSolClass == SOLDIER_CLASS_GREEN_MILITIA || ubSolClass == SOLDIER_CLASS_BANDIT )
|
||||
iChance = ubProgress / 3; // 0-33% chance
|
||||
|
||||
// modify the chance by preset ini setting
|
||||
|
||||
@@ -481,6 +481,9 @@ SOLDIERTYPE* TacticalCreateCivilian( INT32 sGridNo, UINT8 usCivilianGroup, INT8
|
||||
|
||||
// Flugente: assassins are elite soldiers of the civ team that go hostile on a certain event, otherwise they just blend in
|
||||
SOLDIERTYPE* TacticalCreateEnemyAssassin(UINT8 disguisetype);
|
||||
|
||||
SOLDIERTYPE* TacticalCreateBandit();
|
||||
|
||||
void CreateAssassin(UINT8 disguisetype);
|
||||
|
||||
// create a prisoner (in a prison cell) in the current sector
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
#include "PreBattle Interface.h" // added by Flugente
|
||||
#include "LuaInitNPCs.h" // added by Flugente
|
||||
#include "Soldier macros.h" // added by Flugente
|
||||
#include "Creature Spreading.h" // added by Flugente
|
||||
|
||||
|
||||
BOOLEAN gfOriginalList = TRUE;
|
||||
|
||||
@@ -1105,6 +1107,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
ubEliteBSlots++;
|
||||
break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
if( curr->pBasicPlacement->fPriorityExistance && curr->pDetailedPlacement )
|
||||
ubAdminPDSlots++;
|
||||
else if( curr->pBasicPlacement->fPriorityExistance )
|
||||
@@ -1163,6 +1166,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
switch( ubCurrClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pCurrSlots = &ubAdminPDSlots;
|
||||
pCurrTotal = &ubTotalAdmin;
|
||||
break;
|
||||
@@ -1229,6 +1233,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
switch( ubCurrClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pCurrSlots = &ubAdminPSlots;
|
||||
pCurrTotal = &ubTotalAdmin;
|
||||
break;
|
||||
@@ -1285,6 +1290,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
switch( ubCurrClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pCurrSlots = &ubAdminDSlots;
|
||||
pCurrTotal = &ubTotalAdmin;
|
||||
break;
|
||||
@@ -1389,12 +1395,13 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
//ADD REMAINING PLACEMENTS WITH BASIC PLACEMENT INFORMATION
|
||||
//we now have the numbers of available slots for each soldier class, so loop through three times
|
||||
//and randomly choose some (or all) of the matching slots to fill. This is done randomly.
|
||||
for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY; ubCurrClass++ )
|
||||
for( ubCurrClass = SOLDIER_CLASS_ADMINISTRATOR; ubCurrClass <= SOLDIER_CLASS_ARMY; ++ubCurrClass )
|
||||
{
|
||||
//First, prepare the counters.
|
||||
switch( ubCurrClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pCurrSlots = &ubAdminBSlots;
|
||||
pCurrTotal = &ubTotalAdmin;
|
||||
break;
|
||||
@@ -1672,7 +1679,8 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
|
||||
switch( curr->pBasicPlacement->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ELITE: ubEliteSlots++; break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR: ubGreenSlots++; break;
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT: ubGreenSlots++; break;
|
||||
case SOLDIER_CLASS_ARMY: ubRegSlots++; break;
|
||||
}
|
||||
}
|
||||
@@ -1693,6 +1701,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
|
||||
switch( reorder[i] )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
pCurrSlots = &ubGreenSlots;
|
||||
pCurrTotal = &ubNumGreen;
|
||||
break;
|
||||
@@ -1721,6 +1730,7 @@ void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumRegs, UINT8 ubNumEl
|
||||
switch( reorder[i] )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR:
|
||||
case SOLDIER_CLASS_BANDIT:
|
||||
curr->pBasicPlacement->ubSoldierClass = SOLDIER_CLASS_GREEN_MILITIA;
|
||||
break;
|
||||
case SOLDIER_CLASS_ARMY:
|
||||
@@ -2059,7 +2069,125 @@ void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNum
|
||||
}
|
||||
}
|
||||
|
||||
void AddSoldierInitListOtherCreatures( UINT8 usNum )
|
||||
{
|
||||
SOLDIERINITNODE *curr;
|
||||
INT32 iRandom;
|
||||
UINT8 ubFreeSlots;
|
||||
BOOLEAN fDoPlacement;
|
||||
UINT8 ubNumCreatures = usNum;
|
||||
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String( "AddSoldierInitListBloodcats" ) );
|
||||
|
||||
SortSoldierInitList();
|
||||
|
||||
//First fill up only the priority existance slots (as long as the availability and bodytypes match)
|
||||
curr = gSoldierInitHead;
|
||||
while ( curr && curr->pBasicPlacement->fPriorityExistance && ubNumCreatures )
|
||||
{
|
||||
fDoPlacement = TRUE;
|
||||
|
||||
if ( curr->pBasicPlacement->bTeam == CREATURE_TEAM )
|
||||
{
|
||||
//Matching team, now check the soldier class...
|
||||
switch ( guCreatureAttackType )
|
||||
{
|
||||
case CREATURE_ATTACK_TYPE_ZOMBIE:
|
||||
if ( curr->pBasicPlacement->ubBodyType > REGFEMALE )
|
||||
fDoPlacement = FALSE;
|
||||
break;
|
||||
|
||||
case CREATURE_ATTACK_TYPE_BANDIT:
|
||||
if ( curr->pBasicPlacement->ubBodyType > REGFEMALE )
|
||||
fDoPlacement = FALSE;
|
||||
break;
|
||||
|
||||
case CREATURE_ATTACK_TYPE_BLOODCAT:
|
||||
if ( curr->pBasicPlacement->ubBodyType != BLOODCAT )
|
||||
fDoPlacement = FALSE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if ( fDoPlacement )
|
||||
{
|
||||
if ( AddPlacementToWorld( curr ) )
|
||||
{
|
||||
--ubNumCreatures;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
if ( !ubNumCreatures )
|
||||
return;
|
||||
|
||||
//Count how many free creature slots are left.
|
||||
curr = gSoldierInitHead;
|
||||
ubFreeSlots = 0;
|
||||
while ( curr )
|
||||
{
|
||||
if ( !curr->pSoldier && curr->pBasicPlacement->bTeam == CREATURE_TEAM )
|
||||
++ubFreeSlots;
|
||||
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
//Now, if we still have creatures to place, do so completely randomly, overriding priority
|
||||
//placements, etc.
|
||||
curr = gSoldierInitHead;
|
||||
while ( curr && ubFreeSlots && ubNumCreatures )
|
||||
{
|
||||
if ( !curr->pSoldier && curr->pBasicPlacement->bTeam == CREATURE_TEAM )
|
||||
{
|
||||
//Randomly determine if we will use this slot; the more available slots in proportion to
|
||||
//the number of enemies, the lower the chance of accepting the slot.
|
||||
if ( ubFreeSlots <= ubNumCreatures || Random( ubFreeSlots ) < ubNumCreatures )
|
||||
{
|
||||
switch ( guCreatureAttackType )
|
||||
{
|
||||
case CREATURE_ATTACK_TYPE_ZOMBIE:
|
||||
curr->pBasicPlacement->ubBodyType = Random( ADULTFEMALEMONSTER );
|
||||
break;
|
||||
|
||||
case CREATURE_ATTACK_TYPE_BANDIT:
|
||||
curr->pBasicPlacement->ubBodyType = Random( ADULTFEMALEMONSTER );
|
||||
break;
|
||||
|
||||
case CREATURE_ATTACK_TYPE_BLOODCAT:
|
||||
curr->pBasicPlacement->ubBodyType = BLOODCAT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if ( curr->pDetailedPlacement )
|
||||
{
|
||||
//delete the detailed placement information.
|
||||
MemFree( curr->pDetailedPlacement );
|
||||
curr->pDetailedPlacement = NULL;
|
||||
curr->pBasicPlacement->fDetailedPlacement = FALSE;
|
||||
}
|
||||
|
||||
if ( AddPlacementToWorld( curr ) )
|
||||
{
|
||||
--ubNumCreatures;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
--ubFreeSlots;
|
||||
//With the decrementing of the slot vars in this manner, the chances increase so that all slots
|
||||
//will be full by the time the end of the list comes up.
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
}
|
||||
|
||||
SOLDIERINITNODE* FindSoldierInitNodeWithProfileID( UINT16 usProfile );
|
||||
SOLDIERINITNODE* FindSoldierInitNodeWithProfileID( UINT16 usProfile )
|
||||
|
||||
@@ -44,6 +44,7 @@ void AddSoldierInitListEnemyDefenceSoldiers( UINT8 ubTotalAdmin, UINT8 ubTotalTr
|
||||
void AddSoldierInitListCreatures( BOOLEAN fQueen, UINT8 ubNumLarvae, UINT8 ubNumInfants,
|
||||
UINT8 ubNumYoungMales, UINT8 ubNumYoungFemales, UINT8 ubNumAdultMales,
|
||||
UINT8 ubNumAdultFemales );
|
||||
void AddSoldierInitListOtherCreatures( UINT8 usNum );
|
||||
void AddSoldierInitListMilitia( UINT8 ubNumGreen, UINT8 ubNumReg, UINT8 ubNumElites );
|
||||
void AddSoldierInitListMilitiaOnEdge( UINT8 ubStrategicInsertionCode, UINT8 ubNumGreen, UINT8 ubNumReg, UINT8 ubNumElites );
|
||||
|
||||
|
||||
+24
-49
@@ -6477,7 +6477,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
|
||||
// bonus for enemy
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
else if ( (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT) && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
|
||||
@@ -9069,6 +9069,8 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
|
||||
INT32 iImpact, iFluke, iBonus;
|
||||
|
||||
BOOLEAN autoresolve = IsAutoResolveActive();
|
||||
|
||||
// Flugente: check for underbarrel weapons and use that object if necessary (think of bayonets)
|
||||
OBJECTTYPE* pObj = pSoldier->GetUsedWeapon( &(pSoldier->inv[HANDPOS]) );
|
||||
|
||||
@@ -9158,9 +9160,10 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MARTIAL_ARTS_NT ) )
|
||||
{
|
||||
iBonus += ( gSkillTraitValues.ubMABonusDamageHandToHand * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) );
|
||||
}
|
||||
}
|
||||
|
||||
// add bonus for focused punch
|
||||
if (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->usAnimState == FOCUSED_PUNCH || pSoldier->usAnimState == FOCUSED_HTH_KICK )
|
||||
if ( !autoresolve && (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->usAnimState == FOCUSED_PUNCH || pSoldier->usAnimState == FOCUSED_HTH_KICK) )
|
||||
{
|
||||
iBonus += 50;
|
||||
|
||||
@@ -9180,7 +9183,8 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iBonus += ( gSkillTraitValues.ubMABonusDamageHandToHand * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) );
|
||||
|
||||
// The Spinning kicks or aimed punch bonus - SANDRO
|
||||
if (pSoldier->usAnimState == NINJA_SPINKICK || (pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6)))
|
||||
if ( !autoresolve &&
|
||||
(pSoldier->usAnimState == NINJA_SPINKICK || (pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedPunches : 6)) ))
|
||||
{
|
||||
//iImpact = (INT32)((iImpact * (100 + gSkillTraitValues.usMAAimedPunchDamageBonus * NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) ) / 100) + 0.5); // +75% damage per trait
|
||||
iBonus += ( (gSkillTraitValues.ubMABonusDamageHandToHand + 25 )* NUM_SKILL_TRAITS( pSoldier, MARTIAL_ARTS_NT ) );
|
||||
@@ -9196,28 +9200,31 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iBonus += gSkillTraitValues.ubMEDamageBonusBlunt;
|
||||
|
||||
// bonus for aimed attack
|
||||
if ( pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6) )
|
||||
if ( !autoresolve && pSoldier->aiData.bAimTime >= (gGameExternalOptions.fEnhancedCloseCombatSystem ? gSkillTraitValues.ubModifierForAPsAddedOnAimedBladedAttackes : 6) )
|
||||
{
|
||||
iBonus += gSkillTraitValues.usMEAimedMeleeAttackDamageBonus; // incresed damage if focused melee attack
|
||||
iBonus += gSkillTraitValues.usMEAimedMeleeAttackDamageBonus; // incresed damage if focused melee attack
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // original code
|
||||
{
|
||||
if ( gGameExternalOptions.fEnhancedCloseCombatSystem && (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->usAnimState == FOCUSED_PUNCH || pSoldier->usAnimState == FOCUSED_HTH_KICK ))
|
||||
if ( !autoresolve && gGameExternalOptions.fEnhancedCloseCombatSystem && (pSoldier->usAnimState == NINJA_SPINKICK || pSoldier->usAnimState == FOCUSED_PUNCH || pSoldier->usAnimState == FOCUSED_HTH_KICK ))
|
||||
{
|
||||
iBonus += 50;
|
||||
}
|
||||
|
||||
// add bonuses for hand-to-hand and martial arts
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, MARTIALARTS_OT ) )
|
||||
{
|
||||
iBonus += gbSkillTraitBonus[MARTIALARTS_OT] * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT );
|
||||
if (pSoldier->usAnimState == NINJA_SPINKICK)
|
||||
|
||||
if ( !autoresolve && pSoldier->usAnimState == NINJA_SPINKICK)
|
||||
{
|
||||
iBonus += 100;
|
||||
}
|
||||
}
|
||||
|
||||
if ( HAS_SKILL_TRAIT( pSoldier, HANDTOHAND_OT ) )
|
||||
{
|
||||
// SPECIAL - give TRIPLE bonus for damage for hand-to-hand trait
|
||||
@@ -9227,7 +9234,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
}
|
||||
|
||||
// Enhanced Close Combat System - aiming at body parts makes difference
|
||||
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
|
||||
if ( !autoresolve && gGameExternalOptions.fEnhancedCloseCombatSystem)
|
||||
{
|
||||
if ( pSoldier->bAimShotLocation == AIM_SHOT_HEAD )
|
||||
{
|
||||
@@ -9251,22 +9258,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iBonus += 50; // 50% incresed damage on suprising attacks
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: power armour reduces damage taken
|
||||
// SANDRO - huh?!
|
||||
/*INT8 iSlot = VESTPOS;
|
||||
switch( pSoldier->bAimShotLocation )
|
||||
{
|
||||
case AIM_SHOT_HEAD:
|
||||
iSlot = HELMETPOS;
|
||||
break;
|
||||
case AIM_SHOT_LEGS:
|
||||
iSlot = LEGPOS;
|
||||
break;
|
||||
default:
|
||||
iSlot = VESTPOS;
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
// DAMAGE BONUS TO KNIFE ATTACK WITH MELEE SKILL
|
||||
else
|
||||
@@ -9277,42 +9268,27 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iBonus += gSkillTraitValues.ubMEDamageBonusBlades; // +30% damage
|
||||
|
||||
// if this attack happens directly after running, the attack is slightly more powerful due to extra force
|
||||
if (pSoldier->usSoldierFlagMask2 & SOLDIER_BAYONET_RUNBONUS)
|
||||
if ( !autoresolve && pSoldier->usSoldierFlagMask2 & SOLDIER_BAYONET_RUNBONUS)
|
||||
iBonus += 20;
|
||||
}
|
||||
else if ( HAS_SKILL_TRAIT( pSoldier, MELEE_NT ) && ( gGameOptions.fNewTraitSystem ))
|
||||
{
|
||||
iBonus += gSkillTraitValues.ubMEDamageBonusBlades; // +30% damage
|
||||
|
||||
if (pSoldier->usAnimState == FOCUSED_STAB)
|
||||
if ( !autoresolve && pSoldier->usAnimState == FOCUSED_STAB)
|
||||
{
|
||||
iBonus += gSkillTraitValues.usMEAimedMeleeAttackDamageBonus; // 50% increased damage if focused melee attack
|
||||
}
|
||||
}
|
||||
|
||||
// Enhanced Close Combat System
|
||||
if (gGameExternalOptions.fEnhancedCloseCombatSystem)
|
||||
if ( !autoresolve && gGameExternalOptions.fEnhancedCloseCombatSystem)
|
||||
{
|
||||
if (gAnimControl[ pTarget->usAnimState ].ubEndHeight == ANIM_PRONE)
|
||||
{
|
||||
iBonus += 30; // incresed damage to lying characters
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: power armour reduces damage taken
|
||||
// SANDRO - huh?!
|
||||
/*INT8 iSlot = VESTPOS;
|
||||
switch( pSoldier->bAimShotLocation )
|
||||
{
|
||||
case AIM_SHOT_HEAD:
|
||||
iSlot = HELMETPOS;
|
||||
break;
|
||||
case AIM_SHOT_LEGS:
|
||||
iSlot = LEGPOS;
|
||||
break;
|
||||
default:
|
||||
iSlot = VESTPOS;
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
|
||||
// remove flag, regardless of whether it was used
|
||||
@@ -9326,7 +9302,7 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
|
||||
// Flugente: if we are using a garotte, there is a chance that we score an instakill
|
||||
// our level in covert ops and wether the target is aware of us has a huge impact
|
||||
if ( pObj && HasItemFlag(pObj->usItem, GAROTTE) )
|
||||
if ( !autoresolve && pObj && HasItemFlag(pObj->usItem, GAROTTE) )
|
||||
{
|
||||
INT32 instakillchance = 0;
|
||||
INT32 resistchance = 20;
|
||||
@@ -9356,7 +9332,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
|
||||
iImpact = (iImpact * (100 + iBonus) + 50) / 100; // round it properly
|
||||
|
||||
// Flugente: moved the damage calculation into a separate function
|
||||
BOOLEAN autoresolve = IsAutoResolveActive();
|
||||
iImpact = max( 1, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) );
|
||||
|
||||
// Flugente: if the target is a zombie, any melee attack, regardless of hit location, will set the headshot flag. Thus any zombie killed in melee will stay dead (if you play with that option)
|
||||
@@ -10068,7 +10043,7 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
|
||||
else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
|
||||
// bonus for enemy
|
||||
else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
else if ( ( pAttacker->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || pAttacker->ubSoldierClass == SOLDIER_CLASS_BANDIT ) && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
|
||||
else if (pAttacker->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
|
||||
@@ -10746,7 +10721,7 @@ UINT32 CalcThrownChanceToHit(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sVeteranMilitiaCtHBonusPercent) /100);
|
||||
// bonus for enemy
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
else if ( ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT ) && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyAdminCtHBonusPercent) /100);
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
|
||||
iChance += ((iChance * gGameExternalOptions.sEnemyRegularCtHBonusPercent) /100);
|
||||
@@ -11801,7 +11776,7 @@ FLOAT CalcNewChanceToHitBaseSpecialBonus(SOLDIERTYPE *pSoldier)
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaCtHBonusPercent != 0)
|
||||
fBaseModifier += gGameExternalOptions.sVeteranMilitiaCtHBonusPercent;
|
||||
// bonus for enemy
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
else if ( ( pSoldier->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR || pSoldier->ubSoldierClass == SOLDIER_CLASS_BANDIT ) && gGameExternalOptions.sEnemyAdminCtHBonusPercent != 0)
|
||||
fBaseModifier += gGameExternalOptions.sEnemyAdminCtHBonusPercent;
|
||||
else if (pSoldier->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularCtHBonusPercent != 0)
|
||||
fBaseModifier += gGameExternalOptions.sEnemyRegularCtHBonusPercent;
|
||||
|
||||
+15
-14
@@ -4870,18 +4870,19 @@ void DebugSoldierPage4( )
|
||||
switch( pSoldier->ubSoldierClass )
|
||||
{
|
||||
case SOLDIER_CLASS_ADMINISTRATOR: gprintf( 320, LINE_HEIGHT * ubLine, L"(Administrator)" ); break;
|
||||
case SOLDIER_CLASS_ELITE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Army Elite)" ); break;
|
||||
case SOLDIER_CLASS_ARMY: gprintf( 320, LINE_HEIGHT * ubLine, L"(Army Troop)" ); break;
|
||||
case SOLDIER_CLASS_CREATURE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Creature)" ); break;
|
||||
case SOLDIER_CLASS_ELITE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Army Elite)" ); break;
|
||||
case SOLDIER_CLASS_ARMY: gprintf( 320, LINE_HEIGHT * ubLine, L"(Army Troop)" ); break;
|
||||
case SOLDIER_CLASS_CREATURE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Creature)" ); break;
|
||||
case SOLDIER_CLASS_GREEN_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Green Militia)" ); break;
|
||||
case SOLDIER_CLASS_REG_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Reg Militia)" ); break;
|
||||
case SOLDIER_CLASS_ELITE_MILITIA: gprintf( 320, LINE_HEIGHT * ubLine, L"(Elite Militia)" ); break;
|
||||
case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break;
|
||||
case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break;
|
||||
case SOLDIER_CLASS_MINER: gprintf( 320, LINE_HEIGHT * ubLine, L"(Miner)" ); break;
|
||||
case SOLDIER_CLASS_ZOMBIE: gprintf( 320, LINE_HEIGHT * ubLine, L"(Zombie)" ); break;
|
||||
case SOLDIER_CLASS_BANDIT: gprintf( 320, LINE_HEIGHT * ubLine, L"(Bandit)" ); break;
|
||||
|
||||
default: break; //don't care (don't write anything)
|
||||
}
|
||||
ubLine++;
|
||||
++ubLine;
|
||||
|
||||
if( pSoldier->bTeam != OUR_TEAM )
|
||||
{
|
||||
@@ -7785,19 +7786,19 @@ void MakeBloodcatsHostile( void )
|
||||
|
||||
iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID;
|
||||
|
||||
for (pSoldier = MercPtrs[iLoop]; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; iLoop++,pSoldier++ )
|
||||
for (pSoldier = MercPtrs[iLoop]; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; ++iLoop, ++pSoldier )
|
||||
{
|
||||
if ( pSoldier->ubBodyType == BLOODCAT && pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 )
|
||||
{
|
||||
SetSoldierNonNeutral( pSoldier );
|
||||
RecalculateOppCntsDueToNoLongerNeutral( pSoldier );
|
||||
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{
|
||||
CheckForPotentialAddToBattleIncrement( pSoldier );
|
||||
}
|
||||
SetSoldierNonNeutral( pSoldier );
|
||||
RecalculateOppCntsDueToNoLongerNeutral( pSoldier );
|
||||
|
||||
if ( ( gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{
|
||||
CheckForPotentialAddToBattleIncrement( pSoldier );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOLEAN SoldierHasLimitedVision(SOLDIERTYPE * pSoldier)
|
||||
|
||||
Reference in New Issue
Block a user