- Added slower <bEvolution> rates, growth slowdown will be more pronounced on higher stat values. (3 - 0.75x; 4 - 0.5x; 5 - 0.25x) (by Buggler)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6051 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2013-05-02 17:12:43 +00:00
parent 8fb494ff53
commit e8f8e8ae5b
2 changed files with 134 additions and 122 deletions
+129 -121
View File
@@ -160,23 +160,23 @@ void ProfileStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumChances, UINT8 ubReason) void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumChances, UINT8 ubReason)
{ {
UINT32 uiCnt,uiEffLevel; UINT32 uiCnt,uiEffLevel;
INT16 sSubPointChange = 0; INT16 sSubPointChange = 0;
UINT16 usChance=0; UINT16 usChance=0;
UINT16 usSubpointsPerPoint; UINT16 usSubpointsPerPoint;
UINT16 usSubpointsPerLevel; UINT16 usSubpointsPerLevel;
INT8 bCurrentRating; INT8 bCurrentRating;
UINT16 *psStatGainPtr; UINT16 *psStatGainPtr;
BOOLEAN fAffectedByWisdom = TRUE; BOOLEAN fAffectedByWisdom = TRUE;
Assert(pProfile != NULL); Assert(pProfile != NULL);
if ( pProfile->bEvolution == NO_EVOLUTION ) if ( pProfile->bEvolution == NO_EVOLUTION )
return; // No change possible, quit right away return; // No change possible, quit right away
// if this is a Reverse-Evolving merc who attempting to train // if this is a Reverse-Evolving merc who attempting to train
if ( ( ubReason == FROM_TRAINING ) && ( pProfile->bEvolution == DEVOLVE ) ) if ( ( ubReason == FROM_TRAINING ) && ( pProfile->bEvolution == DEVOLVE ) )
return; // he doesn't get any benefit, but isn't penalized either return; // he doesn't get any benefit, but isn't penalized either
if (usNumChances == 0) if (usNumChances == 0)
return; return;
@@ -185,73 +185,73 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel); usSubpointsPerPoint = SubpointsPerPoint(ubStat, pProfile->bExpLevel);
usSubpointsPerLevel = SubpointsPerPoint(EXPERAMT, pProfile->bExpLevel); usSubpointsPerLevel = SubpointsPerPoint(EXPERAMT, pProfile->bExpLevel);
switch (ubStat) switch (ubStat)
{ {
case HEALTHAMT: case HEALTHAMT:
bCurrentRating = pProfile->bLifeMax; bCurrentRating = pProfile->bLifeMax;
psStatGainPtr = (UINT16 *)&(pProfile->sLifeGain); psStatGainPtr = (UINT16 *)&(pProfile->sLifeGain);
// NB physical stat checks not affected by wisdom, unless training is going on // NB physical stat checks not affected by wisdom, unless training is going on
fAffectedByWisdom = FALSE; fAffectedByWisdom = FALSE;
break; break;
case AGILAMT: case AGILAMT:
bCurrentRating = pProfile->bAgility; bCurrentRating = pProfile->bAgility;
psStatGainPtr = (UINT16 *)&(pProfile->sAgilityGain); psStatGainPtr = (UINT16 *)&(pProfile->sAgilityGain);
fAffectedByWisdom = FALSE; fAffectedByWisdom = FALSE;
break; break;
case DEXTAMT: case DEXTAMT:
bCurrentRating = pProfile->bDexterity; bCurrentRating = pProfile->bDexterity;
psStatGainPtr = (UINT16 *)&(pProfile->sDexterityGain); psStatGainPtr = (UINT16 *)&(pProfile->sDexterityGain);
fAffectedByWisdom = FALSE; fAffectedByWisdom = FALSE;
break; break;
case WISDOMAMT: case WISDOMAMT:
bCurrentRating = pProfile->bWisdom; bCurrentRating = pProfile->bWisdom;
psStatGainPtr = (UINT16 *)&(pProfile->sWisdomGain); psStatGainPtr = (UINT16 *)&(pProfile->sWisdomGain);
break; break;
case MEDICALAMT: case MEDICALAMT:
bCurrentRating = pProfile->bMedical; bCurrentRating = pProfile->bMedical;
psStatGainPtr = (UINT16 *)&(pProfile->sMedicalGain); psStatGainPtr = (UINT16 *)&(pProfile->sMedicalGain);
break; break;
case EXPLODEAMT: case EXPLODEAMT:
bCurrentRating = pProfile->bExplosive; bCurrentRating = pProfile->bExplosive;
psStatGainPtr = (UINT16 *)&(pProfile->sExplosivesGain); psStatGainPtr = (UINT16 *)&(pProfile->sExplosivesGain);
break; break;
case MECHANAMT: case MECHANAMT:
bCurrentRating = pProfile->bMechanical; bCurrentRating = pProfile->bMechanical;
psStatGainPtr = (UINT16 *)&(pProfile->sMechanicGain); psStatGainPtr = (UINT16 *)&(pProfile->sMechanicGain);
break; break;
case MARKAMT: case MARKAMT:
bCurrentRating = pProfile->bMarksmanship; bCurrentRating = pProfile->bMarksmanship;
psStatGainPtr = (UINT16 *)&(pProfile->sMarksmanshipGain); psStatGainPtr = (UINT16 *)&(pProfile->sMarksmanshipGain);
break; break;
case EXPERAMT: case EXPERAMT:
bCurrentRating = pProfile->bExpLevel; bCurrentRating = pProfile->bExpLevel;
psStatGainPtr = (UINT16 *)&(pProfile->sExpLevelGain); psStatGainPtr = (UINT16 *)&(pProfile->sExpLevelGain);
break; break;
case STRAMT: case STRAMT:
bCurrentRating = pProfile->bStrength; bCurrentRating = pProfile->bStrength;
psStatGainPtr = (UINT16 *)&(pProfile->sStrengthGain); psStatGainPtr = (UINT16 *)&(pProfile->sStrengthGain);
fAffectedByWisdom = FALSE; fAffectedByWisdom = FALSE;
break; break;
case LDRAMT: case LDRAMT:
bCurrentRating = pProfile->bLeadership; bCurrentRating = pProfile->bLeadership;
psStatGainPtr = (UINT16 *)&(pProfile->sLeadershipGain); psStatGainPtr = (UINT16 *)&(pProfile->sLeadershipGain);
break; break;
default: default:
// BETA message // BETA message
ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"ERROR: ProcessStatChange: Rcvd unknown ubStat %d", ubStat); ScreenMsg( FONT_ORANGE, MSG_BETAVERSION, L"ERROR: ProcessStatChange: Rcvd unknown ubStat %d", ubStat);
return; return;
} }
if (ubReason == FROM_TRAINING) if (ubReason == FROM_TRAINING)
@@ -268,11 +268,11 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
} }
// loop once for each chance to improve // loop once for each chance to improve
for (uiCnt = 0; uiCnt < usNumChances; uiCnt++) for (uiCnt = 0; uiCnt < usNumChances; uiCnt++)
{ {
if (pProfile->bEvolution == NORMAL_EVOLUTION) // Evolves! if (pProfile->bEvolution != DEVOLVE) // Evolves!
{ {
// if this is improving from a failure, and a successful roll would give us enough to go up a point // if this is improving from a failure, and a successful roll would give us enough to go up a point
if ((ubReason == FROM_FAILURE) && ((*psStatGainPtr + 1) >= usSubpointsPerPoint)) if ((ubReason == FROM_FAILURE) && ((*psStatGainPtr + 1) >= usSubpointsPerPoint))
{ {
@@ -280,7 +280,7 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
break; break;
} }
if (ubStat != EXPERAMT) if (ubStat != EXPERAMT)
{ {
// NON-experience level changes, actual usChance depends on bCurrentRating // NON-experience level changes, actual usChance depends on bCurrentRating
// Base usChance is '100 - bCurrentRating' // Base usChance is '100 - bCurrentRating'
@@ -292,62 +292,70 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
usChance = 0; usChance = 0;
} }
} }
else else
{ {
// Experience level changes, actual usChance depends on level // Experience level changes, actual usChance depends on level
// Base usChance is '100 - (10 * current level)' // Base usChance is '100 - (10 * current level)'
usChance = 100 - 10 * (bCurrentRating + (*psStatGainPtr / usSubpointsPerPoint)); usChance = 100 - 10 * (bCurrentRating + (*psStatGainPtr / usSubpointsPerPoint));
} }
// if there IS a usChance, adjust it for high or low wisdom (50 is avg) // if there IS a usChance, adjust it for high or low wisdom (50 is avg)
if (usChance > 0 && fAffectedByWisdom) if (usChance > 0 && fAffectedByWisdom)
{ {
usChance += (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile->bExpLevel)) - 50)) / 100; usChance += (usChance * (pProfile->bWisdom + (pProfile->sWisdomGain / SubpointsPerPoint(WISDOMAMT, pProfile->bExpLevel)) - 50)) / 100;
} }
/* /*
// if the stat is Marksmanship, and the guy is a hopeless shot // if the stat is Marksmanship, and the guy is a hopeless shot
if ((ubStat == MARKAMT) && (pProfile->bSpecialTrait == HOPELESS_SHOT)) if ((ubStat == MARKAMT) && (pProfile->bSpecialTrait == HOPELESS_SHOT))
{ {
usChance /= 5; // MUCH slower to improve, divide usChance by 5 usChance /= 5; // MUCH slower to improve, divide usChance by 5
} }
*/ */
// SANDRO - penalty for primitive people, they get lesser chance to gain point for certain skills // SANDRO - penalty for primitive people, they get lesser chance to gain point for certain skills
if ( gGameOptions.fNewTraitSystem && (usChance > 10) && (ubStat != EXPERAMT) && (pProfile->bCharacterTrait == CHAR_TRAIT_PRIMITIVE) ) if ( gGameOptions.fNewTraitSystem && (usChance > 10) && (ubStat != EXPERAMT) && (pProfile->bCharacterTrait == CHAR_TRAIT_PRIMITIVE) )
{
switch (ubStat)
{ {
case WISDOMAMT: switch (ubStat)
case MEDICALAMT: {
case EXPLODEAMT: case WISDOMAMT:
case MECHANAMT: case MEDICALAMT:
case LDRAMT: case EXPLODEAMT:
usChance = max(1, (usChance - 10)); // -10% chance to gain the point case MECHANAMT:
break; case LDRAMT:
} usChance = max(1, (usChance - 10)); // -10% chance to gain the point
} break;
}
// maximum possible usChance is 99%
if (usChance > 99)
{
usChance = 99;
} }
if (PreRandom(100) < usChance ) // Buggler: more evolution rate choices
{ if (pProfile->bEvolution == THREEQUARTER_EVOLUTION)
(*psStatGainPtr)++; usChance = max(1, usChance * 0.75);
else if (pProfile->bEvolution == HALF_EVOLUTION)
usChance = max(1, usChance * 0.5);
else if (pProfile->bEvolution == ONEQUARTER_EVOLUTION)
usChance = max(1, usChance * 0.25);
// maximum possible usChance is 99%
if (usChance > 99)
{
usChance = 99;
}
if (PreRandom(100) < usChance )
{
(*psStatGainPtr)++;
sSubPointChange++; sSubPointChange++;
// as long as we're not dealing with exp_level changes (already added above!) // as long as we're not dealing with exp_level changes (already added above!)
// and it's not from training, and the exp level isn't max'ed out already // and it's not from training, and the exp level isn't max'ed out already
if ((ubStat != EXPERAMT) && (ubReason != FROM_TRAINING)) if ((ubStat != EXPERAMT) && (ubReason != FROM_TRAINING))
{ {
uiEffLevel = pProfile->bExpLevel + (pProfile->sExpLevelGain / usSubpointsPerLevel); uiEffLevel = pProfile->bExpLevel + (pProfile->sExpLevelGain / usSubpointsPerLevel);
// if level is not at maximum // if level is not at maximum
if (uiEffLevel < MAXEXPLEVEL) if (uiEffLevel < MAXEXPLEVEL)
{ {
// if this is NOT improving from a failure, OR it would NOT give us enough to go up a level // if this is NOT improving from a failure, OR it would NOT give us enough to go up a level
if ((ubReason != FROM_FAILURE) || ((pProfile->sExpLevelGain + 1) < usSubpointsPerLevel)) if ((ubReason != FROM_FAILURE) || ((pProfile->sExpLevelGain + 1) < usSubpointsPerLevel))
@@ -357,14 +365,14 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
} }
} }
} }
} }
} }
else // Regresses! else // Regresses!
{ {
// regression can happen from both failures and successes (but not training, checked above) // regression can happen from both failures and successes (but not training, checked above)
if (ubStat != EXPERAMT) if (ubStat != EXPERAMT)
{ {
// NON-experience level changes, actual usChance depends on bCurrentRating // NON-experience level changes, actual usChance depends on bCurrentRating
switch (ubStat) switch (ubStat)
{ {
@@ -386,8 +394,8 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
usChance = bCurrentRating + (*psStatGainPtr / usSubpointsPerPoint); usChance = bCurrentRating + (*psStatGainPtr / usSubpointsPerPoint);
break; break;
} }
} }
else else
{ {
// Experience level changes, actual usChance depends on level // Experience level changes, actual usChance depends on level
// Base usChance is '10 * (current level - 1)' // Base usChance is '10 * (current level - 1)'
@@ -404,32 +412,32 @@ void ProcessStatChange(MERCPROFILESTRUCT *pProfile, UINT8 ubStat, UINT16 usNumCh
{ {
usChance = 1; usChance = 1;
} }
} }
if (usChance <= 0) if (usChance <= 0)
usChance = 1; usChance = 1;
if (PreRandom(100) < usChance ) if (PreRandom(100) < usChance )
{ {
(*psStatGainPtr)--; (*psStatGainPtr)--;
sSubPointChange--; sSubPointChange--;
// as long as we're not dealing with exp_level changes (already added above!) // as long as we're not dealing with exp_level changes (already added above!)
// and it's not from training, and the exp level isn't max'ed out already // and it's not from training, and the exp level isn't max'ed out already
if ((ubStat != EXPERAMT) && (ubReason != FROM_TRAINING)) if ((ubStat != EXPERAMT) && (ubReason != FROM_TRAINING))
{ {
uiEffLevel = pProfile->bExpLevel + (pProfile->sExpLevelGain / usSubpointsPerLevel ); uiEffLevel = pProfile->bExpLevel + (pProfile->sExpLevelGain / usSubpointsPerLevel );
// if level is not at minimum // if level is not at minimum
if (uiEffLevel > 1) if (uiEffLevel > 1)
{ {
// all other stat changes count towards experience level changes (1 for 1 basis) // all other stat changes count towards experience level changes (1 for 1 basis)
pProfile->sExpLevelGain--; pProfile->sExpLevelGain--;
} }
} }
} }
} }
} }
#ifdef STAT_CHANGE_DEBUG #ifdef STAT_CHANGE_DEBUG
if (sSubPointChange != 0) if (sSubPointChange != 0)
+5 -1
View File
@@ -256,10 +256,14 @@ typedef enum
// training defines for evolution, no stat increase, stat decrease( de-evolve ) // training defines for evolution, no stat increase, stat decrease( de-evolve )
typedef enum{ typedef enum
{
NORMAL_EVOLUTION =0, NORMAL_EVOLUTION =0,
NO_EVOLUTION, NO_EVOLUTION,
DEVOLVE, DEVOLVE,
THREEQUARTER_EVOLUTION,
HALF_EVOLUTION,
ONEQUARTER_EVOLUTION,
} CharacterEvolution; } CharacterEvolution;
#define BUDDY_MERC( prof, bud ) ((prof)->bBuddy[0] == (bud) || (prof)->bBuddy[1] == (bud) || (prof)->bBuddy[2] == (bud) ) #define BUDDY_MERC( prof, bud ) ((prof)->bBuddy[0] == (bud) || (prof)->bBuddy[1] == (bud) || (prof)->bBuddy[2] == (bud) )