Home » MODDING HQ 1.13 » v1.13 Modding, Customising, Editing » v1.13 XML Customization » Facility events - a question about "combined skill"
Facility events - a question about "combined skill"[message #319854] Thu, 16 May 2013 17:38 Go to next message
Durak

 
Messages:58
Registered:April 2010
Hi

let's get right to the point:

Which skills (skill sets) are used for the different hourly facility event checks?



The only hint that there actually is something like a skill check for events (for their good/bad effects on assigned mercs, respectively) can be found in the options ini, under "facility danger rate".
Couldn't find any details on that anywhere.

I'm currently trying to customize the facilitytypes.xml, so any help would be appreciated.


cheers
Durak

[Updated on: Thu, 16 May 2013 17:40] by Moderator

Re: Facility events - a question about "combined skill"[message #319868] Thu, 16 May 2013 20:24 Go to previous messageGo to next message
Flugente

 
Messages:3045
Registered:April 2009
Location: Germany
Well, of you want to know it in detail... I'm not inclined to wrap it up, so here it is:

// This function runs a specific kind of RISK associated with a facility. The character's stats may affect the result.
INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacilityType, UINT8 ubAssignmentType )
{
	INT16 Result = 0;
	
	INT32 iChance;
	INT16 bBaseEffect;
	UINT16 ubRange;

	// Read risk data directly from facility array.
	iChance = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].usChance;
	bBaseEffect = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].bBaseEffect;
	ubRange = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].ubRange;

	// For now, only these variables can effect risk outcome. In the future there may be more effects, like traits
	// and personality, or even sex.
	INT16 ubStrength = EffectiveStrength( pSoldier, FALSE );
	INT16 ubAgility = EffectiveAgility( pSoldier, FALSE );
	INT16 ubDexterity = EffectiveDexterity( pSoldier, FALSE );
	UINT8 ubHealth = __min(pSoldier->stats.bLife, pSoldier->stats.bLifeMax);
	INT16 ubWisdom = EffectiveWisdom( pSoldier );
	UINT8 ubLeadership = EffectiveLeadership( pSoldier );
	UINT8 ubExplosives = EffectiveExplosive( pSoldier );
	UINT8 ubExpLevel = EffectiveExpLevel( pSoldier );
	UINT8 ubLocalLoyalty = 0;
	if (GetTownIdForSector( pSoldier->sSectorX, pSoldier->sSectorY ) != BLANK_SECTOR )
	{
		ubLocalLoyalty = gTownLoyalty[ GetTownIdForSector( pSoldier->sSectorX, pSoldier->sSectorY ) ].ubRating;
	}
	else
	{
		ubLocalLoyalty = 0;
	}
	
	///////////////
	INT16 sAbsoluteMaxResult;
	INT16 sAbsoluteMinResult;

	// Calculate absolute maximum variance. The result can never be outside these.
	if (bBaseEffect < 0)
	{
		sAbsoluteMaxResult = __min((bBaseEffect + ubRange), -1);
		sAbsoluteMinResult = bBaseEffect - ubRange;
	}
	else if (bBaseEffect > 0)
	{
		sAbsoluteMaxResult = bBaseEffect + ubRange;
		sAbsoluteMinResult = __max(1, (bBaseEffect - ubRange));
	}
	else
	{
		sAbsoluteMaxResult = bBaseEffect + ubRange;
		sAbsoluteMinResult = bBaseEffect - ubRange;
	}

	INT16 bCombinedStats;

	// Begin calculating the effect of skills on increasing/reducing final result. Use a mix of stats to reach a range
	// of 0 to 100.

	switch (ubRiskType)
	{
		case RISK_STRENGTH:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.3) + (ubExpLevel * 5));
			break;
		case RISK_DEXTERITY:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.4) + (ubExpLevel * 6));
			break;
		case RISK_AGILITY:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubExpLevel * 8));
			break;
		case RISK_HEALTH:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.5) + (ubExpLevel * 5));
			break;
		case RISK_WISDOM:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.6) + (ubExpLevel * 4));
			break;
		case RISK_MARKSMANSHIP:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.4) + (ubExpLevel * 4));
			break;
		case RISK_MEDICAL:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubDexterity * 0.4) + (ubExpLevel * 3));
			break;
		case RISK_MECHANICAL:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubDexterity * 0.5) + (ubExpLevel * 2));
			break;
		case RISK_LEADERSHIP:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.4) + (ubLeadership * 0.3) + (ubExpLevel * 3));
			break;
		case RISK_EXPLOSIVES:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.3) + (ubDexterity * 0.3) + (ubExpLevel * 2));
			break;
		case RISK_INJURY:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubDexterity * 0.2) + (ubAgility * 0.4) + (ubExpLevel * 2));
			break;
		case RISK_MORALE:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubLeadership * 0.4) + (ubExpLevel * 4));
			break;
		case RISK_FATIGUE:
			bCombinedStats = (INT16)__min(100, (ubAgility * 0.1) + (ubStrength * 0.3) + (ubHealth * 0.2) + (ubExpLevel * 4));
			break;
		case RISK_DRUNK:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.5) + (ubHealth * 0.3) + (ubExpLevel * 2));
			break;
		case RISK_LOYALTY_LOCAL:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubLeadership * 0.3) + (ubStrength * 0.1) + (ubExpLevel * 2) + (ubLocalLoyalty * 0.2) );
			break;
		case RISK_LOYALTY_GLOBAL:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubLeadership * 0.3) + (ubExpLevel * 2) + (ubLocalLoyalty * 0.2));
			break;
		case RISK_WH40K_IMPERIAL_FAITH:
			bCombinedStats = (INT16)__min(100, (ubWisdom * 0.4) + (ubLeadership * 0.1) + (ubLocalLoyalty * 0.5));
			break;
	}

	if (bCombinedStats >= 100)
	{
		// Character is as skilled as possible. Automatic "best" result.
		return (sAbsoluteMaxResult);
	}
	if (bCombinedStats <= 0)
	{
		// Character is completely inept? Strange. Automatic "worst" result.
		return (sAbsoluteMinResult);
	}

	// we now have a range of 0 to 100. Let's apply an externalized modifier of 0 to -100.
	bCombinedStats -= gGameExternalOptions.ubFacilityDangerRate;

	// The chance of triggering an event is also based on stats.
	if (bBaseEffect > 0 )
	{
		// Chance increases with good stats, decreased with bad stats.
		iChance = iChance + ((bCombinedStats * iChance) / 100 );
	}
	else if (bBaseEffect < 0 )
	{
		// Chance decreases with good stats, increases with bad stats.
		iChance = iChance - ((bCombinedStats * iChance) / 100 );
	}
	else
	{
		// Chance is unaffected
	}

        // Limit iChance into a 0 to 50000 range.
        iChance = __max(0, __min(iChance, 50000));

	// Alright, let's see if the event is triggered.
	if (PreRandom(gGameExternalOptions.usFacilityEventRarity)>(UINT32)iChance)
	{
		// Chance failed to trigger.
		return (0);
	}
	else
	{
		// Let's find out how bad/good the result is.

		// By now, the Combined Stats variable is anywhere between -100 and +100. 
		// We use this to move the Base Effect point from its original location, effectively giving us a better
		// or worse result based on our stats.
		bBaseEffect += (bCombinedStats * (ubRange+1)) / 100;
		bBaseEffect = __min(bBaseEffect, sAbsoluteMaxResult);
		bBaseEffect = __max(bBaseEffect, sAbsoluteMinResult);

		// The deviation is also affected by our stats.
		ubRange -= abs((bCombinedStats * (ubRange+1)) / 100); // If the Base Effect has moved any, then the range shrinks accordingly.

		// Effectively what happens is that skilled characters will get better results more consistently, and avoid
		// bad results consistently as well.
		// The opposite is also true - characters with insufficient skills tend to get worse results consistently,
		// and rarely (if ever) get the best results possible.

		//The final result is:
		Result = bBaseEffect + ((PreRandom((ubRange*2)+1)) - ubRange);

		// Naturally, the character can't ever breach the range of possible results as defined by the facility data.
		Result = __min(Result, sAbsoluteMaxResult);
		Result = __max(Result, sAbsoluteMinResult);

		return (Result);
	}
}

...

void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFacilityType, UINT8 ubAssignmentType )
{
	INT32 iCounter = 0;
	INT32 Result = 0;
	INT32 iNewValue = 0;

	CHAR16 sString[256];
	CHAR16 szSectorGrid[10];
	SGPRect pCenteringRect= {0, 0, 640, INV_INTERFACE_START_Y };

	UINT8 ubTownID = 0;
	BOOLEAN fOperatingFacility = (GetSoldierFacilityAssignmentIndex( pSoldier ) == -1) ? FALSE : TRUE;

	BOOLEAN fBadResult = FALSE;

	UINT16 usColor = FONT_MCOLOR_LTRED;

	for (iCounter; iCounter < NUM_RISKS; iCounter++)
	{
		fBadResult = FALSE;

		if (gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[iCounter].usChance > 0)
		{
			if (iCounter == RISK_LOYALTY_LOCAL)
			{
				ubTownID = GetTownIdForSector( pSoldier->sSectorX, pSoldier->sSectorY );
				if (ubTownID == BLANK_SECTOR)
				{
					// No town here, so this risk doesn't have any effect anyway...
					continue;
				}
			}
					
			Result = FacilityRiskResult( pSoldier, iCounter, ubFacilityType, ubAssignmentType);
			if (Result != 0)
			{
				switch (iCounter)
				{
					case RISK_STRENGTH:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usStrengthSubpointsToImprove;
							StatChange( pSoldier, STRAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bStrength - 1))
								Result = -1*(pSoldier->stats.bStrength - 1);
							pSoldier->stats.bStrength += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bStrength	= pSoldier->stats.bStrength;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, STRAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[0], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[0], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_AGILITY:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usAgilitySubpointsToImprove;
							StatChange( pSoldier, AGILAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bAgility - 1))
								Result = -1*(pSoldier->stats.bAgility - 1);
							pSoldier->stats.bAgility += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bAgility	= pSoldier->stats.bAgility;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, AGILAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[1], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[1], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_DEXTERITY:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usDexteritySubpointsToImprove;
							StatChange( pSoldier, DEXTAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bDexterity - 1))
								Result = -1*(pSoldier->stats.bDexterity - 1);
							pSoldier->stats.bDexterity += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bDexterity	= pSoldier->stats.bDexterity;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->name, FALSE, Result, DEXTAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[2], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[2], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_WISDOM:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usWisdomSubpointsToImprove;
							StatChange( pSoldier, WISDOMAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bWisdom - 1))
								Result = -1*(pSoldier->stats.bWisdom - 1);
							pSoldier->stats.bWisdom += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bWisdom	= pSoldier->stats.bWisdom;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, WISDOMAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[3], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[3], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_HEALTH:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usHealthSubpointsToImprove;
							StatChange( pSoldier, HEALTHAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bLifeMax - 1))
								Result = -1*(pSoldier->stats.bLifeMax - 1);
							pSoldier->stats.bLifeMax += Result;
							pSoldier->stats.bLife += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_HEALTH ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeHealthTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( HEALTH_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bLifeMax	= pSoldier->stats.bLifeMax;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							if (pSoldier->stats.bLife < OKLIFE)
							{
								HandleTakeDamageDeath( pSoldier, 0, TAKE_DAMAGE_BLOODLOSS );
							}
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, HEALTHAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							if (pSoldier->stats.bLife >= OKLIFE)
							{
								// Do Screen Message and stop time.
								GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
								if (!fOperatingFacility)
									swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[4], szSectorGrid );
								else
									swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[4], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
								DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
								StopTimeCompression();
							}
							else if(pSoldier->stats.bLife < OKLIFE && pSoldier->stats.bLife > 0)
							{
								// Soldier's health is driven very low. Automatically removed from duty.
								// Do Screen Message and stop time.
								GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
								if (!fOperatingFacility)
									swprintf( sString, gzFacilityErrorMessage[28], pSoldier->GetName(), szSectorGrid );
								else
									swprintf( sString, gzFacilityErrorMessage[29], pSoldier->GetName(), gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
								AddCharacterToAnySquad( pSoldier );
								DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
								StopTimeCompression();
							}
						}
						break;
					case RISK_MARKSMANSHIP:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usMarksmanshipSubpointsToImprove;
							StatChange( pSoldier, MARKAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bMarksmanship - 1))
								Result = -1*(pSoldier->stats.bMarksmanship - 1);
							pSoldier->stats.bMarksmanship += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_MARKSMANSHIP ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeMarksmanshipTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( MRK_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bMarksmanship	= pSoldier->stats.bMarksmanship;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, MARKAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[5], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[5], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_LEADERSHIP:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usLeadershipSubpointsToImprove;
							StatChange( pSoldier, LDRAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bLeadership - 1))
								Result = -1*(pSoldier->stats.bLeadership - 1);
							pSoldier->stats.bLeadership += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_LEADERSHIP ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeLeadershipTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( LDR_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bLeadership	= pSoldier->stats.bLeadership;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, LDRAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[6], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[6], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_MECHANICAL:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usMechanicalSubpointsToImprove;
							StatChange( pSoldier, MECHANAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bMechanical - 1))
								Result = -1*(pSoldier->stats.bMechanical - 1);
							pSoldier->stats.bMechanical += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_MECHANICAL ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeMechanicalTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( MECH_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bMechanical	= pSoldier->stats.bMechanical;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, MECHANAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[7], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[7], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_MEDICAL:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usMedicalSubpointsToImprove;
							StatChange( pSoldier, MEDICALAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bMedical - 1))
								Result = -1*(pSoldier->stats.bMedical - 1);
							pSoldier->stats.bMedical += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_MEDICAL ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeMedicalTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( MED_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bMedical	= pSoldier->stats.bMedical;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, MEDICALAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
														if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[8], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[8], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_EXPLOSIVES:
						if (Result > 0)
						{
							// Soldier doesn't gain stat points directly, instead he gets a number of chances
							// equal to Result*SubPointsPerLevel. Optimally this leads to gaining a number of
							// levels equal to result, but this isn't always the case.
							Result *= gGameExternalOptions.usExplosivesSubpointsToImprove;
							StatChange( pSoldier, EXPLODEAMT, Result, TRUE );
						}
						else
						{
							// Soldier is suffering direct stat damage.
							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							if ( (-1*Result) > (pSoldier->stats.bExplosive - 1))
								Result = -1*(pSoldier->stats.bExplosive - 1);
							pSoldier->stats.bExplosive += Result;
							if ( gGameOptions.fNewTraitSystem && (Result <= 0) )
							{
								pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_EXPLOSIVES ] -= Result;
							}
							else
							{
								// make this stat RED for a while...
								pSoldier->timeChanges.uiChangeExplosivesTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( EXP_INCREASE );
							}
							// Update Profile
							gMercProfiles[ pSoldier->ubProfile ].bExplosive	= pSoldier->stats.bExplosive;

							// merc records - stat damaged
							if( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							///////////////////////////////////////////////////////////////////////////////////////////
							fBadResult = TRUE;

							// Log message
							BuildStatChangeString( sString, pSoldier->GetName(), FALSE, Result, EXPLODEAMT );
							ScreenMsg( usColor, MSG_INTERFACE, sString );

							// Do Screen Message and stop time.
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[17], pSoldier->GetName(), gzFacilityRiskResultStrings[9], szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[18], pSoldier->GetName(), gzFacilityRiskResultStrings[9], gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
							DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
							StopTimeCompression();
						}
						break;
					case RISK_INJURY:
						// This can only be a negative effect... for now.
						if (Result < 0)
						{
							// Soldier is suffering direct unbandaged injury.
							pSoldier->SoldierTakeDamage( 0, abs(Result), 0, abs(Result), TAKE_DAMAGE_BLOODLOSS, NOBODY, NOWHERE, 0, FALSE );
							fBadResult = TRUE;

							// SANDRO - add to merc records - facility accidents counter
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;

							if (pSoldier->stats.bLife > 0)
							{
								if (pSoldier->bBleeding > MIN_BLEEDING_THRESHOLD)
								{
									// Log message
									GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
									swprintf( sString, gzFacilityErrorMessage[31], pSoldier->GetName(), szSectorGrid );
									ScreenMsg( usColor, MSG_INTERFACE, sString );

									// Do Screen Message, stop time, and take character off duty immediately.
									GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
									if (!fOperatingFacility)
										swprintf( sString, gzFacilityErrorMessage[19], pSoldier->GetName(), szSectorGrid );
									else
										swprintf( sString, gzFacilityErrorMessage[20], pSoldier->GetName(), gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
									AddCharacterToAnySquad( pSoldier );
									DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
									StopTimeCompression();
								}
								else
								{
									// Log message
									GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
									swprintf( sString, gzFacilityErrorMessage[30], pSoldier->GetName(), szSectorGrid );
									ScreenMsg( usColor, MSG_INTERFACE, sString );

									// Soldier isn't bleeding too bad. Let the player know, but don't take any action.
									// Do Screen Message and stop time.
									GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
									if (!fOperatingFacility)
										swprintf( sString, gzFacilityErrorMessage[21], pSoldier->GetName(), szSectorGrid );
									else
										swprintf( sString, gzFacilityErrorMessage[22], pSoldier->GetName(), gFacilityTypes[ubFacilityType].szFacilityName, szSectorGrid );
									DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL );
									StopTimeCompression();
								}
							}
						}
						break;
					case RISK_MORALE:
						pSoldier->aiData.bMorale = __min(100,__max(0, pSoldier->aiData.bMorale + Result));
						pSoldier->aiData.bStrategicMoraleMod = __min(50,__max(-50, pSoldier->aiData.bStrategicMoraleMod + Result));
						RefreshSoldierMorale( pSoldier );
						// SANDRO - add to merc records - facility accidents counter
						if ( Result < 0 )
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
						break;
					case RISK_FATIGUE:
						pSoldier->bBreathMax = __min(100,__max(0, pSoldier->bBreathMax + Result));
						pSoldier->bBreath = pSoldier->bBreathMax;
						// SANDRO - add to merc records - facility accidents counter
						if ( Result < 0 )
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
						break;
					case RISK_DRUNK:

						// Has soldier just drunk enough to make him drunk off his head?
						if (GetDrunkLevel(pSoldier) == BORDERLINE)
						{
							// Log message
							swprintf( sString, gzFacilityErrorMessage[27], pSoldier->GetName() );
							ScreenMsg( usColor, MSG_INTERFACE, sString );
						}

						// Add effects
						pSoldier->AddDrugValues( DRUG_TYPE_ALCOHOL, Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect, Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate, Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect );

						// ATE: Make guy collapse from heart attack if too much stuff taken....
						if ( pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] > (  Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect * 3 ) )
						{
							if ( pSoldier->ubProfile == LARRY_NORMAL )
							{
								pSoldier = SwapLarrysProfiles( pSoldier );
							}
							else if ( pSoldier->ubProfile == LARRY_DRUNK )
							{
								gMercProfiles[ LARRY_DRUNK ].bNPCData = 0;
							}

							// Keel over...
							DeductPoints( pSoldier, 0, 10000 );

							///////////////////////////////////////////////////////////////////////////////////////////
							// SANDRO - if our stat is damaged through facility event, make it healable
							// Permanently lower certain stats...
							if ( gGameOptions.fNewTraitSystem )
							{
								// WISDOM decrease
								if ( pSoldier->stats.bWisdom > 5 )
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += 5;
									pSoldier->stats.bWisdom -= 5;
								}
								else
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += (pSoldier->stats.bWisdom - 1);
									pSoldier->stats.bWisdom = 1;
								}
								// DEXTERITY decrease
								if ( pSoldier->stats.bDexterity > 5 )
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += 5;
									pSoldier->stats.bDexterity -= 5;
								}
								else
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += (pSoldier->stats.bDexterity - 1);
									pSoldier->stats.bDexterity = 1;
								}
								// STRENGTH decrease
								if ( pSoldier->stats.bStrength > 5 )
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += 5;
									pSoldier->stats.bStrength -= 5;
								}
								else
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += (pSoldier->stats.bStrength - 1);
									pSoldier->stats.bStrength = 1;
								}
								// AGILITY decrease
								if ( pSoldier->stats.bAgility > 5 )
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += 5;
									pSoldier->stats.bAgility -= 5;
								}
								else
								{
									pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += (pSoldier->stats.bAgility - 1);
									pSoldier->stats.bAgility = 1;
								}
							}
							else // old system
							{
								pSoldier->stats.bAgility	= __max(1, pSoldier->stats.bWisdom-5);
								pSoldier->stats.bDexterity	= __max(1, pSoldier->stats.bDexterity-5);
								pSoldier->stats.bStrength	= __max(1, pSoldier->stats.bStrength-5);
								pSoldier->stats.bAgility	= __max(1, pSoldier->stats.bAgility-5);

								// make those stats RED for a while...
								// SANDRO - we don't need to do this with new system, as we simply show all damaged stats in red until healed
								pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
								pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
								pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
								pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
								pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
							}

							// export stat changes to profile
							gMercProfiles[ pSoldier->ubProfile ].bWisdom	= pSoldier->stats.bWisdom;
							gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->stats.bDexterity;
							gMercProfiles[ pSoldier->ubProfile ].bStrength	= pSoldier->stats.bStrength;
							gMercProfiles[ pSoldier->ubProfile ].bAgility	= pSoldier->stats.bAgility;
							
							fBadResult = TRUE; // stop the time, call a doctor, we had a heart attack!
							
							// merc records - stat damaged
							gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
							gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
							////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
						}
						break;
					case RISK_LOYALTY_LOCAL:
						Result *= GAIN_PTS_PER_LOYALTY_PT; // Transform points into actual loyalty.
						if (Result > 0)
						{
							IncrementTownLoyalty( ubTownID, Result );
						}
						else
						{
							DecrementTownLoyalty( ubTownID, abs(Result) );
							// Log message
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[23], pTownNames[ubTownID], pSoldier->GetName() );
							else
								swprintf( sString, gzFacilityErrorMessage[24], pTownNames[ubTownID], pSoldier->GetName(), gFacilityTypes[ubFacilityType].szFacilityName );
							ScreenMsg( usColor, MSG_INTERFACE, sString );
							
							// SANDRO - add to merc records - facility accidents counter
							if ( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
						}
						break;
					case RISK_LOYALTY_GLOBAL:
						Result *= GAIN_PTS_PER_LOYALTY_PT; // Transform points into actual loyalty.
						if (Result > 0)
						{
							IncrementTownLoyaltyEverywhere( Result );
						}
						else
						{
							DecrementTownLoyaltyEverywhere( abs(Result) );
							// Log message
							GetShortSectorString( pSoldier->sSectorX, pSoldier->sSectorY, szSectorGrid );
							if (!fOperatingFacility)
								swprintf( sString, gzFacilityErrorMessage[25], pSoldier->GetName(), szSectorGrid );
							else
								swprintf( sString, gzFacilityErrorMessage[26], pSoldier->GetName(), szSectorGrid, gFacilityTypes[ubFacilityType].szFacilityName );
							ScreenMsg( usColor, MSG_INTERFACE, sString );
							
							// SANDRO - add to merc records - facility accidents counter
							if ( Result < 0 )
								gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
						}
						break;
					case RISK_WH40K_IMPERIAL_FAITH:
						{
							if ( gGameSettings.fOptions[TOPTION_WH40K] )
							{
								if (Result > 0)
								{
									pSoldier->AddCorruption(IMPERIAL, Result);
								}
							}
						}
						break;
					default:
						break;
				}
				if (fBadResult)
				{
					StopTimeCompression();
				}
			}
		}
	}
}


RISK_WH40K_IMPERIAL_FAITH is not in the trunk though.


Re: Facility events - a question about "combined skill"[message #319874] Thu, 16 May 2013 22:39 Go to previous messageGo to next message
Durak

 
Messages:58
Registered:April 2010
case RISK_STRENGTH:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.3) + (ubExpLevel * 5));
break;
case RISK_DEXTERITY:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.4) + (ubExpLevel * 6));
break;
case RISK_AGILITY:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubExpLevel * Cool);
break;
case RISK_HEALTH:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.5) + (ubExpLevel * 5));
break;
case RISK_WISDOM:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.6) + (ubExpLevel * 4));
break;
case RISK_MARKSMANSHIP:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.4) + (ubExpLevel * 4));
break;
case RISK_MEDICAL:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubDexterity * 0.4) + (ubExpLevel * 3));
break;
case RISK_MECHANICAL:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubDexterity * 0.5) + (ubExpLevel * 2));
break;
case RISK_LEADERSHIP:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.4) + (ubLeadership * 0.3) + (ubExpLevel * 3));
break;
case RISK_EXPLOSIVES:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubAgility * 0.3) + (ubDexterity * 0.3) + (ubExpLevel * 2));
break;
case RISK_INJURY:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubDexterity * 0.2) + (ubAgility * 0.4) + (ubExpLevel * 2));
break;
case RISK_MORALE:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubLeadership * 0.4) + (ubExpLevel * 4));
break;
case RISK_FATIGUE:
bCombinedStats = (INT16)__min(100, (ubAgility * 0.1) + (ubStrength * 0.3) + (ubHealth * 0.2) + (ubExpLevel * 4));
break;
case RISK_DRUNK:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.5) + (ubHealth * 0.3) + (ubExpLevel * 2));
break;
case RISK_LOYALTY_LOCAL:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.2) + (ubLeadership * 0.3) + (ubStrength * 0.1) + (ubExpLevel * 2) + (ubLocalLoyalty * 0.2) );
break;
case RISK_LOYALTY_GLOBAL:
bCombinedStats = (INT16)__min(100, (ubWisdom * 0.3) + (ubLeadership * 0.3) + (ubExpLevel * 2) + (ubLocalLoyalty * 0.2));
break;







This is probably the thing I was looking for.

Thanks!
Re: Facility events - a question about "combined skill"[message #320031] Sat, 18 May 2013 18:44 Go to previous message
Durak

 
Messages:58
Registered:April 2010
Hi again


if I understand the code correctly (well, it's commented explicitly, isn't it?) the chance to trigger an event is also dependant on skills.


Might I suggest to change this behavior, so the chance to trigger an event is dependant on the xml alone?

The reason I say this is because when modding facilities it's rather hard to tell how frequently events will be triggered by different mercs, even if you know which skills are involved.

In my opinion, it would be more convenient to be able to define a flat chance for an event to occur, and refine its effects (and thereby the chance to trigger it in the first place) by editing the danger/benefits in the xml directly.
That way skills would still have an effect on the chance of an event to have an impact on mercs, but it would be easier to "control" for modders.


For example:

An "injury" occurs every 200 hours - statistically, to every merc, trained or untrained - if its chance is set to 5 in the xml, and the facility danger rate value is left at 1000 (default).
By defining a base effect of -5 and a range of 5, an unskilled merc might receive -10 hit points, while there is a chance for a perfectly trained merc to receive no damage at all - which is equivalent to a reduced chance to "trigger" the event.

To cover the case of a facility which has the potential both to injure and to heal:
A merc assigned to said facility could benefit from injury (means hp increase/healing) by defining a second "Injury" section, with values like "chance=10", "base=1" and "range=1", and the same conception would work:
Every merc has a chance to get healed every 100 hours, but unskilled mercs might not "trigger" the event (because base 1 minus range 1 equals 0 hit points; "range" based effects are directly dependant on combined skills), while a very experienced merc might get 0, 1 or 2 hit points back, with a very small chance for 0 and increased chance for 2).

As far as I have explored the depths of the facility.xmls and its possibilities, the same logic should be applicable to all other event types.


*shuts up*


cheers

[Updated on: Sat, 18 May 2013 21:07] by Moderator

Previous Topic: Facilities - Extra info
Next Topic: Skill cap for skill increase via facility assignment possible?
Goto Forum:
  


Current Time: Sun Mar 26 06:25:56 EEST 2017

Total time taken to generate the page: 0.00850 seconds