mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
- Prisoners of war are now spawned in prison sectors. They have fitting dialogue etc. Harming them slightly lowers global loyalty.
- Prisoner system: added ini options that allow display of surrender strength sum, and externalised surrender strength modifier - Fix: wrong assignment string in strategic view git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5895 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -1573,6 +1573,8 @@ void LoadGameExternalOptions()
|
||||
// Flugente: prisoner system
|
||||
gGameExternalOptions.fAllowPrisonerSystem = iniReader.ReadBoolean("Strategic Gameplay Settings","ALLOW_TAKE_PRISONERS", TRUE);
|
||||
gGameExternalOptions.fEnemyCanSurrender = iniReader.ReadBoolean("Strategic Gameplay Settings","ENEMY_CAN_SURRENDER", TRUE);
|
||||
gGameExternalOptions.fDisplaySurrenderSValues = iniReader.ReadBoolean("Strategic Gameplay Settings","DISPLAY_SURRENDER_VALUES", TRUE);
|
||||
gGameExternalOptions.fSurrenderMultiplier = iniReader.ReadFloat("Strategic Gameplay Settings", "SURRENDER_MULTIPLIER", 5.0f, 2.0f, 10.0f);
|
||||
gGameExternalOptions.fPlayerCanAsktoSurrender = iniReader.ReadBoolean("Strategic Gameplay Settings","PLAYER_CAN_ASK_TO_SURRENDER", TRUE);
|
||||
gGameExternalOptions.ubPrisonerReturntoQueenChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_RETURN_TO_ARMY_CHANCE", 50, 0, 100);
|
||||
gGameExternalOptions.ubPrisonerProcessDefectChance = iniReader.ReadInteger("Strategic Gameplay Settings","PRISONER_DEFECT_CHANCE", 10, 0, 100);
|
||||
|
||||
@@ -1185,6 +1185,8 @@ typedef struct
|
||||
// Flugente: prisoner related settings
|
||||
BOOLEAN fAllowPrisonerSystem;
|
||||
BOOLEAN fEnemyCanSurrender;
|
||||
BOOLEAN fDisplaySurrenderSValues;
|
||||
FLOAT fSurrenderMultiplier;
|
||||
BOOLEAN fPlayerCanAsktoSurrender;
|
||||
UINT8 ubPrisonerReturntoQueenChance;
|
||||
UINT8 ubPrisonerProcessDefectChance;
|
||||
|
||||
@@ -3970,17 +3970,11 @@ void AddStringsToMoveBox( void )
|
||||
// add OTHER soldiers (not on duty nor in a vehicle)
|
||||
if( IsSoldierSelectedForMovement( pSoldierMovingList[ iCount ] ) == TRUE )
|
||||
{
|
||||
if ( gGameExternalOptions.fUseXMLSquadNames )
|
||||
swprintf( sString, L" *%s ( %s )*", pSoldierMovingList[ iCount ]->name, SquadNames[ pSoldierMovingList[ iCount ]->bAssignment ].squadname );
|
||||
else
|
||||
swprintf( sString, L" *%s ( %s )*", pSoldierMovingList[ iCount ]->name, pAssignmentStrings[ pSoldierMovingList[ iCount ]->bAssignment ] );
|
||||
swprintf( sString, L" *%s ( %s )*", pSoldierMovingList[ iCount ]->name, pAssignmentStrings[ pSoldierMovingList[ iCount ]->bAssignment ] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( gGameExternalOptions.fUseXMLSquadNames )
|
||||
swprintf( sString, L" %s ( %s )", pSoldierMovingList[ iCount ]->name, SquadNames[ pSoldierMovingList[ iCount ]->bAssignment ].squadname );
|
||||
else
|
||||
swprintf( sString, L" %s ( %s )", pSoldierMovingList[ iCount ]->name, pAssignmentStrings[ pSoldierMovingList[ iCount ]->bAssignment ] );
|
||||
swprintf( sString, L" %s ( %s )", pSoldierMovingList[ iCount ]->name, pAssignmentStrings[ pSoldierMovingList[ iCount ]->bAssignment ] );
|
||||
}
|
||||
AddMonoString(&hStringHandle, sString );
|
||||
}
|
||||
|
||||
@@ -1702,6 +1702,10 @@ void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY
|
||||
case GLOBAL_LOYALTY_LOSE_SAM:
|
||||
iLoyaltyChange = -250;
|
||||
break;
|
||||
// Flugente: morale drop for torturing prisoners
|
||||
case GLOBAL_LOYALTY_PRISONERS_TORTURED:
|
||||
iLoyaltyChange = -25;
|
||||
break;
|
||||
|
||||
default:
|
||||
Assert(FALSE);
|
||||
|
||||
@@ -63,6 +63,8 @@ typedef enum
|
||||
GLOBAL_LOYALTY_GAIN_SAM,
|
||||
GLOBAL_LOYALTY_LOSE_SAM,
|
||||
GLOBAL_LOYALTY_QUEEN_BATTLE_WON,
|
||||
GLOBAL_LOYALTY_GRIZZLY_DEAD, // Flugente: I have no idea what the playn behind this is, but I found it in the lua script. It isn't used anywhere in the code though...
|
||||
GLOBAL_LOYALTY_PRISONERS_TORTURED, // Flugente: the player has attacked prisoners
|
||||
|
||||
} GlobalLoyaltyEventTypes;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef struct
|
||||
UINT8 sWaterType; // Food System
|
||||
UINT16 usNaturalDirt; // Dirt System
|
||||
UINT8 usCurfewValue; // Covert Ops
|
||||
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // Prisoner System
|
||||
UINT32 currentDepth;
|
||||
UINT32 maxReadDepth;
|
||||
} SectorNameParseData;
|
||||
@@ -86,6 +87,14 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
|
||||
SectorExternalData[x][1].usCurfewValue = 0;
|
||||
SectorExternalData[x][2].usCurfewValue = 0;
|
||||
SectorExternalData[x][3].usCurfewValue = 0;
|
||||
|
||||
for(UINT8 i = 0; i <MAX_PRISON_ROOMS; ++i)
|
||||
{
|
||||
SectorExternalData[x][0].usPrisonRoomNumber[i] = 0;
|
||||
SectorExternalData[x][1].usPrisonRoomNumber[i] = 0;
|
||||
SectorExternalData[x][2].usPrisonRoomNumber[i] = 0;
|
||||
SectorExternalData[x][3].usPrisonRoomNumber[i] = 0;
|
||||
}
|
||||
|
||||
if (Sector_Level == 0 )
|
||||
{
|
||||
@@ -135,7 +144,23 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
|
||||
strcmp(name, "szDetailedExploredName") == 0 ||
|
||||
strcmp(name, "sWaterType") == 0 ||
|
||||
strcmp(name, "usNaturalDirt") == 0 ||
|
||||
strcmp(name, "usCurfewValue") == 0 ))
|
||||
strcmp(name, "usCurfewValue") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber00") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber01") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber02") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber03") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber04") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber05") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber06") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber07") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber08") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber09") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber10") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber11") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber12") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber13") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber14") == 0 ||
|
||||
strcmp(name, "usPrisonRoomNumber15") == 0 ))
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT;
|
||||
|
||||
@@ -259,6 +284,12 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
SectorExternalData[ubSectorId][2].usCurfewValue = pData->usCurfewValue;
|
||||
SectorExternalData[ubSectorId][3].usCurfewValue = pData->usCurfewValue;
|
||||
|
||||
for(UINT8 i = 0; i <MAX_PRISON_ROOMS; ++i)
|
||||
{
|
||||
SectorExternalData[ubSectorId][0].usPrisonRoomNumber[i] = pData->usPrisonRoomNumber[i];
|
||||
pData->usPrisonRoomNumber[i] = 0;
|
||||
}
|
||||
|
||||
// clean up values afterwards
|
||||
pData->sWaterType = 0;
|
||||
pData->usNaturalDirt = 100;
|
||||
@@ -327,6 +358,86 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usCurfewValue = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber00") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[0] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber01") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[1] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber02") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[2] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber03") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[3] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber04") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[4] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber05") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[5] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber06") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[6] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber07") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[7] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber08") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[8] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber09") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[9] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber10") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[10] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber11") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[11] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber12") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[12] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber13") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[13] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber14") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[14] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
else if(strcmp(name, "usPrisonRoomNumber15") == 0)
|
||||
{
|
||||
pData->curElement = SECTORNAME_ELEMENT_SECTOR;
|
||||
pData->usPrisonRoomNumber[15] = (UINT8) atoi(pData->szCharData);
|
||||
}
|
||||
|
||||
pData->maxReadDepth--;
|
||||
}
|
||||
|
||||
@@ -480,12 +480,15 @@ OBJECTTYPE* GetExternalFeedingObject(SOLDIERTYPE* pSoldier, OBJECTTYPE * pObject
|
||||
|
||||
BOOLEAN DeductBulletViaExternalFeeding(SOLDIERTYPE* pSoldier, OBJECTTYPE * pObject);
|
||||
|
||||
#define MAX_PRISON_ROOMS 16
|
||||
// Flugente: additional xml data for sectors
|
||||
typedef struct
|
||||
{
|
||||
UINT8 usWaterType; // type of water source in this sector
|
||||
UINT16 usNaturalDirt; // extra dirt percentage when firing in this sector
|
||||
UINT8 usCurfewValue; // determines wether mercs disguising as civilian are automatically discovered (certain sectors are 'restricted' to civilians)
|
||||
UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // room numbers of prisons
|
||||
|
||||
} SECTOR_EXT_DATA;
|
||||
|
||||
// get dirt increase for object with attachments, fConsiderAmmo: with ammo
|
||||
|
||||
@@ -359,7 +359,7 @@ enum
|
||||
UNNAMED_CIV_GROUP_18,
|
||||
UNNAMED_CIV_GROUP_19,
|
||||
ASSASSIN_CIV_GROUP, // Flugente: enemy assassins belong to this group
|
||||
UNNAMED_CIV_GROUP_21,
|
||||
POW_PRISON_CIV_GROUP, // Flugente: prisoners of war the player caught are in this group
|
||||
UNNAMED_CIV_GROUP_22,
|
||||
UNNAMED_CIV_GROUP_23,
|
||||
UNNAMED_CIV_GROUP_24,
|
||||
|
||||
+19
-1
@@ -3824,6 +3824,15 @@ void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldierOld )
|
||||
HandleMurderOfCivilian( pSoldierOld, pSoldierOld->flags.fIntendedTarget );
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: if this was a prisoner of war, reduce their sector count by 1
|
||||
if ( pSoldierOld->bSoldierFlagMask & SOLDIER_POW_PRISON )
|
||||
{
|
||||
// get sector
|
||||
SECTORINFO *pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
|
||||
if ( pSector )
|
||||
pSector->uiNumberOfPrisonersOfWar = max(0, pSector->uiNumberOfPrisonersOfWar - 1);
|
||||
}
|
||||
}
|
||||
else if ( pSoldierOld->bTeam == MILITIA_TEAM )
|
||||
{
|
||||
@@ -8604,6 +8613,11 @@ BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** pp
|
||||
}
|
||||
}
|
||||
}
|
||||
// Flugente: if we attack prisoners, the local support might wane, as we turned out to be cruel oppressors, not liberators
|
||||
else if ( (pTarget->bTeam == CIV_TEAM) && (pTarget->ubCivilianGroup == POW_PRISON_CIV_GROUP) )
|
||||
{
|
||||
HandleGlobalLoyaltyEvent( GLOBAL_LOYALTY_PRISONERS_TORTURED, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
|
||||
}
|
||||
else if (pTarget->bTeam == CREATURE_TEAM && pTarget->ubBodyType == BLOODCAT && pTarget->aiData.bNeutral)
|
||||
{
|
||||
// Attacked a bloodcat.
|
||||
@@ -10130,8 +10144,12 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue )
|
||||
}
|
||||
}
|
||||
|
||||
// print out values
|
||||
if ( gGameExternalOptions.fDisplaySurrenderSValues )
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"PlayerStrength : %d Enemystrength: %6.0f", playersidestrength, gGameExternalOptions.fSurrenderMultiplier * enemysidestrength );
|
||||
|
||||
// perhaps this can be fleshed out more, for now, let's see if this is acceptable behaviour
|
||||
if ( playersidestrength >= 6 * enemysidestrength )
|
||||
if ( playersidestrength >= gGameExternalOptions.fSurrenderMultiplier * enemysidestrength )
|
||||
{
|
||||
// it is enough to simply set all soldiers to captured
|
||||
firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID;
|
||||
|
||||
@@ -363,8 +363,8 @@ enum
|
||||
#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war
|
||||
#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies
|
||||
|
||||
/*#define SOLDIER_EQ_TAKEN 0x00001000 //4096 // this militia's equipment was taken from a sector inventory
|
||||
#define SOLDIER_EQ_EMPTY 0x00002000 //8192 // this militia has no equipment and is to be equipped from the sector inventory
|
||||
#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive
|
||||
/*#define SOLDIER_EQ_EMPTY 0x00002000 //8192 // this militia has no equipment and is to be equipped from the sector inventory
|
||||
#define ENEMY_NET_3_LVL_4 0x00004000 //16384
|
||||
#define ENEMY_NET_4_LVL_4 0x00008000 //32768
|
||||
|
||||
|
||||
@@ -3165,6 +3165,98 @@ void CreateAssassin(UINT8 disguisetype)
|
||||
}
|
||||
}
|
||||
|
||||
extern UINT16* gusWorldRoomInfo;
|
||||
extern SECTOR_EXT_DATA SectorExternalData[256][4];
|
||||
|
||||
static UINT8 roomcnt = 0;
|
||||
|
||||
void CreatePrisonerOfWar()
|
||||
{
|
||||
INT32 insertiongridno = NOWHERE;
|
||||
|
||||
// get sector data and look fo a fitting room
|
||||
UINT8 ubSectorId = SECTOR(gWorldSectorX, gWorldSectorY);
|
||||
if ( ubSectorId >= 0 && ubSectorId < 256 )
|
||||
{
|
||||
UINT8 numrooms = 0;
|
||||
for(UINT8 i = 0; i < MAX_PRISON_ROOMS; ++i)
|
||||
if ( SectorExternalData[ubSectorId][0].usPrisonRoomNumber[i] > 0)
|
||||
++numrooms;
|
||||
|
||||
++roomcnt;
|
||||
if ( roomcnt >= numrooms )
|
||||
roomcnt = 0;
|
||||
|
||||
UINT16 room = SectorExternalData[ubSectorId][0].usPrisonRoomNumber[roomcnt];
|
||||
|
||||
for ( UINT32 uiLoop = 0; uiLoop < WORLD_MAX; ++uiLoop )
|
||||
{
|
||||
if ( (gusWorldRoomInfo[ uiLoop ] == room) )
|
||||
{
|
||||
// we have to make sure that the gridno is deep in the room, as otherwise the gridno might be corrected to be on the other side of a wall
|
||||
if ( gusWorldRoomInfo[ NewGridNo( uiLoop, DirectionInc(NORTH) ) ] == room )
|
||||
if ( gusWorldRoomInfo[ NewGridNo( uiLoop, DirectionInc(EAST) ) ] == room )
|
||||
if ( gusWorldRoomInfo[ NewGridNo( uiLoop, DirectionInc(SOUTH) ) ] == room )
|
||||
if ( gusWorldRoomInfo[ NewGridNo( uiLoop, DirectionInc(WEST) ) ] == room )
|
||||
{
|
||||
// check wether this location is sittable
|
||||
if ( IsLocationSittable( uiLoop, 0 ) )
|
||||
{
|
||||
insertiongridno = uiLoop;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invalid gridno? Get out of here
|
||||
if ( TileIsOutOfBounds(insertiongridno) )
|
||||
return;
|
||||
}
|
||||
|
||||
SOLDIERCREATE_STRUCT MercCreateStruct;
|
||||
UINT8 ubID;
|
||||
|
||||
static INT8 bPowBodyType = REGMALE;
|
||||
|
||||
MercCreateStruct.initialize();
|
||||
MercCreateStruct.bTeam = CIV_TEAM;
|
||||
MercCreateStruct.ubProfile = NO_PROFILE;
|
||||
MercCreateStruct.sSectorX = gWorldSectorX;
|
||||
MercCreateStruct.sSectorY = gWorldSectorY;
|
||||
MercCreateStruct.bSectorZ = gbWorldSectorZ;
|
||||
MercCreateStruct.sInsertionGridNo = insertiongridno;
|
||||
MercCreateStruct.ubDirection = Random(NUM_WORLD_DIRECTIONS);
|
||||
MercCreateStruct.bBodyType = bPowBodyType;
|
||||
|
||||
++bPowBodyType;
|
||||
if ( bPowBodyType > REGFEMALE )
|
||||
bPowBodyType = REGMALE;
|
||||
|
||||
RandomizeNewSoldierStats( &MercCreateStruct );
|
||||
|
||||
SOLDIERTYPE* pSoldier = TacticalCreateSoldier( &MercCreateStruct, &ubID );
|
||||
|
||||
if ( pSoldier )
|
||||
{
|
||||
AddSoldierToSector( pSoldier->ubID );
|
||||
|
||||
// mark this guy
|
||||
pSoldier->bSoldierFlagMask |= SOLDIER_POW_PRISON;
|
||||
|
||||
// set correct civ group
|
||||
pSoldier->ubCivilianGroup = POW_PRISON_CIV_GROUP;
|
||||
|
||||
// set militia name to further irritate the player
|
||||
swprintf( pSoldier->name, TacticalStr[ POW_TEAM_MERC_NAME ] );
|
||||
|
||||
// So we can see them!
|
||||
AllTeamsLookForAll(NO_INTERRUPTS);
|
||||
|
||||
gTacticalStatus.fCivGroupHostile[ POW_PRISON_CIV_GROUP ] = CIV_GROUP_NEUTRAL;
|
||||
}
|
||||
}
|
||||
|
||||
void RandomizeRelativeLevel( INT8 *pbRelLevel, UINT8 ubSoldierClass )
|
||||
{
|
||||
UINT8 ubLocationModifier = 0;
|
||||
|
||||
@@ -430,6 +430,8 @@ SOLDIERTYPE* TacticalCreateCreature( INT8 bCreatureBodyType );
|
||||
SOLDIERTYPE* TacticalCreateEnemyAssassin(UINT8 disguisetype);
|
||||
void CreateAssassin(UINT8 disguisetype);
|
||||
|
||||
void CreatePrisonerOfWar();
|
||||
|
||||
// randomly generates a relative level rating (attributes or equipment)
|
||||
void RandomizeRelativeLevel( INT8 *pbRelLevel, UINT8 ubSoldierClass );
|
||||
|
||||
|
||||
@@ -918,6 +918,10 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
|
||||
if ( bTeam == MILITIA_TEAM )
|
||||
SectorAddAssassins(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
|
||||
// Flugente: spawn prisoners of war in prison sectors
|
||||
if ( bTeam == CIV_TEAM )
|
||||
SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
|
||||
//There aren't any basic placements of desired team, so exit.
|
||||
return ubNumAdded;
|
||||
}
|
||||
@@ -965,6 +969,10 @@ UINT8 AddSoldierInitListTeamToWorld( INT8 bTeam, UINT8 ubMaxNum )
|
||||
if ( bTeam == MILITIA_TEAM )
|
||||
SectorAddAssassins(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
|
||||
// Flugente: spawn prisoners of war in prison sectors
|
||||
if ( bTeam == CIV_TEAM )
|
||||
SectorAddPrisonersofWar(gWorldSectorX, gWorldSectorY, gbWorldSectorZ);
|
||||
|
||||
return ubNumAdded;
|
||||
}
|
||||
|
||||
@@ -2793,3 +2801,59 @@ void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
|
||||
++numberofcivs;
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: decide wether to create prisoners of war in a sector. Not to be confused with player POWs
|
||||
void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ )
|
||||
{
|
||||
// this needs to be turned on on
|
||||
if ( !gGameExternalOptions.fAllowPrisonerSystem )
|
||||
return;
|
||||
|
||||
// not in underground sectors
|
||||
if ( sMapZ > 0 )
|
||||
return;
|
||||
|
||||
// get sector
|
||||
SECTORINFO *pSector = &SectorInfo[ SECTOR( sMapX, sMapY ) ];
|
||||
if ( !pSector )
|
||||
return;
|
||||
|
||||
// only continue if there are prisoners in this sector that need to be placed
|
||||
UINT32 numprisoners = pSector->uiNumberOfPrisonersOfWar;
|
||||
|
||||
numprisoners = 30;
|
||||
|
||||
if ( !numprisoners )
|
||||
return;
|
||||
|
||||
// count current number of civilians and already placed pows
|
||||
UINT16 numberofcivs = 0;
|
||||
UINT16 numberofpows = 0;
|
||||
SOLDIERTYPE* pTeamSoldier = NULL;
|
||||
INT32 cnt = gTacticalStatus.Team[ CIV_TEAM ].bFirstID;
|
||||
INT32 lastid = gTacticalStatus.Team[ CIV_TEAM ].bLastID;
|
||||
for ( pTeamSoldier = MercPtrs[ cnt ]; cnt < lastid; ++cnt, ++pTeamSoldier)
|
||||
{
|
||||
// check if teamsoldier exists in this sector
|
||||
if ( pTeamSoldier && pTeamSoldier->bActive && pTeamSoldier->bInSector && pTeamSoldier->sSectorX == sMapX && pTeamSoldier->sSectorY == sMapY && pTeamSoldier->bSectorZ == sMapZ )
|
||||
++numberofcivs;
|
||||
|
||||
// count how many pows are already placed
|
||||
if ( pTeamSoldier->bSoldierFlagMask & SOLDIER_POW_PRISON )
|
||||
++numberofpows;
|
||||
}
|
||||
|
||||
// we can't spawn if all civilian slots are already taken (we leave a bit of reserve for more important civs)
|
||||
UINT8 maxcivs = max(0, gGameExternalOptions.ubGameMaximumNumberOfCivilians - 3);
|
||||
|
||||
for (UINT8 i = numberofpows; i < numprisoners; ++i)
|
||||
{
|
||||
if ( numberofcivs < maxcivs )
|
||||
{
|
||||
CreatePrisonerOfWar();
|
||||
++numberofcivs;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -62,4 +62,7 @@ void AddProfilesNotUsingProfileInsertionData();
|
||||
// Flugente: decide wether to spawn enemy assassins in this sector (not kingpin's hitmen, they are handled elsewhere)
|
||||
void SectorAddAssassins( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
|
||||
|
||||
// Flugente: decide wether to create prisoners of war in a sector. Not to be confused with player POWs
|
||||
void SectorAddPrisonersofWar( INT16 sMapX, INT16 sMapY, INT16 sMapZ );
|
||||
|
||||
#endif
|
||||
@@ -882,6 +882,7 @@ enum
|
||||
MILITIA_TEAM_MERC_NAME,
|
||||
CIV_TEAM_MERC_NAME,
|
||||
ZOMBIE_TEAM_MERC_NAME,
|
||||
POW_TEAM_MERC_NAME,
|
||||
|
||||
//The text for the 'exiting sector' gui
|
||||
EXIT_GUI_TITLE_STR,
|
||||
|
||||
@@ -2855,6 +2855,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"民兵",
|
||||
L"平民",
|
||||
L"僵尸",
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"离开分区",
|
||||
L"确定",
|
||||
L"取消",
|
||||
|
||||
@@ -2852,6 +2852,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"MILITIE", // L"MILITIA",
|
||||
L"BURGER", // L"CIVILIAN",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"Verlaten Sector", // L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Stoppen", // L"Cancel",
|
||||
|
||||
@@ -2854,6 +2854,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"MILITIA",
|
||||
L"CIVILIAN",
|
||||
L"ZOMBIE",
|
||||
L"PRISONER",
|
||||
L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Cancel",
|
||||
|
||||
@@ -2859,6 +2859,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Milice",
|
||||
L"CIVIL",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"Quitter Secteur",
|
||||
L"OK",
|
||||
L"Annuler",
|
||||
|
||||
@@ -2855,6 +2855,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"MILIZ",
|
||||
L"ZIVILIST",
|
||||
L"ZOMBIE",
|
||||
L"PRISONER",
|
||||
L"Sektor verlassen",
|
||||
L"OK",
|
||||
L"Abbruch",
|
||||
|
||||
@@ -2863,6 +2863,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"SAMOOBRONA",
|
||||
L"CYWIL",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"WyjŚcie z sektora",
|
||||
L"OK",
|
||||
L"Anuluj",
|
||||
|
||||
@@ -2854,6 +2854,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"ОПОЛЧЕНЕЦ",
|
||||
L"ЖИТЕЛЬ",
|
||||
L"ЗОМБИ",
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"Выход из сектора",
|
||||
L"ДА",
|
||||
L"ОТМЕНА",
|
||||
|
||||
@@ -2856,6 +2856,7 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"MILITIA",
|
||||
L"CIVILIAN",
|
||||
L"ZOMBIE", // TODO.Translate
|
||||
L"PRISONER",//TODO.Translate
|
||||
L"Exiting Sector",
|
||||
L"OK",
|
||||
L"Cancel",
|
||||
|
||||
Reference in New Issue
Block a user