Revamped <scrounging>-tag of Backgrounds.xml: instead of hoarding items, mercs steal small amounts of money from the locals, which can lower loyalty.

For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=21308&goto=358321&#msg_358321

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8699 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Flugente
2019-10-22 21:46:53 +00:00
parent e1657cefb7
commit 14619a22cc
15 changed files with 353 additions and 149 deletions
+110 -129
View File
@@ -50,6 +50,8 @@ void HourlyDisabilityUpdate();
void HourlyStealUpdate(); // Flugente: certain characters might steal equipment (backgrounds)
void HourlySnitchUpdate(); // anv: decreasing cooldown after exposition
extern SECTOR_EXT_DATA SectorExternalData[256][4];
extern INT32 GetCurrentBalance( void );
extern void PayOffSkyriderDebtIfAny( );
#ifdef JA2UB
@@ -680,161 +682,140 @@ void HourlyStealUpdate()
{
SOLDIERTYPE * pSoldier = NULL;
SOLDIERTYPE * pOtherSoldier = NULL;
INT8 bSlot = NO_SLOT;
UINT16 usTemptation = 0;
BOOLEAN fBar = FALSE;
OBJECTTYPE* pObj = NULL;
for( INT32 cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt )
{
pSoldier = MercPtrs[ cnt ];
// merc must be alive, not travelling and awake. If he is in the currently loaded sector, we may not be in tactical (we would see an item suddenly disappearing) and not in combat
if ( pSoldier && !pSoldier->flags.fBetweenSectors && pSoldier->bActive && !pSoldier->flags.fMercAsleep && pSoldier->bAssignment != IN_TRANSIT && pSoldier->bAssignment != ASSIGNMENT_POW && !SPY_LOCATION( pSoldier->bAssignment ) &&
!( ( ( gWorldSectorX == pSoldier->sSectorX ) && ( gWorldSectorY == pSoldier->sSectorY ) && (gbWorldSectorZ == pSoldier->bSectorZ ) ) && (gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN )) )
if ( pSoldier
&& Chance( 50 ) // we try to steal something in the first place only half the time
&& pSoldier->HasBackgroundFlag( BACKGROUND_SCROUNGING )
&& !pSoldier->flags.fBetweenSectors
&& pSoldier->bActive
&& !pSoldier->flags.fMercAsleep
&& pSoldier->bAssignment != IN_TRANSIT
&& pSoldier->bAssignment != ASSIGNMENT_POW
&& !( ( ( gWorldSectorX == pSoldier->sSectorX ) && ( gWorldSectorY == pSoldier->sSectorY ) && ( gbWorldSectorZ == pSoldier->bSectorZ ) ) && ( gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN ) ) )
{
if ( pSoldier->HasBackgroundFlag( BACKGROUND_SCROUNGING ) )
UINT8 ubSectorId = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY );
UINT16 wealth = SectorExternalData[ubSectorId][0].wealth;
// only try to steal if there's something worth stealing in the first place
if ( !wealth )
continue;
INT8 sectorz = pSoldier->bSectorZ;
if ( SPY_LOCATION( pSoldier->bAssignment ) )
sectorz = max( 0, sectorz - 10 );
// only works in surface sectors
if ( sectorz )
continue;
// anv: snitches prevent scrounging in the same sector
BOOLEAN fSnitchStoppedBehaviour = FALSE;
for ( UINT32 cnt2 = gTacticalStatus.Team[OUR_TEAM].bFirstID; cnt2 <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt2 )
{
// 50% chance that we'll steal something
if ( Chance(50) )
pOtherSoldier = MercPtrs[cnt2];
// note - snitches stop others, but can scrounge themselves (if they have scrounging specifically set in background...)
if ( pOtherSoldier
&& !pOtherSoldier->flags.fBetweenSectors
&& pOtherSoldier->bAssignment != IN_TRANSIT
&& pOtherSoldier->bAssignment != ASSIGNMENT_POW
&& !SPY_LOCATION( pOtherSoldier->bAssignment )
&& pOtherSoldier->bActive
&& !pOtherSoldier->flags.fMercAsleep
&& pSoldier->ubProfile != pOtherSoldier->ubProfile )
{
// anv: snitches prevent scrounging in the same sector
BOOLEAN fSnitchStoppedBehaviour = FALSE;
for( INT32 cnt2 = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; cnt2 <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt2 )
{
pOtherSoldier = MercPtrs[ cnt2 ];
// note - snitches stop others, but can scrounge themselves (if they have scrounging specifically set in background...)
if( pOtherSoldier && !pOtherSoldier->flags.fBetweenSectors && pOtherSoldier->bAssignment != IN_TRANSIT && pOtherSoldier->bAssignment != ASSIGNMENT_POW && SPY_LOCATION( pOtherSoldier->bAssignment ) &&
pOtherSoldier->bActive && !pOtherSoldier->flags.fMercAsleep && pSoldier->ubProfile != pOtherSoldier->ubProfile )
if ( ProfileHasSkillTrait( pOtherSoldier->ubProfile, SNITCH_NT ) && !( pSoldier->usSoldierFlagMask2 & SOLDIER_PREVENT_MISBEHAVIOUR_OFF ) )
{
if ( pSoldier->sSectorX == pOtherSoldier->sSectorX && pSoldier->sSectorY == pOtherSoldier->sSectorY && sectorz == pOtherSoldier->bSectorZ )
{
if ( ProfileHasSkillTrait( pOtherSoldier->ubProfile, SNITCH_NT ) && !( pSoldier->usSoldierFlagMask2 & SOLDIER_PREVENT_MISBEHAVIOUR_OFF ) )
UINT16 bPreventChance = ( EffectiveLeadership( pOtherSoldier ) + EffectiveExpLevel( pOtherSoldier, FALSE ) / 2 );
if ( gGameOptions.fNewTraitSystem )
{
if( pSoldier->sSectorX == pOtherSoldier->sSectorX && pSoldier->sSectorY == pOtherSoldier->sSectorY && pSoldier->bSectorZ == pOtherSoldier->bSectorZ )
{
UINT16 bPreventChance = ( EffectiveLeadership( pOtherSoldier ) + EffectiveExpLevel( pOtherSoldier, FALSE) / 2);
if (gGameOptions.fNewTraitSystem)
{
bPreventChance += 25 * NUM_SKILL_TRAITS( pOtherSoldier, SQUADLEADER_NT );
bPreventChance -= 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_NT );
}
else
{
bPreventChance -= 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_OT );
}
// keep 1% chance no matter what
bPreventChance = max( 0, min( 99, bPreventChance ) );
if( bPreventChance > PreRandom( 100 ) )
{
// merc is not amused by being prevented
HandleMoraleEvent( pSoldier, MORALE_PREVENTED_MISBEHAVIOUR, pSoldier->sSectorX, pSoldier->sSectorX, pSoldier->bSectorZ );
// also here would be a place for dynamic relationship decrease between them
// Flugente: then lets do that, shall we?
AddOpinionEvent( pSoldier->ubProfile, pOtherSoldier->ubProfile, OPINIONEVENT_SNITCHINTERFERENCE );
fSnitchStoppedBehaviour = TRUE;
continue;
}
}
bPreventChance += 25 * NUM_SKILL_TRAITS( pOtherSoldier, SQUADLEADER_NT );
bPreventChance -= 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_NT );
}
else
{
bPreventChance -= 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_OT );
}
}
}
if ( fSnitchStoppedBehaviour )
continue;
// keep 1% chance no matter what
bPreventChance = max( 0, min( 99, bPreventChance ) );
if ( bPreventChance > PreRandom( 100 ) )
{
// merc is not amused by being prevented
HandleMoraleEvent( pSoldier, MORALE_PREVENTED_MISBEHAVIOUR, pSoldier->sSectorX, pSoldier->sSectorX, pSoldier->bSectorZ );
// also here would be a place for dynamic relationship decrease between them
// Flugente: then lets do that, shall we?
AddOpinionEvent( pSoldier->ubProfile, pOtherSoldier->ubProfile, OPINIONEVENT_SNITCHINTERFERENCE );
// we loop over this sector's inventory and look for something shiny. We will pick it up if we hae enough space in our inventory
// open sector inv
UINT32 uiTotalNumberOfRealItems = 0;
std::vector<WORLDITEM> pWorldItem;//dnl ch75 271013
BOOLEAN fReturn = FALSE;
fSnitchStoppedBehaviour = TRUE;
if ( ( gWorldSectorX == pSoldier->sSectorX ) && ( gWorldSectorY == pSoldier->sSectorY ) && (gbWorldSectorZ == pSoldier->bSectorZ ) )
{
uiTotalNumberOfRealItems = guiNumWorldItems;
if ( !uiTotalNumberOfRealItems )
continue;
pWorldItem = gWorldItems;
}
else
{
// not loaded, load
// get total number, visable and invisible
fReturn = GetNumberOfWorldItemsFromTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, &( uiTotalNumberOfRealItems ), FALSE );
Assert( fReturn );
if( uiTotalNumberOfRealItems > 0 )
{
// allocate space for the list
pWorldItem.resize(uiTotalNumberOfRealItems);//dnl ch75 271013
if ( !uiTotalNumberOfRealItems )
continue;
// now load into mem
LoadWorldItemsFromTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, pWorldItem );
}
}
FLOAT bestpriceweightratio = 50.0f; // must have a value of at least 50$/100 gram
OBJECTTYPE* pTargetObj = NULL;
for( UINT32 uiCount = 0; uiCount < uiTotalNumberOfRealItems; ++uiCount ) // ... for all items in the world ...
{
if( pWorldItem[ uiCount ].fExists ) // ... if item exists ...
{
OBJECTTYPE* pObj = &(pWorldItem[ uiCount ].object); // ... get pointer for this item ...
if ( pObj != NULL && pObj->exists() ) // ... if pointer is not obviously useless ...
{
// test wether item is reachable and useable by militia
if ( (pWorldItem[ uiCount ].usFlags & WORLD_ITEM_REACHABLE) )
{
// of course we prefer money above everything else
if ( Item[pWorldItem[ uiCount ].object.usItem].usItemClass == IC_MONEY )
{
// give it a high enough value
bestpriceweightratio = 1000.0f;
pTargetObj = &(pWorldItem[ uiCount ].object);
}
// ignore objects without weight (how does that happen anyway? careless modders...)
else if ( Item[pWorldItem[ uiCount ].object.usItem].ubWeight )
{
if ( (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].usPrice) / (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].ubWeight) > bestpriceweightratio )
{
bestpriceweightratio = (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].usPrice) / (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].ubWeight);
pTargetObj = &(pWorldItem[ uiCount ].object);
}
}
}
}
}
}
}
}
if ( pTargetObj )
{
if ( AutoPlaceObject( pSoldier, pTargetObj, TRUE ) )
{
// Flugente: dynamic opinion
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_THIEF, TRUE, FALSE );
}
}
if ( fSnitchStoppedBehaviour )
continue;
// save the changed inventory
// open sector inv
if( ( gWorldSectorX == pSoldier->sSectorX )&&( gWorldSectorY == pSoldier->sSectorY ) && (gbWorldSectorZ == pSoldier->bSectorZ ) )
// The old behaviour was to steal items from the sector and put them into our inventory. However that is both very annoying (especially with EPCs) and not very logical (it's more like hoarding).
// So instead we'll now simply steal money from the population and put that into our inventory. That doesn't screw with our items and earns us cash, so players might even want this behaviour.
// The downside is that this angers the population, thus lowering loyalty.
// determine chance of success. If we fail, we get money
UINT8 chanceofsucess = pSoldier->GetThiefStealMoneyChance();
if ( Chance( chanceofsucess ) )
{
// we do train dexterity a tiny bit
StatChange( pSoldier, DEXTAMT, 1, FALSE );
// amount of money is a random value between 1 and 5 times wealth
UINT32 amountstolen = wealth + Random( 4 * wealth );
// set up money object
CreateMoney( amountstolen, &gTempObject );
// put money in inventory or on the floor
if ( !AutoPlaceObject( pSoldier, &( gTempObject ), TRUE ) )
{
// drop money in the sector itself
if ( ( gWorldSectorX == pSoldier->sSectorX ) && ( gWorldSectorY == pSoldier->sSectorY ) && ( gbWorldSectorZ == sectorz ) )
{
guiNumWorldItems = uiTotalNumberOfRealItems;
gWorldItems = pWorldItem;
AddItemToPool( pSoldier->sGridNo, &gTempObject, 1, pSoldier->pathing.bLevel, ( WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO | WORLD_ITEM_REACHABLE ), 0 );
}
else
{
//Save the Items to the the file
SaveWorldItemsToTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, uiTotalNumberOfRealItems, pWorldItem );
AddItemsToUnLoadedSector( pSoldier->sSectorX, pSoldier->sSectorY, sectorz, NOWHERE, 1, &gTempObject, 0, ( WOLRD_ITEM_FIND_SWEETSPOT_FROM_GRIDNO | WORLD_ITEM_REACHABLE ), 0, 1, FALSE );
}
}
}
}
// determine chance of evading detection. If we fail, we are caught and receive a loyalty penalty
UINT8 chanceofevadingdetection = pSoldier->GetThiefEvadeDetectionChance();
if ( !Chance( chanceofevadingdetection ) )
{
// we were caught. Since we have guns and the locals don't, they can't do much apart from being pissed
// of course if we do that while covert, the locals won't 'know' it was us
if ( !SPY_LOCATION( pSoldier->bAssignment ) )
{
// we were caught. Since we have guns and the locals don't, they can't do much apart from being pissed
// lower loyalty in closest town the player has ever controlled (the penalty is lowered by distance)
AffectClosestTownLoyaltyByDistanceFrom( -LOYALTY_STOLE_MONEY_FROM_LOCALS, pSoldier->sSectorX, pSoldier->sSectorY, sectorz );
}
}
// Flugente: dynamic opinion
HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_THIEF, TRUE, FALSE );
}
}
}
+128 -11
View File
@@ -1742,9 +1742,8 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
INT32 iPercentAdjustment;
INT32 iDistanceAdjustedLoyalty;
// preset shortest distances to high values prior to searching for a minimum
for( bTownId = FIRST_TOWN; bTownId < NUM_TOWNS; bTownId++ )
for( bTownId = FIRST_TOWN; bTownId < NUM_TOWNS; ++bTownId )
{
iShortestDistance[ bTownId ] = 999999;
}
@@ -1760,6 +1759,14 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
{
bTownId = (UINT8) pTownNamesList[ uiIndex ];
// Flugente: added to speed up function, remove if removed in loop below this one
// doesn't affect towns where player hasn't established a "presence" yet
if ( !gTownLoyalty[bTownId].fStarted )
{
++uiIndex;
continue;
}
// skip path test if distance is already known to be zero to speed this up a bit
if (iShortestDistance[ bTownId ] > 0 )
{
@@ -1772,14 +1779,13 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
}
}
uiIndex++;
++uiIndex;
}
// must always remove that temporary group!
RemoveGroup( ubTempGroupId );
for( bTownId = FIRST_TOWN; bTownId < NUM_TOWNS; bTownId++ )
for( bTownId = FIRST_TOWN; bTownId < NUM_TOWNS; ++bTownId )
{
// doesn't affect towns where player hasn't established a "presence" yet
if (!gTownLoyalty[ bTownId ].fStarted)
@@ -1799,8 +1805,7 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
// add 25% per sector below the threshold
iPercentAdjustment = 25 * (LOYALTY_EVENT_DISTANCE_THRESHOLD - iShortestDistance[ bTownId ]);
}
else
if (iShortestDistance[ bTownId ] > LOYALTY_EVENT_DISTANCE_THRESHOLD)
else if (iShortestDistance[ bTownId ] > LOYALTY_EVENT_DISTANCE_THRESHOLD)
{
// subtract 10% per sector above the threshold
iPercentAdjustment = -10 * (iShortestDistance[ bTownId ] - LOYALTY_EVENT_DISTANCE_THRESHOLD);
@@ -1816,8 +1821,7 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
// no distance adjustment necessary
iPercentAdjustment = 0;
}
// calculate loyalty affects as adjusted for distance to this town
iDistanceAdjustedLoyalty = (iLoyaltyChange * (100 + iPercentAdjustment)) / 100;
@@ -1838,10 +1842,123 @@ void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX,
DecrementTownLoyalty( bTownId, iDistanceAdjustedLoyalty );
}
}
}
void AffectClosestTownLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
INT16 sEventSector;
UINT8 ubTempGroupId;
INT8 bTownId;
UINT32 uiIndex;
INT32 iThisDistance;
INT32 iShortestDistance[MAX_TOWNS];
INT32 iPercentAdjustment;
INT32 iDistanceAdjustedLoyalty;
INT32 sDistanceToClosestTown = 999999;
INT8 bClosestTown = NUM_TOWNS;
// preset shortest distances to high values prior to searching for a minimum
for ( bTownId = FIRST_TOWN; bTownId < NUM_TOWNS; ++bTownId )
{
iShortestDistance[bTownId] = 999999;
}
sEventSector = sSectorX + ( MAP_WORLD_X * sSectorY );
// need a temporary group create to use for laying down distance paths
ubTempGroupId = CreateNewPlayerGroupDepartingFromSector( (UINT8)sSectorX, (UINT8)sSectorY );
// calc distance to the event sector from EACH SECTOR of each town, keeping only the shortest one for every town
uiIndex = 0;
while ( pTownNamesList[uiIndex] != 0 )
{
bTownId = (UINT8)pTownNamesList[uiIndex];
// Flugente: added to speed up function, remove if removed in loop below this one
// doesn't affect towns where player hasn't established a "presence" yet
if ( !gTownLoyalty[bTownId].fStarted )
{
++uiIndex;
continue;
}
// skip path test if distance is already known to be zero to speed this up a bit
if ( iShortestDistance[bTownId] > 0 )
{
// calculate across how many sectors the fastest travel path from event to this town sector
iThisDistance = FindStratPath( sEventSector, (INT16)pTownLocationsList[uiIndex], ubTempGroupId, FALSE );
if ( iThisDistance < iShortestDistance[bTownId] )
{
iShortestDistance[bTownId] = iThisDistance;
}
if ( iThisDistance < sDistanceToClosestTown )
{
bClosestTown = bTownId;
sDistanceToClosestTown = iThisDistance;
}
}
++uiIndex;
}
// must always remove that temporary group!
RemoveGroup( ubTempGroupId );
if ( bClosestTown < NUM_TOWNS )
{
// if event was underground, double effective distance
if ( bSectorZ != 0 )
{
sDistanceToClosestTown *= 2;
}
// This number here controls how many sectors away is the "norm" for the unadjusted loyalty change value
if ( sDistanceToClosestTown < LOYALTY_EVENT_DISTANCE_THRESHOLD )
{
// add 25% per sector below the threshold
iPercentAdjustment = 25 * ( LOYALTY_EVENT_DISTANCE_THRESHOLD - sDistanceToClosestTown );
}
else if ( sDistanceToClosestTown > LOYALTY_EVENT_DISTANCE_THRESHOLD )
{
// subtract 10% per sector above the threshold
iPercentAdjustment = -10 * ( sDistanceToClosestTown - LOYALTY_EVENT_DISTANCE_THRESHOLD );
// don't allow it to go below -100, that would change the sign of the loyalty effect!
if ( iPercentAdjustment < -100 )
{
iPercentAdjustment = -100;
}
}
else
{
// no distance adjustment necessary
iPercentAdjustment = 0;
}
// calculate loyalty affects as adjusted for distance to this town
iDistanceAdjustedLoyalty = ( iLoyaltyChange * ( 100 + iPercentAdjustment ) ) / 100;
if ( iDistanceAdjustedLoyalty == 0 )
{
// no measurable effect, skip this town
return;
}
if ( iDistanceAdjustedLoyalty > 0 )
{
IncrementTownLoyalty( bClosestTown, iDistanceAdjustedLoyalty );
}
else
{
// the decrement amount MUST be positive
iDistanceAdjustedLoyalty *= -1;
DecrementTownLoyalty( bClosestTown, iDistanceAdjustedLoyalty );
}
}
}
// to be called whenever player gains control of a sector in any way
void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSectorY )
+6
View File
@@ -50,6 +50,9 @@
// Flugente: a rotting corpse is so decayed that it disappeared (we're the ones making all those corpses, the last we could do is clean up afterwards)
#define LOYALTY_PENALTY_ROTTED_CORPSE (1 * GAIN_PTS_PER_LOYALTY_PT)
// Flugente: one of our thieves was caught stealing
#define LOYALTY_STOLE_MONEY_FROM_LOCALS ((4/7) * GAIN_PTS_PER_LOYALTY_PT)
typedef enum
{
// There are only for distance-adjusted global loyalty effects. Others go into list above instead!
@@ -186,6 +189,9 @@ void DecrementTownLoyaltyEverywhere( UINT32 uiLoyaltyDecrease );
void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ);
void AffectAllTownsLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ);
// Flugente: like AffectAllTownsLoyaltyByDistanceFrom(...) but only for the closest town
void AffectClosestTownLoyaltyByDistanceFrom( INT32 iLoyaltyChange, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// handle a town being liberated for the first time
void CheckIfEntireTownHasBeenLiberated( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
void CheckIfEntireTownHasBeenLost( INT8 bTownId, INT16 sSectorX, INT16 sSectorY );
+12
View File
@@ -100,6 +100,7 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
strcmp(name, "snakechance" ) == 0 ||
strcmp(name, "numsnakes" ) == 0 ||
strcmp(name, "maxworkers" ) == 0 ||
strcmp(name, "wealth" ) == 0 ||
strcmp(name, "bloodcatraidpossible" ) == 0 ||
strcmp(name, "zombieraidpossible" ) == 0 ||
strcmp(name, "banditraidpossible" ) == 0 ))
@@ -234,6 +235,11 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
SectorExternalData[ubSectorId][2].maxworkers = 0;
SectorExternalData[ubSectorId][3].maxworkers = 0;
SectorExternalData[ubSectorId][0].wealth = pData->sectordata.wealth;
SectorExternalData[ubSectorId][1].wealth = 0;
SectorExternalData[ubSectorId][2].wealth = 0;
SectorExternalData[ubSectorId][3].wealth = 0;
SectorExternalData[ubSectorId][0].usSectorFlagMask = pData->sectordata.usSectorFlagMask;
SectorExternalData[ubSectorId][1].usSectorFlagMask = 0;
SectorExternalData[ubSectorId][2].usSectorFlagMask = 0;
@@ -263,6 +269,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
pData->sectordata.snakechance = 0;
pData->sectordata.numsnakes = 0;
pData->sectordata.maxworkers = 0;
pData->sectordata.wealth = 0;
pData->sectordata.usSectorFlagMask = 0;
}
else
@@ -387,6 +394,11 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->sectordata.maxworkers = (UINT8)atoi( pData->szCharData );
}
else if ( strcmp( name, "wealth" ) == 0 )
{
pData->curElement = ELEMENT;
pData->sectordata.wealth = (UINT16)atoi( pData->szCharData );
}
else if ( strcmp( name, "bloodcatraidpossible" ) == 0 )
{
pData->curElement = ELEMENT;
+2 -1
View File
@@ -517,7 +517,8 @@ typedef struct
UINT8 snakechance; // if positive, snakes can attack in water, the higher the number, the more often it happens
UINT8 numsnakes; // how many snakes can be active at maximum
UINT8 maxworkers; // maximum number of workers in this sector;
UINT8 maxworkers; // maximum number of workers in this sector
UINT16 wealth; // rating of how rich the population in this sector is
UINT32 usSectorFlagMask; // various flags
+83
View File
@@ -20327,6 +20327,89 @@ FLOAT SOLDIERTYPE::GetAdministrationModifier()
return 1.0f;
}
// Flugente: those with the <scrounging> background occasionally steal money from the locals
UINT8 SOLDIERTYPE::GetThiefStealMoneyChance()
{
if ( this->stats.bLife < OKLIFE )
return 0;
UINT32 val = 1 * EffectiveAgility( this, FALSE ) + 8 * EffectiveDexterity( this, FALSE ) + 10 * EffectiveExpLevel( this, FALSE );
// personality/disability modifiers
FLOAT persmodifier = 1.0f;
//if ( DoesMercHaveDisability( this, HEAT_INTOLERANT ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, NERVOUS ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, CLAUSTROPHOBIC ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, NONSWIMMER ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) ) persmodifier -= 0.20f;
if ( DoesMercHaveDisability( this, FORGETFUL ) ) persmodifier -= 0.12f;
//if ( DoesMercHaveDisability( this, PSYCHO ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, DEAF ) ) persmodifier -= 0.15f;
if ( DoesMercHaveDisability( this, SHORTSIGHTED ) ) persmodifier -= 0.30f;
//if ( DoesMercHaveDisability( this, HEMOPHILIAC ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, AFRAID_OF_HEIGHTS ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, SELF_HARM ) ) persmodifier -= 0.20f;
if ( gGameOptions.fNewTraitSystem )
{
if ( DoesMercHavePersonality( this, CHAR_TRAIT_SOCIABLE ) ) persmodifier += 0.25f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_LONER ) ) persmodifier -= 0.05f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_OPTIMIST ) ) persmodifier += 0.05f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_ASSERTIVE ) ) persmodifier += 0.15f;
//if ( DoesMercHavePersonality( this, CHAR_TRAIT_INTELLECTUAL ) ) persmodifier += 0.15f;
//if ( DoesMercHavePersonality( this, CHAR_TRAIT_PRIMITIVE ) ) persmodifier -= 0.15f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_AGGRESSIVE ) ) persmodifier -= 0.15f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_PHLEGMATIC ) ) persmodifier -= 0.05f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_DAUNTLESS ) ) persmodifier -= 0.13f;
//if ( DoesMercHavePersonality( this, CHAR_TRAIT_PACIFIST ) ) persmodifier -= 0.03f;
//if ( DoesMercHavePersonality( this, CHAR_TRAIT_MALICIOUS ) ) persmodifier -= 0.13f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_SHOWOFF ) ) persmodifier -= 0.08f;
if ( DoesMercHavePersonality( this, CHAR_TRAIT_COWARD ) ) persmodifier -= 0.25f;
}
UINT32 totalvalue = val * persmodifier / 10.0f;
ReducePointsForFatigue( this, &totalvalue );
totalvalue = min( 100, max( 0, totalvalue ) );
return totalvalue;
}
UINT8 SOLDIERTYPE::GetThiefEvadeDetectionChance()
{
if ( this->stats.bLife < OKLIFE )
return 0;
// the theoretical unboosted maximum is 1100, yet we treat it like 1000 - effectively you can boost stealth gear to give you a serious edge
UINT32 val = 250 + 5 * EffectiveExpLevel( this, FALSE ) + 5 * EffectiveAgility( this, FALSE ) + 3 * GetWornStealth( this );
ReducePointsForFatigue( this, &val );
// personality/disability modifiers
FLOAT persmodifier = 1.0f;
//if ( DoesMercHaveDisability( this, HEAT_INTOLERANT ) ) persmodifier -= 0.20f;
if ( DoesMercHaveDisability( this, NERVOUS ) ) persmodifier -= 0.04f;
//if ( DoesMercHaveDisability( this, CLAUSTROPHOBIC ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, NONSWIMMER ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, FEAR_OF_INSECTS ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, FORGETFUL ) ) persmodifier -= 0.50f;
//if ( DoesMercHaveDisability( this, PSYCHO ) ) persmodifier -= 0.20f;
if ( DoesMercHaveDisability( this, DEAF ) ) persmodifier -= 0.06f;
//if ( DoesMercHaveDisability( this, SHORTSIGHTED ) ) persmodifier -= 0.40f;
//if ( DoesMercHaveDisability( this, HEMOPHILIAC ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, AFRAID_OF_HEIGHTS ) ) persmodifier -= 0.20f;
//if ( DoesMercHaveDisability( this, SELF_HARM ) ) persmodifier -= 0.20f;
UINT32 totalvalue = val * persmodifier / 10.0f;
ReducePointsForFatigue( this, &totalvalue );
totalvalue = min( 100, max( 0, totalvalue ) );
return totalvalue;
}
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
{
INT8 bBandaged; //,savedOurTurn;
+4
View File
@@ -2006,6 +2006,10 @@ public:
// Flugente: administration assignment
UINT32 GetAdministrationPoints();
FLOAT GetAdministrationModifier();
// Flugente: those with the <scrounging> background occasionally steal money from the locals
UINT8 GetThiefStealMoneyChance();
UINT8 GetThiefEvadeDetectionChance();
//////////////////////////////////////////////////////////////////////////////
}; // SOLDIERTYPE;
+1 -1
View File
@@ -9000,7 +9000,7 @@ STR16 szBackgroundText_Flags[]=
L" 会消耗掉背包中的药品 \n", //L" might consume drugs in inventory\n",
L" 蔑视其他背景的角色 \n", //L" disregard for other backgrounds\n",
L" +1 角色等级在地下分区时 \n", //L" +1 level in underground sectors\n",
L" 会盗窃物品 \n", //L" might steal items\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 埋设炸弹等级 \n", //L" +1 traplevel to planted bombs\n",
L" 会导致附近的佣兵腐败 \n", //L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9018,7 +9018,7 @@ STR16 szBackgroundText_Flags[]=
L" might consume drugs in inventory\n",
L" disregard for all other backgrounds\n",
L" +1 level in underground sectors\n",
L" might steal items\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 traplevel to planted bombs\n",
L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9000,7 +9000,7 @@ STR16 szBackgroundText_Flags[]=
L" might consume drugs in inventory\n",
L" disregard for all other backgrounds\n",
L" +1 level in underground sectors\n",
L" might steal items\n",
L" steals money from the locals sometimes\n",
L" +1 traplevel to planted bombs\n",
L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9000,7 +9000,7 @@ STR16 szBackgroundText_Flags[]=
L" peut consommer des drogues se trouvant dans son inventaire\n",
L" ne tient pas compte des autres passifs\n",
L" +1 Niveau dans les souterrains\n",
L" peut voler des objets\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 Niveau pour poser des pièges\n",
L" répand la corruption aux mercenaires proches\n",
+1 -1
View File
@@ -8830,7 +8830,7 @@ STR16 szBackgroundText_Flags[]=
L" might consume drugs in inventory\n",
L" disregard for all other backgrounds\n",
L" +1 level in underground sectors\n",
L" might steal items\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 traplevel to planted bombs\n",
L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9009,7 +9009,7 @@ STR16 szBackgroundText_Flags[]=
L" might consume drugs in inventory\n",
L" disregard for all other backgrounds\n",
L" +1 level in underground sectors\n",
L" might steal items\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 traplevel to planted bombs\n",
L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9022,7 +9022,7 @@ STR16 szBackgroundText_Flags[]=
L" might consume drugs in inventory\n",
L" disregard for all other backgrounds\n",
L" +1 level in underground sectors\n",
L" might steal items\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 traplevel to planted bombs\n",
L" spreads corruption to nearby mercs\n",
+1 -1
View File
@@ -9000,7 +9000,7 @@ STR16 szBackgroundText_Flags[]=
L" может употреблять наркотики из инвентаря\n",
L" вне зависимости от других особенностей биографии\n",
L" +1 уровень в подземных секторах\n",
L" может красть предметы\n",
L" steals money from the locals sometimes\n", // TODO.Translate
L" +1 уровень ловушек при установке мин\n",
L" разлагает других наёмников\n",