Home » PLAYER'S HQ 1.13 » JA2 Complete Mods & Sequels » JA2 Wildfire » Stealthy, Night Ops and mathematics
Stealthy, Night Ops and mathematics[message #330310]
|
Tue, 04 February 2014 17:51
|
|
tigerpunch |
|
Messages:8
Registered:May 2012 |
|
|
Hi there,
I've built my IMP to have stealthy and night ops skills. In my previous game, my IMP had 87 agility and it had night ops/stealthy combination as well (now it has 90 agility).
The problem is, my previous IMP had no problems with running/crawling with the stealth mode. But this character prduces sound when running or crawling with the stealth mde (I mean not always but it still does)
To clarify the test, I've picked Magic the guy with 98 agility and stealth skill slipped over the ground with abslutely no sound...
The questions are: Are there any formulations for us to calculate and observe the effects of skills such as teaching, knifing, night ops and stealth etc since the effects I read are null and meaningless (I mean what does +25 stealth benefit? Or what is the penalty for wielding 2 weapons and how does ambidexter skill and ambidexter (expert) skill let us overcome those hardships) also I 'd like to see some formulas to calculate the total values of those skills.
Also as a night attacker I want to know all combinations with details such as night ops/stealth, stealth (expert), night ops (expert)
Report message to a moderator
|
Private
|
|
|
Re: Stealthy, Night Ops and mathematics[message #330324]
|
Tue, 04 February 2014 21:36
|
|
Flugente |
|
Messages:3507
Registered:April 2009 Location: Germany |
|
|
That is a question that isn't easy to answer. While the formulas involve no complicated functions, they are long, and I'm currently not in the mood to explain them entirely, you'll see why in a moment
This is actually a problem in most games with stats - if you really want to know the exact effect of a stat, the answer becomes very complicated. I fondly remember Diablo 2, where %LifeLeech was influenced, among others, by damage, global physical resistance, individual physical resistance, crushing blow/critical hit, global lifeleech penalties and numerous other stuff.
This are the two relevant functions for stealth:
#define MAX_MOVEMENT_NOISE 9
UINT8 MovementNoise( SOLDIERTYPE *pSoldier )
{
INT32 iStealthSkill, iRoll;
UINT8 ubMaxVolume, ubVolume, ubBandaged, ubEffLife;
INT8 bInWater = FALSE;
if ( pSoldier->bTeam == ENEMY_TEAM )
{
return( (UINT8) (MAX_MOVEMENT_NOISE - PreRandom( 2 )) );
}
// CHANGED BY SANDRO - LET'S MAKE THE STEALTH BASED ON AGILITY LIKE IT SHOULD BE
//iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveDexterity( pSoldier ) * 4) / 10); // 24-100
iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveAgility( pSoldier, FALSE ) * 4) / 10); // 24-100
// big bonus for those "extra stealthy" mercs
if ( pSoldier->ubBodyType == BLOODCAT )
{
iStealthSkill += 50;
}
// SANDRO - new/old traits
else if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT ))
{
iStealthSkill += gSkillTraitValues.ubSTBonusToMoveQuietly;
}
else if ( !gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_OT ))
{
iStealthSkill += 25 * NUM_SKILL_TRAITS( pSoldier, STEALTHY_OT );
}
INT16 wornstealth = GetWornStealth(pSoldier);
if ( wornstealth > 0 )
iStealthSkill += wornstealth / 2;
//NumMessage("Base Stealth = ",stealthSkill);
ubBandaged = pSoldier->stats.bLifeMax - pSoldier->stats.bLife - pSoldier->bBleeding;
ubEffLife = pSoldier->stats.bLife + (ubBandaged / 2);
// IF "SNEAKER'S" "EFFECTIVE LIFE" IS AT LESS THAN 50
if (ubEffLife < 50)
{
// reduce effective stealth skill by up to 50% for low life
iStealthSkill -= (iStealthSkill * (50 - ubEffLife)) / 100;
}
// if breath is below 50%
if (pSoldier->bBreath < 50)
{
// reduce effective stealth skill by up to 50%
iStealthSkill -= (iStealthSkill * (50 - pSoldier->bBreath)) / 100;
}
// if sneaker is moving through water
if (Water( pSoldier->sGridNo ) )
{
iStealthSkill -= 10; // 10% penalty
}
else if (DeepWater( pSoldier->sGridNo ) )
{
iStealthSkill -= 20; // 20% penalty
}
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// minus 3 percent per bonus AP from adrenaline
iStealthSkill -= 3 * pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ];
}
/*
// if sneaker is too eager and impatient to "do it right"
if ((pSoldier->bTrait == OVER_ENTHUS) || (pSoldier->aiData.bAttitude == AGGRESSIVE))
{
ubStealthSkill -= 10; // 10% penalty
}
*/
//NumMessage("Modified Stealth = ",stealthSkill);
iStealthSkill = __max( iStealthSkill, 0 );
if (!pSoldier->bStealthMode) // REGULAR movement
{
ubMaxVolume = MAX_MOVEMENT_NOISE - (iStealthSkill / 16); // 9 - (0 to 6) => 3 to 9
if (bInWater)
{
ubMaxVolume++; // in water, can be even louder
}
switch (pSoldier->usAnimState)
{
case CRAWLING:
ubMaxVolume -= 2;
break;
case SWATTING:
ubMaxVolume -= 1;
break;
case RUNNING:
ubMaxVolume += 3;
break;
}
if (ubMaxVolume < 2)
{
ubVolume = ubMaxVolume;
}
else
{
ubVolume = 1 + (UINT8) PreRandom(ubMaxVolume); // actual volume is 1 to max volume
}
}
else // in STEALTH mode
{
iRoll = (INT32) PreRandom(100); // roll them bones!
if (iRoll >= iStealthSkill) // v1.13 modification: give a second chance!
{
iRoll = (INT32) PreRandom(100);
}
if (iRoll < iStealthSkill)
{
ubVolume = 0; // made it, stayed quiet moving through this tile
}
else // OOPS!
{
ubVolume = 1 + ((iRoll - iStealthSkill + 1) / 16); // volume is 1 - 7 ...
switch (pSoldier->usAnimState)
{
case CRAWLING:
ubVolume -= 2;
break;
case SWATTING:
ubVolume -= 1;
break;
case RUNNING:
ubVolume += 3;
break;
}
if (ubVolume < 1)
{
ubVolume = 0;
}
// randomize at which movement step the sneaking failure will happen
// Status.stepsTilNoise = Random(MAXMOVESTEPS); // 0 - 6
}
}
//NumMessage("Volume = ",volume);
// save noise volume where stepped HandleSteppedLook can back get at it later
// Status.moveNoiseVolume = ubVolume;
return( ubVolume );
}
...
INT16 GetWornStealth( SOLDIERTYPE * pSoldier )
{
//note: Stealth bonus is capped at 100
//note: Stealth is not a perk! Stealth bonus only applies to equipment, and stacks with camouflage
//note: stealth bonus is not affected by terrain like the camo bonus, otherwise they're very similar
//note: stealth bonus also affects noise made by characters walking
INT8 bLoop;
INT16 ttl=0;
for (bLoop = HELMETPOS; bLoop <= LEGPOS; ++bLoop)
{
if ( pSoldier->inv[bLoop].exists() == true )
ttl += GetStealthBonus(&pSoldier->inv[bLoop]);
}
// Add some default stealth ability to mercs with STEALTHY trait - SANDRO
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT ))
ttl += gSkillTraitValues.ubSTStealthBonus;
ttl += pSoldier->GetBackgroundValue(BG_PERC_STEALTH);
return __min( ttl, 100 );
}
The Night ops stuff is pretty easy to understand (you are looking at the values in Skills_Settings.ini, are you?) - You see better, hear better, interrupt better. Here's the stuff for interrupts:
INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN fUseWatchSpots )
{
INT32 iPoints;
INT8 bLightLevel;
UINT8 ubDistance;
DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"CalcInterruptDuelPts");
// extra check to make sure neutral folks never get interrupts
if (pSoldier->aiData.bNeutral)
{
return( NO_INTERRUPT );
}
// Old: BASE is one point for each experience level.
// Snap: Agility should be a factor, since it is a measure of
// a person's reactions. We'll give more weight to experience
// though, since combat initiative is too important to be left up
// to an ordinary skill like agility.
// BASE = (2*lev + agi/10) / 3
// Robot has interrupt points based on the controller...
// Controller's interrupt points are reduced by 2 for being distracted...
if ( pSoldier->flags.uiStatusFlags & SOLDIER_ROBOT && pSoldier->CanRobotBeControlled( ) )
{
//iPoints = EffectiveExpLevel( MercPtrs[ pSoldier->ubRobotRemoteHolderID ] ) - 2;
// Snap: (do some proper rounding here)
iPoints = ( 20*EffectiveExpLevel( MercPtrs[ pSoldier->ubRobotRemoteHolderID ] )
+ EffectiveAgility( MercPtrs[ pSoldier->ubRobotRemoteHolderID ], FALSE ) + 15 ) / 30 - 2;
}
else
{
//iPoints = EffectiveExpLevel( pSoldier );
// Snap:
iPoints = ( 20*EffectiveExpLevel( pSoldier ) + EffectiveAgility( pSoldier, FALSE ) + 15 ) / 30;
/*
if ( pSoldier->bTeam == ENEMY_TEAM )
{
// modify by the difficulty level setting
iPoints += gbDiff[ DIFF_ENEMY_INTERRUPT_MOD ][ SoldierDifficultyLevel( pSoldier ) ];
iPoints = __max( iPoints, 9 );
}
*/
if ( pSoldier->ControllingRobot( ) )
{
iPoints -= 2;
}
}
if (fUseWatchSpots)
{
// if this is a previously noted spot of enemies, give bonus points!
iPoints += GetWatchedLocPoints( pSoldier->ubID, MercPtrs[ ubOpponentID ]->sGridNo, MercPtrs[ ubOpponentID ]->pathing.bLevel );
}
// LOSE one point for each 2 additional opponents he currently sees, above 2
if (pSoldier->aiData.bOppCnt > 2)
{
// subtract 1 here so there is a penalty of 1 for seeing 3 enemies
iPoints -= (pSoldier->aiData.bOppCnt - 1) / 2;
}
// LOSE one point if he's trying to interrupt only by hearing
if (pSoldier->aiData.bOppList[ubOpponentID] == HEARD_THIS_TURN)
{
iPoints--;
}
//hayden, multiplayer add advantage for a ready'd reapon
if(is_networked)
{
if ( ( gAnimControl[ pSoldier->usAnimState ].uiFlags &( ANIM_FIREREADY | ANIM_FIRE ) ))
{
iPoints=(iPoints + cWeaponReadyBonus);
}
}
// if soldier is still in shock from recent injuries, that penalizes him
iPoints -= pSoldier->aiData.bShock;
ubDistance = (UINT8) PythSpacesAway( pSoldier->sGridNo, MercPtrs[ ubOpponentID ]->sGridNo );
// if we are in combat mode - thus doing an interrupt rather than determine who gets first turn -
// then give bonus
if ( (gTacticalStatus.uiFlags & INCOMBAT) && (pSoldier->bTeam != gTacticalStatus.ubCurrentTeam) )
{
// passive player gets penalty due to range
iPoints -= (ubDistance / 10);
}
else
{
// either non-combat or the player with the current turn... i.e. active...
// unfortunately we can't use opplist here to record whether or not we saw this guy before, because at this point
// the opplist has been updated to seen. But we can use gbSeenOpponents ...
// this soldier is moving, so give them a bonus for crawling or swatting at long distances
if ( !gbSeenOpponents[ ubOpponentID ][ pSoldier->ubID ] )
{
if (pSoldier->usAnimState == SWATTING && ubDistance > (MaxNormalDistanceVisible() / 2) ) // more than 1/2 sight distance
{
iPoints++;
}
else if (pSoldier->usAnimState == CRAWLING && ubDistance > (MaxNormalDistanceVisible() / 4) ) // more than 1/4 sight distance
{
iPoints += ubDistance / STRAIGHT;
}
}
}
// whether active or not, penalize people who are running
if ( pSoldier->usAnimState == RUNNING && !gbSeenOpponents[ pSoldier->ubID ][ ubOpponentID ] )
{
iPoints -= 2;
}
if (pSoldier->ubServicePartner != NOBODY)
{
// distracted by being bandaged/doing bandaging
iPoints -= 2;
}
if (gGameOptions.fNewTraitSystem) // new/old traits check - SANDRO
{
if ( HAS_SKILL_TRAIT( pSoldier, NIGHT_OPS_NT ) )
{
bLightLevel = LightTrueLevel(pSoldier->sGridNo, pSoldier->pathing.bLevel);
if (bLightLevel > NORMAL_LIGHTLEVEL_DAY + 3)
{
// it's dark, give a bonus for interrupts
iPoints += gSkillTraitValues.ubNOIterruptsBonusInDark;
}
}
// Phlegmatics get a small penalty to interrupts
if ( gMercProfiles[ pSoldier->ubProfile ].bCharacterTrait == CHAR_TRAIT_PHLEGMATIC )
{
iPoints -= 1;
}
}
else
{
if ( HAS_SKILL_TRAIT( pSoldier, NIGHTOPS_OT ) )
{
bLightLevel = LightTrueLevel(pSoldier->sGridNo, pSoldier->pathing.bLevel);
if (bLightLevel > NORMAL_LIGHTLEVEL_DAY + 3)
{
// it's dark, give a bonus for interrupts
iPoints += 1 * NUM_SKILL_TRAITS( pSoldier, NIGHTOPS_OT );
}
}
}
// Flugente: interrupt modifier from special stats
iPoints += pSoldier->GetInterruptModifier( ubDistance );
// if he's a computer soldier
// CJC note: this will affect friendly AI as well...
if ( pSoldier->flags.uiStatusFlags & SOLDIER_PC )
{
if ( pSoldier->bAssignment >= ON_DUTY )
{
// make sure don't get interrupts!
iPoints = -10;
}
// GAIN one point if he's previously seen the opponent
// check for TRUE because -1 means we JUST saw him (always so here)
if (gbSeenOpponents[pSoldier->ubID][ubOpponentID] == TRUE)
{
iPoints++; // seen him before, easier to react to him
}
}
else if ( pSoldier->bTeam == ENEMY_TEAM )
{
// GAIN one point if he's previously seen the opponent
// check for TRUE because -1 means we JUST saw him (always so here)
if (gbSeenOpponents[pSoldier->ubID][ubOpponentID] == TRUE)
{
iPoints++; // seen him before, easier to react to him
}
else if (gbPublicOpplist[pSoldier->bTeam][ubOpponentID] != NOT_HEARD_OR_SEEN)
{
// GAIN one point if opponent has been recently radioed in by his team
iPoints++;
}
}
if ( TANK( pSoldier ) )
{
// reduce interrupt possibilities for tanks!
iPoints /= 2;
}
if (iPoints >= AUTOMATIC_INTERRUPT)
{
#ifdef BETAVERSION
NumMessage("CalcInterruptDuelPts: ERROR - Invalid bInterruptDuelPts calculated for soldier ",pSoldier->guynum);
#endif
iPoints = AUTOMATIC_INTERRUPT - 1; // hack it to one less than max so its legal
}
#ifdef DEBUG_INTERRUPTS
DebugMsg( TOPIC_JA2INTERRUPT, DBG_LEVEL_3, String("Calculating int pts for %d vs %d, number is %d", pSoldier->ubID, ubOpponentID, iPoints ) );
#endif
if(is_networked)
{
SOLDIERTYPE *pOpp = &Menptr[ubOpponentID];
#ifdef JA2BETAVERSION
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_MPSYSTEM, L"Interrupt: '%s' vs '%s' = %d points.",pSoldier->name,pOpp->name, iPoints );
#endif
}
DebugMsg (TOPIC_JA2INTERRUPT,DBG_LEVEL_3,"CalcInterruptDuelPts done");
return( (INT8)iPoints );
}
TL;DR: If you really want to know it exactly, read the code
Report message to a moderator
|
|
|
|
|
Re: Stealthy, Night Ops and mathematics[message #330335]
|
Wed, 05 February 2014 01:51
|
|
Flugente |
|
Messages:3507
Registered:April 2009 Location: Germany |
|
|
Read the code. Dexterity isn't relevant to stealth anymore, it's agility:
iStealthSkill = 20 + 4 * EffectiveExpLevel( pSoldier ) + ((EffectiveAgility( pSoldier, FALSE ) * 4) / 10); // 24-100
The highest value you can achieve here is 100 with a lvl 10 merc with 100 AGI, not taking into account squadleader boni, drugs and backgrounds. The stealth boni come later in that formula.
That wiki is, to say it politely, inaccurate and should be taken only as a very broad generalisation.
tigerpunch(DEX / 2) + (LVL * 5) and my Wildfire is probably a retail version v6.04 which I couldnt find the file you proposed Dex is irrelevant, and... eh... what?
Stealth does not hide you visually. Camouflage does that.
Read the Skills_Settings.ini, and read the code bit I've quoted. In most cases, the expert level of traits simply gives 2 times the normal level of boni. It would also be helpful to know wether you play with old or new traits - for example, Night Ops and Stealth only have one level in the new Trait system.
Report message to a moderator
|
|
|
|
|
Re: Stealthy, Night Ops and mathematics[message #362146 is a reply to message #330378]
|
Thu, 31 December 2020 07:23
|
|
Bullpup |
|
Messages:42
Registered:December 2020 |
|
|
If Stealth is capped at 100 and you can get that with lvl 10 Agi 100 merc, does that mean that the Stealth perk or the Spotter/Stalker backgrounds get less usefull in late game?
Edit: I just noticed this is Wildfire thread, I was asking for 8914 1.13.
[Updated on: Thu, 31 December 2020 07:26] Report message to a moderator
|
Corporal
|
|
|
Goto Forum:
Current Time: Mon Jan 13 19:45:15 GMT+2 2025
Total time taken to generate the page: 0.00870 seconds
|