************************************************************

* Merged Source Code from Development Trunk: Revision 4063 *
************************************************************
- Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- This will be the Source for the Beta 2011 Test

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2011-01-18 09:11:09 +00:00
parent 44e1646410
commit 91087ca8c0
469 changed files with 118108 additions and 24678 deletions
+1305 -310
View File
File diff suppressed because it is too large Load Diff
+44 -39
View File
@@ -28,45 +28,47 @@
// Assignments Defines
enum{
SQUAD_1 =0,
SQUAD_2,
SQUAD_3,
SQUAD_4,
SQUAD_5,
SQUAD_6,
SQUAD_7,
SQUAD_8,
SQUAD_9,
SQUAD_10,
SQUAD_11,
SQUAD_12,
SQUAD_13,
SQUAD_14,
SQUAD_15,
SQUAD_16,
SQUAD_17,
SQUAD_18,
SQUAD_19,
SQUAD_20,
ON_DUTY,
DOCTOR,
PATIENT,
VEHICLE,
IN_TRANSIT,
REPAIR,
TRAIN_SELF,
TRAIN_TOWN,
TRAIN_MOBILE, // HEADROCK HAM 3.6: Training mobile militia.
TRAIN_TEAMMATE,
TRAIN_BY_OTHER,
FACILITY_STAFF, // HEADROCK HAM 3.6: Operating a facility for strategic gain.
FACILITY_REST, // HEADROCK HAM 3.6: Facility equivalent of resting (no assignment)
ASSIGNMENT_DEAD,
ASSIGNMENT_UNCONCIOUS, // unused
ASSIGNMENT_POW,
ASSIGNMENT_HOSPITAL,
ASSIGNMENT_EMPTY,
enum
{
SQUAD_1 = 0,
SQUAD_2,
SQUAD_3,
SQUAD_4,
SQUAD_5,
SQUAD_6,
SQUAD_7,
SQUAD_8,
SQUAD_9,
SQUAD_10,
SQUAD_11,
SQUAD_12,
SQUAD_13,
SQUAD_14,
SQUAD_15,
SQUAD_16,
SQUAD_17,
SQUAD_18,
SQUAD_19,
SQUAD_20,
ON_DUTY,
DOCTOR,
PATIENT,
VEHICLE,
IN_TRANSIT,
REPAIR,
TRAIN_SELF,
TRAIN_TOWN,
TRAIN_MOBILE, // HEADROCK HAM 3.6: Training mobile militia.
TRAIN_TEAMMATE,
TRAIN_BY_OTHER,
FACILITY_STAFF, // HEADROCK HAM 3.6: Operating a facility for strategic gain.
FACILITY_REST, // HEADROCK HAM 3.6: Facility equivalent of resting (no assignment)
ASSIGNMENT_DEAD,
ASSIGNMENT_UNCONCIOUS, // unused
ASSIGNMENT_POW,
ASSIGNMENT_HOSPITAL,
ASSIGNMENT_EMPTY,
NUM_ASSIGNMENTS,
};
#define NO_ASSIGNMENT 127 //used when no pSoldier->ubDesiredSquad
@@ -370,6 +372,9 @@ extern INT8 gubFacilityInSubmenu;
extern UINT8 gubFacilityLineForSubmenu;
extern SOLDIERTYPE *gpFacilityStaffer;
// SANDRO - function to award record points for militia training
void RecordNumMilitiaTrainedForMercs( INT16 sX, INT16 sY, INT8 sZ, UINT8 ubMilitiaTrained, BOOLEAN fMobile );
#endif
+455 -38
View File
@@ -67,6 +67,7 @@
#include "MilitiaSquads.h"
// #include "Strategic AI.h"
#include "interface Dialogue.h"
#include "AIInternals.h" // added by SANDRO
#endif
#include "Reinforcement.h"
@@ -727,6 +728,7 @@ void RefreshMerc( SOLDIERTYPE *pSoldier )
{
pSoldier->stats.bLife = pSoldier->stats.bLifeMax;
pSoldier->bBleeding = 0;
pSoldier->iHealableInjury = 0; // added by SANDRO
pSoldier->bBreath = pSoldier->bBreathMax = 100;
pSoldier->sBreathRed = 0;
if( gpAR->pRobotCell)
@@ -1381,21 +1383,41 @@ void ExpandWindow()
}
UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus )
//////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - This whole procedure was merged with the surgery ability of the doctor trait
UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus, BOOLEAN fOnSurgery )
{
UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs;
UINT8 bBelowOKlife, bPtsLeft;
INT8 bInitialBleeding;
if( pVictim->bBleeding < 1 )
if( pVictim->bBleeding < 1 && !fOnSurgery )
return 0; // nothing to do, shouldn't have even been called!
if ( pVictim->stats.bLife == 0 )
return 0;
if (fOnSurgery && pVictim->ubID == pSoldier->ubID) // cannot make surgery on self
return 0;
// calculate wound-dressing skill (3x medical, 2x equip,1x level, 1x dex)
uiDressSkill = ( ( 3 * EffectiveMedical( pSoldier ) ) + // medical knowledge
( 2 * sStatus) + // state of medical kit
(10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience
EffectiveDexterity( pSoldier ) ) / 7; // general "handiness"
bInitialBleeding = pVictim->bBleeding;
if ( !gGameOptions.fNewTraitSystem && fOnSurgery) // cannot make surgery if not new traits
fOnSurgery = FALSE;
// calculate wound-dressing skill (3x medical, 2x equip, 1x level, 1x dex)
if ( gGameOptions.fNewTraitSystem )
{
uiDressSkill = ( ( 7 * EffectiveMedical( pSoldier ) ) + // medical knowledge
( sStatus) + // state of medical kit
(10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience
EffectiveDexterity( pSoldier ) ) / 10; // general "handiness"
}
else
{
uiDressSkill = ( ( 3 * EffectiveMedical( pSoldier ) ) + // medical knowledge
( 2 * sStatus) + // state of medical kit
(10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience
EffectiveDexterity( pSoldier ) ) / 7; // general "handiness"
}
// try to use every AP that the merc has left
uiAvailAPs = pSoldier->bActionPoints;
@@ -1413,9 +1435,16 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
if (!uiPossible)
return 0;
if (Item[pSoldier->inv[0].usItem].medicalkit ) // using the GOOD medic stuff
if (Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
uiPossible += ( uiPossible / 2); // add extra 50 %
// Doctor trait improves basic bandaging ability
if (!(fOnSurgery) && gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT ))
{
uiPossible = uiPossible * (100 - gSkillTraitValues.bSpeedModifierBandaging) / 100;
uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) / 100);
}
uiActual = uiPossible; // start by assuming maximum possible
// figure out how far below OKLIFE the victim is
@@ -1432,7 +1461,11 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
{ // then add how many healing pts we need to stop bleeding (1x cost)
uiDeficiency += ( pVictim->bBleeding - bBelowOKlife );
}
// On surgery, alter this by amount of life we can heal
if ( fOnSurgery )
{
uiDeficiency += (pVictim->iHealableInjury / 100);
}
// now, make sure we weren't going to give too much
if ( uiActual > uiDeficiency) // if we were about to apply too much
uiActual = uiDeficiency; // reduce actual not to waste anything
@@ -1440,13 +1473,20 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
// now make sure we HAVE that much
if( Item[pKit->usItem].medicalkit )
{
uiMedcost = uiActual / 2; // cost is only half
if (fOnSurgery)
uiMedcost = (uiActual * gSkillTraitValues.usDOSurgeryMedBagConsumption ) /100; // surgery drains the kit a lot
else
uiMedcost = (uiActual + 1) / 2; // cost is only half, rounded up
if ( uiMedcost == 0 && uiActual > 0)
uiMedcost = 1;
if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this
if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this
{
uiMedcost = sKitPts; // what CAN we afford?
uiActual = uiMedcost * 2; // give double this as aid
if (fOnSurgery) // surgery check
uiActual = (uiMedcost * 100 )/ gSkillTraitValues.usDOSurgeryMedBagConsumption;
else
uiActual = uiMedcost * 2; // give double this as aid
}
}
else
@@ -1466,7 +1506,15 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
{
// if we have enough points to bring him all the way to OKLIFE this turn
if ( bPtsLeft >= (2 * bBelowOKlife ) )
{ // raise life to OKLIFE
{
// insta-healable injury check
if (pVictim->iHealableInjury > 0)
{
pVictim->iHealableInjury -= ((OKLIFE - pVictim->stats.bLife) * 100);
if (pVictim->iHealableInjury < 0)
pVictim->iHealableInjury = 0;
}
// raise life to OKLIFE
pVictim->stats.bLife = OKLIFE;
// reduce bleeding by the same number of life points healed up
pVictim->bBleeding -= bBelowOKlife;
@@ -1475,6 +1523,13 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
}
else
{
// insta-healable injury check
if (pVictim->iHealableInjury > 0)
{
pVictim->iHealableInjury -= (( bPtsLeft / 2) * 100);
if (pVictim->iHealableInjury < 0)
pVictim->iHealableInjury = 0;
}
pVictim->stats.bLife += ( bPtsLeft / 2);
pVictim->bBleeding -= ( bPtsLeft / 2);
bPtsLeft = bPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1
@@ -1496,6 +1551,99 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
}
}
// SURGERY
// first return the real life back, then bandage the rest if possible
if (fOnSurgery && gGameOptions.fNewTraitSystem) // double check for new traits
{
INT32 iLifeReturned = 0;
UINT16 usReturnDamagedStatRate = 0;
// find out if we will repair any stats...
if ( NumberOfDamagedStats( pVictim ) > 0 )
{
usReturnDamagedStatRate = ((gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )));
usReturnDamagedStatRate -= max( 0, ((usReturnDamagedStatRate * gSkillTraitValues.ubDORepStPenaltyIfAlsoHealing ) / 100));
// ... in which case, reduce the points
bPtsLeft = max(0, ((bPtsLeft * ( 100 - gSkillTraitValues.ubDOHealingPenaltyIfAlsoStatRepair )) / 100));
}
// Important note! : HealableInjury is always stores the total HPs the victim is missing, not the amount which we will heal,
// so we always take a portion of patient's damage here, reduce the HealableInjury by this portion, while only healing a portion of this portion in actual HPs;
// this means the rest of HPs will remain as "unhealable", the patient will miss X HPs but has no HealableInjury on self..
if (bPtsLeft >= (pVictim->iHealableInjury/100))
{
iLifeReturned = pVictim->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ))/100;
pVictim->iHealableInjury = 0;
// keep the rest of the points to bandaging if neccessary
if (pVictim->bBleeding > 0)
{
bPtsLeft = max(0, (bPtsLeft - (iLifeReturned / 100)));
bPtsLeft += (bPtsLeft/2); // we use medical bag so add the bonus for that.
}
else
{
bPtsLeft = 0;
}
// add to record - another surgery undergoed
if ( pVictim->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
gMercProfiles[ pVictim->ubProfile ].records.usTimesSurgeryUndergoed++;
// add to record - another surgery made
if ( pSoldier->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
gMercProfiles[ pSoldier->ubProfile ].records.usSurgeriesMade++;
}
else
{
iLifeReturned = bPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ));
pVictim->iHealableInjury -= (bPtsLeft * 100);
bPtsLeft = 0;
}
// repair the stats here!
if ( usReturnDamagedStatRate > 0 )
{
RegainDamagedStats( pVictim, (iLifeReturned * usReturnDamagedStatRate / 100) );
}
// some paranoya checks for sure
if ((pVictim->stats.bLife + (iLifeReturned / 100)) <= pVictim->stats.bLifeMax)
{
pVictim->stats.bLife += (iLifeReturned/100);
if (pVictim->bBleeding >= (iLifeReturned/100))
{
pVictim->bBleeding -= (iLifeReturned/100);
uiMedcost += (iLifeReturned / 200); // add medkit points cost for unbandaged part
}
else
{
pVictim->bBleeding = 0;
uiMedcost += max( 0, (((iLifeReturned/100) - pVictim->bBleeding) / 2)); // add medkit points cost for unbandaged part
}
}
else // this shouldn't even happen, but we still want to have it here for sure
{
pVictim->stats.bLife = pVictim->stats.bLifeMax;
pVictim->iHealableInjury = 0;
pVictim->bBleeding = 0;
}
// Reduce max breath based on life returned
if ( (pVictim->bBreathMax - (((iLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100)) <= BREATHMAX_ABSOLUTE_MINIMUM )
{
pVictim->bBreathMax = BREATHMAX_ABSOLUTE_MINIMUM;
}
else
{
pVictim->bBreathMax -= (((iLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100);
}
if (pVictim->iHealableInjury > ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100))
pVictim->iHealableInjury = ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100);
else if (pVictim->iHealableInjury < 0)
pVictim->iHealableInjury = 0;
}
// if any healing points remain, apply that to any remaining bleeding (1/1)
// DON'T spend any APs/kit pts to cure bleeding until merc is no longer dying
//if ( bPtsLeft && pVictim->bBleeding && !pVictim->dying)
@@ -1513,24 +1661,47 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
}
}
// if there are any ptsLeft now, then we didn't actually get to use them
uiActual -= bPtsLeft;
uiActual = max(0, (uiActual - bPtsLeft));
// usedAPs equals (actionPts) * (%of possible points actually used)
uiUsedAPs = ( uiActual * uiAvailAPs ) / uiPossible;
if (Item[pSoldier->inv[0].usItem].medicalkit ) // using the GOOD medic stuff
if (Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery)) // using the GOOD medic stuff
uiUsedAPs = ( uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds
if ( uiActual / 2)
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
StatChange(pSoldier,MEDICALAMT,( (UINT16)(uiActual / 2) ),FALSE);
// surgery is harder so cost more BPs
if (fOnSurgery)
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( uiUsedAPs * 15 ) );
else
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( ( uiUsedAPs * APBPConstants[BP_PER_AP_LT_EFFORT]) ) );
if ( uiActual / 4)
// DEXTERITY GAIN (actual / 4): Helped someone by giving first aid
StatChange(pSoldier,DEXTAMT,(UINT16)( ( uiActual / 4) ),FALSE);
// surgery is harder so gives more exp
if (fOnSurgery)
{
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
StatChange(pSoldier, MEDICALAMT, (UINT16)(uiActual + 2), FALSE);
// DEXTERITY GAIN (actual / 6): Helped someone by giving first aid
StatChange(pSoldier, DEXTAMT, (UINT16)((uiActual / 3) + 2), FALSE);
}
else
{
if ( uiActual / 2)
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
StatChange(pSoldier,MEDICALAMT,( (UINT16)(uiActual / 2) ),FALSE);
if ( uiActual / 4)
// DEXTERITY GAIN (actual / 4): Helped someone by giving first aid
StatChange(pSoldier,DEXTAMT,(UINT16)( ( uiActual / 4) ),FALSE);
}
// merc records - bandaging
if( bInitialBleeding > 1 && pVictim->bBleeding == 0 && pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pSoldier->ubProfile ].records.usMercsBandaged++;
return uiMedcost;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
OBJECTTYPE* FindMedicalKit()
{
@@ -1581,7 +1752,7 @@ UINT32 AutoBandageMercs()
continue;
break;
}
uiPointsUsed = VirtualSoldierDressWound( gpMercs[ i ].pSoldier, gpMercs[ i ].pSoldier, pKit, usKitPts, usKitPts );
uiPointsUsed = VirtualSoldierDressWound( gpMercs[ i ].pSoldier, gpMercs[ i ].pSoldier, pKit, usKitPts, usKitPts, FALSE ); // changed by SANDRO
UseKitPoints( pKit, (UINT16)uiPointsUsed, gpMercs[ i ].pSoldier );
uiCurrPointsUsed += uiPointsUsed;
cnt++;
@@ -1605,12 +1776,13 @@ UINT32 AutoBandageMercs()
if( gpMercs[ i ].pSoldier->stats.bMedical > gpMercs[ iBest ].pSoldier->stats.bMedical )
{
iBest = i;
}
}
}
}
for( i = 0; i < gpAR->ubMercs; i++ )
{
cnt = 0; // SANDRO - added safety check
while( gpMercs[ i ].pSoldier->bBleeding && gpMercs[ i ].pSoldier->stats.bLife )
{ //This merc needs medical attention
if( !pKit )
@@ -1629,10 +1801,15 @@ UINT32 AutoBandageMercs()
fComplete = FALSE;
continue;
}
uiPointsUsed = VirtualSoldierDressWound( gpMercs[ iBest ].pSoldier, gpMercs[ i ].pSoldier, pKit, usKitPts, usKitPts );
uiPointsUsed = VirtualSoldierDressWound( gpMercs[ iBest ].pSoldier, gpMercs[ i ].pSoldier, pKit, usKitPts, usKitPts, FALSE );
UseKitPoints( pKit, (UINT16)uiPointsUsed, gpMercs[ i ].pSoldier );
uiParallelPointsUsed += uiPointsUsed;
fComplete = TRUE;
// SANDRO - added safety check
cnt++;
if( cnt > 500 )
break;
}
}
if( fComplete )
@@ -1941,6 +2118,7 @@ static void ARCreateMilitia( UINT8 mclass, INT32 i, INT16 sX, INT16 sY)
{
// reset counter of how many mortars this team has rolled
ResetMortarsOnTeamCount();
ResetNumSquadleadersInArmyGroup(); // added by SANDRO
if( !gpBattleGroup ) {
//AssertMsg(0, "No battle group set while creating militia");
@@ -2370,8 +2548,40 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Autoresolve2");
else if( gpAR->ubBattleStatus == BATTLE_VICTORY )
{ //merc is alive, so group them at the center gridno.
gpMercs[ i ].pSoldier->ubStrategicInsertionCode = INSERTION_CODE_CENTER;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - records - autoresolve battles
if( gpMercs[ i ].pSoldier->ubProfile != NO_PROFILE )
{
// if we ran before the battle was over but the others won in the end, we still get retreated counter, no victory
if ( gpMercs[ i ].uiFlags & CELL_RETREATED || gpMercs[ i ].uiFlags & CELL_RETREATING )
{
gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].records.usBattlesRetreated++;
}
else
{
gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].records.usBattlesAutoresolve++;
if ( gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].records.usLargestBattleFought < gpAR->ubEnemies )
{
gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].records.usLargestBattleFought = gpAR->ubEnemies;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].usBattlesFought++;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
else if( gpAR->ubBattleStatus == BATTLE_RETREAT )
{
if( gpMercs[ i ].uiFlags & CELL_RETREATED || gpMercs[ i ].uiFlags & CELL_RETREATING )
{
if( gpMercs[ i ].pSoldier->ubProfile != NO_PROFILE && !AM_A_ROBOT( gpMercs[ i ].pSoldier ) )
{
gMercProfiles[ gpMercs[ i ].pSoldier->ubProfile ].records.usBattlesRetreated++;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
for( i = 0; i < gpAR->iNumMercFaces; i++ )
@@ -3610,6 +3820,8 @@ void CalculateAttackValues()
gpAR->usPlayerAttack = 0;
gpAR->usPlayerDefence = 0;
UINT8 uiEffectiveLevelExp = 0; // added by SANDRO
//if( gpAR->ubEnemies )
//{
// //bonus equals 20 if good guys outnumber bad guys 2 to 1.
@@ -3648,7 +3860,12 @@ void CalculateAttackValues()
//bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease
//usBonus += 7 * (pSoldier->stats.bExpLevel-2);
usBonus += EXP_BONUS * (pSoldier->stats.bExpLevel-5);
// SANDRO - STOMP traits - Squadleaders bonus to effective level
uiEffectiveLevelExp = pSoldier->stats.bExpLevel;
if ( gGameOptions.fNewTraitSystem )
uiEffectiveLevelExp = min(10,(uiEffectiveLevelExp + (gSkillTraitValues.ubSLEffectiveLevelInRadius * GetSquadleadersCountInVicinity( pSoldier, TRUE, TRUE ))));
usBonus += EXP_BONUS * (uiEffectiveLevelExp-5);
usBonus += gpAR->ubPlayerDefenceAdvantage;
pCell->usAttack = pCell->usAttack * usBonus / 100;
pCell->usDefence = pCell->usDefence * usBonus / 100;
@@ -3692,7 +3909,12 @@ void CalculateAttackValues()
usBonus = 100 + gpAR->ubPlayerLeadership/10;// + sOutnumberBonus;
//bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease
//usBonus += 7 * (pSoldier->stats.bExpLevel-2);
usBonus += EXP_BONUS * (pSoldier->stats.bExpLevel-5);
// SANDRO - STOMP traits - Squadleaders bonus to effective level
uiEffectiveLevelExp = pSoldier->stats.bExpLevel;
if ( gGameOptions.fNewTraitSystem )
uiEffectiveLevelExp = min(10,(uiEffectiveLevelExp + (gSkillTraitValues.ubSLEffectiveLevelInRadius * GetSquadleadersCountInVicinity( pSoldier, TRUE, TRUE ))));
usBonus += EXP_BONUS * (uiEffectiveLevelExp-5);
usBonus += gpAR->ubPlayerDefenceAdvantage;
pCell->usAttack = pCell->usAttack * usBonus / 100;
pCell->usDefence = pCell->usDefence * usBonus / 100;
@@ -3751,7 +3973,12 @@ void CalculateAttackValues()
usBonus = 100 + gpAR->ubPlayerLeadership/10;// + sOutnumberBonus;
//bExpLevel adds a bonus of 7% per level after 2, level 1 soldiers get a 7% decrease
//usBonus += 7 * (pSoldier->stats.bExpLevel-2);
usBonus += EXP_BONUS * (pSoldier->stats.bExpLevel-5);
// SANDRO - STOMP traits - Squadleaders bonus to effective level
uiEffectiveLevelExp = pSoldier->stats.bExpLevel;
if ( gGameOptions.fNewTraitSystem )
uiEffectiveLevelExp = min(10,(uiEffectiveLevelExp + (gSkillTraitValues.ubSLEffectiveLevelInRadius * GetSquadleadersCountInVicinity( pSoldier, TRUE, TRUE ))));
usBonus += EXP_BONUS * (uiEffectiveLevelExp-5);
usBonus += gpAR->ubEnemyDefenceAdvantage;
pCell->usAttack = pCell->usAttack * usBonus / 100;
pCell->usDefence = pCell->usDefence * usBonus / 100;
@@ -3942,7 +4169,7 @@ BOOLEAN FireAShot( SOLDIERCELL *pAttacker )
PlayAutoResolveSample( Weapon[ pItem->usItem ].sSound, RATE_11025, 50, 1, MIDDLEPAN );
if( pAttacker->uiFlags & CELL_MERC )
{
gMercProfiles[ pAttacker->pSoldier->ubProfile ].usShotsFired++;
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usShotsFired++;
// MARKSMANSHIP GAIN: Attacker fires a shot
StatChange( pAttacker->pSoldier, MARKAMT, 3, FALSE );
@@ -4020,6 +4247,61 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
usDefence = (UINT16)(pTarget->usDefence + PreRandom((INT16)(gGameExternalOptions.iAutoResolveLuckFactor*1000.0) - pTarget->usDefence ));
else
usDefence = (UINT16)(950 + PreRandom( 50 ));
///////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Iincrease Militia Strength in autoresolve battles
// because the attack and defense is limited to max 1000, rather than only increasing the attack of milita,
// decrease the defense of target - so +100% bonus means +50% attack of attacker and -50% defense of target
//if militita is attacking increase attack by half and decrease the defense of enemy
if (pAttacker->pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaAutoresolveStrength != 0)
{
usAttack += (usAttack * gGameExternalOptions.sGreenMilitiaAutoresolveStrength /200);
usDefence -= (usDefence * gGameExternalOptions.sGreenMilitiaAutoresolveStrength /200);
}
else if (pAttacker->pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaAutoresolveStrength != 0)
{
usAttack += (usAttack * gGameExternalOptions.sRegularMilitiaAutoresolveStrength /200);
usDefence -= (usDefence * gGameExternalOptions.sRegularMilitiaAutoresolveStrength /200);
}
else if (pAttacker->pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaAutoresolveStrength != 0)
{
usAttack += (usAttack * gGameExternalOptions.sVeteranMilitiaAutoresolveStrength /200);
usDefence -= (usDefence * gGameExternalOptions.sVeteranMilitiaAutoresolveStrength /200);
}
else if (pAttacker->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveOffenseBonus != 0)
{
usAttack += (usAttack * gGameExternalOptions.sMercsAutoresolveOffenseBonus /200);
usDefence -= (usDefence * gGameExternalOptions.sMercsAutoresolveOffenseBonus /200);
}
//if enemy is attacking decrease his attack by half and increase the defense of militia by half
if (pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.sGreenMilitiaAutoresolveStrength != 0)
{
usDefence += (usDefence * gGameExternalOptions.sGreenMilitiaAutoresolveStrength /200);
usAttack -= (usAttack * gGameExternalOptions.sGreenMilitiaAutoresolveStrength /200);
}
else if (pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.sRegularMilitiaAutoresolveStrength != 0)
{
usDefence += (usDefence * gGameExternalOptions.sRegularMilitiaAutoresolveStrength /200);
usAttack -= (usAttack * gGameExternalOptions.sRegularMilitiaAutoresolveStrength /200);
}
else if (pTarget->pSoldier->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.sVeteranMilitiaAutoresolveStrength != 0)
{
usDefence += (usDefence * gGameExternalOptions.sVeteranMilitiaAutoresolveStrength /200);
usAttack -= (usAttack * gGameExternalOptions.sVeteranMilitiaAutoresolveStrength /200);
}
else if (pTarget->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveDeffenseBonus != 0)
{
usDefence += (usDefence * gGameExternalOptions.sMercsAutoresolveDeffenseBonus /200);
usAttack -= (usAttack * gGameExternalOptions.sMercsAutoresolveDeffenseBonus /200);
}
// reapair values
usAttack = max(0, min(1000, usAttack ));
usDefence = max(0, min(1000, usDefence ));
///////////////////////////////////////////////////////////////////////////////////////////
if( pAttacker->uiFlags & CELL_FEMALECREATURE )
{
pAttacker->bWeaponSlot = HANDPOS;
@@ -4105,6 +4387,17 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
ubLocation = AIM_SHOT_TORSO;
ubAccuracy = (UINT8)((usAttack - usDefence + PreRandom( usDefence - pTarget->usDefence ) )/10);
iImpact = BulletImpact( pAttacker->pSoldier, pTarget->pSoldier, ubLocation, ubImpact, ubAccuracy, NULL );
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - increased mercs' offense/deffense rating
if (pAttacker->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveOffenseBonus != 0)
{
iImpact += (iImpact * gGameExternalOptions.sMercsAutoresolveOffenseBonus /150);
}
else if (pTarget->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveDeffenseBonus != 0 && (iImpact > 3))
{
iImpact = max( 3, ((iImpact * (100 - (gGameExternalOptions.sMercsAutoresolveDeffenseBonus / 2))) /100));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
if ( bAttackIndex == -1 )
{
@@ -4146,7 +4439,7 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
//switch items
tempItem = pAttacker->pSoldier->inv[ HANDPOS ];
pAttacker->pSoldier->inv[ HANDPOS ] = pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ]; //CTD
iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife | fClaw) );
iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife || fClaw) );
pAttacker->pSoldier->inv[ pAttacker->bWeaponSlot ] = pAttacker->pSoldier->inv[ HANDPOS ];
pAttacker->pSoldier->inv[ HANDPOS ] = tempItem;
}
@@ -4154,6 +4447,17 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
{
iImpact = HTHImpact( pAttacker->pSoldier, pTarget->pSoldier, ubAccuracy, (BOOLEAN)(fKnife || fClaw) );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - increased mercs' offense/deffense rating
if (pAttacker->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveOffenseBonus != 0)
{
iImpact += (iImpact * gGameExternalOptions.sMercsAutoresolveOffenseBonus /150);
}
else if (pTarget->uiFlags & CELL_MERC && gGameExternalOptions.sMercsAutoresolveDeffenseBonus != 0 && (iImpact > 3))
{
iImpact = max( 3, ((iImpact * (100 - (gGameExternalOptions.sMercsAutoresolveDeffenseBonus / 2))) /100));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// WANNE: Why is impact here always set to 0? The impact was calculated a few lines before!
//iImpact = 0;
@@ -4166,13 +4470,14 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
if( pAttacker->uiFlags & CELL_MERC )
{ //Attacker is a player, so increment the number of shots that hit.
gMercProfiles[ pAttacker->pSoldier->ubProfile ].usShotsHit++;
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usShotsHit++;
// MARKSMANSHIP GAIN: Attacker's shot hits
StatChange( pAttacker->pSoldier, MARKAMT, 6, FALSE ); // in addition to 3 for taking a shot
}
if( pTarget->uiFlags & CELL_MERC )
{ //Target is a player, so increment the times he has been wounded.
gMercProfiles[ pTarget->pSoldier->ubProfile ].usTimesWounded++;
if( iImpact > 1 )
gMercProfiles[ pTarget->pSoldier->ubProfile ].records.usTimesWoundedStabbed++;
// EXPERIENCE GAIN: Took some damage
StatChange( pTarget->pSoldier, EXPERAMT, ( UINT16 )( 5 * ( iImpact / 10 ) ), FALSE );
}
@@ -4190,7 +4495,34 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
{ //soldier has been killed
if( pAttacker->uiFlags & CELL_MERC )
{ //Player killed the enemy soldier -- update his stats as well as any assisters.
gMercProfiles[ pAttacker->pSoldier->ubProfile ].usKills++;
/////////////////////////////////////////////////////////////////////////////////////
// SANDRO - experimental - more specific statistics of mercs
switch(pTarget->pSoldier->ubSoldierClass)
{
case SOLDIER_CLASS_ELITE :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsElites++;
break;
case SOLDIER_CLASS_ARMY :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsRegulars++;
break;
case SOLDIER_CLASS_ADMINISTRATOR :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsAdmins++;
break;
case SOLDIER_CLASS_CREATURE :
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
break;
default :
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsTanks++;
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsHostiles++;
else
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usKillsOthers++;
break;
}
/////////////////////////////////////////////////////////////////////////////////////
gStrategicStatus.usPlayerKills++;
}
else if( pAttacker->uiFlags & CELL_MILITIA )
@@ -4203,6 +4535,15 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
PlayAutoResolveSample( (UINT8)HEADCR_1, RATE_11025, HIGHVOLUME, 1, MIDDLEPAN );
}
}
///////////////////////////////////////////////////////////////
// SANDRO - added the insta-healable value for doctor trait
else if ((IS_MERC_BODY_TYPE( pTarget->pSoldier ) || IS_CIV_BODY_TYPE( pTarget->pSoldier )) && ( gGameOptions.fNewTraitSystem ))
{
pTarget->pSoldier->iHealableInjury += ((pTarget->pSoldier->stats.bLife - iNewLife) * 100);
if (pTarget->pSoldier->iHealableInjury > ((pTarget->pSoldier->stats.bLifeMax - pTarget->pSoldier->stats.bLife) * 100))
pTarget->pSoldier->iHealableInjury = ((pTarget->pSoldier->stats.bLifeMax - pTarget->pSoldier->stats.bLife) * 100);
}
///////////////////////////////////////////////////////////////
//Adjust the soldiers stats based on the damage.
pTarget->pSoldier->stats.bLife = (INT8)max( iNewLife, 0 );
if( pTarget->uiFlags & CELL_MERC && gpAR->pRobotCell)
@@ -4218,6 +4559,10 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget )
}
if( !pTarget->pSoldier->stats.bLife )
{
// SANDRO - added check to erase insta-healable amount of HPs if dead
if (pTarget->pSoldier->iHealableInjury > 0)
{ pTarget->pSoldier->iHealableInjury = 0; }
gpAR->fRenderAutoResolve = TRUE;
#ifdef INVULNERABILITY
if( 1 )
@@ -4294,13 +4639,14 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
if( pAttacker->uiFlags & CELL_MERC )
{ //Attacker is a player, so increment the number of shots that hit.
gMercProfiles[ pAttacker->pSoldier->ubProfile ].usShotsHit++;
gMercProfiles[ pAttacker->pSoldier->ubProfile ].records.usShotsHit++;
// MARKSMANSHIP GAIN: Attacker's shot hits
StatChange( pAttacker->pSoldier, MARKAMT, 6, FALSE ); // in addition to 3 for taking a shot
}
if( pTarget->uiFlags & CELL_MERC && pTarget->usHitDamage[ index ] )
{ //Target is a player, so increment the times he has been wounded.
gMercProfiles[ pTarget->pSoldier->ubProfile ].usTimesWounded++;
if( pTarget->usHitDamage[index] > 1 )
gMercProfiles[ pTarget->pSoldier->ubProfile ].records.usTimesWoundedShot++;
// EXPERIENCE GAIN: Took some damage
StatChange( pTarget->pSoldier, EXPERAMT, ( UINT16 )( 5 * ( pTarget->usHitDamage[ index ] / 10 ) ), FALSE );
}
@@ -4337,7 +4683,34 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{
if( pKiller->uiFlags & CELL_MERC )
{
gMercProfiles[ pKiller->pSoldier->ubProfile ].usKills++;
/////////////////////////////////////////////////////////////////////////////////////
// SANDRO - new mercs' records
switch(pTarget->pSoldier->ubSoldierClass)
{
case SOLDIER_CLASS_ELITE :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsElites++;
break;
case SOLDIER_CLASS_ARMY :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsRegulars++;
break;
case SOLDIER_CLASS_ADMINISTRATOR :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsAdmins++;
break;
case SOLDIER_CLASS_CREATURE :
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
break;
default :
if ( CREATURE_OR_BLOODCAT( pTarget->pSoldier ) )
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsCreatures++;
else if ( TANK( pTarget->pSoldier ) ) // we hardly can kill a tank in autoresolve, but well.. who knows..
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsTanks++;
else if ( pTarget->pSoldier->bTeam == CIV_TEAM && !pTarget->pSoldier->aiData.bNeutral && pTarget->pSoldier->bSide != gbPlayerNum )
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsHostiles++;
else
gMercProfiles[ pKiller->pSoldier->ubProfile ].records.usKillsOthers++;
break;
}
/////////////////////////////////////////////////////////////////////////////////////
gStrategicStatus.usPlayerKills++;
// EXPERIENCE CLASS GAIN: Earned a kill
StatChange( pKiller->pSoldier, EXPERAMT, ( UINT16 )( 10 * pTarget->pSoldier->pathing.bLevel ), FALSE );
@@ -4350,7 +4723,22 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{
if( pAssister1->uiFlags & CELL_MERC )
{
gMercProfiles[ pAssister1->pSoldier->ubProfile ].usAssists++;
/////////////////////////////////////////////////////////////////////////////////////
// SANDRO - new mercs' records
if( pKiller )
{
if( pKiller->uiFlags & CELL_MERC && pKiller->pSoldier->bTeam == gbPlayerNum )
gMercProfiles[ pAssister1->pSoldier->ubProfile ].records.usAssistsMercs++;
else if ( pKiller->pSoldier->bTeam == MILITIA_TEAM )
gMercProfiles[ pAssister1->pSoldier->ubProfile ].records.usAssistsMilitia++;
else
gMercProfiles[ pAssister1->pSoldier->ubProfile ].records.usAssistsOthers++;
}
else
{
gMercProfiles[ pAssister1->pSoldier->ubProfile ].records.usAssistsOthers++;
}
/////////////////////////////////////////////////////////////////////////////////////
// EXPERIENCE CLASS GAIN: Earned an assist
StatChange( pAssister1->pSoldier, EXPERAMT, ( UINT16 )( 5 * pTarget->pSoldier->pathing.bLevel ), FALSE );
}
@@ -4361,7 +4749,22 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
{
if( pAssister2->uiFlags & CELL_MERC )
{
gMercProfiles[ pAssister2->pSoldier->ubProfile ].usAssists++;
/////////////////////////////////////////////////////////////////////////////////////
// SANDRO - new mercs' records
if( pKiller )
{
if( pKiller->uiFlags & CELL_MERC && pKiller->pSoldier->bTeam == gbPlayerNum )
gMercProfiles[ pAssister2->pSoldier->ubProfile ].records.usAssistsMercs++;
else if ( pKiller->pSoldier->bTeam == MILITIA_TEAM )
gMercProfiles[ pAssister2->pSoldier->ubProfile ].records.usAssistsMilitia++;
else
gMercProfiles[ pAssister2->pSoldier->ubProfile ].records.usAssistsOthers++;
}
else
{
gMercProfiles[ pAssister2->pSoldier->ubProfile ].records.usAssistsOthers++;
}
/////////////////////////////////////////////////////////////////////////////////////
// EXPERIENCE CLASS GAIN: Earned an assist
StatChange( pAssister2->pSoldier, EXPERAMT, ( UINT16 )( 5 * pTarget->pSoldier->pathing.bLevel ), FALSE );
}
@@ -4396,6 +4799,15 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
return;
#endif
}
///////////////////////////////////////////////////////////////
// SANDRO - added the insta-healable value for doctor trait
else if ((IS_MERC_BODY_TYPE( pTarget->pSoldier ) || IS_CIV_BODY_TYPE( pTarget->pSoldier )) && ( gGameOptions.fNewTraitSystem ))
{
pTarget->pSoldier->iHealableInjury += ((pTarget->pSoldier->stats.bLife - iNewLife) * 100);
if (pTarget->pSoldier->iHealableInjury > ((pTarget->pSoldier->stats.bLifeMax - pTarget->pSoldier->stats.bLife) * 100))
pTarget->pSoldier->iHealableInjury = ((pTarget->pSoldier->stats.bLifeMax - pTarget->pSoldier->stats.bLife) * 100);
}
///////////////////////////////////////////////////////////////
//Adjust the soldiers stats based on the damage.
pTarget->pSoldier->stats.bLife = (INT8)max( iNewLife, 0 );
if( pTarget->uiFlags & CELL_MERC && gpAR->pRobotCell)
@@ -4409,6 +4821,10 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index )
pTarget->pSoldier->bBleeding = (INT8)(pTarget->pSoldier->stats.bLifeMax - pTarget->pSoldier->stats.bLife);
if( !pTarget->pSoldier->stats.bLife )
{
// SANDRO - added check to erase insta-healable amount of HPs if dead
if (pTarget->pSoldier->iHealableInjury > 0)
{ pTarget->pSoldier->iHealableInjury = 0; }
gpAR->fRenderAutoResolve = TRUE;
if( pTarget->uiFlags & CELL_MERC )
{
@@ -4504,6 +4920,7 @@ BOOLEAN IsBattleOver()
{
gpMercs[ i ].pSoldier->DoMercBattleSound( BATTLE_SOUND_DIE1 );
gpMercs[ i ].pSoldier->stats.bLife = 0;
gpMercs[ i ].pSoldier->iHealableInjury = 0; // added by SANDRO
gpAR->ubAliveMercs--;
}
}
+3 -2
View File
@@ -20,7 +20,7 @@
#endif
#include "connect.h"
#include "VFS/vfs.h"
#include <vfs/Core/vfs.h>
#include "XMLWriter.h"
#include "UndergroundInit.h"
@@ -434,7 +434,8 @@ void BuildUndergroundSectorInfoList()
TrashUndergroundSectorInfo();
if (LetLuaBuildUndergroundSectorInfoList())
//if (LetLuaBuildUndergroundSectorInfoList())
g_luaUnderground.InitializeSectorList();
// lua script succeeded
return;
+12 -1
View File
@@ -210,7 +210,7 @@ typedef struct FACILITYRISKTYPE
{
// The risks involved with perfoming an assignment at a specific facility.
UINT8 ubChance; // Chance out of X that this risk will trigger every hour. X is INI-defined and is normally 1000.
UINT16 usChance; // Chance out of X that this risk will trigger every hour. X is INI-defined and is normally 1000.
INT8 bBaseEffect; // Base result. If negative, result will always be negative. If positive, result will always be positive.
// If 0, result can be either negative or positive.
UINT8 ubRange; // Range of deviation for the base effect.
@@ -480,6 +480,9 @@ typedef struct UNDERGROUND_SECTORINFO
UINT8 ubCreatureHabitat; //determines how creatures live in this sector (see creature spreading.c)
UINT8 ubElitesInBattle, ubTroopsInBattle, ubAdminsInBattle, ubCreaturesInBattle;
// adding these (should not change struct layout due to padding)
UINT8 ubMusicMode, ubUnsed;
UINT32 uiNumberOfWorldItemsInTempFileThatCanBeSeenByPlayer;
INT8 bPadding[36];
//no padding left!
@@ -492,4 +495,12 @@ extern std::vector<SECTORINFO> SectorInfo;
extern UNDERGROUND_SECTORINFO *gpUndergroundSectorInfoHead;
enum CreateMusic
{
CM_COMPAT,
CM_AUTO,
CM_NEVER,
CM_ALWAYS,
};
#endif
+68 -32
View File
@@ -33,6 +33,7 @@
#include "Map Information.h"
#endif
#include "Strategic Mines.h"
#include "connect.h"
@@ -106,7 +107,7 @@
//When either in a cave level with blue lights or there is a creature presence, then
//we override the normal music with the creature music. The conditions are maintained
//inside the function PrepareCreaturesForBattle() in this module.
BOOLEAN gfUseCreatureMusic = FALSE;
//BOOLEAN gfUseCreatureMusic = FALSE; // moved to music control.cpp
BOOLEAN gfCreatureMeanwhileScenePlayed = FALSE;
enum
{
@@ -148,7 +149,7 @@ extern UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSect
extern void BuildUndergroundSectorInfoList();
void DeleteCreatureDirectives();
extern MINE_STATUS_TYPE gMineStatus[ MAX_NUMBER_OF_MINES ];
//extern MINE_STATUS_TYPE gMineStatus[ MAX_NUMBER_OF_MINES ];
CREATURE_DIRECTIVE* NewDirective( UINT8 ubSectorID, UINT8 ubSectorZ, UINT8 ubCreatureHabitat )
{
@@ -329,26 +330,35 @@ void InitCreatureQuest()
memset( fMineInfectible, 1, sizeof( BOOLEAN ) * 4 );
if( gMineStatus[ MINE_DRASSEN ].fAttackedHeadMiner ||
gMineStatus[ MINE_DRASSEN ].uiOreRunningOutPoint ||
StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_D13 ) ].fEnemyControlled )
//gMineStatus[ MINE_DRASSEN ].uiOreRunningOutPoint ||
!gMineStatus[ MINE_DRASSEN ].fInfectible ||
//StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_D13 ) ].fEnemyControlled
StrategicMap[ gMineStatus[MINE_DRASSEN].StrategicIndex() ].fEnemyControlled
)
{ //If head miner was attacked, ore will/has run out, or enemy controlled
fMineInfectible[ 0 ] = FALSE;
}
if( gMineStatus[ MINE_CAMBRIA ].fAttackedHeadMiner ||
gMineStatus[ MINE_CAMBRIA ].uiOreRunningOutPoint ||
StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_H8 ) ].fEnemyControlled )
//gMineStatus[ MINE_CAMBRIA ].uiOreRunningOutPoint ||
!gMineStatus[ MINE_CAMBRIA ].fInfectible ||
//StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_H8 ) ].fEnemyControlled )
StrategicMap[ gMineStatus[MINE_CAMBRIA].StrategicIndex() ].fEnemyControlled )
{ //If head miner was attacked, ore will/has run out, or enemy controlled
fMineInfectible[ 1 ] = FALSE;
}
if( gMineStatus[ MINE_ALMA ].fAttackedHeadMiner ||
gMineStatus[ MINE_ALMA ].uiOreRunningOutPoint ||
StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_I14 ) ].fEnemyControlled )
//gMineStatus[ MINE_ALMA ].uiOreRunningOutPoint ||
!gMineStatus[ MINE_ALMA ].fInfectible ||
//StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_I14 ) ].fEnemyControlled )
StrategicMap[ gMineStatus[MINE_ALMA].StrategicIndex() ].fEnemyControlled )
{ //If head miner was attacked, ore will/has run out, or enemy controlled
fMineInfectible[ 2 ] = FALSE;
}
if( gMineStatus[ MINE_GRUMM ].fAttackedHeadMiner ||
gMineStatus[ MINE_GRUMM ].uiOreRunningOutPoint ||
StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_H3 ) ].fEnemyControlled )
//gMineStatus[ MINE_GRUMM ].uiOreRunningOutPoint ||
!gMineStatus[ MINE_GRUMM ].fInfectible ||
//StrategicMap[ SECTOR_INFO_TO_STRATEGIC_INDEX( SEC_H3 ) ].fEnemyControlled )
StrategicMap[ gMineStatus[MINE_GRUMM].StrategicIndex() ].fEnemyControlled )
{ //If head miner was attacked, ore will/has run out, or enemy controlled
fMineInfectible[ 3 ] = FALSE;
}
@@ -786,7 +796,7 @@ void ChooseTownSectorToAttack( UINT8 ubSectorID, BOOLEAN fOverrideTest )
{
case SEC_D13: //DRASSEN
gsCreatureInsertionCode = INSERTION_CODE_GRIDNO;
gsCreatureInsertionGridNo = 20703;
gsCreatureInsertionGridNo = 20703;//dnl!!!
break;
case SEC_C13:
gsCreatureInsertionCode = INSERTION_CODE_SOUTH;
@@ -796,7 +806,7 @@ void ChooseTownSectorToAttack( UINT8 ubSectorID, BOOLEAN fOverrideTest )
break;
case SEC_H3: //GRUMM
gsCreatureInsertionCode = INSERTION_CODE_GRIDNO;
gsCreatureInsertionGridNo = 10303;
gsCreatureInsertionGridNo = 10303; //dnl!!!
break;
case SEC_H2:
gsCreatureInsertionCode = INSERTION_CODE_EAST;
@@ -812,7 +822,7 @@ void ChooseTownSectorToAttack( UINT8 ubSectorID, BOOLEAN fOverrideTest )
break;
case SEC_H8: //CAMBRIA
gsCreatureInsertionCode = INSERTION_CODE_GRIDNO;
gsCreatureInsertionGridNo = 13005;
gsCreatureInsertionGridNo = 13005; //dnl!!!
break;
case SEC_G8:
gsCreatureInsertionCode = INSERTION_CODE_SOUTH;
@@ -828,7 +838,7 @@ void ChooseTownSectorToAttack( UINT8 ubSectorID, BOOLEAN fOverrideTest )
break;
case SEC_I14: //ALMA
gsCreatureInsertionCode = INSERTION_CODE_GRIDNO;
gsCreatureInsertionGridNo = 9726;
gsCreatureInsertionGridNo = 9726; //dnl!!!
break;
case SEC_I13:
gsCreatureInsertionCode = INSERTION_CODE_EAST;
@@ -940,7 +950,7 @@ void CreatureAttackTown( UINT8 ubSectorID, BOOLEAN fOverrideTest )
case CREATURE_BATTLE_CODE_TACTICALLYADD:
if (is_networked)
{
if(is_server && CREATURE_ENABLED==1)
if(is_server && gCreatureEnabled == 1)
PrepareCreaturesForBattle();
}
else
@@ -1215,35 +1225,56 @@ BOOLEAN PrepareCreaturesForBattle()
if( !gubCreatureBattleCode )
{
ubNumColors = LightGetColors( LColors );
if (! gbWorldSectorZ )
{
UseCreatureMusic(LColors->peBlue);
return FALSE; //Creatures don't attack overworld with this battle code.
}
pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if( !pSector )
{
return FALSE;
}
//if( ubNumColors != 1 )
// ScreenMsg( FONT_RED, MSG_ERROR, L"This map has more than one light color -- KM, LC : 1" );
//By default, we only play creature music in the cave levels (the creature levels all consistently
//have blue lights while human occupied mines have red lights. We always play creature music
//when creatures are in the level.
if( LColors->peBlue )
gfUseCreatureMusic = TRUE;
else
gfUseCreatureMusic = FALSE;
BOOLEAN fCreatures = pSector->ubNumCreatures > 0;
if( !gbWorldSectorZ )
return FALSE; //Creatures don't attack overworld with this battle code.
pSector = FindUnderGroundSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
if( !pSector )
switch (pSector->ubMusicMode)
{
case CM_AUTO:
UseCreatureMusic(fCreatures);
break;
case CM_NEVER:
UseCreatureMusic(FALSE);
break;
case CM_ALWAYS:
UseCreatureMusic(TRUE);
break;
case CM_COMPAT:
default:
UseCreatureMusic(LColors->peBlue || fCreatures);
break;
}
if( !fCreatures )
{
return FALSE;
}
if( !pSector->ubNumCreatures )
{
return FALSE;
}
gfUseCreatureMusic = TRUE; //creatures are here, so play creature music
//gfUseCreatureMusic = TRUE; //creatures are here, so play creature music
ubCreatureHabitat = pSector->ubCreatureHabitat;
ubNumCreatures = pSector->ubNumCreatures;
}
else
{ //creatures are attacking a town sector
gfUseCreatureMusic = TRUE;
//gfUseCreatureMusic = TRUE;
UseCreatureMusic(TRUE);
SetMusicMode( MUSIC_TACTICAL_NOTHING );
ubCreatureHabitat = MINE_EXIT;
ubNumCreatures = gubNumCreaturesAttackingTown;
@@ -1401,6 +1432,8 @@ void CreatureNightPlanning()
void CheckConditionsForTriggeringCreatureQuest( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
// move to Scripts/StrategicTownLoyalty.lua
UINT8 ubValidMines = 0;
if( !(gGameOptions.ubGameStyle == STYLE_SCIFI) || !gGameExternalOptions.fEnableCrepitus)
return; //No scifi, no creatures...
@@ -1452,7 +1485,8 @@ BOOLEAN SaveCreatureDirectives( HWFILE hFile )
{
return( FALSE );
}
FileWrite( hFile, &gfUseCreatureMusic, 1, &uiNumBytesWritten );
BOOLEAN fUseCreatureMusic = UsingCreatureMusic();
FileWrite( hFile, &fUseCreatureMusic, 1, &uiNumBytesWritten );
if( uiNumBytesWritten != sizeof( BOOLEAN ) )
{
return( FALSE );
@@ -1486,11 +1520,13 @@ BOOLEAN LoadCreatureDirectives( HWFILE hFile, UINT32 uiSavedGameVersion )
return( FALSE );
}
FileRead( hFile, &gfUseCreatureMusic, 1, &uiNumBytesRead );
BOOLEAN fUseCreatureMusic;
FileRead( hFile, &fUseCreatureMusic, 1, &uiNumBytesRead );
if( uiNumBytesRead != sizeof( BOOLEAN ) )
{
return( FALSE );
}
UseCreatureMusic(fUseCreatureMusic);
if( uiSavedGameVersion >= 82 )
{
@@ -1535,7 +1571,7 @@ BOOLEAN LoadCreatureDirectives( HWFILE hFile, UINT32 uiSavedGameVersion )
void ForceCreaturesToAvoidMineTemporarily( UINT8 ubMineIndex )
{
gMineStatus[ MINE_GRUMM ].usValidDayCreaturesCanInfest = (UINT16)(GetWorldDay() + 2);
gMineStatus[ ubMineIndex ].usValidDayCreaturesCanInfest = (UINT16)(GetWorldDay() + 2);
}
BOOLEAN PlayerGroupIsInACreatureInfestedMine()
+3 -1
View File
@@ -20,7 +20,7 @@ void CheckConditionsForTriggeringCreatureQuest( INT16 sSectorX, INT16 sSectorY,
void ForceCreaturesToAvoidMineTemporarily( UINT8 ubMineIndex );
extern BOOLEAN gfUseCreatureMusic;
//extern BOOLEAN gfUseCreatureMusic;
BOOLEAN MineClearOfMonsters( UINT8 ubMineIndex );
@@ -55,4 +55,6 @@ void DetermineCreatureTownCompositionBasedOnTacticalInformation( UINT8 *pubNumCr
BOOLEAN PlayerGroupIsInACreatureInfestedMine();
extern INT32 giLairID;
#endif
+372 -87
View File
@@ -281,7 +281,7 @@ INT16 GetSectorModifier( SOLDIERTYPE *pSoldier, UINT8 ubModifierType )
case FACILITY_SLEEP_MOD:
case FACILITY_KIT_DEGRADE_MOD:
case FACILITY_MINE_INCOME_MOD:
Result = 100 + ((100-Result) + (100-sCurrent));
Result = 100 + ((Result-100) + (sCurrent-100));
break;
case FACILITY_MAX_MORALE:
@@ -517,7 +517,7 @@ void UpdateSkyriderCostModifier()
ubCounter++;
continue;
}
UINT8 ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
UINT8 ubAssignmentType = (UINT8)GetSoldierFacilityAssignmentIndex( pSoldier );
// Is character using a facility?
if ( CanCharacterFacility( pSoldier, ubFacilityType, ubAssignmentType ) &&
@@ -580,7 +580,7 @@ void UpdateFacilityUsageCosts( )
ubCounter++;
continue;
}
UINT8 ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
UINT8 ubAssignmentType = (UINT8)GetSoldierFacilityAssignmentIndex( pSoldier );
// Is character using a facility?
if ( CanCharacterFacility( pSoldier, ubFacilityType, ubAssignmentType ) &&
@@ -715,7 +715,7 @@ INT32 MineIncomeModifierFromFacility( UINT8 ubMine )
ubCounter++;
continue;
}
UINT8 ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
UINT8 ubAssignmentType = (UINT8)GetSoldierFacilityAssignmentIndex( pSoldier );
// Is character using a facility?
if ( CanCharacterFacility( pSoldier, ubFacilityType, ubAssignmentType ) &&
@@ -816,6 +816,9 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
case EXPLOSIVE_ASSIGN:
bAssignmentIndex = FAC_PRACTICE_EXPLOSIVES;
break;
default:
bAssignmentIndex = -1;
break;
}
break;
case TRAIN_TEAMMATE:
@@ -848,6 +851,9 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
case EXPLOSIVE_ASSIGN:
bAssignmentIndex = FAC_TRAINER_EXPLOSIVES;
break;
default:
bAssignmentIndex = -1;
break;
}
break;
case TRAIN_BY_OTHER:
@@ -880,6 +886,9 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
case EXPLOSIVE_ASSIGN:
bAssignmentIndex = FAC_STUDENT_EXPLOSIVES;
break;
default:
bAssignmentIndex = -1;
break;
}
break;
case FACILITY_STAFF:
@@ -890,6 +899,7 @@ INT8 GetSoldierFacilityAssignmentIndex( SOLDIERTYPE *pSoldier )
break;
default:
bAssignmentIndex = -1;
break;
}
return (bAssignmentIndex);
@@ -901,12 +911,12 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
{
INT16 Result = 0;
UINT8 ubChance;
INT32 iChance;
INT8 bBaseEffect;
UINT8 ubRange;
// Read risk data directly from facility array.
ubChance = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].ubChance;
iChance = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].usChance;
bBaseEffect = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].bBaseEffect;
ubRange = gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[ubRiskType].ubRange;
@@ -931,24 +941,24 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
}
///////////////
INT8 bAbsoluteMaxResult;
INT8 bAbsoluteMinResult;
INT16 sAbsoluteMaxResult;
INT16 sAbsoluteMinResult;
// Calculate absolute maximum variance. The result can never be outside these.
if (bBaseEffect < 0)
{
bAbsoluteMaxResult = __min((bBaseEffect + ubRange), -1);
bAbsoluteMinResult = bBaseEffect - ubRange;
sAbsoluteMaxResult = __min((bBaseEffect + ubRange), -1);
sAbsoluteMinResult = bBaseEffect - ubRange;
}
else if (bBaseEffect > 0)
{
bAbsoluteMaxResult = bBaseEffect + ubRange;
bAbsoluteMinResult = __max(1, (bBaseEffect - ubRange));
sAbsoluteMaxResult = bBaseEffect + ubRange;
sAbsoluteMinResult = __max(1, (bBaseEffect - ubRange));
}
else
{
bAbsoluteMaxResult = bBaseEffect + ubRange;
bAbsoluteMinResult = bBaseEffect - ubRange;
sAbsoluteMaxResult = bBaseEffect + ubRange;
sAbsoluteMinResult = bBaseEffect - ubRange;
}
INT8 bCombinedStats;
@@ -995,7 +1005,7 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
bCombinedStats = (INT8)__min(100, (ubWisdom * 0.2) + (ubLeadership * 0.4) + (ubExpLevel * 4));
break;
case RISK_FATIGUE:
bCombinedStats = (INT8)__min(100, (ubAgility * 0.1) + (ubStrength * 0.3) + (ubHealth * 0.2) + (ubExpLevel * 5));
bCombinedStats = (INT8)__min(100, (ubAgility * 0.1) + (ubStrength * 0.3) + (ubHealth * 0.2) + (ubExpLevel * 4));
break;
case RISK_DRUNK:
bCombinedStats = (INT8)__min(100, (ubWisdom * 0.5) + (ubHealth * 0.3) + (ubExpLevel * 2));
@@ -1008,15 +1018,15 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
break;
}
if (bCombinedStats == 100)
if (bCombinedStats >= 100)
{
// Character is as skilled as possible. Automatic "best" result.
return (bAbsoluteMaxResult);
return (sAbsoluteMaxResult);
}
if (bCombinedStats == 0)
if (bCombinedStats <= 0)
{
// Character is completely inept? Strange. Automatic "worst" result.
return (bAbsoluteMinResult);
return (sAbsoluteMinResult);
}
// we now have a range of 0 to 100. Let's apply an externalized modifier of 0 to -100.
@@ -1026,20 +1036,23 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
if (bBaseEffect > 0 )
{
// Chance increases with good stats, decreased with bad stats.
ubChance = ubChance + ((bCombinedStats * ubChance) / 100 );
iChance = iChance + ((bCombinedStats * iChance) / 100 );
}
else if (bBaseEffect < 0 )
{
// Chance decreases with good stats, increases with bad stats.
ubChance = ubChance - ((bCombinedStats * ubChance) / 100 );
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)>ubChance)
if (PreRandom(gGameExternalOptions.usFacilityEventRarity)>(UINT32)iChance)
{
// Chance failed to trigger.
return (0);
@@ -1052,8 +1065,8 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
// 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, bAbsoluteMaxResult);
bBaseEffect = __max(bBaseEffect, bAbsoluteMinResult);
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.
@@ -1067,13 +1080,14 @@ INT16 FacilityRiskResult( SOLDIERTYPE *pSoldier, UINT8 ubRiskType, UINT8 ubFacil
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, bAbsoluteMaxResult);
Result = __max(Result, bAbsoluteMinResult);
Result = __min(Result, sAbsoluteMaxResult);
Result = __max(Result, sAbsoluteMinResult);
return (Result);
}
}
void HandleHourlyRisks()
{
INT32 iCounter = 0;
@@ -1104,11 +1118,11 @@ void HandleRisksForSoldier( SOLDIERTYPE *pSoldier )
UINT8 ubFacilityType = 0;
UINT8 ubAssignmentType = 0;
if (pSoldier->sFacilityTypeOperated != -1)
if (pSoldier->sFacilityTypeOperated != -1 && GetSoldierFacilityAssignmentIndex( pSoldier ) != -1)
{
// Soldier is working at a specific facility. Risks associated with this specific facility and assignment
// have priority.
ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
ubAssignmentType = (UINT8)GetSoldierFacilityAssignmentIndex( pSoldier );
ubFacilityType = (UINT8)pSoldier->sFacilityTypeOperated;
HandleRisksForSoldierFacilityAssignment( pSoldier, ubFacilityType, ubAssignmentType );
}
@@ -1145,7 +1159,7 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
{
fBadResult = FALSE;
if (gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[iCounter].ubChance > 0)
if (gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].Risk[iCounter].usChance > 0)
{
if (iCounter == RISK_LOYALTY_LOCAL)
{
@@ -1174,11 +1188,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bStrength = __max(1,pSoldier->stats.bStrength + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1207,11 +1240,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bAgility = __max(1,pSoldier->stats.bAgility + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1240,11 +1292,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bDexterity = __max(1,pSoldier->stats.bDexterity + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1273,11 +1344,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bWisdom = __max(1,pSoldier->stats.bWisdom + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1306,12 +1396,31 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bLifeMax = __max(1,pSoldier->stats.bLifeMax + Result);
gMercProfiles[ pSoldier->ubProfile ].bLifeMax = pSoldier->stats.bLifeMax;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeHealthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( HEALTH_INCREASE );
///////////////////////////////////////////////////////////////////////////////////////////
// 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 );
@@ -1360,11 +1469,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bMarksmanship = __max(1,pSoldier->stats.bMarksmanship + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeMarksmanshipTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( MRK_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1393,11 +1521,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bLeadership = __max(1,pSoldier->stats.bLeadership + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeLeadershipTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( LDR_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1426,11 +1573,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bMechanical = __max(1,pSoldier->stats.bMechanical + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeMechanicalTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( MECH_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1459,11 +1625,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bMedical = __max(1,pSoldier->stats.bMedical + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeMedicalTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( MED_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1492,11 +1677,30 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
{
// Soldier is suffering direct stat damage.
pSoldier->stats.bExplosive = __max(1,pSoldier->stats.bExplosive + Result);
///////////////////////////////////////////////////////////////////////////////////////////
// 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;
// make this stat RED for a while...
pSoldier->timeChanges.uiChangeExplosivesTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( EXP_INCREASE );
// merc records - stat damaged
if( Result < 0 )
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
gMercProfiles[ pSoldier->ubProfile ].records.usFacilityAccidents++;
///////////////////////////////////////////////////////////////////////////////////////////
fBadResult = TRUE;
// Log message
@@ -1521,6 +1725,9 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
pSoldier->SoldierTakeDamage( 0, abs(Result), 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)
@@ -1564,10 +1771,16 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
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:
@@ -1612,23 +1825,87 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
// Keel over...
DeductPoints( pSoldier, 0, 10000 );
///////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if our stat is damaged through facility event, make it healable
// Permanently lower certain stats...
pSoldier->stats.bWisdom = __max(1, pSoldier->stats.bWisdom-5);
pSoldier->stats.bDexterity = __max(1, pSoldier->stats.bDexterity-5);
pSoldier->stats.bStrength = __max(1, pSoldier->stats.bStrength-5);
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;
// make those stats RED for a while...
pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
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:
@@ -1646,6 +1923,10 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
swprintf( sString, gzFacilityErrorMessage[24], pTownNames[ubTownID], pSoldier->name, 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:
@@ -1664,6 +1945,10 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
else
swprintf( sString, gzFacilityErrorMessage[26], pSoldier->name, 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;
default:
@@ -1692,11 +1977,11 @@ INT32 GetTotalFacilityHourlyCosts( BOOLEAN fPositive )
// Is character truly valid?
if( !( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) &&
pSoldier->bSectorZ == 0 &&
pSoldier->bSectorZ == 0 && pSoldier != NULL &&
pSoldier->stats.bLife >= OKLIFE &&
!(pSoldier->flags.fMercAsleep) )
{
UINT8 ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
INT8 ubAssignmentType = GetSoldierFacilityAssignmentIndex( pSoldier );
if (ubAssignmentType == -1)
{
// Skip this character.
@@ -1704,15 +1989,15 @@ INT32 GetTotalFacilityHourlyCosts( BOOLEAN fPositive )
continue;
}
UINT8 ubSector = SECTOR(pSoldier->sSectorX, pSoldier->sSectorY);
UINT8 ubFacilityType = (UINT8)pSoldier->sFacilityTypeOperated;
//UINT8 ubSector = SECTOR(pSoldier->sSectorX, pSoldier->sSectorY);
INT16 ubFacilityType = pSoldier->sFacilityTypeOperated;
if (!fPositive && // We want facilities that cost money to operate
if (!fPositive && ubFacilityType != -1 && // We want facilities that cost money to operate
gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].sCostPerHour > 0) // This facility costs money
{
iTotal += gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].sCostPerHour;
}
else if (fPositive && // We want facilities that GENERATE money
else if (fPositive && ubFacilityType != -1 && // We want facilities that GENERATE money
gFacilityTypes[ubFacilityType].AssignmentData[ubAssignmentType].sCostPerHour < 0)
{
// Flip the value to positive
+6
View File
@@ -27,6 +27,8 @@
#include "GameSettings.h"
#endif
#include "LuaInitNPCs.h"
//#define DEBUG_GAME_CLOCK
extern BOOLEAN gfFadeOut;
@@ -247,6 +249,10 @@ void AdvanceClock( UINT8 ubWarpCode )
guiDay = ( guiGameClock / NUM_SEC_IN_DAY );
guiHour = ( guiGameClock - ( guiDay * NUM_SEC_IN_DAY ) ) / NUM_SEC_IN_HOUR;
guiMin = ( guiGameClock - ( ( guiDay * NUM_SEC_IN_DAY ) + ( guiHour * NUM_SEC_IN_HOUR ) ) ) / NUM_SEC_IN_MIN;
uiHourLua = guiHour;
uiDayLua = guiDay;
uiMinLua = guiMin;
swprintf( WORLDTIMESTR, L"%s %d, %02d:%02d", gpGameClockString[ STR_GAMECLOCK_DAY_NAME ], guiDay, guiHour, guiMin );
+1 -1
View File
@@ -206,7 +206,7 @@ BOOLEAN ExecuteStrategicEvent( STRATEGICEVENT *pEvent )
DailyUpdateOfMercSite( (UINT16)GetWorldDay() );
break;
case EVENT_DAY3_ADD_EMAIL_FROM_SPECK:
if(!bMercDayOne)
if ( gGameExternalOptions.fMercDayOne == FALSE && gGameExternalOptions.fAllMercsAvailable == FALSE )
{
AddEmail(MERC_INTRO, MERC_INTRO_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin( ), -1 );
}
+167 -138
View File
@@ -63,12 +63,20 @@
#include "Interface Panels.h"
// HEADROCK HAM 3.6: Include for adding facility debt reset
#include "Facilities.h"
// HEADROCK HAM 4: Include for initializing Manual Restrictions
#include "MilitiaSquads.h"
#include "Map Screen Interface Map Inventory.h"//dnl ch51 081009
#endif
#include "Vehicles.h"
#include "text.h"
#include "connect.h"
#include "XML.h"
#include "mercs.h"
#include "aim.h"
#include "LuaInitNPCs.h"
class OBJECTTYPE;
class SOLDIERTYPE;
@@ -85,7 +93,11 @@ extern UNDERGROUND_SECTORINFO* FindUnderGroundSector( INT16 sMapX, INT16 sMapY,
UINT8 gubScreenCount=0;
void InitNPCs( void )
{
{
LetLuaGameInit(1);
#if 0
MERCPROFILESTRUCT * pProfile;
// add the pilot at a random location!
@@ -264,6 +276,9 @@ void InitNPCs( void )
// set up Devin so he will be placed ASAP
gMercProfiles[ DEVIN ].bNPCData = 3;
#endif
}
void InitBloodCatSectors()
@@ -320,7 +335,7 @@ void InitBloodCatSectors()
}
else
{
THROWEXCEPTION(L"At least one Bloodcat Lair must be defined in BloodcatPlacements.XML!");
SGP_THROW(L"At least one Bloodcat Lair must be defined in BloodcatPlacements.XML!");
}
/*
@@ -430,6 +445,9 @@ void InitStrategicLayer( void )
// HEADROCK HAM 3.6: Initialize facilities.
InitFacilities();
// HEADROCK HAM 4: Initialize Manual Mobile Militia Restrictions.
InitManualMobileRestrictions();
// free up any leave list arrays that were left allocated
ShutDownLeaveList( );
// re-set up leave list arrays for dismissed mercs
@@ -460,11 +478,8 @@ void ShutdownStrategicLayer()
}
BOOLEAN InitNewGame( BOOLEAN fReset )
{
INT32 iStartingCash;
{
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame");
// static fScreenCount = 0;
if( fReset )
{
@@ -507,6 +522,7 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: init arms dealers");
//Initialize the Arms Dealers and Bobby Rays inventory
if( gubScreenCount == 0 )
{
@@ -516,11 +532,82 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
}
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame: clearing messages");
// clear tactical
ClearTacticalMessageQueue( );
// clear mapscreen messages
if(!is_networked)FreeGlobalMessageList(); //hayden
if(!is_networked)
FreeGlobalMessageList(); //hayden
// Do not hide any person names
if ( gGameExternalOptions.fIndividualHiddenPersonNames == FALSE )
{
for (int i=0;i<500;i++)
{
zHiddenNames[i].Hidden = FALSE;
}
}
else
{
// Hide individual person names depending on HiddenNames.xml
LoadHiddenNames();
}
// ------------------------
// Camo Faces
// ------------------------
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
for (int i=0;i<255;i++)
{
gCamoFace[i].gCamoface = FALSE;
gCamoFace[i].gUrbanCamoface = FALSE;
gCamoFace[i].gDesertCamoface = FALSE;
gCamoFace[i].gSnowCamoface = FALSE;
}
if ( !gGameOptions.fNewTraitSystem ) // SANDRO - only with old traits, we get the camo instantly
{
for(int uiLoop=0; uiLoop< NUM_PROFILES; uiLoop++)
{
if ( ProfileHasSkillTrait( uiLoop, CAMOUFLAGED_OT ) > 0 )
{
gCamoFace[uiLoop].gCamoface = TRUE;
}
}
}
}
// ------------------------
// Reset mercs profiles
// ------------------------
UINT8 i;
for(i=0; i<NUM_PROFILES; i++)
{
gConditionsForMercAvailability[i].uiIndex = gConditionsForMercAvailabilityTemp[i].uiIndex;
gConditionsForMercAvailability[i].ProfilId = gConditionsForMercAvailabilityTemp[i].ProfilId;
gConditionsForMercAvailability[i].usMoneyPaid = gConditionsForMercAvailabilityTemp[i].usMoneyPaid;
gConditionsForMercAvailability[i].usDay = gConditionsForMercAvailabilityTemp[i].usDay;
gConditionsForMercAvailability[i].ubMercArrayID = gConditionsForMercAvailabilityTemp[i].ubMercArrayID;
gConditionsForMercAvailability[i].NewMercsAvailable = gConditionsForMercAvailabilityTemp[i].NewMercsAvailable;
gConditionsForMercAvailability[i].StartMercsAvailable = gConditionsForMercAvailabilityTemp[i].StartMercsAvailable;
gConditionsForMercAvailability[i].Drunk = gConditionsForMercAvailabilityTemp[i].Drunk;
gConditionsForMercAvailability[i].uiAlternateIndex = gConditionsForMercAvailabilityTemp[i].uiAlternateIndex;
gConditionsForMercAvailability[i].MercBio = gConditionsForMercAvailabilityTemp[i].MercBio;
}
for(i=0; i<NUM_PROFILES; i++)
{
gAimAvailability[i].uiIndex = gAimAvailabilityTemp[i].uiIndex;
gAimAvailability[i].ProfilId = gAimAvailabilityTemp[i].ProfilId;
gAimAvailability[i].ubAimArrayID = gAimAvailabilityTemp[i].ubAimArrayID;
gAimAvailability[i].AimBio = gAimAvailabilityTemp[i].AimBio;
}
//Lua
IniLuaGlobal();
// IF our first time, go into laptop!
if ( gubScreenCount == 0 )
@@ -536,106 +623,29 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
// this is for the "mercs climbing down from a rope" animation, NOT Skyrider!!
ResetHeliSeats( );
LetLuaGameInit(0);
UINT32 uiDaysTimeMercSiteAvailable = Random( 2 ) + 1;
if(!is_networked)
{
// Setup two new messages!
AddPreReadEmail(OLD_ENRICO_1,OLD_ENRICO_1_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddPreReadEmail(OLD_ENRICO_2,OLD_ENRICO_2_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddPreReadEmail(RIS_REPORT,RIS_REPORT_LENGTH,RIS_EMAIL, GetWorldTotalMin() );
AddPreReadEmail(OLD_ENRICO_3,OLD_ENRICO_3_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
AddEmail(IMP_EMAIL_INTRO,IMP_EMAIL_INTRO_LENGTH,CHAR_PROFILE_SITE, GetWorldTotalMin(), -1);
//AddEmail(ENRICO_CONGRATS,ENRICO_CONGRATS_LENGTH,MAIL_ENRICO, GetWorldTotalMin() );
if(gGameExternalOptions.fMercDayOne)
{
AddEmail(MERC_INTRO, MERC_INTRO_LENGTH, SPECK_FROM_MERC, GetWorldTotalMin( ), -1 );
}
}
// ATE: Set starting cash....
switch( gGameOptions.ubDifficultyLevel )
{
case DIF_LEVEL_EASY:
iStartingCash = gGameExternalOptions.iStartingCashNovice;
//iStartingCash = 45000;
break;
case DIF_LEVEL_MEDIUM:
iStartingCash = gGameExternalOptions.iStartingCashExperienced;
//iStartingCash = 35000;
break;
case DIF_LEVEL_HARD:
iStartingCash = gGameExternalOptions.iStartingCashExpert;
//iStartingCash = 30000;
break;
case DIF_LEVEL_INSANE:
iStartingCash = gGameExternalOptions.iStartingCashInsane;
// iStartingCash = 15000;
break;
default:
Assert(0);
return( FALSE );
}
// Setup initial money
AddTransactionToPlayersBook( ANONYMOUS_DEPOSIT, 0, GetWorldTotalMin(), iStartingCash );
{
UINT32 uiDaysTimeMercSiteAvailable = Random( 2 ) + 1;
// schedule email for message from spec at 7am 3 days in the future
AddFutureDayStrategicEvent( EVENT_DAY3_ADD_EMAIL_FROM_SPECK, 60*7, 0, uiDaysTimeMercSiteAvailable );
}
// schedule email for message from spec at 7am 3 days in the future
AddFutureDayStrategicEvent( EVENT_DAY3_ADD_EMAIL_FROM_SPECK, 60*7, 0, uiDaysTimeMercSiteAvailable );
// HEADROCK HAM 3.5: Reset LZ to default arrival
gsMercArriveSectorX = gGameExternalOptions.ubDefaultArrivalSectorX;
gsMercArriveSectorY = gGameExternalOptions.ubDefaultArrivalSectorY;
#ifdef CRIPPLED_VERSION
{
UINT32 cnt;
//loop through the first 20 AIM mercs and set them to be away
for( cnt = 0; cnt < 20; cnt++)
{
gMercProfiles[ cnt ].bMercStatus = MERC_WORKING_ELSEWHERE;
gMercProfiles[ cnt ].uiDayBecomesAvailable = 14; // 14 days should be ok considering crippled version only goes to day 7
}
}
//Add an event to check for the end of the crippled version
AddEveryDayStrategicEvent( EVENT_CRIPPLED_VERSION_END_GAME_CHECK, 0, 0 );
#endif
if(is_networked)
{
SetLaptopExitScreen( MAP_SCREEN ); //hayden
SetPendingNewScreen( MAP_SCREEN );
// WANNE: No more used
/*
ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L"------------------------------------------------------");
ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[0]);
ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, L"------------------------------------------------------");
ScreenMsg( MSG_FONT_WHITE, MSG_MPSYSTEM, MPHelp[1]);
*/
SetPendingNewScreen( MAP_SCREEN );
}
else
{
SetLaptopExitScreen( INIT_SCREEN );
SetPendingNewScreen(LAPTOP_SCREEN);
SetLaptopExitScreen( INIT_SCREEN );
SetPendingNewScreen(LAPTOP_SCREEN);
}
gubScreenCount = 1;
//Set the fact the game is in progress
@@ -644,53 +654,13 @@ BOOLEAN InitNewGame( BOOLEAN fReset )
return( TRUE );
}
/*
if( ( guiExitScreen == MAP_SCREEN ) && ( LaptopSaveInfo.gfNewGameLaptop ) )
{
SetLaptopExitScreen( GAME_SCREEN );
return( TRUE );
}
*/
if ( gubScreenCount == 1 )
{
// OK , FADE HERE
//BeginFade( INIT_SCREEN, 35, FADE_OUT_REALFADE, 5 );
//BeginFade( INIT_SCREEN, 35, FADE_OUT_VERSION_FASTER, 25 );
//BeginFade( INIT_SCREEN, 35, FADE_OUT_VERSION_SIDE, 0 );
{
gubScreenCount = 2;
return( TRUE );
}
/*
if ( gubScreenCount == 2 )
{
if ( !SetCurrentWorldSector( startingX, startingY, startingZ ) )
{
}
SetLaptopExitScreen( MAP_SCREEN );
FadeInGameScreen( );
EnterTacticalScreen( );
if( gfAtLeastOneMercWasHired == TRUE )
{
gubScreenCount = 3;
}
else
{
}
return( TRUE );
}
*/
DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"InitNewGame done");
return( TRUE );
@@ -782,7 +752,10 @@ void QuickSetupOfMercProfileItems( UINT32 uiCount, UINT8 ubProfileIndex )
gMercProfiles[ ubProfileIndex ].bInvStatus[ BIGPOCK1POS ] = 100;
gMercProfiles[ ubProfileIndex ].bInvNumber[ BIGPOCK1POS ] = 1;
gMercProfiles[ ubProfileIndex ].bSkillTrait = MARTIALARTS;
if (gGameOptions.fNewTraitSystem) // SANDRO - traits
gMercProfiles[ ubProfileIndex ].bSkillTraits[0] = MARTIAL_ARTS_NT;
else
gMercProfiles[ ubProfileIndex ].bSkillTraits[0] = MARTIALARTS_OT;
gMercProfiles[ ubProfileIndex ].inv[ SMALLPOCK3POS ] = KEY_2;
gMercProfiles[ ubProfileIndex ].bInvStatus[ SMALLPOCK3POS ] = 100;
@@ -938,6 +911,58 @@ void ReStartingGame()
//Reset the sectors
gWorldSectorX = gWorldSectorY = 0;
gbWorldSectorZ = -1;
//Legion by Jazz
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//Camo Face
for (int i=0;i<255;i++)
{
gCamoFace[i].gCamoface = FALSE;
gCamoFace[i].gUrbanCamoface = FALSE;
gCamoFace[i].gDesertCamoface = FALSE;
gCamoFace[i].gSnowCamoface = FALSE;
}
if ( !gGameOptions.fNewTraitSystem ) // SANDRO - only with old traits, we get the camo instantly
{
for(int uiLoop=0; uiLoop< NUM_PROFILES; uiLoop++)
{
if ( ProfileHasSkillTrait( uiLoop, CAMOUFLAGED_OT ) > 0 )
{
gCamoFace[uiLoop].gCamoface = TRUE;
}
// else if ( gMercProfiles[uiLoop].bSkillTrait == CAMOUFLAGED_URBAN || gMercProfiles[uiLoop].bSkillTrait2 == CAMOUFLAGED_URBAN )
// {
// gCamoFace[uiLoop].gUrbanCamoface = TRUE;
// }
// else if ( gMercProfiles[uiLoop].bSkillTrait == CAMOUFLAGED_DESERT || gMercProfiles[uiLoop].bSkillTrait2 == CAMOUFLAGED_DESERT )
// {
// gCamoFace[uiLoop].gDesertCamoface = TRUE;
// }
// else if ( gMercProfiles[uiLoop].bSkillTrait == CAMOUFLAGED_SNOW || gMercProfiles[uiLoop].bSkillTrait2 == CAMOUFLAGED_SNOW )
// {
// gCamoFace[uiLoop].gSnowCamoface = TRUE;
// }
}
}
}
//Legion by Jazz
if ( gGameExternalOptions.fIndividualHiddenPersonNames == FALSE )
{
for (int i=0;i<500;i++)
{
zHiddenNames[i].Hidden = FALSE;
}
}
else
{
//Restart Game and New Game
LoadHiddenNames();
}
SoundStopAll( );
@@ -1016,4 +1041,8 @@ void ReStartingGame()
gubCheatLevel = STARTING_CHEAT_LEVEL;
else
gubCheatLevel = 0;
//Lua
IniLuaGlobal();
}
+8 -1
View File
@@ -21,6 +21,8 @@
#include "Strategic AI.h"
#endif
#include "Luaglobal.h"
#include "LuaInitNPCs.h"
#include "SaveLoadGame.h"
#include "GameSettings.h"
#include "connect.h"
@@ -130,6 +132,10 @@ void HandleQuarterHourUpdate()
void HourlyQuestUpdate( void )
{
UINT32 uiHour = GetWorldHour();
#ifdef LUA_HOURLY_QUEST_UPDATE
LetLuaHourlyQuestUpdate(0);
#else
// brothel
if ( uiHour == 4 )
@@ -184,6 +190,7 @@ void HourlyQuestUpdate( void )
SetFactFalse( FACT_MUSEUM_OPEN );
}
#endif
}
#define BAR_TEMPTATION 4
@@ -246,7 +253,7 @@ void HourlyLarryUpdate( void )
if ( usTemptation < BAR_TEMPTATION && GetCurrentBalance() >= Item[ ALCOHOL ].usPrice )
{
if ( pSoldier->bSectorZ == 0 &&
( ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_B) ||
( ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_D) ||
( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_C) ||
( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_C) ||
( pSoldier->sSectorX == 6 && pSoldier->sSectorY == MAP_ROW_C) ||
File diff suppressed because it is too large Load Diff
+75
View File
@@ -0,0 +1,75 @@
#ifndef _LUAINITNPCS_H
#define _LUAINITNPCS_H
#include "Types.h"
typedef struct
{
BOOLEAN fGlobalLuaBool;
UINT32 iGlobalLuaVal;
} LUA_GLOBAL;
extern LUA_GLOBAL gLuaGlobal[1000];
#define MAX_ACTION_NAMES_CHARS 30
typedef struct
{
UINT16 uiIndex;
UINT8 ActionID;
UINT32 BombItem;
CHAR16 szName[MAX_ACTION_NAMES_CHARS];
UINT8 BlowUp;
} ACTION_ITEM_VALUES;
extern ACTION_ITEM_VALUES ActionItemsValues[500];
extern UINT32 uiHourLua;
extern UINT32 uiDayLua;
extern UINT32 uiMinLua;
extern UINT16 PROFILLUA_sSectorX;
extern UINT16 PROFILLUA_sSectorY;
extern UINT8 PROFILLUA_bSectorZ;
extern UINT8 PROFILLUA_Level;
extern UINT8 PROFILLUA_ubID;
extern UINT32 PROFILLUA_sGridNo;
extern UINT8 PROFILLUA_ubDirectiono;
extern UINT8 PROFILLUA_bTeam;
extern UINT8 PROFILLUA2_ubProfile;
extern UINT16 PROFILLUA2_sSectorX;
extern UINT16 PROFILLUA2_sSectorY;
extern UINT8 PROFILLUA2_bSectorZ;
extern UINT8 PROFILLUA2_ubID;
extern UINT32 PROFILLUA2_sGridNo;
extern BOOLEAN LetHandleLoyaltyChangeForNPCAction(UINT8 ubNPCProfileId , UINT8 Init);
extern BOOLEAN LuaHandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , UINT8 Init);
extern BOOLEAN LetLuaHandleEarlyMorningEvents(UINT8 Init);
extern BOOLEAN LetLuaHourlyQuestUpdate(UINT8 Init);
extern BOOLEAN LetLuaMyCustomHandleAtNewGridNo(UINT8 bNewSide, UINT8 ProfileId, UINT8 Init);
extern BOOLEAN LetLuaPerformItemAction(UINT32 Action, INT32 sGridNo, UINT8 InitFunction);
extern BOOLEAN LetLuaGameInit(UINT8 Init);
extern BOOLEAN LetLuaInterfaceDialogue( UINT8 ubNPC, UINT8 InitFunction);
extern BOOLEAN LuaHandlePlayerTeamMemberDeath(UINT8 ProfileId, UINT8 Init);
extern BOOLEAN LuaHandleNPCTeamMemberDeath(UINT8 ProfileId, UINT8 Init);
extern BOOLEAN LuaCheckForKingpinsMoneyMissing( BOOLEAN fFirstCheck, UINT8 Init);
extern BOOLEAN LuaHandleQuestCodeOnSectorExit( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 Init);
extern BOOLEAN LuaHandleQuestCodeOnSectorEntry( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ, UINT8 Init);
extern BOOLEAN LuaHandleDelayedItemsArrival( UINT32 uiReason, UINT8 Init);
extern BOOLEAN LetLuaHandleNPCSystemEvent( UINT32 uiEvent, UINT8 Init);
extern BOOLEAN LuaCheckFact ( UINT16 usFact, UINT8 ubProfileID , UINT32 Init);
extern BOOLEAN LuaHandleNPCDoAction( UINT8 ubTargetNPC, UINT16 usActionCode, UINT8 ubQuoteNum , UINT8 InitFunction);
extern void IniLuaGlobal();
extern BOOLEAN LoadLuaGlobalFromLoadGameFile( HWFILE hFile );
extern BOOLEAN SaveLuaGlobalToSaveGameFile( HWFILE hFile );
//Intro
extern BOOLEAN LuaIntro(UINT8 Init, UINT32 uiCurrentVideo, INT8 bIntroType, UINT32 iStringToUse);
#endif
+200
View File
@@ -0,0 +1,200 @@
#include <iostream>
#include <string>
#include <sstream>
#include "connect.h"
#include "FileMan.h"
#include "GameSettings.h"
#include "Game Init.h"
#include "interface Dialogue.h"
#include "opplist.h"
#include "Strategic All.h"
#include "Luaglobal.h"
#include "Boxing.h"
#include "LuaInitNPCs.h"
#include "Game Clock.h"
#include "Overhead.h"
#include "Music Control.h"
#include "Intro.h"
#include "End Game.h"
#include "Queen Command.h"
#include "gamescreen.h"
#include "Map Screen Interface Map.h"
#include "Creature Spreading.h"
#include "World Items.h"
#include "Map Screen Helicopter.h"
#include "Campaign Types.h"
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
using namespace std;
extern BOOLEAN gfDoneWithSplashScreen;
void IniGlobalGameSetting(lua_State *L)
{
// -------------------------------
// Start new game settings (use "new" prefix)
// -------------------------------
lua_pushinteger(L, gGameOptions.ubGameStyle);
lua_setglobal(L, "newGAME_STYLE");
lua_pushinteger(L, gGameOptions.ubDifficultyLevel);
lua_setglobal(L, "newDIFFICULTY_LEVEL");
// -------------------------------
// ja2_options.ini Settings (use "ini" prefix)
// -------------------------------
lua_pushinteger(L, gGameExternalOptions.fEnableCrepitus);
lua_setglobal(L, "iniENABLE_CREPITUS");
// WANNE: Currently not used
lua_pushboolean(L, gGameExternalOptions.gfInvestigateSector);
lua_setglobal(L, "iniENEMY_INVESTIGATE_SECTOR");
lua_pushboolean(L, gGameExternalOptions.fMercDayOne);
lua_setglobal(L, "iniMERC_WEBSITE_IMMEDIATELY_AVAILABLE");
lua_pushinteger(L, gGameExternalOptions.ubChanceTonyAvailable);
lua_setglobal(L, "iniCHANCE_TONY_AVAILABLE");
lua_pushinteger(L, gGameExternalOptions.iStartingCashNovice);
lua_setglobal(L, "iniSTARTING_CASH_NOVICE");
lua_pushinteger(L, gGameExternalOptions.iStartingCashExperienced);
lua_setglobal(L, "iniSTARTING_CASH_EXPERIENCED");
lua_pushinteger(L, gGameExternalOptions.iStartingCashExpert);
lua_setglobal(L, "iniSTARTING_CASH_EXPERT");
lua_pushinteger(L, gGameExternalOptions.iStartingCashInsane);
lua_setglobal(L, "iniSTARTING_CASH_INSANE");
// WANNE: Currently not used
lua_pushinteger(L, gGameExternalOptions.fCanTrueCiviliansBecomeHostile);
lua_setglobal(L, "iniCAN_TRUE_CIVILIANS_BECOME_HOSTILE");
// -------------------------------
// Other global variables
// -------------------------------
lua_pushinteger(L, gGameExternalOptions.ubDefaultArrivalSectorY);
lua_setglobal(L, "ubDefaultArrivalSectorY");
lua_pushinteger(L, gGameExternalOptions.ubDefaultArrivalSectorX);
lua_setglobal(L, "ubDefaultArrivalSectorX");
lua_pushinteger(L, gGameExternalOptions.iFirstArrivalDelay);
lua_setglobal(L, "iFirstArrivalDelay");
lua_pushinteger(L, guiHelicopterSkyriderTalkState);
lua_setglobal(L, "guiHelicopterSkyriderTalkState");
lua_pushinteger(L, guiTimeOfLastSkyriderMonologue);
lua_setglobal(L, "guiTimeOfLastSkyriderMonologue");
lua_pushinteger(L, gubBloodcatLairSectorId);
lua_setglobal(L, "gubBloodcatLairSectorId");
lua_pushinteger(L, gubSrcSoldierProfile);
lua_setglobal(L, "gubSrcSoldierProfile");
lua_pushinteger(L, giLairID);
lua_setglobal(L, "giLairID");
lua_pushinteger(L, is_networked);
lua_setglobal(L, "is_networked");
lua_pushinteger(L, gWorldSectorX);
lua_setglobal(L, "gWorldSectorX");
lua_pushinteger(L, gWorldSectorY);
lua_setglobal(L, "gWorldSectorY");
lua_pushinteger(L, gbWorldSectorZ);
lua_setglobal(L, "gWorldSectorZ");
lua_pushinteger(L, gbWorldSectorZ);
lua_setglobal(L, "gbWorldSectorZ");
lua_pushinteger(L, giHospitalTempBalance);
lua_setglobal(L, "giHospitalTempBalance");
lua_pushinteger(L, gbHospitalPriceModifier);
lua_setglobal(L, "gbHospitalPriceModifier");
lua_pushinteger(L, giHospitalRefund);
lua_setglobal(L, "giHospitalRefund");
lua_pushboolean(L, gfBoxersResting);
lua_setglobal(L, "gfBoxersResting");
lua_pushinteger(L, gubBoxersRests);
lua_setglobal(L, "gubBoxersRests");
lua_pushinteger(L, gubBoxingMatchesWon);
lua_setglobal(L, "gubBoxingMatchesWon");
lua_pushinteger(L, uiHourLua);
lua_setglobal(L, "cHour");
lua_pushinteger(L, uiDayLua);
lua_setglobal(L, "cDay");
lua_pushinteger(L, uiMinLua);
lua_setglobal(L, "cMin");
lua_pushinteger(L, gbPlayerNum);
lua_setglobal(L, "gbPlayerNum");
lua_pushinteger(L, GetMusicHandle());
lua_setglobal(L, "uiMusicHandle");
lua_pushinteger(L, GetMusicMode());
lua_setglobal(L, "gubMusicMode");
lua_pushboolean(L, IsMusicPlaying());
lua_setglobal(L, "fMusicPlaying");
// unused
//lua_pushboolean(L, gfForceMusicToTense);
//lua_setglobal(L, "gfForceMusicToTense");
// WANNE: Currently not used
lua_pushinteger(L, guiNumWorldItems);
lua_setglobal(L, "guiNumWorldItems");
lua_pushboolean(L, gfEnteringMapScreen);
lua_setglobal(L, "gfEnteringMapScreen");
lua_pushboolean(L, guiIntroExitScreen);
lua_setglobal(L, "guiIntroExitScreen");
lua_pushboolean(L, gfIntroScreenExit);
lua_setglobal(L, "gfIntroScreenExit");
lua_pushinteger(L, sSelMapX);
lua_setglobal(L, "sSelMapX");
lua_pushinteger(L, sSelMapY);
lua_setglobal(L, "sSelMapY");
lua_pushinteger(L, iCurrentMapSectorZ);
lua_setglobal(L, "iCurrentMapSectorZ");
lua_pushboolean(L, gfDoneWithSplashScreen);
lua_setglobal(L, "gfDoneWithSplashScreen");
lua_pushinteger(L, gbIntroScreenMode);
lua_setglobal(L, "gbIntroScreenMode");
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef _LUAGLOBAL_H
#define _LUAGLOBAL_H
#include "Types.h"
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
// --------------------------
// WANNE: Should we enable lua scripting for different actions, or should we use "hardcoded" stuff instead?
#define LUA_INTRO // Intro.lua
#define LUA_HOURLY_QUEST_UPDATE // HourlyUpdate.lua
#define LUA_STRATEGY_EVENT_HANDLER // StrategicEventHandler.lua
#define LUA_STRATEGY_TOWN_LOYALTY // StrategicTownLoyalty.lua
#define LUA_OVERHEAD // Overhead.lua
// --------------------------
void IniGlobalGameSetting(lua_State *L);
#endif
+9 -3
View File
@@ -72,7 +72,7 @@ extern UINT8 ubSAMControlledSectors[ MAP_WORLD_Y ][ MAP_WORLD_X ];
extern INT32 iSeatingCapacities[];
// the static NPC dialogue faces
extern UINT32 uiExternalStaticNPCFaces[];
//extern UINT32 uiExternalStaticNPCFaces[];
// the squad mvt groups
extern INT8 SquadMovementGroups[ ];
@@ -376,10 +376,15 @@ BOOLEAN HandleHeliEnteringSector( INT16 sX, INT16 sY )
else
{
// Say quote: "Gonna have to abort. Enemies below"
if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE)
//CHRISL: Whether skyrider is set to silent or not, we should still say this if we aren't allowing landing in a hot lz.
//if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE)
if(gGameExternalOptions.ubSkyriderHotLZ == 0)
HeliCharacterDialogue( pSkyRider, ARRIVED_IN_HOSTILE_SECTOR );
else
HeliCharacterDialogue( pSkyRider, HELI_HOT_DROP );
//StopTimeCompression();
PaySkyriderBill();
StopTimeCompression();
}
if( CheckForArrivalAtRefuelPoint( ) )
@@ -2230,6 +2235,7 @@ void PaySkyriderBill( void)
ScreenMsg( FONT_MCOLOR_DKRED, MSG_INTERFACE, pSkyriderText[ 1 ], -gMercProfiles[ SKYRIDER ].iBalance );
// kick everyone out! (we know we're in a safe sector if we're paying)
//CHRISL: This may no longer be the case but I'm not sure of a better way to handle things.
MoveAllInHelicopterToFootMovementGroup( );
MakeHeliReturnToBase();
+2
View File
@@ -40,6 +40,8 @@
#define HELI_TOOK_MINOR_DAMAGE 52
#define HELI_TOOK_MAJOR_DAMAGE 53
#define HELI_GOING_DOWN 54
#define HELI_PATH_THROUGH_ENEMEY_AIRSPACE 55
#define HELI_HOT_DROP 56
// enums for skyrider monologue
+294 -12
View File
@@ -23,6 +23,12 @@
#include "Strategic Town Loyalty.h"
#include "strategicmap.h"
#include "Assignments.h"
// HEADROCK HAM 4: Now accepts INI settings
#include "GameSettings.h"
// Also include Town Militia for checks regarding Mobile Militia Restrictions
#include "Town Militia.h"
// Also include Quests, for checking whether a fact is true.
#include "Quests.h"
#endif
@@ -32,6 +38,27 @@
//#define MAP_BORDER_CORNER_X 584
//#define MAP_BORDER_CORNER_Y 279
// HEADROCK HAM 4: Now defining X/Y coordinates for Map Bottom buttons. Some day perhaps variable coordinates?
UINT16 MAP_BORDER_TOWN_BTN_X;
UINT16 MAP_BORDER_TOWN_BTN_Y;
UINT16 MAP_BORDER_MINE_BTN_X;
UINT16 MAP_BORDER_MINE_BTN_Y;
UINT16 MAP_BORDER_TEAMS_BTN_X;
UINT16 MAP_BORDER_TEAMS_BTN_Y;
UINT16 MAP_BORDER_AIRSPACE_BTN_X;
UINT16 MAP_BORDER_AIRSPACE_BTN_Y;
UINT16 MAP_BORDER_ITEM_BTN_X;
UINT16 MAP_BORDER_ITEM_BTN_Y;
UINT16 MAP_BORDER_MILITIA_BTN_X;
UINT16 MAP_BORDER_MILITIA_BTN_Y;
UINT16 MAP_BORDER_MOBILE_BTN_X;
UINT16 MAP_BORDER_MOBILE_BTN_Y;
UINT16 MAP_LEVEL_MARKER_X;
UINT16 MAP_LEVEL_MARKER_Y;
UINT16 MAP_LEVEL_MARKER_DELTA;
UINT16 MAP_LEVEL_MARKER_WIDTH;
// extern to anchored button in winbart97
extern GUI_BUTTON *gpAnchoredButton;
extern BOOLEAN gfAnchoredState;
@@ -54,6 +81,7 @@ BOOLEAN fShowTeamFlag = FALSE;
BOOLEAN fShowMilitia = FALSE;
BOOLEAN fShowAircraftFlag = FALSE;
BOOLEAN fShowItemsFlag = FALSE;
BOOLEAN fShowMobileRestrictionsFlag = FALSE; // HEADROCK HAM 4
BOOLEAN fZoomFlag = FALSE;
//BOOLEAN fShowVehicleFlag = FALSE;
@@ -64,8 +92,9 @@ BOOLEAN fZoomFlag = FALSE;
// buttons & button images
INT32 giMapBorderButtons[ 6 ] = { -1, -1, -1, -1, -1, -1 };
INT32 giMapBorderButtonsImage[ 6 ] = { -1, -1, -1, -1, -1, -1 };
// HEADROCK HAM 4: Increase both arrays by one to accomodate new Mobile Restrictions button
INT32 giMapBorderButtons[ 7 ] = { -1, -1, -1, -1, -1, -1, -1 };
INT32 giMapBorderButtonsImage[ 7 ] = { -1, -1, -1, -1, -1, -1, -1 };
//UINT32 guiMapBorderScrollButtons[ 4 ] = { -1, -1, -1, -1 };
//UINT32 guiMapBorderScrollButtonsImage[ 4 ];
@@ -101,6 +130,8 @@ void BtnItemCallback(GUI_BUTTON *btn,INT32 reason);
void BtnAircraftCallback(GUI_BUTTON *btn,INT32 reason);
void BtnTeamCallback(GUI_BUTTON *btn,INT32 reason);
void BtnMilitiaCallback(GUI_BUTTON *btn,INT32 reason);
// HEADROCK HAM 4: Mobile Restrictions Button callback
void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason);
//void BtnZoomCallback(GUI_BUTTON *btn,INT32 reason);
void BtnGenericMouseMoveButtonCallbackForMapBorder(GUI_BUTTON *btn,INT32 reason);
@@ -215,7 +246,15 @@ void RenderMapBorder( void )
// get and blt border
GetVideoObject(&hHandle, guiMapBorder );
BltVideoObject( guiSAVEBUFFER , hHandle, 0, MAP_BORDER_X, MAP_BORDER_Y, VO_BLT_SRCTRANSPARENCY,NULL );
// HEADROCK HAM 4: Load different map border depending on whether we want to display the mobile militia button or not.
if (gGameExternalOptions.gfAllowMilitiaGroups)
{
BltVideoObject( guiSAVEBUFFER , hHandle, 1, MAP_BORDER_X, MAP_BORDER_Y, VO_BLT_SRCTRANSPARENCY,NULL );
}
else
{
BltVideoObject( guiSAVEBUFFER , hHandle, 0, MAP_BORDER_X, MAP_BORDER_Y, VO_BLT_SRCTRANSPARENCY,NULL );
}
if (iResolution == 1 || iResolution == 2)
{
@@ -301,6 +340,8 @@ BOOLEAN CreateButtonsForMapBorder( void )
{
// will create the buttons needed for the map screen border region
// HEADROCK HAM 4: Call to initiate coordinates for all buttons.
InitMapBorderButtonCoordinates();
/*
// up button
guiMapBorderScrollButtonsImage[ ZOOM_MAP_SCROLL_UP ] = LoadButtonImage( "INTERFACE\\map_screen_bottom_arrows.sti" ,11,4,-1,6,-1 );
@@ -333,43 +374,56 @@ BOOLEAN CreateButtonsForMapBorder( void )
SetButtonFastHelpText( guiMapBorderScrollButtons[ 3 ], pMapScreenBorderButtonHelpText[ 9 ] );
*/
// HEADROCK HAM 4: Button X/Y coordinates are now INIT'ed separately.
// towns
giMapBorderButtonsImage[ MAP_BORDER_TOWN_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,5,-1,14,-1 );
giMapBorderButtons[ MAP_BORDER_TOWN_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_TOWN_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 152), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_TOWN_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_TOWN_BTN ], MAP_BORDER_TOWN_BTN_X, MAP_BORDER_TOWN_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnTownCallback);
// mines
giMapBorderButtonsImage[ MAP_BORDER_MINE_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,4,-1,13,-1 );
giMapBorderButtons[ MAP_BORDER_MINE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MINE_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 109), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_MINE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MINE_BTN ], MAP_BORDER_MINE_BTN_X, MAP_BORDER_MINE_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnMineCallback);
// people
giMapBorderButtonsImage[ MAP_BORDER_TEAMS_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,3,-1,12,-1 );
giMapBorderButtons[ MAP_BORDER_TEAMS_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_TEAMS_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 66), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_TEAMS_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_TEAMS_BTN ], MAP_BORDER_TEAMS_BTN_X, MAP_BORDER_TEAMS_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnTeamCallback);
// militia
giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,8,-1,17,-1 );
giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 23), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ], MAP_BORDER_MILITIA_BTN_X, MAP_BORDER_MILITIA_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnMilitiaCallback);
// airspace
giMapBorderButtonsImage[ MAP_BORDER_AIRSPACE_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,2,-1,11,-1 );
giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_AIRSPACE_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 20), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_AIRSPACE_BTN ], MAP_BORDER_AIRSPACE_BTN_X, MAP_BORDER_AIRSPACE_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnAircraftCallback);
// items
giMapBorderButtonsImage[ MAP_BORDER_ITEM_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,1,-1,10,-1 );
giMapBorderButtons[ MAP_BORDER_ITEM_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_ITEM_BTN ], MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 63), (SCREEN_HEIGHT - 160),
giMapBorderButtons[ MAP_BORDER_ITEM_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_ITEM_BTN ], MAP_BORDER_ITEM_BTN_X, MAP_BORDER_ITEM_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnItemCallback);
// WANNE: Only display the buton when mobile militia is allowed!
// HEADROCK HAM 4: Mobile Restrictions Button
if (gGameExternalOptions.gfAllowMilitiaGroups)
{
giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti" ,-1,20,-1,21,-1 );
giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ] = QuickCreateButton( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ], MAP_BORDER_MOBILE_BTN_X, MAP_BORDER_MOBILE_BTN_Y,
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH,
(GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnMobileCallback);
}
// raise and lower view level
@@ -395,6 +449,9 @@ BOOLEAN CreateButtonsForMapBorder( void )
SetButtonFastHelpText( giMapBorderButtons[ 4 ], pMapScreenBorderButtonHelpText[ 4 ] );
SetButtonFastHelpText( giMapBorderButtons[ 5 ], pMapScreenBorderButtonHelpText[ 5 ] );
if (gGameExternalOptions.gfAllowMilitiaGroups)
SetButtonFastHelpText( giMapBorderButtons[ 6 ], pMapScreenBorderButtonHelpText[ 6 ] ); // HEADROCK HAM 4: Mobile Militia button
//SetButtonFastHelpText( guiMapBorderLandRaiseButtons[ 0 ], pMapScreenBorderButtonHelpText[ 10 ] );
//SetButtonFastHelpText( guiMapBorderLandRaiseButtons[ 1 ], pMapScreenBorderButtonHelpText[ 11 ] );
@@ -405,6 +462,9 @@ BOOLEAN CreateButtonsForMapBorder( void )
SetButtonCursor(giMapBorderButtons[ 4 ], MSYS_NO_CURSOR );
SetButtonCursor(giMapBorderButtons[ 5 ], MSYS_NO_CURSOR );
if (gGameExternalOptions.gfAllowMilitiaGroups)
SetButtonCursor(giMapBorderButtons[ 6 ], MSYS_NO_CURSOR ); // HEADROCK HAM 4: Mobile Militia button
// SetButtonCursor(guiMapBorderLandRaiseButtons[ 0 ], MSYS_NO_CURSOR );
// SetButtonCursor(guiMapBorderLandRaiseButtons[ 1 ], MSYS_NO_CURSOR );
@@ -432,6 +492,10 @@ void DeleteMapBorderButtons( void )
RemoveButton( giMapBorderButtons[ 4 ]);
RemoveButton( giMapBorderButtons[ 5 ]);
// WANNE: Only remove if we added the button
if (gGameExternalOptions.gfAllowMilitiaGroups)
RemoveButton( giMapBorderButtons[ 6 ]); // HEADROCK HAM 4
//RemoveButton( guiMapBorderLandRaiseButtons[ 0 ]);
//RemoveButton( guiMapBorderLandRaiseButtons[ 1 ]);
@@ -451,11 +515,17 @@ void DeleteMapBorderButtons( void )
UnloadButtonImage( giMapBorderButtonsImage[ 4 ] );
UnloadButtonImage( giMapBorderButtonsImage[ 5 ] );
// WANNE: Only unload if we added the button
if (gGameExternalOptions.gfAllowMilitiaGroups)
UnloadButtonImage( giMapBorderButtonsImage[ 6 ] ); // HEADROCK HAM 4
//UnloadButtonImage( guiMapBorderLandRaiseButtonsImage[ 0 ] );
//UnloadButtonImage( guiMapBorderLandRaiseButtonsImage[ 1 ] );
for ( ubCnt = 0; ubCnt < 6; ubCnt++ )
// HEADROCK HAM 4: Increased number of buttons by one.
for ( ubCnt = 0; ubCnt < NUM_MAP_BORDER_BTNS; ubCnt++ )
{
giMapBorderButtons[ ubCnt ] = -1;
giMapBorderButtonsImage[ ubCnt ] = -1;
@@ -608,6 +678,21 @@ void BtnItemCallback(GUI_BUTTON *btn,INT32 reason)
}
}
// HEADROCK HAM 4: Callback for Mobile Restrictions Button
void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
CommonBtnCallbackBtnDownChecks();
ToggleMobileFilter();
}
else if(reason & MSYS_CALLBACK_REASON_RBUTTON_DWN )
{
CommonBtnCallbackBtnDownChecks();
}
}
/*
void BtnZoomCallback(GUI_BUTTON *btn,INT32 reason)
@@ -723,6 +808,12 @@ void ToggleShowMinesMode( void )
fShowItemsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_ITEM_BTN );
}
// HEADROCK HAM 4: Mobile Militia Restrictions
if( fShowMobileRestrictionsFlag == TRUE )
{
fShowMobileRestrictionsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
}
}
fMapPanelDirty = TRUE;
@@ -859,6 +950,26 @@ void ToggleItemsFilter( void )
}
}
// HEADROCK HAM 4: Toggle Mobile Restrictions Button
void ToggleMobileFilter( void )
{
if( fShowMobileRestrictionsFlag == TRUE )
{
// turn items OFF
fShowMobileRestrictionsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
// dirty regions
fMapPanelDirty = TRUE;
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
}
else
{
// turn items ON
TurnOnMobileFilterMode();
}
}
/*
void ShowDestinationOfPlottedPath( STR16 pLoc )
@@ -1279,6 +1390,12 @@ void TurnOnShowTeamsMode( void )
fShowMilitia = FALSE;
MapBorderButtonOff( MAP_BORDER_MILITIA_BTN );
}
// HEADROCK HAM 4: Turn off Show Militia Restrictions
if (fShowMobileRestrictionsFlag == TRUE)
{
fShowMobileRestrictionsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
}
/*
if( fShowAircraftFlag == TRUE )
@@ -1340,6 +1457,12 @@ void TurnOnAirSpaceMode( void )
MapBorderButtonOff( MAP_BORDER_MILITIA_BTN );
}
*/
// HEADROCK HAM 4: Turn off Militia Restrictions
if (fShowMobileRestrictionsFlag == TRUE)
{
fShowMobileRestrictionsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
}
// Turn off items
if( fShowItemsFlag == TRUE )
@@ -1403,6 +1526,12 @@ void TurnOnItemFilterMode( void )
fShowMilitia = FALSE;
MapBorderButtonOff( MAP_BORDER_MILITIA_BTN );
}
// HEADROCK HAM 4: Turn off Militia Restrictions
if (fShowMobileRestrictionsFlag == TRUE)
{
fShowMobileRestrictionsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
}
if( fShowAircraftFlag == TRUE )
{
@@ -1422,6 +1551,77 @@ void TurnOnItemFilterMode( void )
}
}
// HEADROCK HAM 4: Activate "View Mobile Restrictions" mode.
void TurnOnMobileFilterMode( void )
{
// if mode already on, leave, else set and redraw
if( fShowMobileRestrictionsFlag == FALSE )
{
fShowMobileRestrictionsFlag = TRUE;
MapBorderButtonOn( MAP_BORDER_MOBILE_BTN );
// Also turn on Militia mode
fShowMilitia = FALSE; // Fool the function so that it always turns militia ON.
ToggleShowMilitiaMode();
if( fShowMineFlag == TRUE )
{
fShowMineFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_MINE_BTN );
}
if( fShowTeamFlag == TRUE )
{
fShowTeamFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_TEAMS_BTN );
}
if( fShowAircraftFlag == TRUE )
{
fShowAircraftFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN );
}
// Turn off items
if( fShowItemsFlag == TRUE )
{
fShowItemsFlag = FALSE;
MapBorderButtonOff( MAP_BORDER_ITEM_BTN );
}
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) )
{
AbortMovementPlottingMode( );
}
STR16 pwString = NULL;
// check if player has any Mobile militia
if ( DoesPlayerHaveAnyMobileMilitia( ) == 1 )
{
// say you need to train mobiles first
pwString = zMarksMapScreenText[ 25 ];
MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pwString );
}
if ( !gubFact[ FACT_MOBILE_RESTRICTIONS_VIEWED ] )
{
// say you need to train mobiles first
pwString = zMarksMapScreenText[ 26 ];
MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, pwString );
SetFactTrue( FACT_MOBILE_RESTRICTIONS_VIEWED );
}
// dirty regions
fMapPanelDirty = TRUE;
fTeamPanelDirty = TRUE;
fCharacterInfoPanelDirty = TRUE;
}
}
/*
void UpdateLevelButtonStates( void )
@@ -1536,6 +1736,15 @@ void InitializeMapBorderButtonStates( void )
{
MapBorderButtonOff( MAP_BORDER_MILITIA_BTN );
}
if( fShowMobileRestrictionsFlag )
{
MapBorderButtonOn( MAP_BORDER_MOBILE_BTN );
}
else
{
MapBorderButtonOff( MAP_BORDER_MOBILE_BTN );
}
}
@@ -1562,6 +1771,39 @@ BOOLEAN DoesPlayerHaveAnyMilitia( void )
return( FALSE );
}
// HEADROCK HAM 4: Check for Mobile Militia
UINT8 DoesPlayerHaveAnyMobileMilitia( void )
{
INT16 sX, sY;
if (!gGameExternalOptions.gfAllowMilitiaGroups)
{
// Mobile Militia not allowed at all.
return (0);
}
// run through list of towns that might have militia..if any return TRUE..else return FALSE
for( sX = 1; sX < MAP_WORLD_X - 1; sX++ )
{
for( sY = 1; sY < MAP_WORLD_Y - 1; sY++ )
{
// Look only in sectors where Militia Training is not allowed at all. If any militia are found there,
// it means that they had to MOVE there, hence mobile militia.
if (!MilitiaTrainingAllowedInSector( sX, sY, 0 ))
{
if( ( SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] + SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]
+ SectorInfo[ SECTOR( sX, sY )].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] ) > 0 )
{
// found at least one
return( 2 );
}
}
}
}
// Militia are allowed, but none have been found.
return( 1 );
}
void CommonBtnCallbackBtnDownChecks( void )
@@ -1591,13 +1833,16 @@ void InitMapScreenFlags( void )
fShowAircraftFlag = FALSE;
fShowItemsFlag = FALSE;
// HEADROCK HAM 4: Militia Restrictions
fShowMobileRestrictionsFlag = FALSE;
}
void MapBorderButtonOff( UINT8 ubBorderButtonIndex )
{
Assert( ubBorderButtonIndex < 6 );
Assert( ubBorderButtonIndex < NUM_MAP_BORDER_BTNS );
if( fShowMapInventoryPool )
{
@@ -1618,7 +1863,7 @@ void MapBorderButtonOff( UINT8 ubBorderButtonIndex )
void MapBorderButtonOn( UINT8 ubBorderButtonIndex )
{
Assert( ubBorderButtonIndex < 6 );
Assert( ubBorderButtonIndex < NUM_MAP_BORDER_BTNS );
if( fShowMapInventoryPool )
{
@@ -1635,3 +1880,40 @@ void MapBorderButtonOn( UINT8 ubBorderButtonIndex )
ButtonList[ giMapBorderButtons[ ubBorderButtonIndex ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
// HEADROCK HAM 4: Init the coordinates for all Map Border buttons
void InitMapBorderButtonCoordinates()
{
MAP_BORDER_TOWN_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 152);
MAP_BORDER_TOWN_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_MINE_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 109);
MAP_BORDER_MINE_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_TEAMS_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 66);
MAP_BORDER_TEAMS_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_AIRSPACE_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 20);
MAP_BORDER_AIRSPACE_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_ITEM_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 63);
MAP_BORDER_ITEM_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_MILITIA_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 - 23);
MAP_BORDER_MILITIA_BTN_Y = (SCREEN_HEIGHT - 160);
MAP_BORDER_MOBILE_BTN_X = 0;
MAP_BORDER_MOBILE_BTN_Y = 0;
MAP_LEVEL_MARKER_X = (MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 114));
MAP_LEVEL_MARKER_Y = (SCREEN_HEIGHT - 160); //(SCREEN_HEIGHT - 157) //323
MAP_LEVEL_MARKER_DELTA = 8;
MAP_LEVEL_MARKER_WIDTH = 55; //( (SCREEN_WIDTH - 20) - MAP_LEVEL_MARKER_X )
if (gGameExternalOptions.gfAllowMilitiaGroups)
{
// Mobile button appears next to Militia button.
MAP_BORDER_MOBILE_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 16);
MAP_BORDER_MOBILE_BTN_Y = (SCREEN_HEIGHT - 160);
// Airspace, Items, ZLevel buttons all moved to the right (+22px, +22px, +10px).
MAP_BORDER_AIRSPACE_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 42);
MAP_BORDER_ITEM_BTN_X = MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 85);
MAP_LEVEL_MARKER_X = (MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 124));
}
}
+17 -5
View File
@@ -30,6 +30,8 @@ enum{
MAP_BORDER_AIRSPACE_BTN,
MAP_BORDER_ITEM_BTN,
MAP_BORDER_MILITIA_BTN,
MAP_BORDER_MOBILE_BTN, // HEADROCK HAM 4: Mobile Militia Restrictions button
NUM_MAP_BORDER_BTNS, // end enumeration marker
};
@@ -41,10 +43,12 @@ enum{
*/
#define MAP_LEVEL_MARKER_X (MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 114)) //MAP_BORDER_X + MAP_BORDER_X_OFFSET + 384 //(SCREEN_WIDTH - 75) //565
#define MAP_LEVEL_MARKER_Y (SCREEN_HEIGHT - 160) //(SCREEN_HEIGHT - 157) //323
#define MAP_LEVEL_MARKER_DELTA 8
#define MAP_LEVEL_MARKER_WIDTH 55 //( (SCREEN_WIDTH - 20) - MAP_LEVEL_MARKER_X )
// HEADROCK HAM 4: Turned these into EXTERNS to allow dynamic modification
//#define MAP_LEVEL_MARKER_X (MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X) / 2 + 114)) //MAP_BORDER_X + MAP_BORDER_X_OFFSET + 384 //(SCREEN_WIDTH - 75) //565
extern UINT16 MAP_LEVEL_MARKER_X;
extern UINT16 MAP_LEVEL_MARKER_Y;
extern UINT16 MAP_LEVEL_MARKER_DELTA;
extern UINT16 MAP_LEVEL_MARKER_WIDTH;
extern BOOLEAN fShowTownFlag;
@@ -54,6 +58,7 @@ extern BOOLEAN fShowMilitia;
extern BOOLEAN fShowAircraftFlag;
extern BOOLEAN fShowItemsFlag;
extern BOOLEAN fZoomFlag;
extern BOOLEAN fShowMobileRestrictionsFlag; // HEADROCK HAM 4: Manual Mobile Militia mode
//extern BOOLEAN fShowVehicleFlag;
//extern BOOLEAN fMapScrollDueToPanelButton;
@@ -77,10 +82,14 @@ void ToggleShowMilitiaMode( void );
void ToggleShowTeamsMode( void );
void ToggleAirspaceMode( void );
void ToggleItemsFilter( void );
// HEADROCK HAM 4: Toggle Mobile Militia Restrictions Filter
void ToggleMobileFilter( void );
void TurnOnShowTeamsMode( void );
void TurnOnAirSpaceMode( void );
void TurnOnItemFilterMode( void );
// HEADROCK HAM 4: Turn on Mobile Militia Restrictions Filter
void TurnOnMobileFilterMode( void );
/*
// enable disable map border
@@ -95,6 +104,8 @@ BOOLEAN CreateButtonsForMapBorder( void );
// render the pop up for eta in path plotting in map screen
void RenderMapBorderEtaPopUp( void );
BOOLEAN DoesPlayerHaveAnyMilitia( void );
// HEADROCK HAM 4: Same with Mobiles.
UINT8 DoesPlayerHaveAnyMobileMilitia( void );
//void UpdateLevelButtonStates( void );
@@ -107,6 +118,7 @@ void InitMapScreenFlags( void );
void MapBorderButtonOff( UINT8 ubBorderButtonIndex );
void MapBorderButtonOn( UINT8 ubBorderButtonIndex );
// HEADROCK HAM 4: Initialize coordinates for Map Border buttons
void InitMapBorderButtonCoordinates();
#endif
@@ -49,6 +49,8 @@
#include "GameSettings.h"
#include "_Ja25EnglishText.h"
#include "SaveLoadScreen.h"
#include "Interface Control.h"
#include "Sys Globals.h"
#include "game init.h"
#endif
@@ -1928,6 +1930,10 @@ void HandleExitsFromMapScreen( void )
case MAP_EXIT_TO_TACTICAL:
SetCurrentWorldSector( sSelMapX, sSelMapY, ( INT8 )iCurrentMapSectorZ );
// silversurfer: bugfix for panel redraw issue after quickload from tactical screen
// this will make sure that the tactical screen gets refreshed and guiTacticalInterfaceFlags is reset
fFirstTimeInGameScreen = TRUE;
guiTacticalInterfaceFlags &= (~INTERFACE_MAPSCREEN );
break;
case MAP_EXIT_TO_OPTIONS:
@@ -849,7 +849,10 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason )
//CHRISL: Make it possible to right click and pull up stack popup and/or item description boxes
WORLDITEM * twItem = &(pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ]);
bool fValidPointer = false;
if ( !InSectorStackPopup( ) && !InItemStackPopup( ) && !InItemDescriptionBox( ) && !InKeyRingPopup( ) && twItem->object.exists() == true && (bSelectedInfoChar != -1 && gCharactersList[bSelectedInfoChar].fValid))
//CHRISL: Try to update InSector value so we don't have to "activate" a sector
if(MercPtrs[gCharactersList[bSelectedInfoChar].usSolID]->sSectorX == sSelMapX && MercPtrs[gCharactersList[bSelectedInfoChar].usSolID]->sSectorY == sSelMapY && MercPtrs[gCharactersList[bSelectedInfoChar].usSolID]->bSectorZ == iCurrentMapSectorZ && !MercPtrs[gCharactersList[bSelectedInfoChar].usSolID]->flags.fBetweenSectors)
MercPtrs[gCharactersList[bSelectedInfoChar].usSolID]->bInSector=TRUE;
if ( !InSectorStackPopup( ) && !InItemStackPopup( ) /*&& !InItemDescriptionBox( ) */ && !InKeyRingPopup( ) && twItem->object.exists() == true && (bSelectedInfoChar != -1 && gCharactersList[bSelectedInfoChar].fValid))
{
if(OK_CONTROL_MERC( MercPtrs[gCharactersList[bSelectedInfoChar].usSolID] ))
{
@@ -863,7 +866,7 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason )
{
if(gpItemPointer->usItem == twItem->object.usItem)
fValidPointer = true;
if(ValidAttachment(gpItemPointer->usItem, twItem->object.usItem) == TRUE)
if(ValidAttachment(gpItemPointer->usItem, &(twItem->object)) == TRUE)
fValidPointer = true;
if(ValidAmmoType(twItem->object.usItem, gpItemPointer->usItem) == TRUE)
fValidPointer = true;
@@ -871,6 +874,12 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason )
if(twItem->object.ubNumberOfObjects == 1 && fValidPointer)
{
fShowInventoryFlag = TRUE;
if (InItemDescriptionBox( ))
{
DeleteItemDescriptionBox();
}
MAPInternalInitItemDescriptionBox( &twItem->object, 0, MercPtrs[gCharactersList[bSelectedInfoChar].usSolID] );
}
else if(fValidPointer)
@@ -1007,6 +1016,17 @@ void MapInvenPoolSlots(MOUSE_REGION * pRegion, INT32 iReason )
usNewItemIndex = gpItemPointer->usItem;
iOldNumberOfObjects = pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].object.ubNumberOfObjects;
//CHRISL: Allow CTRL+LMB to clean up stacks just like we do with personal inventory
//Curretly, screen isn't automatically refreshing. You have to move your cursor after CTRL+LMB to see the results.
if ( _KeyDown(CTRL) )
{
CleanUpStack( &( pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].object ), gpItemPointer );
if ( gpItemPointer->exists() == false )
{
MAPEndItemPointer( );
}
return;
}
// Else, try to place here
if ( PlaceObjectInInventoryStash( &( pInventoryPoolList[ ( iCurrentInventoryPoolPage * MAP_INVENTORY_POOL_SLOT_COUNT ) + iCounter ].object ), gpItemPointer ) )
@@ -2672,7 +2692,8 @@ INT32 SellItem( OBJECTTYPE& object, BOOLEAN useModifier )
}
iPrice += ( itemPrice * object[bLoop]->data.objectStatus / 100 );
for (attachmentList::iterator iter = object[bLoop]->attachments.begin(); iter != object[bLoop]->attachments.end(); ++iter) {
iPrice += SellItem(*iter, FALSE);
if(iter->exists())
iPrice += SellItem(*iter, FALSE);
}
}
}
@@ -2683,7 +2704,8 @@ INT32 SellItem( OBJECTTYPE& object, BOOLEAN useModifier )
{
iPrice += ( itemPrice * object[bLoop]->data.objectStatus / 100 );
for (attachmentList::iterator iter = object[bLoop]->attachments.begin(); iter != object[bLoop]->attachments.end(); ++iter) {
iPrice += SellItem(*iter, FALSE);
if(iter->exists())
iPrice += SellItem(*iter, FALSE);
}
}
+355 -39
View File
@@ -48,6 +48,7 @@
#include "Quests.h"
#include "connect.h"
#include "Strategic Mines.h"
// HEADROCK HAM 3.5: included for detectionlevels
#include "Facilities.h"
#include "MilitiaSquads.h"
@@ -272,6 +273,14 @@ enum{
MAP_SHADE_DK_GREEN,
MAP_SHADE_LT_RED,
MAP_SHADE_DK_RED,
// HEADROCK HAM 4: Several new shades, used with the new Manual Mobile Militia restrictions, and the greyed-out map display.
MAP_SHADE_MD_RED,
MAP_SHADE_LT_YELLOW,
MAP_SHADE_DK_YELLOW,
MAP_SHADE_LT_CYAN,
MAP_SHADE_DK_CYAN,
MAP_SHADE_LT_GREY,
MAP_SHADE_DK_GREY,
};
// the big map .pcx
UINT32 guiBIGMAP;
@@ -342,8 +351,8 @@ INT16 sElitesOnCursor = 0;
INT16 sSelectedMilitiaTown = 0;
extern MINE_LOCATION_TYPE gMineLocation[];
extern MINE_STATUS_TYPE gMineStatus[];
//extern MINE_LOCATION_TYPE gMineLocation[];
//extern MINE_STATUS_TYPE gMineStatus[];
// sublevel graphics
UINT32 guiSubLevel1, guiSubLevel2, guiSubLevel3;
@@ -374,6 +383,14 @@ UINT16 *pMapLTRedPalette;
UINT16 *pMapDKRedPalette;
UINT16 *pMapLTGreenPalette;
UINT16 *pMapDKGreenPalette;
// HEADROCK HAM 4: Several new palettes for yellow, cyan, grey.
UINT16 *pMapMDRedPalette;
UINT16 *pMapLTYellowPalette;
UINT16 *pMapDKYellowPalette;
UINT16 *pMapLTCyanPalette;
UINT16 *pMapDKCyanPalette;
UINT16 *pMapLTGreyPalette;
UINT16 *pMapDKGreyPalette;
// the map border eta pop up
@@ -770,42 +787,130 @@ UINT32 DrawMap( void )
// LATE DESIGN CHANGE: darken sectors not yet visited, instead of those under known enemy control
if(!is_networked) //hayden - dont darken anything
{
if( GetSectorFlagStatus( cnt, cnt2, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) == FALSE )
// if ( IsTheSectorPerceivedToBeUnderEnemyControl( cnt, cnt2, ( INT8 )( iCurrentMapSectorZ ) ) )
// HEADROCK HAM 4: Mobile View shows all tiles as explored.
if (!fShowMobileRestrictionsFlag && !iCurrentMapSectorZ )
{
if( fShowAircraftFlag && !iCurrentMapSectorZ )
if( GetSectorFlagStatus( cnt, cnt2, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) == FALSE )
// if ( IsTheSectorPerceivedToBeUnderEnemyControl( cnt, cnt2, ( INT8 )( iCurrentMapSectorZ ) ) )
{
if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled )
if( fShowAircraftFlag && !iCurrentMapSectorZ )
{
// sector not visited, not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN );
if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled )
{
// sector not visited, not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN );
}
else
{
// sector not visited, controlled and air not
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED );
}
}
// HEADROCK HAM 4: Show Manual Mobile Militia Restrictions
else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ )
{
/* For now, Mobile View Mode shows all tiles as explored.
UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt,cnt2) );
switch ( ubManualMobileMovementAllowed )
{
case 0:
// Sector not visited, Mobiles not allowed here at all.
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED );
break;
case 1:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_YELLOW );
break;
case 2:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_CYAN );
break;
case 3:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN );
break;
}*/
}
else
{
// sector not visited, controlled and air not
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED );
// not visited
if (gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR])
{
// HEADROCK HAM 4: An alternate display for the map in normal mode. Unexplored sectors
// are in grey, similar to a recon map. Others are left in normal vivid color.
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY );
}
else
{
ShadeMapElem( cnt, cnt2, MAP_SHADE_BLACK );
}
}
}
else
{
// not visited
ShadeMapElem( cnt, cnt2, MAP_SHADE_BLACK );
if( fShowAircraftFlag && !iCurrentMapSectorZ )
{
if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled )
{
// sector visited and air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN);
}
else
{
// sector visited but not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED );
}
}
// HEADROCK HAM 4: Show Manual Mobile Militia Restrictions
else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ )
{
/* For now, Mobile View Mode shows all tiles as explored.
UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt, cnt2) );
switch ( ubManualMobileMovementAllowed )
{
case 0:
// Sector not visited, Mobiles not allowed here at all.
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED );
break;
case 1:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_YELLOW );
break;
case 2:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_CYAN );
break;
case 3:
// sector not visited, Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN );
break;
}*/
}
}
}
else
else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ)
{
if( fShowAircraftFlag && !iCurrentMapSectorZ )
// HEADROCK HAM 4: Show Manual Mobile Militia Restrictions
UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt, cnt2) );
switch ( ubManualMobileMovementAllowed )
{
if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled )
{
// sector visited and air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN);
}
else
{
// sector visited but not air controlled
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED );
}
case 0:
// Mobiles not allowed here at all.
ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY );
break;
case 1:
// Mobiles forbidden by player
ShadeMapElem( cnt, cnt2, MAP_SHADE_MD_RED );
break;
case 2:
// Mobiles can enter but not leave
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_YELLOW );
break;
case 3:
// Mobiles can enter
ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN );
break;
}
}
}
@@ -835,7 +940,8 @@ UINT32 DrawMap( void )
// draw mine icons
for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; iCounter++ )
{
BlitMineIcon( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY );
//BlitMineIcon( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY );
BlitMineIcon( gMineStatus[ iCounter ].sSectorX, gMineStatus[ iCounter ].sSectorY );
}
@@ -845,7 +951,8 @@ UINT32 DrawMap( void )
// show mine name/production text
for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; iCounter++ )
{
BlitMineText( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY );
//BlitMineText( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY );
BlitMineText( gMineStatus[ iCounter ].sSectorX, gMineStatus[ iCounter ].sSectorY );
}
}
@@ -1434,7 +1541,6 @@ BOOLEAN ShadeMapElem( INT16 sMapX, INT16 sMapY, INT32 iColor )
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_DK_RED ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
@@ -1454,8 +1560,135 @@ BOOLEAN ShadeMapElem( INT16 sMapX, INT16 sMapY, INT32 iColor )
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
UnLockVideoSurface( guiSAVEBUFFER );
break;
/////////////////////////////////////////////////////////
// HEADROCK HAM 4: New colors for map shaders
/////////////////////////////////////////////////////////
case( MAP_SHADE_MD_RED ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapMDRedPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_LT_YELLOW ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapLTYellowPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_DK_YELLOW ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapDKYellowPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_LT_CYAN ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapLTCyanPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_DK_CYAN ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapDKCyanPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_LT_GREY ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapLTGreyPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_DK_GREY ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapDKGreyPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip );
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
///////////////////////////////////////////////
// HEADROCK HAM 4: End new shaders
///////////////////////////////////////////////
}
// restore original palette
@@ -1643,6 +1876,45 @@ BOOLEAN ShadeMapElemZoomIn(INT16 sMapX, INT16 sMapY, INT32 iColor )
break;
// HEADROCK HAM 4: Add two new colors here.
case( MAP_SHADE_LT_YELLOW ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapLTYellowPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
// now blit
Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY , &clip);
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
case( MAP_SHADE_DK_YELLOW ):
// grab video surface and set palette
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
hSrcVSurface->p16BPPPalette = pMapDKYellowPalette;
// lock source and dest buffers
pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES);
CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) );
pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES);
// now blit
Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY , &clip);
// unlock source and dest buffers
UnLockVideoSurface( guiBIGMAP );
UnLockVideoSurface( guiSAVEBUFFER );
break;
}
}
@@ -1674,8 +1946,17 @@ BOOLEAN InitializePalettesForMap( void )
// set up various palettes
pMapLTRedPalette = Create16BPPPaletteShaded( pPalette, 400, 0, 0, TRUE );
pMapDKRedPalette = Create16BPPPaletteShaded( pPalette, 200, 0, 0, TRUE );
pMapLTGreenPalette = Create16BPPPaletteShaded( pPalette, 0, 400, 0, TRUE );
pMapLTGreenPalette = Create16BPPPaletteShaded( pPalette, 100, 300, 0, TRUE );
pMapDKGreenPalette = Create16BPPPaletteShaded( pPalette, 0, 200, 0, TRUE );
// HEADROCK HAM 4: Several new palettes for Yellow, Cyan, Grey
pMapMDRedPalette = Create16BPPPaletteShaded( pPalette, 300, 0, 0, TRUE );
pMapLTYellowPalette = Create16BPPPaletteShaded( pPalette, 400, 350, 0, TRUE );
pMapDKYellowPalette = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE );
pMapLTCyanPalette = Create16BPPPaletteShaded( pPalette, 0, 350, 350, TRUE );
pMapDKCyanPalette = Create16BPPPaletteShaded( pPalette, 0, 200, 200, TRUE );
pMapLTGreyPalette = Create16BPPPaletteShaded( pPalette, 400, 400, 400, TRUE );
pMapDKGreyPalette = Create16BPPPaletteShaded( pPalette, 250, 250, 250, TRUE );
// delete image
DeleteVideoSurfaceFromIndex(uiTempMap);
@@ -1692,14 +1973,26 @@ void ShutDownPalettesForMap( void )
MemFree( pMapDKRedPalette );
MemFree( pMapLTGreenPalette );
MemFree( pMapDKGreenPalette );
// HEADROCK HAM 4: Several new palettes (see also below)
MemFree( pMapMDRedPalette );
MemFree( pMapLTYellowPalette );
MemFree( pMapDKYellowPalette );
MemFree( pMapLTCyanPalette );
MemFree( pMapDKCyanPalette );
MemFree( pMapLTGreyPalette );
MemFree( pMapDKGreyPalette );
pMapLTRedPalette = NULL;
pMapDKRedPalette = NULL;
pMapLTGreenPalette = NULL;
pMapDKGreenPalette = NULL;
pMapMDRedPalette = NULL;
pMapLTYellowPalette = NULL;
pMapDKYellowPalette = NULL;
pMapLTCyanPalette = NULL;
pMapDKCyanPalette = NULL;
pMapLTGreyPalette = NULL;
pMapDKGreyPalette = NULL;
return;
}
@@ -2038,9 +2331,12 @@ void DisplayHelicopterTempPath( void )
return;
}
extern BOOLEAN HeliCharacterDialogue( SOLDIERTYPE *pSoldier, UINT16 usQuoteNum );
void PlotPathForHelicopter( INT16 sX, INT16 sY )
{
SOLDIERTYPE *pSkyRider = NULL;
// will plot the path for the helicopter
// no heli...go back
@@ -2058,6 +2354,12 @@ void PlotPathForHelicopter( INT16 sX, INT16 sY )
// set up mvt group for helicopter
SetUpHelicopterForMovement( );
//CHRISL: If we've plotted a path through enemy controlled airspace, we have a new Skyrider speech we want to hear.
if( GetNumUnSafeSectorsInPath( ) > 0 && !gGameSettings.fOptions[TOPTION_SILENT_SKYRIDER] )
{
HeliCharacterDialogue( pSkyRider, HELI_PATH_THROUGH_ENEMEY_AIRSPACE );
}
// move to beginning of list
//pHelicopterPath = MoveToBeginningOfPathList( pVehicleList[ iHelicopterVehicleId ].pMercPath );
MoveToBeginningOfPathList( pVehicleList[ iHelicopterVehicleId ].pMercPath );
@@ -4723,7 +5025,7 @@ void BlitMineText( INT16 sMapX, INT16 sMapY )
if (PlayerControlsMine(ubMineIndex) && !gMineStatus[ ubMineIndex ].fEmpty)
{
// show current production
swprintf( wSubString, L"%d", PredictDailyIncomeFromAMine(ubMineIndex) );
swprintf( wSubString, L"%d", PredictDailyIncomeFromAMine(ubMineIndex, TRUE) );
InsertCommasForDollarFigure( wSubString );
InsertDollarSignInToString( wSubString );
wcscpy( wString, wSubString );
@@ -4741,9 +5043,9 @@ void BlitMineText( INT16 sMapX, INT16 sMapY )
if (GetMaxPeriodicRemovalFromMine(ubMineIndex) > 0)
{
#ifdef CHINESE
swprintf( wSubString, L" (%d%£¥%%)", (PredictDailyIncomeFromAMine(ubMineIndex) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
swprintf( wSubString, L" (%d%£¥%%)", (PredictDailyIncomeFromAMine(ubMineIndex, TRUE) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
#else
swprintf( wSubString, L" (%d%%%%)", (PredictDailyIncomeFromAMine(ubMineIndex) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
swprintf( wSubString, L" (%d%%%%)", (PredictDailyIncomeFromAMine(ubMineIndex, TRUE) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
#endif
wcscat( wString, wSubString );
@@ -4879,7 +5181,8 @@ void BlitMineGridMarkers( void )
{
if( fZoomFlag )
{
GetScreenXYFromMapXYStationary( ( INT16 )( gMineLocation[ iCounter ].sSectorX), ( INT16 )( gMineLocation[ iCounter ].sSectorY ) , &sScreenX, &sScreenY );
//GetScreenXYFromMapXYStationary( ( INT16 )( gMineLocation[ iCounter ].sSectorX), ( INT16 )( gMineLocation[ iCounter ].sSectorY ) , &sScreenX, &sScreenY );
GetScreenXYFromMapXYStationary( ( INT16 )( gMineStatus[ iCounter ].sSectorX), ( INT16 )( gMineStatus[ iCounter ].sSectorY ) , &sScreenX, &sScreenY );
sScreenX -= MAP_GRID_X;
sScreenY -= MAP_GRID_Y;
@@ -4889,7 +5192,8 @@ void BlitMineGridMarkers( void )
else
{
// get location on screen
GetScreenXYFromMapXY( ( INT16 )( gMineLocation[ iCounter ].sSectorX ), ( INT16 )( gMineLocation[ iCounter ].sSectorY ), &sScreenX, &sScreenY );
//GetScreenXYFromMapXY( ( INT16 )( gMineLocation[ iCounter ].sSectorX ), ( INT16 )( gMineLocation[ iCounter ].sSectorY ), &sScreenX, &sScreenY );
GetScreenXYFromMapXY( ( INT16 )( gMineStatus[ iCounter ].sSectorX ), ( INT16 )( gMineStatus[ iCounter ].sSectorY ), &sScreenX, &sScreenY );
sWidth = MAP_GRID_X;
sHeight= MAP_GRID_Y;
@@ -6451,7 +6755,7 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
// There's also a special case flag used when players encounter enemies in a sector, then retreat. You can only
// see the size of their force while the clock is paused. When unpaused, the flag is reset.
if ( CanMercsScoutThisSector( sSectorX, sSectorY, 0 ) ||
CanNearbyMilitiaScoutThisSector( sSectorX, sSectorY ) ||
CanSomeoneNearbyScoutThisSector( sSectorX, sSectorY, FALSE ) || // merged militia check with scouting check - SANDRO
( uiSectorFlags & SF_PLAYER_KNOWS_ENEMIES_ARE_HERE ) )
{
fDetection = TRUE;
@@ -6463,6 +6767,18 @@ UINT32 WhatPlayerKnowsAboutEnemiesInSector( INT16 sSectorX, INT16 sSectorY )
fCount = TRUE;
}
}
// SADNRO - Scouting trait check for detection of nearby enemies
if (CanSomeoneNearbyScoutThisSector( sSectorX, sSectorY, TRUE )) // scouting trait check
{
if (gSkillTraitValues.fSCCanDetectEnemyPresenseAround)
{
// show their presence
fDetection = TRUE;
// show their numbers
if (gSkillTraitValues.fSCCanDetermineEnemyNumbersAround)
fCount = TRUE;
}
}
// Explored Sector Detection
// Enemy can be detected in any previously-visited sector.
@@ -30,6 +30,7 @@
#include "debug.h"
#endif
#include "Strategic Mines.h"
#define BOX_BUTTON_WIDTH 100
#define BOX_BUTTON_HEIGHT 20
@@ -52,8 +53,9 @@ UINT32 guiMapButtonInventory[2];
UINT16 sTotalButtonWidth = 0;
extern MINE_LOCATION_TYPE gMineLocation[];
extern MINE_STATUS_TYPE gMineStatus[];
//extern MINE_LOCATION_TYPE gMineLocation[];
//extern MINE_STATUS_TYPE gMineStatus[];
extern BOOLEAN fMapScreenBottomDirty;
//extern UINT8 gubMonsterMineInfestation[];
@@ -435,7 +437,7 @@ void AddTextToMineBox( void )
swprintf( wString, L"%s:", pwMineStrings[ 3 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d", PredictDailyIncomeFromAMine( ubMineIndex ) );
swprintf( wString, L"%d", PredictDailyIncomeFromAMine( ubMineIndex, TRUE ) );
InsertCommasForDollarFigure( wString );
InsertDollarSignInToString( wString );
AddSecondColumnMonoString( &hStringHandle, wString );
@@ -457,7 +459,7 @@ void AddTextToMineBox( void )
// production rate (current production as a percentage of potential production)
swprintf( wString, L"%s:", pwMineStrings[ 10 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", (PredictDailyIncomeFromAMine(ubMineIndex) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
swprintf( wString, L"%d%%%%", (PredictDailyIncomeFromAMine(ubMineIndex, TRUE) * 100 ) / GetMaxDailyRemovalFromMine(ubMineIndex) );
AddSecondColumnMonoString( &hStringHandle, wString );
}
@@ -465,16 +467,19 @@ void AddTextToMineBox( void )
// town control percentage
swprintf( wString, L"%s:", pwMineStrings[ 12 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( gMineLocation[ ubMineIndex ].bAssociatedTown ) * 100) / GetTownSectorSize( gMineLocation[ ubMineIndex ].bAssociatedTown ));
//swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( gMineLocation[ ubMineIndex ].bAssociatedTown ) * 100) / GetTownSectorSize( gMineLocation[ ubMineIndex ].bAssociatedTown ));
swprintf( wString, L"%d%%%%", (GetTownSectorsUnderControl( gMineStatus[ ubMineIndex ].bAssociatedTown ) * 100) / GetTownSectorSize( gMineStatus[ ubMineIndex ].bAssociatedTown ));
AddSecondColumnMonoString( &hStringHandle, wString );
ubTown = gMineLocation[ ubMineIndex ].bAssociatedTown;
//ubTown = gMineLocation[ ubMineIndex ].bAssociatedTown;
ubTown = gMineStatus[ ubMineIndex ].bAssociatedTown;
if( gTownLoyalty[ ubTown ].fStarted && gfTownUsesLoyalty[ ubTown ])
{
// town loyalty percentage
swprintf( wString, L"%s:", pwMineStrings[ 13 ]);
AddMonoString( &hStringHandle, wString );
swprintf( wString, L"%d%%%%", gTownLoyalty[ gMineLocation[ ubMineIndex ].bAssociatedTown ].ubRating);
//swprintf( wString, L"%d%%%%", gTownLoyalty[ gMineLocation[ ubMineIndex ].bAssociatedTown ].ubRating);
swprintf( wString, L"%d%%%%", gTownLoyalty[ gMineStatus[ ubMineIndex ].bAssociatedTown ].ubRating);
AddSecondColumnMonoString( &hStringHandle, wString );
}
+12 -5
View File
@@ -2699,7 +2699,8 @@ void GoToPrevCharacterInList( void )
void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen )
//void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen )
void HandleMinerEvent( UINT8 ubHeadMinerIndex, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen )
{
BOOLEAN fFromMapscreen = FALSE;
@@ -2719,6 +2720,8 @@ void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16
}
}
HEAD_MINER_TYPE* miner = &gHeadMinerData[ubHeadMinerIndex];
if ( fFromMapscreen )
{
// if not showing map surface level
@@ -2735,14 +2738,18 @@ void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16
fMapPanelDirty = TRUE;
// post dialogue events for miners to say this quote and flash the sector where his mine is
CharacterDialogueWithSpecialEvent( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, bMinerNumber , DIALOGUE_EXTERNAL_NPC_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, START_RED_SECTOR_LOCATOR, 1 );
CharacterDialogue( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, ( UINT8 )( UINT8 )uiExternalStaticNPCFaces[ bMinerNumber ], DIALOGUE_EXTERNAL_NPC_UI, FALSE , FALSE );
CharacterDialogueWithSpecialEvent( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, bMinerNumber , DIALOGUE_EXTERNAL_NPC_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, STOP_RED_SECTOR_LOCATOR, 1 );
//CharacterDialogueWithSpecialEvent( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, bMinerNumber , DIALOGUE_EXTERNAL_NPC_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, START_RED_SECTOR_LOCATOR, 1 );
//CharacterDialogue( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, ( UINT8 )( UINT8 )uiExternalStaticNPCFaces[ bMinerNumber ], DIALOGUE_EXTERNAL_NPC_UI, FALSE , FALSE );
//CharacterDialogueWithSpecialEvent( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, bMinerNumber , DIALOGUE_EXTERNAL_NPC_UI , FALSE , FALSE , DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, STOP_RED_SECTOR_LOCATOR, 1 );
CharacterDialogueWithSpecialEvent( ( UINT8 )miner->usProfileId, sQuoteNumber, miner->ubExternalFaceIndex, DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE, DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, START_RED_SECTOR_LOCATOR, 1 );
CharacterDialogue( ( UINT8 )miner->usProfileId, sQuoteNumber, ( UINT8 )uiExternalStaticNPCFaces[miner->ubExternalFaceIndex], DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE );
CharacterDialogueWithSpecialEvent( ( UINT8 )miner->usProfileId, sQuoteNumber, miner->ubExternalFaceIndex, DIALOGUE_EXTERNAL_NPC_UI, FALSE, FALSE, DIALOGUE_SPECIAL_EVENT_MINESECTOREVENT, STOP_RED_SECTOR_LOCATOR, 1 );
}
else // stay in tactical
{
// no need to to highlight mine sector
CharacterDialogue( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, ( UINT8 )( UINT8 )uiExternalStaticNPCFaces[ bMinerNumber ], DIALOGUE_EXTERNAL_NPC_UI, FALSE , FALSE );
//CharacterDialogue( ( UINT8 )uiExternalFaceProfileIds[ bMinerNumber ], sQuoteNumber, ( UINT8 )( UINT8 )uiExternalStaticNPCFaces[ bMinerNumber ], DIALOGUE_EXTERNAL_NPC_UI, FALSE , FALSE );
CharacterDialogue( ( UINT8 )miner->usProfileId, sQuoteNumber, ( UINT8 )uiExternalStaticNPCFaces[miner->ubExternalFaceIndex], DIALOGUE_EXTERNAL_NPC_UI, FALSE , FALSE );
}
}
+2 -1
View File
@@ -511,7 +511,8 @@ void GoToPrevCharacterInList( void );
void GoToNextCharacterInList( void );
// this does the whole miner giving player info speil
void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen );
//void HandleMinerEvent( UINT8 bMinerNumber, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen );
void HandleMinerEvent( UINT8 ubHeadMinerIndex, INT16 sSectorX, INT16 sSectorY, INT16 sQuoteNumber, BOOLEAN fForceMapscreen );
// set up the event of animating a mine sector
void SetUpAnimationOfMineSectors( INT32 iEvent );
+5 -2
View File
@@ -839,7 +839,8 @@ void CheckIfMercGetsAnotherContract( SOLDIERTYPE *pSoldier )
// multiply by experience level
iChance *= pSoldier->stats.bExpLevel;
if( (INT32) Random( 100 ) < iChance )
//tais: disabled mercs going on other assignment after being fired..
if( (INT32) Random( 100 ) < iChance && gGameExternalOptions.fMercsOnAssignment < 2 )
{
// B'bye!
pSoldier->flags.fSignedAnotherContract = TRUE;
@@ -1100,7 +1101,9 @@ void NotifyPlayerOfMercDepartureAndPromptEquipmentPlacement( SOLDIERTYPE *pSoldi
}
//if the character is an RPC
if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
//if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
//new profiles by Jazz
if ( gProfilesRPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile )
{
if( gMercProfiles[ pSoldier->ubProfile ].bSex == MALE )
{
+1
View File
@@ -11,6 +11,7 @@ enum
CONTRACT_EXTEND_1_DAY,
CONTRACT_EXTEND_1_WEEK,
CONTRACT_EXTEND_2_WEEK,
NUM_CONTRACT_EXTEND,
};
+179 -8
View File
@@ -66,6 +66,8 @@
INT32 iRestrictedSectorArraySize;
UINT32 gRestrictMilitia[256];
// HEADROCK HAM 4: Yet ANOTHER array, this one holds player-set restrictions.
UINT8 gubManualRestrictMilitia[ 256 ];
// HEADROCK HAM B1: Alternate array keeps track of dynamically unrestricted sectors
BOOLEAN gDynamicRestrictMilitia[ 256 ];
// HEADROCK HAM B1: Function that dynamically unrestricts sectors as we take over towns.
@@ -173,6 +175,8 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
UINT8 ubTargetRegularPercent = 0;
UINT8 ubTempLeadership = ubBestLeadership;
UINT8 ubActualyAdded = 0; // Added by SANDRO
// Does trainer have enough leadership to train a squad?
if ( ubBestLeadership < gGameExternalOptions.ubMinimumLeadershipToTrainMobileMilitia )
{
@@ -311,6 +315,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, 1);
ubTargetElite--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else if (ubTargetRegular > 0)
{
@@ -318,6 +323,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, 1);
ubTargetRegular--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else if (ubTargetGreen > 0)
{
@@ -325,6 +331,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, 1);
ubTargetGreen--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else
{
@@ -347,6 +354,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, 1);
ubTargetElite--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else if (ubTargetRegular > 0 && // Got a regular
(!gGameExternalOptions.gfTrainVeteranMilitia || // Not allowed to train Elites
@@ -356,6 +364,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, ELITE_MILITIA, 1);
ubTargetElite--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
// Else, we've got more men to train but no room for them. In this case, upgrade existing
// militia to the next class, using our remainder men as "upgrade points".
@@ -376,12 +385,14 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
// Comes at a cost of one regular that we were supposed to train.
ubTargetRegular--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else
{
// No regulars to train? Remove two greens instead.
ubTargetGreen -= 2;
ubMilitiaToTrain -= 2;
ubActualyAdded += 2;
}
}
// Else elite training was not allowed or we simply did not have enough points to add an elite
@@ -391,6 +402,7 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, 1);
ubTargetGreen--;
ubMilitiaToTrain--;
ubActualyAdded++;
}
else
{
@@ -407,6 +419,11 @@ void GenerateMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY,
}
}
// SANDRO - merc records (num militia trained)
if( ubActualyAdded > 0 )
RecordNumMilitiaTrainedForMercs( sMapX, sMapY, 0, ubActualyAdded, TRUE );
// This reduces the group back to "maximum" size. It starts by eliminating extra greens, then regulars, then elites.
// That produces a group of max size, with only the best troops remaining.
while( CountMilitia(pTargetSector) > gGameExternalOptions.iMaxMilitiaPerSector )
@@ -463,13 +480,45 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
{
// Wilderness->Wilderness movement. Calculate Spread Out chance based on threats.
if (NumEnemiesInFiveSectors( sMapX, sMapY ) == 0 &&
NumEnemiesInFiveSectors( sTMapX, sTMapY ) > 0 )
UINT8 ubNumEnemiesNearOrigin = NumEnemiesInFiveSectors( sMapX, sMapY );
UINT8 ubNumEnemiesNearTarget = NumEnemiesInFiveSectors( sTMapX, sTMapY );
if (ubNumEnemiesNearOrigin == 0 &&
ubNumEnemiesNearTarget > 0 )
{
// Target sector is threatened, while source sector is not.
// Target sector gets all the militia it can, in preperation for a possible enemy attack.
ubChanceToSpreadOut = 0;
}
else if (ubNumEnemiesNearOrigin > 0 &&
ubNumEnemiesNearTarget == 0 )
{
// Source sector is threatened, while destination is not. The group does not
// move at all, as it is already in a good position to defend.
return;
}
else if (ubNumEnemiesNearOrigin > 0 &&
ubNumEnemiesNearTarget > 0 )
{
// Both sectors threatened.
if (gGameExternalOptions.gfAllowReinforcements && !gGameExternalOptions.gfAllowReinforcementsOnlyInCity)
{
// Militia will spread out between the two sectors to maximize defensive capability, since they can
// always reinforce one another if either sector is attacked.
ubChanceToSpreadOut = 100;
}
else
{
// Militia chance to spread out is based on whether the Origin or the Destination are under greater
// threat. If the destination is more threatened, militia are more likely to reinforce it
// (move en-masse). If the origin is more threatened, militia are more likely to spread out evenly
// between the two sectors, to give at least some chance of defeating ONE of the enemy groups.
UINT16 usTotalNumEnemies = ubNumEnemiesNearTarget + ubNumEnemiesNearOrigin;
ubChanceToSpreadOut = __min( 100, (ubNumEnemiesNearOrigin * 100) / usTotalNumEnemies );
}
}
else if (NumEnemiesInFiveSectors( sMapX, sMapY ) > 0 &&
NumEnemiesInFiveSectors( sTMapX, sTMapY ) > 0 )
{
@@ -507,6 +556,13 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL
// Target sector is empty, source group is not full. Do not spread out.
ubChanceToSpreadOut = 0;
}
// HEADROCK HAM 4: Groups moving into a NO_LEAVE sector will always reinforce it.
// this ignores any of the possible options above.
if (gubManualRestrictMilitia[ SECTOR(sTMapX, sTMapY) ] == MANUAL_MOBILE_NO_LEAVE )
{
ubChanceToSpreadOut = 0;
}
}
}
@@ -902,6 +958,11 @@ UINT16 CountDirectionRating( INT16 sMapX, INT16 sMapY, UINT8 uiDir )
iRes = 0;
}
// HEADROCK HAM 4: Increase desire to move into a NO-LEAVE sector (Player-Set restrictions system)
if (gubManualRestrictMilitia[ SECTOR(sDMapX, sDMapY) ] == MANUAL_MOBILE_NO_LEAVE )
{
iRes = (INT32)((FLOAT)iRes * 1.5);
}
// Test for player mercs in target sector.
if( PlayerMercsInSector_MSE( (UINT8)sDMapX, (UINT8)sDMapY, FALSE ))
@@ -1338,6 +1399,12 @@ void UpdateMilitiaSquads(INT16 sMapX, INT16 sMapY )
UINT8 uiMilitiaCount;
BOOLEAN fSourceCityAllowsRoaming;
// HEADROCK HAM 4: Player can set a sector to NO_LEAVE, forcing Mobiles to stay put if they enter the sector at all.
if (gubManualRestrictMilitia[ SECTOR( sMapX, sMapY ) ] == MANUAL_MOBILE_NO_LEAVE )
{
// NO_LEAVE zone. Militia can't even consider moving.
return;
}
// If we don't want roaming militia
// We shouldn't be here.
@@ -1696,7 +1763,7 @@ void DoMilitiaHelpFromAdjacentSectors( INT16 sMapX, INT16 sMapY )
if (gfStrategicMilitiaChangesMade)
{
RemoveMilitiaFromTactical();
if(is_server && MILITIA_ENABLED==1)
if(is_server && gMilitiaEnabled == 1)
PrepareMilitiaForTactical(FALSE);
}
}
@@ -2120,11 +2187,16 @@ void AdjustRoamingRestrictions()
gDynamicRestrictMilitia[cnt] = false;
}
for (cnt=0; (cnt < 5001 && gDynamicRestrictions[cnt].bSectorID >= 0); cnt++)
for (cnt=0; (cnt < 5001 && gDynamicRestrictions[cnt].sSectorID >= 0); cnt++)
{
if (!(~uiCapturedTownsFlag & gDynamicRestrictions[cnt].uiReqTownFlags))
{
gDynamicRestrictMilitia[gDynamicRestrictions[cnt].bSectorID] = true;
gDynamicRestrictMilitia[gDynamicRestrictions[cnt].sSectorID] = true;
// HEADROCK HAM 4: Also adjust Player-based restrictions.
if (gubManualRestrictMilitia[ gDynamicRestrictions[cnt].sSectorID ] == MANUAL_MOBILE_RESTRICTED)
{
gubManualRestrictMilitia[ gDynamicRestrictions[cnt].sSectorID ] = MANUAL_MOBILE_NO_RESTRICTION;
}
}
}
}
@@ -2290,8 +2362,13 @@ BOOLEAN IsSectorRoamingAllowed( UINT32 uiSector )
// Has the sector ever been visited?
if ( SectorInfo[ uiSector ].fSurfaceWasEverPlayerControlled )
{
// Always return TRUE.
return TRUE;
// HEADROCK HAM 4: Take player-based restrictions into account...
if ( gubManualRestrictMilitia[ uiSector ] == MANUAL_MOBILE_NO_RESTRICTION ||
gubManualRestrictMilitia[ uiSector ] == MANUAL_MOBILE_NO_LEAVE )
{
// Always return TRUE.
return TRUE;
}
}
}
// Please note that with exploration restrictions, an UNVISITED sector is not neccesarily RESTRICTED.
@@ -2307,7 +2384,21 @@ BOOLEAN IsSectorRoamingAllowed( UINT32 uiSector )
return FALSE;
}
}
else
{
// HEADROCK HAM 4: Take player restrictions into account
if ( gubManualRestrictMilitia[ uiSector ] == MANUAL_MOBILE_NO_ENTER )
{
if ( !NumEnemiesInSector( SECTORX(uiSector), SECTORY(uiSector) ) )
{
// The player has disallowed movement into this sector, manually. As the condition above
// dictates, this only takes effect if there are no enemies in the target sector. Otherwise,
// militia can move to intercept them anyway.
return FALSE;
}
}
}
return TRUE;
}
@@ -2350,3 +2441,83 @@ UINT16 MilitiaUpgradeSlotsCheck( SECTORINFO * pSectorInfo )
return (usNumUpgradeSlots);
}
// HEADROCK HAM 4: Returns whether sector is allowed for militia roaming, taking into account player-set restrictions.
UINT8 ManualMobileMovementAllowed( UINT8 ubSector )
{
BOOLEAN fRestricted = TRUE;
if (gGameExternalOptions.gflimitedRoaming)
{
if (gGameExternalOptions.fUnrestrictVisited)
{
// Has the sector ever been visited?
if ( SectorInfo[ ubSector ].fSurfaceWasEverPlayerControlled )
{
// Always return TRUE.
fRestricted = FALSE;
}
}
if(gGameExternalOptions.fDynamicRestrictRoaming)
{
if (gDynamicRestrictMilitia[ ubSector ] )
{
fRestricted = FALSE;
}
}
}
else
{
fRestricted = FALSE;
}
if (fRestricted)
{
// Restricted roaming! Militia can't go here ever.
return (0);
}
else
{
if (gubManualRestrictMilitia[ ubSector ] == MANUAL_MOBILE_NO_ENTER )
{
// Player-restricted. Militia can potentially go here, if the player removed the restriction.
return (1);
}
else if (gubManualRestrictMilitia[ ubSector ] == MANUAL_MOBILE_NO_LEAVE )
{
// Militia allowed to enter, but not leave.
return (2);
}
else
{
// Roaming allowed.
return (3);
}
}
}
void InitManualMobileRestrictions()
{
UINT16 x;
for ( x = 0; x < 256; x++ )
{
UINT8 ubTownID = GetTownIdForSector( SECTORX(x), SECTORY(x) );
if (ubTownID != BLANK_SECTOR )
{
if (gfMilitiaAllowedInTown[ubTownID])
{
// Major town. Set to NO-ENTER by default.
gubManualRestrictMilitia[x] = MANUAL_MOBILE_NO_ENTER;
continue;
}
else
{
// Minor town. Set to NO_RESTRICTIONS by default.
gubManualRestrictMilitia[x] = MANUAL_MOBILE_NO_RESTRICTION;
continue;
}
}
// By default, all other sectors are "go".
gubManualRestrictMilitia[x] = MANUAL_MOBILE_NO_RESTRICTION;
}
}
+9 -1
View File
@@ -26,6 +26,8 @@ void MilitiaFollowPlayer( INT16 sMapX, INT16 sMapY, INT16 sDMapX, INT16 sDMapY )
// HEADROCK HAM B1: Changes the allowed militia sectors
extern void AdjustRoamingRestrictions();
// HEADROCK HAM 4: Yet ANOTHER array, this one holds player-set restrictions. It interacts with the dynamic one below.
extern UINT8 gubManualRestrictMilitia[ 256 ];
// HEADROCK HAM B1: Alternate array keeps track of dynamically unrestricted sectors
extern BOOLEAN gDynamicRestrictMilitia[ 256 ];
// HEADROCK HAM B2.7: Wonder why this function wasn't declared here. It is now, to allow Town Militia.cpp to
@@ -40,7 +42,7 @@ void GenerateDirectionInfosForTraining( INT16 sMapX, INT16 sMapY, UINT8* uiDirNu
// HEADROCK HAM 3.4: Stores restriction data from XML, including required cities for each sector to be allowed.
typedef struct DYNAMICRESTRICTIONS
{
INT8 bSectorID;
INT16 sSectorID;
UINT32 uiReqTownFlags;
} DYNAMICRESTRICTIONS;
@@ -56,4 +58,10 @@ void AddToBlockMoveList(INT16 sMapX, INT16 sMapY);
// And this:
UINT8 CountMilitia(SECTORINFO *pSectorInfo);
// HEADROCK HAM 4: Returns whether sector is allowed for militia roaming, taking into account player-set restrictions.
UINT8 ManualMobileMovementAllowed( UINT8 ubSector );
// HEADROCK HAM 4: Initialize all manual restrictions;
void InitManualMobileRestrictions();
#endif
+136 -43
View File
@@ -44,6 +44,9 @@
#include "Soldier macros.h"
#include "history.h"
#include "Cheats.h"
// added by SANDRO
#include "Tactical Save.h"
#include "message.h"
#endif
extern void InitializeTacticalStatusAtBattleStart();
@@ -262,6 +265,7 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
INT8 bBestExpLevel = 0;
BOOLEAN fRetreatAnOption = TRUE;
SECTORINFO *pSector;
BOOLEAN fScoutPresent = FALSE; // Added by SANDRO
// ARM: Feb01/98 - Cancel out of mapscreen movement plotting if PBI subscreen is coming up
if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) )
@@ -493,7 +497,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
ubGroupID = MercPtrs[ i ]->ubGroupID;
if( !gpBattleGroup )
gpBattleGroup = GetGroup( ubGroupID );
if( bBestExpLevel > MercPtrs[ i ]->stats.bExpLevel )
//if( bBestExpLevel > MercPtrs[ i ]->stats.bExpLevel ) // SANDRO - WTF!! This is a bug!
if( bBestExpLevel < MercPtrs[ i ]->stats.bExpLevel ) // SANDRO - WTF!! This is a bug!
bBestExpLevel = MercPtrs[ i ]->stats.bExpLevel;
if( MercPtrs[ i ]->ubPrevSectorID == 255 )
{ //Not able to retreat (calculate it for group)
@@ -508,6 +513,12 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
fUsePluralVersion = TRUE;
}
guiNumInvolved ++;
// SANDRO - added check if we have a scout in group, needed later
if( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ) && gSkillTraitValues.fSCPreventsTheEnemyToAmbushMercs )
{
fScoutPresent = TRUE;
}
}
else {
guiNumUninvolved++;
@@ -518,6 +529,8 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
ubNumStationaryEnemies = NumStationaryEnemiesInSector( gubPBSectorX, gubPBSectorY );
ubNumMobileEnemies = NumMobileEnemiesInSector( gubPBSectorX, gubPBSectorY );
ubNumMercs = PlayerMercsInSector( gubPBSectorX, gubPBSectorY, gubPBSectorZ );
BOOLEAN fAmbushPrevented = FALSE;
if( gfPersistantPBI )
{
@@ -542,63 +555,111 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
{
if( Chance( 90 ) )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
// SANDRO - Scout prevents ambushes no matter what
if ( !fScoutPresent )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
}
else
{
fAmbushPrevented = TRUE;
if ( gSkillTraitValues.fSCThrowMessageIfAmbushPrevented )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_ENEMY_AMBUSH_PREVENTED] );
}
}
}
else if( gfAutoAmbush && ubNumMobileEnemies > ubNumMercs )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
// SANDRO - Scout prevents ambushes no matter what
if ( !fScoutPresent )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
}
else
{
fAmbushPrevented = TRUE;
if ( gSkillTraitValues.fSCThrowMessageIfAmbushPrevented )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_ENEMY_AMBUSH_PREVENTED] );
}
}
// Madd:
// WANNE: Added an ja2_options.ini Property "ENABLE_CHANCE_OF_ENEMY_AMBUSHES_ON_INSANE_DIFFICULT"
else if( gGameExternalOptions.fEnableChanceOfEnemyAmbushesOnInsaneDifficult &&
gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE &&
CurrentPlayerProgressPercentage() >= 25 )
{ //if the enemy outnumbers the players, then there is a chance of the enemies ambushing the group
if( ubNumMobileEnemies > ubNumMercs )
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - changed this a lot, now on any difficulty, the enemy can ambush your squad
// based on difficulty level, number of mercs/enemies and other aspects
else if( gGameExternalOptions.fEnableChanceOfEnemyAmbushes )
{
INT32 iChance;
// Basic chance - progress level/2 minus highest merc exp level*2, and 10% on top
iChance = (UINT8)( ((CurrentPlayerProgressPercentage() / 2 ) - bBestExpLevel*2 ) + 15 );
pSector = &SectorInfo[ SECTOR( gubPBSectorX, gubPBSectorY ) ];
if( pSector->uiFlags & SF_ENEMY_AMBUSH_LOCATION )
iChance += 20;
if( gfCantRetreatInPBI )
iChance += 20;
// adjust the chance for size of our squad
if( ubNumMercs == 1 ) // one person is almost invisible to an army group, so reduce the chance a lot
iChance -= 40;
else if ( ubNumMercs == 2 ) // 2 persons are still hardly detectable
iChance -= 25;
else if ( ubNumMercs <= 10 ) // 3 to 10 mercs
iChance -= (5 * (5 - ubNumMercs)); // -5% adjustment per merc (-10% to +25%)
else // more than 10 mercs
iChance += 30; // maximum of +30% per squad size
// the more enemies are there the lesser the chance to be ambushed
// (large groups of enemies can be seen from afar, so the chance is lesser)
if ((ubNumMobileEnemies + ubNumStationaryEnemies) <= 2 )
iChance += 20; // can make hunting retreated enemies easier
else if ((ubNumMobileEnemies + ubNumStationaryEnemies) <= 6 ) // smaller groups actually increase the chance
iChance += (3 * (6 - (ubNumMobileEnemies + ubNumStationaryEnemies))); // +3% adjustment per enemy
else
iChance -= (2 * ((ubNumMobileEnemies + ubNumStationaryEnemies) - 6)); // -2% adjustment per enemy beyond 6
// adjust the chance for difficulty setting
if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_EASY )
iChance -= 15;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_MEDIUM )
iChance += 5;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_HARD )
iChance += 12;
else if( gGameOptions.ubDifficultyLevel == DIF_LEVEL_INSANE )
iChance += 25;
// adjust the chance for what we know about the sector
if( WhatPlayerKnowsAboutEnemiesInSector( gubPBSectorX, gubPBSectorY ) == KNOWS_NOTHING )
iChance += 20;
else if( WhatPlayerKnowsAboutEnemiesInSector( gubPBSectorX, gubPBSectorY ) == KNOWS_THEYRE_THERE )
iChance += 5;
//if( GetSectorFlagStatus( gubPBSectorX, gubPBSectorY, 0, SF_ALREADY_VISITED ) == TRUE )
// iChance -= 10; // if we already visited this sector
// there is always a little chance
if( iChance <= 0 )
iChance = 1;
// externalized modifier
if( gGameExternalOptions.bChanceModifierEnemyAmbushes != 0 )
iChance = ((iChance * (100 + gGameExternalOptions.bChanceModifierEnemyAmbushes)) / 100);
if( (INT32)PreRandom( 100 ) < iChance )
{
INT32 iChance;
pSector = &SectorInfo[ SECTOR( gubPBSectorX, gubPBSectorY ) ];
iChance = (UINT8)( (CurrentPlayerProgressPercentage() - bBestExpLevel*2 ) );
if( pSector->uiFlags & SF_ENEMY_AMBUSH_LOCATION )
{
iChance += 20;
}
if( gfCantRetreatInPBI )
{
iChance += 20;
}
if( (INT32)PreRandom( 100 ) < iChance )
if ( !fScoutPresent )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
}
}
}
else if( WhatPlayerKnowsAboutEnemiesInSector( gubPBSectorX, gubPBSectorY ) == KNOWS_NOTHING &&
CurrentPlayerProgressPercentage() >= 30 - gGameOptions.ubDifficultyLevel * 5 )
{ //if the enemy outnumbers the players, then there is a small chance of the enemies ambushing the group
if( ubNumMobileEnemies > ubNumMercs )
{
INT32 iChance;
pSector = &SectorInfo[ SECTOR( gubPBSectorX, gubPBSectorY ) ];
if( !(pSector->uiFlags & SF_ALREADY_VISITED) )
else
{
iChance = (UINT8)( 4 - bBestExpLevel + 2 * gGameOptions.ubDifficultyLevel + CurrentPlayerProgressPercentage() / 10 );
if( pSector->uiFlags & SF_ENEMY_AMBUSH_LOCATION )
{
iChance += 20;
}
if( gfCantRetreatInPBI )
{
iChance += 20;
}
if( (INT32)PreRandom( 100 ) < iChance )
{
gubEnemyEncounterCode = ENEMY_AMBUSH_CODE;
}
fAmbushPrevented = TRUE;
if ( gSkillTraitValues.fSCThrowMessageIfAmbushPrevented )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_ENEMY_AMBUSH_PREVENTED] );
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}
@@ -628,6 +689,26 @@ void InitPreBattleInterface( GROUP *pBattleGroup, BOOLEAN fPersistantPBI )
gfHighPotentialForAmbush = FALSE;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - ambush experienced
if( gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE || fAmbushPrevented )
{
for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ )
{
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{
if ( PlayerMercInvolvedInThisCombat( MercPtrs[ i ] ) && MercPtrs[ i ]->ubProfile != NO_PROFILE )
{
if ( gubEnemyEncounterCode == ENEMY_AMBUSH_CODE || gubEnemyEncounterCode == BLOODCAT_AMBUSH_CODE )
gMercProfiles[ MercPtrs[ i ]->ubProfile ].records.usAmbushesExperienced++;
else if ( fAmbushPrevented && HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ) ) // Scouts actually get this as number of prevented ambushes
gMercProfiles[ MercPtrs[ i ]->ubProfile ].records.usAmbushesExperienced++;
}
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if( gfAutomaticallyStartAutoResolve )
{
DisableButton( iPBButton[1] );
@@ -1395,6 +1476,18 @@ void RetreatMercsCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
/////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
for( UINT8 i = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; i <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; i++ )
{
if ( MercPtrs[i]->bActive && MercPtrs[i]->stats.bLife >= OKLIFE )
{
if ( PlayerMercInvolvedInThisCombat( MercPtrs[i] ) && MercPtrs[i]->ubProfile != NO_PROFILE )
gMercProfiles[ MercPtrs[i]->ubProfile ].records.usBattlesRetreated++;
}
}
/////////////////////////////////////////////////////////////////////////////////
// get them outta here!
RetreatAllInvolvedPlayerGroups();
+21 -7
View File
@@ -561,7 +561,7 @@ BOOLEAN PrepareEnemyForSectorBattle()
pSector = &SectorInfo[ SECTOR( gWorldSectorX, gWorldSectorY ) ];
// OJW - 20090403 - override max ai in co-op
if (is_networked && is_server && OVERRIDE_MAX_AI == 1)
if (is_networked && is_server && gMaxEnemiesEnabled == 1)
{
float totalEnemies = (float)(pSector->ubNumAdmins + pSector->ubNumTroops + pSector->ubNumElites);
ubTotalAdmins = (unsigned int)(((float)pSector->ubNumAdmins / totalEnemies) * mapMaximumNumberOfEnemies);
@@ -1314,7 +1314,7 @@ void AddPossiblePendingEnemiesToBattle()
// haydent
if (is_networked)
{
if ((is_client && !is_server) || ENEMY_ENABLED==0)
if ((is_client && !is_server) || gEnemyEnabled == 0)
{
return;
}
@@ -1475,7 +1475,11 @@ void AddPossiblePendingEnemiesToBattle()
ubInsertionCode = INSERTION_CODE_NORTH;
else
{
Assert(0);
// WANNE: Hack: If no valid insertion is found, get random insertion instead of Assert() error
UINT32 rndInsertionCode = GetRndNum(3);
ubInsertionCode = rndInsertionCode;
//Assert(0);
}
}
else if( pGroup->ubNextX && pGroup->ubNextY )
@@ -1490,7 +1494,11 @@ void AddPossiblePendingEnemiesToBattle()
ubInsertionCode = INSERTION_CODE_NORTH;
else
{
Assert(0);
// WANNE: Hack: If no valid insertion is found, get random insertion instead of Assert() error
UINT32 rndInsertionCode = GetRndNum(3);
ubInsertionCode = rndInsertionCode;
//Assert(0);
}
}
else
@@ -1914,10 +1922,10 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
// TODO.WANNE: Hardcoded grid number
static INT32 sAlmaCaptureGridNos[] = { 9208, 9688, 9215 };
static INT32 sAlmaCaptureItemsGridNo[] = { 12246, 12406, 13046 };
static INT32 sAlmaCaptureGridNos[] = { 9208, 9688, 9215 }; //dnl!!!
static INT32 sAlmaCaptureItemsGridNo[] = { 12246, 12406, 13046 }; //dnl!!!
static INT32 sInterrogationItemGridNo[] = { 12089, 12089, 12089 };
static INT32 sInterrogationItemGridNo[] = { 12089, 12089, 12089 }; //dnl!!!
AssertNotNIL(pSoldier);
@@ -1940,6 +1948,7 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
if ( AM_AN_EPC( pSoldier ) )
{
pSoldier->stats.bLife = 0;
pSoldier->iHealableInjury = 0; // added by SANDRO
HandleSoldierDeath( pSoldier, &fMadeCorpse );
return;
}
@@ -2069,6 +2078,8 @@ void EnemyCapturesPlayerSoldier( SOLDIERTYPE *pSoldier )
{
pSoldier->stats.bLife += (INT8)(10 - Random( 21 ) );
}
// SANDRO - make the lost life insta-healable
pSoldier->iHealableInjury = ((pSoldier->stats.bLifeMax - pSoldier->stats.bLife) * 100);
// make him quite exhausted when found
pSoldier->bBreath = pSoldier->bBreathMax = 50;
@@ -2089,6 +2100,7 @@ void HandleEnemyStatusInCurrentMapBeforeLoadingNewMap()
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife < OKLIFE && MercPtrs[ i ]->stats.bLife )
{
MercPtrs[ i ]->stats.bLife = 0;
MercPtrs[ i ]->iHealableInjury = 0; // added just for sure - SANDRO
HandleSoldierDeath( MercPtrs[ i ], &fMadeCorpse );
bKilledEnemies++;
}
@@ -2109,6 +2121,7 @@ void HandleEnemyStatusInCurrentMapBeforeLoadingNewMap()
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife < OKLIFE && MercPtrs[ i ]->stats.bLife )
{
MercPtrs[ i ]->stats.bLife = 0;
MercPtrs[ i ]->iHealableInjury = 0; // added just for sure - SANDRO
HandleSoldierDeath( MercPtrs[ i ], &fMadeCorpse );
bKilledRebels++;
}
@@ -2119,6 +2132,7 @@ void HandleEnemyStatusInCurrentMapBeforeLoadingNewMap()
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife < OKLIFE && MercPtrs[ i ]->stats.bLife )
{
MercPtrs[ i ]->stats.bLife = 0;
MercPtrs[ i ]->iHealableInjury = 0; // added just for sure - SANDRO
HandleSoldierDeath( MercPtrs[ i ], &fMadeCorpse );
bKilledCivilians++;
}
+9 -3
View File
@@ -3301,7 +3301,9 @@ void AddNPCsInSectorToArray()
if ( ( pSoldier != NULL ) && pSoldier->bActive )
{
//if soldier is a NPC, add him to the local NPC array
if( ( pSoldier->ubProfile >= FIRST_RPC ) && ( pSoldier->ubProfile < GASTON ) )
//if( ( pSoldier->ubProfile >= FIRST_RPC ) && ( pSoldier->ubProfile < GASTON ) )
//new profiles by Jazz
if ( gProfilesRPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || gProfilesNPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile || gProfilesVehicle[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile )
{
gubCurrentNpcInSector[ i ] = pSoldier->ubProfile;
i++;
@@ -3698,7 +3700,9 @@ void RefreshAllNPCInventory()
if( Menptr[ usCnt ].bActive == 1 )
{
//is the merc a rpc or npc
if( Menptr[ usCnt ].ubProfile >= FIRST_RPC && Menptr[ usCnt ].ubProfile < GASTON )
//if( Menptr[ usCnt ].ubProfile >= FIRST_RPC && Menptr[ usCnt ].ubProfile < GASTON )
//new profiles by Jazz
if ( gProfilesRPC[Menptr[ usCnt ].ubProfile].ProfilId == Menptr[ usCnt ].ubProfile || gProfilesNPC[Menptr[ usCnt ].ubProfile].ProfilId == Menptr[ usCnt ].ubProfile || gProfilesVehicle[Menptr[ usCnt ].ubProfile].ProfilId == Menptr[ usCnt ].ubProfile )
{
//refresh the mercs inventory
for ( usItemCnt = 0; usItemCnt< Menptr[ usCnt ].inv.size(); usItemCnt++ )
@@ -3982,7 +3986,9 @@ UINT8 WhichPanelShouldTalkingMercUse( )
return( QDS_NO_PANEL );
}
if( gTalkingMercSoldier->ubProfile < FIRST_RPC || gTalkingMercSoldier->ubProfile >= GASTON )
//if( gTalkingMercSoldier->ubProfile < FIRST_RPC || gTalkingMercSoldier->ubProfile >= GASTON )
//new profiles by Jazz
if ( gProfilesAIM[gTalkingMercSoldier->ubProfile].ProfilId == gTalkingMercSoldier->ubProfile || gProfilesMERC[gTalkingMercSoldier->ubProfile].ProfilId == gTalkingMercSoldier->ubProfile || gProfilesIMP[gTalkingMercSoldier->ubProfile].ProfilId == gTalkingMercSoldier->ubProfile )
{
return( QDS_REGULAR_PANEL );
}
+112 -11
View File
@@ -331,6 +331,23 @@ BOOLEAN CheckNPCIsEPC( UINT8 ubProfileID )
return( (pNPC->ubWhatKindOfMercAmI == MERC_TYPE__EPC ) );
}
BOOLEAN CheckNPCIsRPC( UINT8 ubProfileID )
{
SOLDIERTYPE * pNPC;
if ( gMercProfiles[ ubProfileID ].bMercStatus == MERC_IS_DEAD )
{
return( FALSE );
}
pNPC = FindSoldierByProfileID( ubProfileID, TRUE );
if (!pNPC)
{
return( FALSE );
}
return( (pNPC->ubWhatKindOfMercAmI == MERC_TYPE__NPC ) );
}
BOOLEAN NPCInRoom( UINT8 ubProfileID, UINT8 ubRoomID )
{
SOLDIERTYPE * pNPC;
@@ -914,10 +931,10 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID )
case FACT_RECEIVING_INCOME_FROM_DCAC:
gubFact[usFact] = (
( PredictDailyIncomeFromAMine( MINE_DRASSEN ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_ALMA ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CAMBRIA ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CHITZENA ) > 0 ) );
( PredictDailyIncomeFromAMine( MINE_DRASSEN, TRUE ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_ALMA, TRUE ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CAMBRIA, TRUE ) > 0 ) &&
( PredictDailyIncomeFromAMine( MINE_CHITZENA, TRUE ) > 0 ) );
break;
case FACT_PLAYER_BEEN_TO_K4:
@@ -994,15 +1011,21 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID )
break;
case FACT_PLAYER_OWNS_2_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == 3 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == gGameExternalOptions.ubEarlyRebelsRecruitment[1] || gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 1
|| ( gubQuest[QUEST_FOOD_ROUTE] == QUESTDONE && gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 4 ) ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
break;
case FACT_PLAYER_OWNS_3_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == 5 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() == gGameExternalOptions.ubEarlyRebelsRecruitment[2] || gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 1
|| ( gubQuest[QUEST_FOOD_ROUTE] == QUESTDONE && gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 4 ) ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
break;
case FACT_PLAYER_OWNS_4_TOWNS_INCLUDING_OMERTA:
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() >= 6 ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
gubFact[usFact] = ( ( GetNumberOfWholeTownsUnderControl() >= gGameExternalOptions.ubEarlyRebelsRecruitment[3] || gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 1
|| ( gubQuest[QUEST_FOOD_ROUTE] == QUESTDONE && gGameExternalOptions.ubEarlyRebelsRecruitment[0] == 4 ) ) && IsTownUnderCompleteControlByPlayer( OMERTA ) );
// silversurfer: this is the highest requirement and therefore we will automatically enable recruitment of Miguel
if ( gubFact[usFact] )
SetFactTrue(40); // Miguel will now be willing to join and so will the other RPC
break;
case FACT_PLAYER_FOUGHT_THREE_TIMES_TODAY:
@@ -1224,8 +1247,8 @@ BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID )
gubFact[usFact] = !BoxerExists();
break;
case 245: // Can dimitri be recruited? should be true if already true, OR if Miguel has been recruited already
gubFact[usFact] = ( gubFact[usFact] || FindSoldierByProfileID( MIGUEL, TRUE ) );
case 245: // Can dimitri be recruited? should be true if already true, OR if Miguel has been recruited already OR is available for recruitment
gubFact[usFact] = ( gubFact[usFact] || FindSoldierByProfileID( MIGUEL, TRUE ) || gubFact[40] );
/*
case FACT_:
gubFact[usFact] = ;
@@ -1269,8 +1292,67 @@ void EndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY )
void InternalEndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fUpdateHistory )
{
if ( gubQuest[ubQuest ] == QUESTINPROGRESS )
// SANDRO merc records - quests handled counter
if ( gubQuest[ubQuest] != QUESTDONE && fUpdateHistory ) // only public quests
{
switch (ubQuest)
{
case QUEST_FOOD_ROUTE :
// food quest is handled differently (completing when spoken to father Walker)
break;
case QUEST_DELIVER_LETTER :
case QUEST_LEATHER_SHOP_DREAM :
GiveQuestRewardPoint( sSectorX, sSectorY, 3, NO_PROFILE );
break;
case QUEST_ESCORT_SKYRIDER :
case QUEST_CHOPPER_PILOT :
case QUEST_FREE_CHILDREN :
case QUEST_RESCUE_MARIA :
case QUEST_FIND_SCIENTIST :
case QUEST_DELIVER_VIDEO_CAMERA :
case QUEST_FIND_HERMIT :
GiveQuestRewardPoint( sSectorX, sSectorY, 4, NO_PROFILE );
break;
case QUEST_FREE_DYNAMO :
// don't give Dynamo reward for himself
if( gMercProfiles[ DYNAMO ].bMercStatus != MERC_IS_DEAD )
GiveQuestRewardPoint( sSectorX, sSectorY, 4, DYNAMO );
break;
case QUEST_KINGPIN_IDOL :
case QUEST_CHITZENA_IDOL :
case QUEST_HELD_IN_ALMA :
case QUEST_RUNAWAY_JOEY :
case QUEST_ESCORT_TOURISTS :
GiveQuestRewardPoint( sSectorX, sSectorY, 5, NO_PROFILE );
break;
case QUEST_ARMY_FARM :
case QUEST_KINGPIN_MONEY :
GiveQuestRewardPoint( sSectorX, sSectorY, 6, NO_PROFILE );
break;
case QUEST_BLOODCATS :
GiveQuestRewardPoint( sSectorX, sSectorY, 7, NO_PROFILE );
break;
case QUEST_INTERROGATION : // we get here only if wiped out enemies after interrogation
case QUEST_CREATURES :
GiveQuestRewardPoint( sSectorX, sSectorY, 8, NO_PROFILE );
break;
case QUEST_KILL_TERRORISTS : // only reduced experiences if we chosen Slay over Carmen
if( gMercProfiles[ CARMEN ].bMercStatus == MERC_IS_DEAD )
GiveQuestRewardPoint( sSectorX, sSectorY, 5, NO_PROFILE );
else
GiveQuestRewardPoint( sSectorX, sSectorY, 9, NO_PROFILE );
break;
case QUEST_KILL_DEIDRANNA :
GiveQuestRewardPoint( sSectorX, sSectorY, 25, NO_PROFILE );
break;
default :
GiveQuestRewardPoint( sSectorX, sSectorY, 4, NO_PROFILE );
break;
}
}
if ( gubQuest[ubQuest ] == QUESTINPROGRESS )
{
gubQuest[ubQuest] = QUESTDONE;
if ( fUpdateHistory )
@@ -1290,7 +1372,6 @@ void InternalEndQuest( UINT8 ubQuest, INT16 sSectorX, INT16 sSectorY, BOOLEAN fU
gMercProfiles[ MADAME ].bNPCData = 0;
gMercProfiles[ MADAME ].bNPCData2 = 0;
}
};
void InitQuestEngine()
@@ -1390,7 +1471,27 @@ BOOLEAN LoadQuestInfoFromSavedGameFile( HWFILE hFile )
return( TRUE );
}
// SANDRO - a function to add quest-done point to merc records, and award some exp possibly
void GiveQuestRewardPoint( INT16 sQuestSectorX, INT16 sQuestsSectorY, INT8 bExpReward, UINT8 bException )
{
ScreenMsg( FONT_MCOLOR_LTBLUE, MSG_TESTVERSION, L"QUEST COMPLETED - Adding to merc records and awarding experiences (%d).", (bExpReward * gGameExternalOptions.usAwardSpecialExpForQuests) );
for ( UINT8 i = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; i <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; i++ )
{
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife >= CONSCIOUSNESS && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) && MercPtrs[ i ]->ubProfile != NO_PROFILE &&
MercPtrs[ i ]->sSectorX == sQuestSectorX && MercPtrs[ i ]->sSectorY == sQuestsSectorY && !MercPtrs[ i ]->flags.fBetweenSectors && MercPtrs[ i ]->bTeam == gbPlayerNum &&
MercPtrs[ i ]->bAssignment != IN_TRANSIT && MercPtrs[ i ]->bAssignment != ASSIGNMENT_DEAD && gMercProfiles[ MercPtrs[ i ]->ubProfile ].ubBodyType != 21 ) // != ROBOTNOWEAPON )
{
if ( MercPtrs[ i ]->ubProfile != bException )
{
gMercProfiles[ MercPtrs[ i ]->ubProfile ].records.ubQuestsHandled++;
if ( bExpReward > 0 && gGameExternalOptions.usAwardSpecialExpForQuests > 0 )
StatChange( MercPtrs[ i ], EXPERAMT, (bExpReward * gGameExternalOptions.usAwardSpecialExpForQuests), FALSE );
}
}
}
}
+34
View File
@@ -516,6 +516,8 @@ enum Facts
FACT_CONRAD_SHOULD_GO = 367,
FACT_PLAYER_KILLED_BOXERS = 368,
// HEADROCK HAM 4: Seen Mobile Militia screen after having at least one mobile unit?
FACT_MOBILE_RESTRICTIONS_VIEWED = 369,
} ;
//** END FACTS *************************
@@ -563,6 +565,38 @@ void InitQuestEngine();
BOOLEAN LoadQuestInfoFromSavedGameFile( HWFILE hFile );
BOOLEAN SaveQuestInfoToSavedGameFile( HWFILE hFile );
// added by SANDRO
void GiveQuestRewardPoint( INT16 sQuestSectorX, INT16 sQuestsSectorY, INT8 bExpReward, UINT8 bException );
extern BOOLEAN CheckNPCWounded( UINT8 ubProfileID, BOOLEAN fByPlayerOnly );
extern BOOLEAN CheckNPCInOkayHealth( UINT8 ubProfileID );
extern BOOLEAN CheckNPCBleeding( UINT8 ubProfileID );
extern BOOLEAN CheckNPCWithin( UINT8 ubFirstNPC, UINT8 ubSecondNPC, UINT8 ubMaxDistance );
extern BOOLEAN CheckGuyVisible( UINT8 ubNPC, UINT8 ubGuy );
extern BOOLEAN CheckNPCAt( UINT8 ubNPC, INT32 sGridNo );
extern BOOLEAN CheckNPCIsEnemy( UINT8 ubProfileID );
extern BOOLEAN CheckIfMercIsNearNPC( SOLDIERTYPE *pMerc, UINT8 ubProfileId );
extern INT8 NumWoundedMercsNearby( UINT8 ubProfileID );
extern INT8 NumMercsNear( UINT8 ubProfileID, UINT8 ubMaxDist );
extern BOOLEAN CheckNPCIsEPC( UINT8 ubProfileID );
extern BOOLEAN NPCInRoom( UINT8 ubProfileID, UINT8 ubRoomID );
extern BOOLEAN NPCInRoomRange( UINT8 ubProfileID, UINT8 ubRoomID1, UINT8 ubRoomID2 );
extern BOOLEAN PCInSameRoom( UINT8 ubProfileID );
extern INT8 NumMalesPresent( UINT8 ubProfileID );
extern BOOLEAN FemalePresent( UINT8 ubProfileID );
extern BOOLEAN CheckPlayerHasHead( void );
extern BOOLEAN CheckNPCSector( UINT8 ubProfileID, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
extern BOOLEAN AIMMercWithin( INT32 sGridNo, INT16 sDistance );
extern BOOLEAN CheckNPCCowering( UINT8 ubProfileID );
extern BOOLEAN CheckNPCIsUnderFire( UINT8 ubProfileID );
extern BOOLEAN NPCHeardShot( UINT8 ubProfileID );
extern BOOLEAN InTownSectorWithTrainingLoyalty( INT16 sSectorX, INT16 sSectorY );
extern BOOLEAN CheckFact( UINT16 usFact, UINT8 ubProfileID );
extern BOOLEAN CheckNPCIsRPC( UINT8 ubProfileID );
extern BOOLEAN CheckTalkerStrong( void );
extern BOOLEAN CheckForNewShipment( void );
extern BOOLEAN CheckTalkerFemale( void );
extern BOOLEAN CheckTalkerUnpropositionedFemale( void );
#endif
+2 -1
View File
@@ -263,6 +263,7 @@ UINT8 DoReinforcementAsPendingEnemy( INT16 sMapX, INT16 sMapY )
gfPendingEnemies = TRUE;
ResetMortarsOnTeamCount();
ResetNumSquadleadersInArmyGroup(); // added by SANDRO
}
}
@@ -385,7 +386,7 @@ void AddPossiblePendingMilitiaToBattle()
// Haydent
if (is_networked)
{
if ((is_client && !is_server) || MILITIA_ENABLED==0)
if ((is_client && !is_server) || gMilitiaEnabled == 0)
{
return;
}
+130 -23
View File
@@ -628,10 +628,12 @@ BOOLEAN PlayerForceTooStrong( UINT8 ubSectorID, UINT16 usOffensePoints, UINT16 *
ubSectorY = (UINT8)SECTORY( ubSectorID );
pSector = &SectorInfo[ ubSectorID ];
*pusDefencePoints = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 +
pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 +
pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 +
PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5;
// SANDRO - EVALUATE THE STRENGTH OF MILITIA BASED ON INI SETTING
*pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5;
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength )/100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength)/100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength)/100);
if( *pusDefencePoints > usOffensePoints )
{
return TRUE;
@@ -1513,18 +1515,116 @@ void InitStrategicAI()
//final thing to do is choose 1 cache map out of 5 possible maps. Simply select the sector randomly,
//set up the flags to use the alternate map, then place 8-12 regular troops there (no ai though).
//changing MAX_STRATEGIC_TEAM_SIZE may require changes to to the defending force here.
if ( !gGameExternalOptions.fEnableAllWeaponCaches )
if ( !gGameOptions.fEnableAllWeaponCaches ) // SANDRO - weapon caches settings changed
{
switch( Random( 5 ) )
// added a chance to have more than one weapon caches in game
INT8 ubPicked[2] = { 0,0 };
UINT8 cnt, cnt2, ubNumberCaches, ubSector;
ubNumberCaches = ( Chance( 50 ) ? (Chance( 25 ) ? 3 : 2 ) : 1);
cnt2 = 0;
for (cnt = 0; cnt < ubNumberCaches; cnt++)
{
case 0: pSector = &SectorInfo[ SEC_E11 ]; break;
case 1: pSector = &SectorInfo[ SEC_H5 ]; break;
case 2: pSector = &SectorInfo[ SEC_H10 ]; break;
case 3: pSector = &SectorInfo[ SEC_J12 ]; break;
case 4: pSector = &SectorInfo[ SEC_M9 ]; break;
ubSector = (1 + Random ( 5 ));
switch( ubSector )
{
case 1:
if( ubPicked[0] != ubSector && ubPicked[1] != ubSector )
{
pSector = &SectorInfo[ SEC_E11 ];
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
ubPicked[1] = ubSector;
else
cnt2 += 25;
}
else
{
cnt--;
}
break;
case 2:
if( ubPicked[0] != ubSector && ubPicked[1] != ubSector )
{
pSector = &SectorInfo[ SEC_H5 ];
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
ubPicked[1] = ubSector;
else
cnt2 += 25;
}
else
{
cnt--;
}
break;
case 3:
if( ubPicked[0] != ubSector && ubPicked[1] != ubSector )
{
pSector = &SectorInfo[ SEC_H10 ];
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
ubPicked[1] = ubSector;
else
cnt2 += 25;
}
else
{
cnt--;
}
break;
case 4:
if( ubPicked[0] != ubSector && ubPicked[1] != ubSector )
{
pSector = &SectorInfo[ SEC_J12 ];
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
ubPicked[1] = ubSector;
else
cnt2 += 25;
}
else
{
cnt--;
}
break;
case 5:
if( ubPicked[0] != ubSector && ubPicked[1] != ubSector )
{
pSector = &SectorInfo[ SEC_M9 ];
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
if (ubPicked[0] == 0)
ubPicked[0] = ubSector;
else if (ubPicked[1] == 0)
ubPicked[1] = ubSector;
else
cnt2 += 25;
}
else
{
cnt--;
}
break;
}
cnt2++;
if (cnt2 > 25)
break;
}
pSector->uiFlags |= SF_USE_ALTERNATE_MAP;
pSector->ubNumTroops = (UINT8)(6 + gGameOptions.ubDifficultyLevel * 2);
}
else
{
@@ -1959,10 +2059,12 @@ BOOLEAN ReinforcementsApproved( INT32 iGarrisonID, UINT16 *pusDefencePoints )
ubSectorX = (UINT8)SECTORX( gGarrisonGroup[ iGarrisonID ].ubSectorID );
ubSectorY = (UINT8)SECTORY( gGarrisonGroup[ iGarrisonID ].ubSectorID );
*pusDefencePoints = pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 +
pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 +
pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 +
PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 4;
// SANDRO - EVALUATE THE MILITIA STRENGTH REGARDING THE GAME SETTINGS
*pusDefencePoints = PlayerMercsInSector( ubSectorX, ubSectorY, 0 ) * 5;
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] * 1 * (100 + gGameExternalOptions.sGreenMilitiaAutoresolveStrength )/100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] * 2 * (100 + gGameExternalOptions.sRegularMilitiaAutoresolveStrength)/100);
*pusDefencePoints += (pSector->ubNumberOfCivsAtLevel[ ELITE_MILITIA ] * 3 * (100 + gGameExternalOptions.sVeteranMilitiaAutoresolveStrength)/100);
usOffensePoints = gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bAdminPercentage * 2 +
gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bTroopPercentage * 3 +
gArmyComp[ gGarrisonGroup[ iGarrisonID ].ubComposition ].bElitePercentage * 4 +
@@ -4553,10 +4655,15 @@ void HourlyCheckStrategicAI()
#ifdef JA2BETAVERSION
#include "VFS/vfs.h"
#include "VFS/Tools/Log.h"
#include "sgp_logger.h"
static CLog& s_stratD = *CLog::create(L"Strategic Decisions.txt", true);
static struct StratDecLog {
sgp::Logger_ID id;
StratDecLog() {
id = sgp::Logger::instance().createLogger();
sgp::Logger::instance().connectFile(id, L"Strategic Decisions.txt", false, sgp::Logger::FLUSH_ON_DELETE);
}
} s_stratD;
void LogStrategicMsg( STR8 str, ... )
{
@@ -4576,7 +4683,7 @@ void LogStrategicMsg( STR8 str, ... )
#ifndef USE_VFS
fprintf( fp, "%s\n", string );
#else
s_stratD << string << CLog::ENDL;
SGP_LOG(s_stratD.id, string);
#endif
if( gfDisplayStrategicAILogs )
@@ -4612,7 +4719,7 @@ void LogStrategicEvent( STR8 str, ... )
fprintf( fp, "\n%S:\n", WORLDTIMESTR );
fprintf( fp, "%s\n", string );
#else
s_stratD.endl() << WORLDTIMESTR << ":" << CLog::ENDL << string << CLog::ENDL;
SGP_LOG(s_stratD.id) << sgp::endl << WORLDTIMESTR << ":" << sgp::endl << string << sgp::endl;
#endif
if( gfDisplayStrategicAILogs )
{
@@ -4639,7 +4746,7 @@ void ClearStrategicLog()
fclose( fp );
#else
s_stratD.flush();
SGP_LOG(s_stratD.id) << sgp::flush;
#endif
}
#endif
+25 -10
View File
@@ -33,7 +33,9 @@
#endif
#include "BobbyRMailOrder.h"
#include "Luaglobal.h"
#include "connect.h"
#include "LuaInitNPCs.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -52,6 +54,8 @@ UINT32 guiPabloExtraDaysBribed = 0;
UINT8 gubCambriaMedicalObjects;
extern INT8 NumMercsNear( UINT8 ubProfileID, UINT8 ubMaxDist );
// WANNE: No more used for the new airport code
//void DropOffItemsInMeduna( UINT8 ubOrderNum );
@@ -722,8 +726,10 @@ void HandleNPCSystemEvent( UINT32 uiEvent )
}
break;
case NPC_ACTION_DELAYED_MAKE_BRENDA_LEAVE:
//IC:
//TriggerNPCRecord( 85, 9 );
// silversurfer: reenabled this
// but only play Brendas quote when we are near enough to hear her
if ( NumMercsNear( 85, 8 ) > 0 )
TriggerNPCRecord( 85, 9 );
SetFactTrue( FACT_BRENDA_PATIENCE_TIMER_EXPIRED );
break;
case NPC_ACTION_SET_DELAY_TILL_GIRLS_AVAILABLE:
@@ -799,16 +805,25 @@ void HandleNPCSystemEvent( UINT32 uiEvent )
void HandleEarlyMorningEvents( void )
{
#ifdef LUA_STRATEGY_EVENT_HANDLER
LetLuaHandleEarlyMorningEvents(0);
#else
UINT32 cnt;
UINT32 uiAmount;
// loop through all *NPCs* and reset "default response used recently" flags
for (cnt = FIRST_RPC; cnt < GASTON; cnt++)
//for (cnt = FIRST_RPC; cnt < GASTON; cnt++)
for (cnt = 0; cnt < NUM_PROFILES; cnt++)
{
gMercProfiles[cnt].bFriendlyOrDirectDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].bRecruitDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].bThreatenDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].ubMiscFlags2 &= (~PROFILE_MISC_FLAG2_BANDAGED_TODAY);
//new profiles by Jazz
if ( gProfilesRPC[cnt].ProfilId == cnt || gProfilesNPC[cnt].ProfilId == cnt || gProfilesVehicle[cnt].ProfilId == cnt )
{
gMercProfiles[cnt].bFriendlyOrDirectDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].bRecruitDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].bThreatenDefaultResponseUsedRecently = FALSE;
gMercProfiles[cnt].ubMiscFlags2 &= (~PROFILE_MISC_FLAG2_BANDAGED_TODAY);
}
}
// reset Father Walker's drunkenness level!
gMercProfiles[ FATHER ].bNPCData = (INT8) Random( 4 );
@@ -834,8 +849,8 @@ void HandleEarlyMorningEvents( void )
if( gMercProfiles[ TONY ].ubLastDateSpokenTo > 0 && !( gWorldSectorX == 5 && gWorldSectorY == MAP_ROW_C && gbWorldSectorZ == 0 ) )
{
// San Mona C5 is not loaded so make Tony possibly not available
if (Random( 4 ))
// San Mona C5 is not loaded so make Tony possibly not availableif
if (Random( 99 ) < gGameExternalOptions.ubChanceTonyAvailable) // silversurfer/SANDRO
{
// Tony IS available
SetFactFalse( FACT_TONY_NOT_AVAILABLE );
@@ -1026,7 +1041,7 @@ void HandleEarlyMorningEvents( void )
{
CheckForMissingHospitalSupplies();
}
#endif
}
void MakeCivGroupHostileOnNextSectorEntrance( UINT8 ubCivGroup )
+225 -37
View File
@@ -248,7 +248,7 @@ void MercDailyUpdate()
// CJC: For some personalities, reset personality quote said flag
if ( pSoldier->ubProfile != NO_PROFILE )
{
switch( gMercProfiles[ pSoldier->ubProfile ].bPersonalityTrait )
switch( gMercProfiles[ pSoldier->ubProfile ].bDisability )
{
case HEAT_INTOLERANT:
case CLAUSTROPHOBIC:
@@ -282,7 +282,9 @@ void MercDailyUpdate()
{
}
//if the character is an RPC
else if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
//else if( pSoldier->ubProfile >= FIRST_RPC && pSoldier->ubProfile < FIRST_NPC )
//new profiles by Jazz
else if ( gProfilesRPC[pSoldier->ubProfile].ProfilId == pSoldier->ubProfile )
{
INT16 sSalary = gMercProfiles[ pSoldier->ubProfile ].sSalary;
INT32 iMoneyOwedToMerc = 0;
@@ -397,9 +399,11 @@ void MercDailyUpdate()
}
}
}
//Loop through all the profiles
for( cnt = 0; cnt < NUM_PROFILES; cnt++)
// WANNE: Only send mails from the original 1.13 merc, and not from the wildfire merc,
// otherwise we get wrong mails cause of hardcoded Email.edt structure!!!!!
UINT16 numOriginalProfiles = 255;
for( cnt = 0; cnt < numOriginalProfiles; cnt++)
{
pProfile = &(gMercProfiles[ cnt ]);
@@ -461,8 +465,23 @@ void MercDailyUpdate()
//remove the Flag, so if the merc goes on another assignment, the player can leave an email.
pProfile->ubMiscFlags3 &= ~PROFILE_MISC_FLAG3_PLAYER_LEFT_MSG_FOR_MERC_AT_AIM;
// TO DO: send E-mail to player telling him the merc has returned from an assignment
AddEmail( ( UINT8 )( iOffset + ( cnt * AIM_REPLY_LENGTH_BARRY ) ), AIM_REPLY_LENGTH_BARRY, ( UINT8 )( 6 + cnt ), GetWorldTotalMin(), -1 );
// Read from Email.edt
if (cnt < 170)
{
// TO DO: send E-mail to player telling him the merc has returned from an assignment
AddEmail( ( UINT8 )( iOffset + ( cnt * AIM_REPLY_LENGTH_BARRY ) ), AIM_REPLY_LENGTH_BARRY, ( UINT8 )( 6 + cnt ), GetWorldTotalMin(), -1 );
}
else
{
UINT16 iMsgLength = cnt;
UINT8 sender = cnt - 119; // SenderNameList.xml
// Fake Barry Unger mail, but with the msgLength of the WF merc ID -> Correct in PreProcessEmail()
AddEmailWFMercLevelUp( ( UINT8 )( iOffset + 0 * AIM_REPLY_LENGTH_BARRY ), iMsgLength, sender, GetWorldTotalMin(), -1 );
}
// WANNE: Should we stop time compression. I don't know.
//StopTimeCompression();
}
}
}
@@ -473,7 +492,8 @@ void MercDailyUpdate()
if( IsProfileIdAnAimOrMERCMerc( (UINT8)cnt ) )
{
// check to see if he goes on another assignment
if (cnt < MAX_NUMBER_MERCS)
//if (cnt < MAX_NUMBER_MERCS)
if ( gProfilesAIM[ cnt ].ProfilId == cnt ) //new profiles by Jazz
{
// A.I.M. merc
uiChance = 2 * pProfile->bExpLevel;
@@ -481,7 +501,7 @@ void MercDailyUpdate()
// player has now had a chance to hire him, so he'll eligible to get killed off on another job
pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE;
}
else
else if ( gProfilesMERC[ cnt ].ProfilId == cnt ) //new profiles by Jazz
{
// M.E.R.C. merc - very rarely get other work
uiChance = 1 * pProfile->bExpLevel;
@@ -493,8 +513,8 @@ void MercDailyUpdate()
pProfile->ubMiscFlags3 |= PROFILE_MISC_FLAG3_PLAYER_HAD_CHANCE_TO_HIRE;
}
}
if (Random(100) < uiChance)
// tais: disable mercs being on assignment
if (Random(100) < uiChance && gGameExternalOptions.fMercsOnAssignment < 2)
{
pProfile->bMercStatus = MERC_WORKING_ELSEWHERE;
pProfile->uiDayBecomesAvailable = 1 + Random(6 + (pProfile->bExpLevel / 2) ); // 1-(6 to 11) days
@@ -1098,41 +1118,178 @@ void HourlyCamouflageUpdate( void )
{
if ( pSoldier->bActive )
{
// if the merc has non-zero camo, degrade it by 1%
if( ( pSoldier->bCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED) ) ) )
// SANDRO - new Ranger trait reduces camo degrading, which replaces camouflage trait
// may be a little awkward solution with chances, but can work
if (gGameOptions.fNewTraitSystem)
{
pSoldier->bCamo -= 2;
if (pSoldier->bCamo <= 0)
if( pSoldier->bCamo > 0 )
{
pSoldier->bCamo = 0;
camoWoreOff = TRUE;
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
pSoldier->bCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->bCamo -= 2;
if (pSoldier->bCamo <= 0)
{
pSoldier->bCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->urbanCamo > 0 )
{
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
pSoldier->urbanCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->urbanCamo -= 2;
if (pSoldier->urbanCamo <= 0)
{
pSoldier->urbanCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->desertCamo > 0 )
{
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
pSoldier->desertCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->desertCamo -= 2;
if (pSoldier->desertCamo <= 0)
{
pSoldier->desertCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( pSoldier->snowCamo > 0 )
{
if (HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
{
pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
pSoldier->snowCamo -= (Chance(__max(0, 100 - gSkillTraitValues.ubRACamoWornountSpeedReduction * NUM_SKILL_TRAITS( pSoldier, RANGER_NT ))) ? 1 : 0 );
}
else
pSoldier->snowCamo -= 2;
if (pSoldier->snowCamo <= 0)
{
pSoldier->snowCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
if( ( pSoldier->urbanCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_URBAN) ) ) )
else
{
pSoldier->urbanCamo -= 2;
if (pSoldier->urbanCamo <= 0)
// if the merc has non-zero camo, degrade it by 1%
// SANDRO - different types of Camouflaged trait have been merged together
if( ( pSoldier->bCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->urbanCamo = 0;
camoWoreOff = TRUE;
pSoldier->bCamo -= 2;
if (pSoldier->bCamo <= 0)
{
pSoldier->bCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
if( ( pSoldier->desertCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_DESERT) ) ) )
{
pSoldier->desertCamo -= 2;
if (pSoldier->desertCamo <= 0)
if( ( pSoldier->urbanCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->desertCamo = 0;
camoWoreOff = TRUE;
pSoldier->urbanCamo -= 2;
if (pSoldier->urbanCamo <= 0)
{
pSoldier->urbanCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
if( ( pSoldier->snowCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_SNOW) ) ) )
{
pSoldier->snowCamo -= 2;
if (pSoldier->snowCamo <= 0)
if( ( pSoldier->desertCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->snowCamo = 0;
camoWoreOff = TRUE;
pSoldier->desertCamo -= 2;
if (pSoldier->desertCamo <= 0)
{
pSoldier->desertCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
if( ( pSoldier->snowCamo > 0) && ( !( HAS_SKILL_TRAIT( pSoldier, CAMOUFLAGED_OT) ) ) )
{
pSoldier->snowCamo -= 2;
if (pSoldier->snowCamo <= 0)
{
pSoldier->snowCamo = 0;
camoWoreOff = TRUE;
if (gGameExternalOptions.fShowCamouflageFaces == TRUE )
{
//legion camo, remove camo face and create face
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );
}
}
}
}
@@ -1144,7 +1301,38 @@ void HourlyCamouflageUpdate( void )
pSoldier->CreateSoldierPalettes( );
}
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
if ( pSoldier->bCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_JUNGLE_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->urbanCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gUrbanCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_URBAN_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->snowCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gSnowCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_SNOW_WORN_OFF], pSoldier->name );
}
else if ( pSoldier->desertCamo <= 0 )
{
gCamoFace[pSoldier->ubProfile].gDesertCamoface = FALSE;
DeleteSoldierFace( pSoldier );// remove face
pSoldier->iFaceIndex = InitSoldierFace( pSoldier );// create new face
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_DESERT_WORN_OFF], pSoldier->name );
}
// ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, Message[STR_CAMMO_WORN_OFF], pSoldier->name );
DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 );
camoWoreOff = FALSE;
}
+567
View File
@@ -0,0 +1,567 @@
#include <vector>
#include <cctype>
#include <sstream>
#include <string>
#include "DEBUG.H"
#include "Dialogue Control.h"
#include "FileMan.h"
#include "GameSettings.h"
#include "Soldier Profile.h"
#include "strategic.h"
#include "strategicmap.h"
#include "Strategic Mines.h"
#include "Strategic Mines LUA.h"
#include "UndergroundInit.h"
#include <vfs/Core/vfs_debug.h> // for CBasicException
#include "connect.h"
using namespace std;
static bool locationStrToCoords(string str, INT16* x, INT16* y);
// global
LuaMines g_luaMines;
/////////////////////////////////////////
////////////////////////////////////////
LuaMines::LuaMines()
: m_log(L"initmines.log", false)
{
m_L = lua_open();
luaL_openlibs(m_L);
}
void LuaMines::LoadScript()
{
char * filename = "scripts\\initmines.lua";
UINT32 size, bytesRead;
HWFILE file = FileOpen(filename, FILE_ACCESS_READ, FALSE);
if (!file)
{
string msg("Cannot open file: ");
msg.append(filename);
m_log << msg << vfs::Log::endl;
SGP_THROW(msg);
}
size = FileSize(filename);
vector<char> buffer = vector<char>(size+1);
buffer[size] = 0;
FileRead(file, &buffer[0], size, &bytesRead);
FileClose(file);
if (luaL_dostring(m_L, &buffer[0]))
{
string error("lua parsing error: ");
error.append(lua_tostring(m_L, -1));
m_log << error << vfs::Log::endl;
lua_pop(m_L, 1);
SGP_THROW(error);
}
else
{
lua_getglobal(m_L, "InitializeMines");
if (!lua_isfunction(m_L, -1))
{
string error("missing LUA function 'InitializeMines'");
m_log << error << vfs::Log::endl;
lua_pop(m_L, 1);
SGP_THROW(error);
}
else
m_initMinesFuncID = luaL_ref(m_L, LUA_REGISTRYINDEX);
lua_getglobal(m_L, "InitializeHeadMiners");
if (!lua_isfunction(m_L, -1))
{
string error("missing LUA function 'InitializeHeadMiners'");
m_log << error << vfs::Log::endl;
lua_pop(m_L, 1);
SGP_THROW(error);
}
else
m_initMinersFuncID = luaL_ref(m_L, LUA_REGISTRYINDEX);
lua_getglobal(m_L, "logging");
if (!lua_isnil(m_L, -1) && lua_isboolean(m_L, -1) && lua_toboolean(m_L, -1))
m_log.ToggleLogging(true);
lua_pop(m_L, 1);
}
}
void LuaMines::Reset()
{
gMineStatus.clear();
gHeadMinerData.clear();
// just to be sure
ShutdownStaticExternalNPCFaces();
InitalizeStaticExternalNPCFaces();
}
void LuaMines::InitMinerFaces()
{
if (gHeadMinerData.size() > 0)
{
for (vector<HEAD_MINER_TYPE>::iterator miner = gHeadMinerData.begin();
miner != gHeadMinerData.end(); ++miner)
{
// load external face
UINT32 extFaceIndex = static_cast<UINT32>(
InitFace(static_cast<UINT8>(miner->usProfileId), NOBODY, FACE_FORCE_SMALL) );
if (extFaceIndex != -1)
{
miner->ubExternalFaceIndex = uiExternalStaticNPCFaces.size();
uiExternalStaticNPCFaces.push_back(extFaceIndex);
}
else
miner->ubExternalFaceIndex = -1;
}
}
}
void LuaMines::InitializeMines()
{
Reset();
m_log << "Calling 'InitializeMines'" << vfs::Log::endl;
// WANNE: Init mines in a multiplayer game, only if we already received the server game difficulty level (ubDifficultyLevel > 0)!!
// set global, maybe pass as parameter instead?
if (!is_networked || gGameOptions.ubDifficultyLevel > 0)
{
AssertT(gGameOptions.ubDifficultyLevel > 0);
lua_pushinteger(m_L, gGameOptions.ubDifficultyLevel);
lua_setglobal(m_L, "newDIFFICULTY_LEVEL");
m_log << "global newDIFFICULTY_LEVEL=" << static_cast<int>(gGameOptions.ubDifficultyLevel) << vfs::Log::endl;
// quick fix for ini override option
lua_pushinteger(m_L, gGameExternalOptions.bWhichMineRunsOut);
lua_setglobal(m_L, "iniWHICH_MINE_SHUTS_DOWN");
m_log << "global iniWHICH_MINE_SHUTS_DOWN=" << static_cast<int>(gGameExternalOptions.bWhichMineRunsOut) << vfs::Log::endl;
// load and call lua function
lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_initMinesFuncID);
if (lua_pcall(m_L, 0, 1, 0) != 0)
{
string error(lua_tostring(m_L, -1));
lua_pop(m_L, 1);
SGP_THROW(error);
}
// The script is supposed to return an array of tables.
// Iterate over each table.
int currentTable = 1; // first table, lua indexing is 1-based
while (1)
{
MINE_STATUS_TYPE mineStatus = MINE_STATUS_TYPE();
// load table
lua_pushinteger(m_L, currentTable);
lua_gettable(m_L, -2);
if (lua_isnil(m_L, -1))
// done, no more tables
break;
lua_getfield(m_L, -1, "Location");
string loc = lua_tostring(m_L, -1);
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "Type");
mineStatus.ubMineType = lua_tointeger(m_L, -1);
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "MaxRemovalRate");
mineStatus.uiMaxRemovalRate = lua_tointeger(m_L, -1);
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "RemainingOreSupply");
mineStatus.uiRemainingOreSupply = lua_tointeger(m_L, -1);
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "Infectible");
mineStatus.fInfectible = lua_tointeger(m_L, -1) != 0;
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "AssociatedUnderground");
if (!lua_isnil(m_L, -1))
{
// again, this field is a table/array
int currentSubTable = 1; // first lua index
while (1)
{
// get next array element
lua_pushinteger(m_L, currentSubTable);
lua_gettable(m_L, -2);
if (lua_isnil(m_L, -1))
// done
break;
string str(lua_tostring(m_L, -1));
AssociatedMineSector sector;
if (locationStringToCoordinates(str, &sector.x, &sector.y, &sector.z))
{
sector.mineID = gMineStatus.size();
associatedMineSectors.push_back(sector);
}
lua_pop(m_L, 1);
currentSubTable++;
}
lua_pop(m_L, 1); // pop nil
}
lua_pop(m_L, 1); // pop field or nil value
if (locationStrToCoords(loc, &mineStatus.sSectorX, &mineStatus.sSectorY))
{
// valid location, add new mine
mineStatus.fEmpty = mineStatus.uiMaxRemovalRate == 0;
mineStatus.fRunningOut = FALSE;
mineStatus.fWarnedOfRunningOut = FALSE;
mineStatus.fShutDown = FALSE;
mineStatus.fPrevInvadedByMonsters = FALSE;
mineStatus.fSpokeToHeadMiner = FALSE;
mineStatus.fMineHasProducedForPlayer = FALSE;
mineStatus.fQueenRetookProducingMine = FALSE;
mineStatus.fShutDownIsPermanent = FALSE;
// this was usually set to 0 except for the mine that is supposed to
// be running out (in which case the calculation below applies)
// TODO: see if this works for all mines
mineStatus.uiOreRunningOutPoint = mineStatus.uiRemainingOreSupply / 4;
// gather associated town id from sector coordinates
int index = CALCULATE_STRATEGIC_INDEX(mineStatus.sSectorX, mineStatus.sSectorY);
mineStatus.bAssociatedTown = StrategicMap[index].bNameId;
gMineStatus.push_back(mineStatus);
// log
m_log << "create mine" << vfs::Log::endl;
m_log << "\tSector: " << string(1, 'A'-1+mineStatus.sSectorY) << mineStatus.sSectorX << vfs::Log::endl;
m_log << "\tType: " << (mineStatus.ubMineType ? "gold" : "silver") << vfs::Log::endl;
m_log << "\tMaxRemovalRate: " << mineStatus.uiMaxRemovalRate << vfs::Log::endl;
m_log << "\tRemainingOreSupply: " << mineStatus.uiRemainingOreSupply << vfs::Log::endl;
m_log << "\tOreRunningOutPoint: " << mineStatus.uiOreRunningOutPoint << vfs::Log::endl;
m_log << "\tInfectible: " << (mineStatus.fInfectible ? 1 : 0 ) << vfs::Log::endl;
}
else
{
m_log << "WARNING: not creating mine #" << currentTable << " due to bad location string ("
<< loc << ")" << vfs::Log::endl;
}
lua_pop(m_L, 1); // pop this table
currentTable++;
}
// update global
MAX_NUMBER_OF_MINES = gMineStatus.size();
lua_pop(m_L, 1); // pop nil value
lua_pop(m_L, 1); // pop return value
}
}
BOOLEAN LuaMines::InitializeHeadMiners(UINT8 firstMineID)
{
m_log << vfs::Log::endl;
m_log << "Calling 'InitializeHeadMiners'" << vfs::Log::endl;
lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_initMinersFuncID);
m_log << "parameter 1 ('mines')" << vfs::Log::endl;
// push parameters
lua_newtable(m_L);
for (size_t i = 0; i < gMineStatus.size(); i++)
{
int luaIndex = i + 1;
lua_pushnumber(m_L, luaIndex);
m_log << "\tindex #" << luaIndex << ": ";
lua_newtable(m_L);
{
MINE_STATUS_TYPE& mine = gMineStatus[i];
lua_pushstring(m_L, "MaxRemovalRate");
lua_pushinteger(m_L, mine.uiMaxRemovalRate);
m_log << "\t\tMaxRemovalRate:" << mine.uiMaxRemovalRate << vfs::Log::endl;
lua_settable(m_L, -3);
}
lua_settable(m_L, -3);
}
// add 1 due to lua indexing starting at 1
int luaFirstMine = firstMineID + 1;
lua_pushnumber(m_L, luaFirstMine);
m_log << "parameter 2 ('currentMine'): " << luaFirstMine << vfs::Log::endl;
if (lua_pcall(m_L, 2, 1, 0) != 0)
{
string error(lua_tostring(m_L, -1));
lua_pop(m_L, 1);
SGP_THROW(error);
}
if (lua_isnil(m_L, -1))
{
// lua script did not initialize head miners yet
lua_pop(m_L, 1); // pop return value (nil)
m_log << "script returned nil" << vfs::Log::endl;
return FALSE;
}
// The script is supposed to return an array of tables.
// Iterate over each element.
int currentTable = 1;
while (1)
{
HEAD_MINER_TYPE headMiner;
// get this element of result array
lua_pushinteger(m_L, currentTable);
lua_gettable(m_L, -2);
if (lua_isnil(m_L, -1))
// done, no more elements in result
break;
lua_getfield(m_L, -1, "Profile");
headMiner.usProfileId = lua_tointeger(m_L, -1);
lua_pop(m_L, 1);
lua_getfield(m_L, -1, "Quotes");
INT8 quotes[4] = { -1, -1, -1, -1 };
for (int quoteIndex = 0; quoteIndex < 4; quoteIndex++)
{
lua_pushinteger(m_L, quoteIndex+1); // 1-based lua index
lua_gettable(m_L, -2);
if (lua_isnil(m_L, -1))
{
// not enough quote ids, issue warning?
lua_pop(m_L, 1); // pop nil
break;
}
quotes[quoteIndex] = lua_tointeger(m_L, -1);
lua_pop(m_L, 1);
}
memcpy(headMiner.bQuoteNum, quotes, 4);
lua_pop(m_L, 1); // pop quotes array
int mineId = -1;
lua_getfield(m_L, -1, "MineID");
if (!lua_isnil(m_L, -1))
mineId = lua_tointeger(m_L, -1) - 1; // lua is 1-based, convert to 0-based
lua_pop(m_L, 1);
if (mineId > -1 && mineId < int(gMineStatus.size()))
{
MINE_STATUS_TYPE* mine = &gMineStatus[mineId];
MERCPROFILESTRUCT* minerProfile = &gMercProfiles[headMiner.usProfileId];
// place miner
minerProfile->bTown = mine->bAssociatedTown;
minerProfile->sSectorX = mine->sSectorX;
minerProfile->sSectorY = mine->sSectorY;
minerProfile->bSectorZ = 0;
gHeadMinerData.push_back(headMiner);
// log
m_log << "create miner" << vfs::Log::endl;
m_log << "\tProfileID: " << headMiner.usProfileId << vfs::Log::endl;
m_log << "\tQuotes:";
for (int i = 0; i < 4; i++)
m_log << " " << headMiner.bQuoteNum[i];
m_log << vfs::Log::endl;
m_log << "\tMineID: " << mineId << vfs::Log::endl;
m_log << "\tAssociated Town: " << minerProfile->bTown << vfs::Log::endl;
m_log << "\tSector: " << string(1, 'A'-1+minerProfile->sSectorY) << minerProfile->sSectorX << vfs::Log::endl;
}
else
{
m_log << "WARNING: not creating miner #" << currentTable << " due to illegal mine id (" << mineId << ")" << vfs::Log::endl;
}
lua_pop(m_L, 1); // pop current element of result table
currentTable++;
}
lua_pop(m_L, 1); // pop nil value
lua_pop(m_L, 1); // pop return value
InitMinerFaces();
// update global
NUM_HEAD_MINERS = gHeadMinerData.size();
return TRUE;
}
LuaMines::~LuaMines()
{
lua_close(m_L);
}
BOOLEAN LuaMines::Load(HWFILE hFile)
{
Reset();
UINT32 uiNumBytesRead;
INT32 numMines;
MINE_STATUS_TYPE mineStatus;
gMineStatus.clear();
FileRead(hFile, &numMines, sizeof(INT32), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(INT32))
return FALSE;
for (int i = 0; i < numMines; i++)
{
FileRead(hFile, &mineStatus, sizeof(MINE_STATUS_TYPE), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(MINE_STATUS_TYPE))
return FALSE;
gMineStatus.push_back(mineStatus);
}
MAX_NUMBER_OF_MINES = gMineStatus.size();
INT32 numSectors;
AssociatedMineSector sector;
associatedMineSectors.clear();
FileRead(hFile, &numSectors, sizeof(INT32), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(INT32))
return FALSE;
for (int i = 0; i < numSectors; i++)
{
FileRead(hFile, &sector, sizeof(AssociatedMineSector), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(AssociatedMineSector))
return FALSE;
associatedMineSectors.push_back(sector);
}
INT32 numHeadMiners;
HEAD_MINER_TYPE miner;
gHeadMinerData.clear();
FileRead(hFile, &numHeadMiners, sizeof(INT32), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(INT32))
return FALSE;
for (int i = 0; i < numHeadMiners; i++)
{
FileRead(hFile, &miner, sizeof(HEAD_MINER_TYPE), &uiNumBytesRead);
if (uiNumBytesRead != sizeof(HEAD_MINER_TYPE))
return FALSE;
gHeadMinerData.push_back(miner);
}
NUM_HEAD_MINERS = gHeadMinerData.size();
InitMinerFaces();
return TRUE;
}
BOOLEAN LuaMines::Save(HWFILE hFile)
{
UINT32 uiNumBytesWritten;
INT32 numMines = gMineStatus.size();
FileWrite(hFile, &numMines, sizeof(INT32), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(INT32))
return FALSE;
for (std::vector<MINE_STATUS_TYPE>::iterator it = gMineStatus.begin();
it != gMineStatus.end(); ++it)
{
FileWrite(hFile, &*it, sizeof(MINE_STATUS_TYPE), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(MINE_STATUS_TYPE))
return FALSE;
}
INT32 numSectors = associatedMineSectors.size();
FileWrite(hFile, &numSectors, sizeof(INT32), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(INT32))
return FALSE;
for (std::vector<AssociatedMineSector>::iterator it = associatedMineSectors.begin();
it != associatedMineSectors.end(); ++it)
{
FileWrite(hFile, &*it, sizeof(AssociatedMineSector), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(AssociatedMineSector))
return FALSE;
}
INT32 numMiners = gHeadMinerData.size();
FileWrite(hFile, &numMiners, sizeof(INT32), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(INT32))
return FALSE;
for (std::vector<HEAD_MINER_TYPE>::iterator it = gHeadMinerData.begin();
it != gHeadMinerData.end(); ++it)
{
FileWrite(hFile, &*it, sizeof(HEAD_MINER_TYPE), &uiNumBytesWritten);
if (uiNumBytesWritten != sizeof(HEAD_MINER_TYPE))
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////
//////////////////////////////////////////////
static bool locationStrToCoords(string str, INT16* x, INT16* y)
{
if (str.length() < 2 || str.length() > 3)
return false;
char yy = tolower(str[0]);
if (yy < 'a' || yy > 'p')
return false;
*y = yy - 'a' + 1;
str = str.substr(1);
stringstream ss;
ss << str;
ss >> *x;
if (*x < 1 || *x > 16)
return false;
return true;
}
+66
View File
@@ -0,0 +1,66 @@
#ifndef STRATEGIC_MINES_LUA_H
#define STRATEGIC_MINES_LUA_H
#include "Types.h"
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
#include "UndergroundInit.h"
//#include <vfs/Tools/vfs_log.h>
//class LuaLogger
//{
// bool m_active;
// vfs::Log& m_log;
//
//public:
// enum LoggingState
// {
// OFF,
// ON,
// };
//
// LuaLogger(const vfs::Path filename, bool enable = true, bool append = false, vfs::Log::EFlushMode flushMode = vfs::Log::FLUSH_ON_ENDL)
// : m_log(*vfs::Log::create(filename, append, flushMode)), m_active(enable) {}
// ~LuaLogger() { Flush(); }
// void ToggleLogging(bool enable) { m_active = enable; }
// void Flush() { m_log.flush(); }
//
// template <typename T> LuaLogger& operator<<(const T& message) { if (m_active) m_log << message; return *this; }
// template <> LuaLogger& operator<<(const vfs::Log::_endl& endl) { if (m_active) m_log << vfs::Log::endl; return *this; }
// template <> LuaLogger& operator<<(const LoggingState& state) { m_active = state == ON; return *this; }
//
//};
class LuaMines
{
public:
void LoadScript();
void InitializeMines();
BOOLEAN InitializeHeadMiners(UINT8 firstMineID);
BOOLEAN Save(HWFILE hFile);
BOOLEAN Load(HWFILE hFile);
LuaMines();
virtual ~LuaMines();
private:
void Reset();
void InitMinerFaces();
int m_initMinesFuncID;
int m_initMinersFuncID;
lua_State * m_L;
LuaLogger m_log;
};
extern LuaMines g_luaMines;
#endif
+155 -116
View File
@@ -24,6 +24,8 @@
#include "Facilities.h"
#endif
#include "Strategic Mines LUA.h"
#include <vector>
// this .c file will handle the strategic level of mines and income from them
@@ -63,49 +65,53 @@ INT32 GetCurrentWorkRateOfMineForEnemy( INT8 bMineIndex );
// DATA TABLES
// this table holds mine values that change during the course of the game and must be saved
MINE_STATUS_TYPE gMineStatus[ MAX_NUMBER_OF_MINES ];
//MINE_STATUS_TYPE gMineStatus[ MAX_NUMBER_OF_MINES ];
std::vector<MINE_STATUS_TYPE> gMineStatus;
INT32 MAX_NUMBER_OF_MINES; // equals gMineStatus.size()
std::vector<AssociatedMineSector> associatedMineSectors;
// this table holds mine values that never change and don't need to be saved
MINE_LOCATION_TYPE gMineLocation[MAX_NUMBER_OF_MINES] =
{
{ 4, 4, SAN_MONA },
{ 13, 4, DRASSEN },
{ 14, 9, ALMA },
{ 8, 8, CAMBRIA },
{ 2, 2, CHITZENA },
{ 3, 8, GRUMM },
};
//MINE_LOCATION_TYPE gMineLocation[MAX_NUMBER_OF_MINES] =
//{
// { 4, 4, SAN_MONA },
// { 13, 4, DRASSEN },
// { 14, 9, ALMA },
// { 8, 8, CAMBRIA },
// { 2, 2, CHITZENA },
// { 3, 8, GRUMM },
//};
// the are not being randomized at all at this time
UINT8 gubMineTypes[]={
GOLD_MINE, // SAN MONA
SILVER_MINE, // DRASSEN
SILVER_MINE, // ALMA
SILVER_MINE, // CAMBRIA
SILVER_MINE, // CHITZENA
GOLD_MINE, // GRUMM
};
//UINT8 gubMineTypes[]={
// GOLD_MINE, // SAN MONA
// SILVER_MINE, // DRASSEN
// SILVER_MINE, // ALMA
// SILVER_MINE, // CAMBRIA
// SILVER_MINE, // CHITZENA
// GOLD_MINE, // GRUMM
//};
// These values also determine the most likely ratios of mine sizes after random production increases are done
UINT32 guiMinimumMineProduction[]={
0, // SAN MONA
1000, // DRASSEN
1500, // ALMA
1500, // CAMBRIA
500, // CHITZENA
2000, // GRUMM
};
//UINT32 guiMinimumMineProduction[]={
// 0, // SAN MONA
// 1000, // DRASSEN
// 1500, // ALMA
// 1500, // CAMBRIA
// 500, // CHITZENA
// 2000, // GRUMM
//};
HEAD_MINER_TYPE gHeadMinerData[NUM_HEAD_MINERS] =
{
// Profile # running out creatures! all dead! creatures again! external face graphic
{ FRED, 17, 18, 27, 26, MINER_FRED_EXTERNAL_FACE },
{ MATT, -1, 18, 32, 31, MINER_MATT_EXTERNAL_FACE },
{ OSWALD, 14, 15, 24, 23, MINER_OSWALD_EXTERNAL_FACE },
{ CALVIN, 14, 15, 24, 23, MINER_CALVIN_EXTERNAL_FACE },
{ CARL, 14, 15, 24, 23, MINER_CARL_EXTERNAL_FACE },
};
std::vector<HEAD_MINER_TYPE> gHeadMinerData;
INT32 NUM_HEAD_MINERS; // equals gHeadMinerData.size()
//HEAD_MINER_TYPE gHeadMinerData[NUM_HEAD_MINERS] =
//{
// // Profile # running out creatures! all dead! creatures again! external face graphic
// { FRED, 17, 18, 27, 26, MINER_FRED_EXTERNAL_FACE },
// { MATT, -1, 18, 32, 31, MINER_MATT_EXTERNAL_FACE },
// { OSWALD, 14, 15, 24, 23, MINER_OSWALD_EXTERNAL_FACE },
// { CALVIN, 14, 15, 24, 23, MINER_CALVIN_EXTERNAL_FACE },
// { CARL, 14, 15, 24, 23, MINER_CARL_EXTERNAL_FACE },
//};
@@ -124,7 +130,7 @@ UINT8 gubMonsterMineInfestation[]={
*/
// the static NPC dialogue faces
extern UINT32 uiExternalStaticNPCFaces[];
//extern UINT32 uiExternalStaticNPCFaces[];
extern FACETYPE *gpCurrentTalkingFace;
extern UINT8 gubCurrentTalkingID;
@@ -132,6 +138,9 @@ extern UINT8 gubCurrentTalkingID;
void InitializeMines( void )
{
// Don't execute hardcoded logic. Leave initialization to the Lua script.
g_luaMines.InitializeMines();
#if 0
UINT8 ubMineIndex;
MINE_STATUS_TYPE *pMineStatus;
UINT8 ubMineProductionIncreases;
@@ -250,6 +259,7 @@ void InitializeMines( void )
pMineStatus->uiOreRunningOutPoint = 0;
}
}
#endif
}
@@ -316,7 +326,8 @@ void HourlyMinesUpdate(void)
if ( gubQuest[ QUEST_CREATURES ] == QUESTNOTSTARTED )
{
// start it now!
StartQuest( QUEST_CREATURES, gMineLocation[ ubMineIndex ].sSectorX, gMineLocation[ ubMineIndex ].sSectorY );
//StartQuest( QUEST_CREATURES, gMineLocation[ ubMineIndex ].sSectorX, gMineLocation[ ubMineIndex ].sSectorY );
StartQuest( QUEST_CREATURES, gMineStatus[ ubMineIndex ].sSectorX, gMineStatus[ ubMineIndex ].sSectorY );
}
}
@@ -392,27 +403,8 @@ INT8 GetTownAssociatedWithMine( INT8 bMineIndex )
{
Assert( ( bMineIndex >= 0 ) && ( bMineIndex < MAX_NUMBER_OF_MINES ) );
return ( gMineLocation[ bMineIndex ].bAssociatedTown );
}
INT8 GetMineAssociatedWithThisTown( INT8 bTownId )
{
INT8 bCounter = 0;
// run through list of mines
for( bCounter = 0; bCounter < MAX_NUMBER_OF_MINES; bCounter++ )
{
if( gMineLocation[ bCounter ].bAssociatedTown == bTownId )
{
// town found, return the fact
return( gMineLocation[ bCounter ].bAssociatedTown );
}
}
// return that no town found..a 0
return( 0 );
//return ( gMineLocation[ bMineIndex ].bAssociatedTown );
return ( gMineStatus[ bMineIndex ].bAssociatedTown );
}
@@ -451,7 +443,8 @@ UINT32 ExtractOreFromMine( INT8 bMineIndex, UINT32 uiAmount )
GetMineSector( bMineIndex, &sSectorX, &sSectorY );
StrategicHandleMineThatRanOut( ( UINT8 ) SECTOR( sSectorX, sSectorY ) );
AddHistoryToPlayersLog( HISTORY_MINE_RAN_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
//AddHistoryToPlayersLog( HISTORY_MINE_RAN_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
AddHistoryToPlayersLog( HISTORY_MINE_RAN_OUT, gMineStatus[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY );
}
else // still some left after this extraction
{
@@ -477,7 +470,8 @@ UINT32 ExtractOreFromMine( INT8 bMineIndex, UINT32 uiAmount )
// that mine's head miner tells player that the mine is running out
IssueHeadMinerQuote( bMineIndex, HEAD_MINER_STRATEGIC_QUOTE_RUNNING_OUT );
gMineStatus[ bMineIndex ].fWarnedOfRunningOut = TRUE;
AddHistoryToPlayersLog( HISTORY_MINE_RUNNING_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
//AddHistoryToPlayersLog( HISTORY_MINE_RUNNING_OUT, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
AddHistoryToPlayersLog( HISTORY_MINE_RUNNING_OUT, gMineStatus[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY );
}
}
}
@@ -509,7 +503,8 @@ INT32 GetAvailableWorkForceForMineForPlayer( INT8 bMineIndex )
}
bTownId = gMineLocation[ bMineIndex ].bAssociatedTown;
//bTownId = gMineLocation[ bMineIndex ].bAssociatedTown;
bTownId = gMineStatus[ bMineIndex ].bAssociatedTown;
Assert ( GetTownSectorSize( bTownId ) != 0 );
@@ -546,7 +541,8 @@ INT32 GetAvailableWorkForceForMineForEnemy( INT8 bMineIndex )
return ( 0 );
}
bTownId = gMineLocation[ bMineIndex ].bAssociatedTown;
//bTownId = gMineLocation[ bMineIndex ].bAssociatedTown;
bTownId = gMineStatus[ bMineIndex ].bAssociatedTown;
if( GetTownSectorSize( bTownId ) == 0 )
{
@@ -695,7 +691,7 @@ void HandleIncomeFromMines( void )
}
UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex, BOOLEAN fIncludeFacilities )
{
// predict income from this mine, estimate assumes mining situation will not change during next 4 income periods
// (miner loyalty, % town controlled, monster infestation level, and current max removal rate may all in fact change)
@@ -714,7 +710,7 @@ UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
// yes reduce to value of mine
uiAmtExtracted = gMineStatus[ bMineIndex ].uiRemainingOreSupply;
}
if (bMineIndex)
if (bMineIndex && fIncludeFacilities)
{
// HEADROCK HAM 3.6: Facility modifier applied as a percentage
iFacilityModifier = 100 + MineIncomeModifierFromFacility( bMineIndex );
@@ -727,7 +723,7 @@ UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex )
}
INT32 PredictIncomeFromPlayerMines( void )
INT32 PredictIncomeFromPlayerMines( BOOLEAN fIncludeFacilities )
{
INT32 iTotal = 0;
INT8 bCounter = 0;
@@ -735,7 +731,7 @@ INT32 PredictIncomeFromPlayerMines( void )
for( bCounter = 0; bCounter < MAX_NUMBER_OF_MINES; bCounter++ )
{
// add up the total
iTotal += PredictDailyIncomeFromAMine( bCounter );
iTotal += PredictDailyIncomeFromAMine( bCounter, fIncludeFacilities );
}
return( iTotal );
@@ -768,7 +764,8 @@ INT8 GetMineIndexForSector( INT16 sX, INT16 sY )
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
{
if( ( gMineLocation[ ubMineIndex ].sSectorX == sX ) && ( gMineLocation[ ubMineIndex ].sSectorY == sY ) )
//if( ( gMineLocation[ ubMineIndex ].sSectorX == sX ) && ( gMineLocation[ ubMineIndex ].sSectorY == sY ) )
if( ( gMineStatus[ ubMineIndex ].sSectorX == sX ) && ( gMineStatus[ ubMineIndex ].sSectorY == sY ) )
{
// yep mine here
return( ubMineIndex );
@@ -782,8 +779,10 @@ void GetMineSector( UINT8 ubMineIndex, INT16 * psX, INT16 * psY )
{
Assert( ( ubMineIndex >= 0 ) && ( ubMineIndex < MAX_NUMBER_OF_MINES ) );
*psX = gMineLocation[ ubMineIndex ].sSectorX;
*psY = gMineLocation[ ubMineIndex ].sSectorY;
//*psX = gMineLocation[ ubMineIndex ].sSectorX;
//*psY = gMineLocation[ ubMineIndex ].sSectorY;
*psX = gMineStatus[ ubMineIndex ].sSectorX;
*psY = gMineStatus[ ubMineIndex ].sSectorY;
}
@@ -795,7 +794,8 @@ INT8 GetMineIndexForTown( INT8 bTownId )
// given town id, send sector value of mine, a 0 means no mine for this town
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
{
if( gMineLocation[ ubMineIndex ].bAssociatedTown == bTownId )
//if( gMineLocation[ ubMineIndex ].bAssociatedTown == bTownId )
if( gMineStatus[ ubMineIndex ].bAssociatedTown == bTownId )
{
return( ubMineIndex );
}
@@ -814,9 +814,11 @@ INT16 GetMineSectorForTown( INT8 bTownId )
// given town id, send sector value of mine, a 0 means no mine for this town
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
{
if( gMineLocation[ ubMineIndex ].bAssociatedTown == bTownId )
//if( gMineLocation[ ubMineIndex ].bAssociatedTown == bTownId )
if( gMineStatus[ ubMineIndex ].bAssociatedTown == bTownId )
{
sMineSector = gMineLocation[ ubMineIndex ].sSectorX + ( gMineLocation[ ubMineIndex ].sSectorY * MAP_WORLD_X );
//sMineSector = gMineLocation[ ubMineIndex ].sSectorX + ( gMineLocation[ ubMineIndex ].sSectorY * MAP_WORLD_X );
sMineSector = gMineStatus[ ubMineIndex ].sSectorX + ( gMineStatus[ ubMineIndex ].sSectorY * MAP_WORLD_X );
break;
}
}
@@ -833,7 +835,8 @@ BOOLEAN IsThereAMineInThisSector( INT16 sX, INT16 sY )
// run through the list...if a mine here, great
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
{
if( ( gMineLocation[ ubMineIndex ].sSectorX == sX ) && ( gMineLocation[ ubMineIndex ].sSectorY == sY ) )
//if( ( gMineLocation[ ubMineIndex ].sSectorX == sX ) && ( gMineLocation[ ubMineIndex ].sSectorY == sY ) )
if( ( gMineStatus[ ubMineIndex ].sSectorX == sX ) && ( gMineStatus[ ubMineIndex ].sSectorY == sY ) )
{
return( TRUE );
}
@@ -845,7 +848,8 @@ BOOLEAN IsThereAMineInThisSector( INT16 sX, INT16 sY )
BOOLEAN PlayerControlsMine(INT8 bMineIndex)
{
// a value of TRUE is from the enemy's point of view
if (StrategicMap[( gMineLocation[ bMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineLocation[ bMineIndex ].sSectorY ) )].fEnemyControlled == TRUE )
//if (StrategicMap[( gMineLocation[ bMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineLocation[ bMineIndex ].sSectorY ) )].fEnemyControlled == TRUE )
if (StrategicMap[( gMineStatus[ bMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineStatus[ bMineIndex ].sSectorY ) )].fEnemyControlled == TRUE )
return(FALSE);
else
{
@@ -864,6 +868,9 @@ BOOLEAN PlayerControlsMine(INT8 bMineIndex)
BOOLEAN SaveMineStatusToSaveGameFile( HWFILE hFile )
{
return g_luaMines.Save(hFile);
#if 0
UINT32 uiNumBytesWritten;
//Save the MineStatus
@@ -874,11 +881,15 @@ BOOLEAN SaveMineStatusToSaveGameFile( HWFILE hFile )
}
return( TRUE );
#endif
}
BOOLEAN LoadMineStatusFromSavedGameFile( HWFILE hFile )
{
return g_luaMines.Load(hFile);
#if 0
UINT32 uiNumBytesRead;
//Load the MineStatus
@@ -889,6 +900,7 @@ BOOLEAN LoadMineStatusFromSavedGameFile( HWFILE hFile )
}
return( TRUE );
#endif
}
@@ -899,7 +911,8 @@ void ShutOffMineProduction( INT8 bMineIndex )
if ( !gMineStatus[ bMineIndex ].fShutDown )
{
gMineStatus[ bMineIndex ].fShutDown = TRUE;
AddHistoryToPlayersLog( HISTORY_MINE_SHUTDOWN, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
//AddHistoryToPlayersLog( HISTORY_MINE_SHUTDOWN, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
AddHistoryToPlayersLog( HISTORY_MINE_SHUTDOWN, gMineStatus[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY );
}
}
@@ -913,7 +926,8 @@ void RestartMineProduction( INT8 bMineIndex )
if ( gMineStatus[ bMineIndex ].fShutDown )
{
gMineStatus[ bMineIndex ].fShutDown = FALSE;
AddHistoryToPlayersLog( HISTORY_MINE_REOPENED, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
//AddHistoryToPlayersLog( HISTORY_MINE_REOPENED, gMineLocation[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY );
AddHistoryToPlayersLog( HISTORY_MINE_REOPENED, gMineStatus[ bMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY );
}
}
}
@@ -948,22 +962,27 @@ UINT8 GetHeadMinerIndexForMine( INT8 bMineIndex )
{
usProfileId = gHeadMinerData[ ubMinerIndex ].usProfileId;
if (gMercProfiles[ usProfileId ].bTown == gMineLocation[ bMineIndex ].bAssociatedTown)
//if (gMercProfiles[ usProfileId ].bTown == gMineLocation[ bMineIndex ].bAssociatedTown)
if (gMercProfiles[ usProfileId ].bTown == gMineStatus[ bMineIndex ].bAssociatedTown)
{
return(ubMinerIndex);
}
}
// not found - yack!
Assert( FALSE );
return( 0 );
//Assert( FALSE );
//return( 0 );
// Do not assert but use an error code instead,
// as a mod might intentionally want to not have a head miner at every mine.
return -1;
}
UINT16 GetHeadMinerProfileIdForMine( INT8 bMineIndex )
{
return(gHeadMinerData[ GetHeadMinerIndexForMine( bMineIndex ) ].usProfileId);
}
//UINT16 GetHeadMinerProfileIdForMine( INT8 bMineIndex )
//{
// return(gHeadMinerData[ GetHeadMinerIndexForMine( bMineIndex ) ].usProfileId);
//}
void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
@@ -981,6 +1000,8 @@ void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
Assert( CheckFact( FACT_MINERS_PLACED, 0 ) );
ubHeadMinerIndex = GetHeadMinerIndexForMine( bMineIndex );
if (ubHeadMinerIndex == -1)
return;
usHeadMinerProfileId = gHeadMinerData[ ubHeadMinerIndex ].usProfileId;
// make sure the miner ain't dead
@@ -992,9 +1013,11 @@ void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
}
bQuoteNum = gHeadMinerData[ ubHeadMinerIndex ].bQuoteNum[ ubQuoteType ];
Assert( bQuoteNum != -1 );
//Assert( bQuoteNum != -1 );
if (bQuoteNum == -1)
return;
ubFaceIndex = ( UINT8 ) uiExternalStaticNPCFaces[ gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace ];
ubFaceIndex = ( UINT8 ) uiExternalStaticNPCFaces[ gHeadMinerData[ ubHeadMinerIndex ].ubExternalFaceIndex ];
// transition to mapscreen is not necessary for "creatures gone" quote - player is IN that mine, so he'll know
if ( ubQuoteType != HEAD_MINER_STRATEGIC_QUOTE_CREATURES_GONE )
@@ -1025,7 +1048,7 @@ void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
// there's no head miner in San Mona, this is an error!
case MINE_SAN_MONA:
default:
Assert( FALSE );
//Assert( FALSE );
sXPos = DEFAULT_EXTERN_PANEL_X_POS, sYPos = DEFAULT_EXTERN_PANEL_Y_POS;
break;
}
@@ -1033,7 +1056,9 @@ void IssueHeadMinerQuote( INT8 bMineIndex, UINT8 ubQuoteType )
SetExternMapscreenSpeechPanelXY( sXPos, sYPos );
// cause this quote to come up for this profile id and an indicator to flash over the mine sector
HandleMinerEvent( gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace, gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY, (INT16) bQuoteNum, fForceMapscreen );
//HandleMinerEvent( gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace, gMineLocation[ bMineIndex ].sSectorX, gMineLocation[ bMineIndex ].sSectorY, (INT16) bQuoteNum, fForceMapscreen );
//HandleMinerEvent( gHeadMinerData[ ubHeadMinerIndex ].ubExternalFace, gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY, (INT16) bQuoteNum, fForceMapscreen );
HandleMinerEvent( ubHeadMinerIndex, gMineStatus[ bMineIndex ].sSectorX, gMineStatus[ bMineIndex ].sSectorY, (INT16) bQuoteNum, fForceMapscreen );
// stop time compression with any miner quote - these are important events.
StopTimeCompression();
@@ -1047,7 +1072,8 @@ UINT8 GetHeadMinersMineIndex( UINT8 ubMinerProfileId)
// find which mine this guy represents
for( ubMineIndex = 0; ubMineIndex < MAX_NUMBER_OF_MINES; ubMineIndex++ )
{
if (gMineLocation[ ubMineIndex ].bAssociatedTown == gMercProfiles[ ubMinerProfileId ].bTown)
//if (gMineLocation[ ubMineIndex ].bAssociatedTown == gMercProfiles[ ubMinerProfileId ].bTown)
if (gMineStatus[ ubMineIndex ].bAssociatedTown == gMercProfiles[ ubMinerProfileId ].bTown)
{
return(ubMineIndex);
}
@@ -1068,7 +1094,8 @@ void PlayerSpokeToHeadMiner( UINT8 ubMinerProfileId )
// if this is our first time set a history fact
if( gMineStatus[ ubMineIndex ].fSpokeToHeadMiner == FALSE )
{
AddHistoryToPlayersLog( HISTORY_TALKED_TO_MINER, gMineLocation[ ubMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ ubMineIndex ].sSectorX, gMineLocation[ ubMineIndex ].sSectorY );
//AddHistoryToPlayersLog( HISTORY_TALKED_TO_MINER, gMineLocation[ ubMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineLocation[ ubMineIndex ].sSectorX, gMineLocation[ ubMineIndex ].sSectorY );
AddHistoryToPlayersLog( HISTORY_TALKED_TO_MINER, gMineStatus[ ubMineIndex ].bAssociatedTown, GetWorldTotalMin( ), gMineStatus[ ubMineIndex ].sSectorX, gMineStatus[ ubMineIndex ].sSectorY );
gMineStatus[ ubMineIndex ].fSpokeToHeadMiner = TRUE;
}
}
@@ -1096,7 +1123,8 @@ BOOLEAN IsHisMineDisloyal( UINT8 ubMinerProfileId )
ubMineIndex = GetHeadMinersMineIndex( ubMinerProfileId );
if (gTownLoyalty[ gMineLocation[ ubMineIndex ].bAssociatedTown ].ubRating < LOW_MINE_LOYALTY_THRESHOLD)
//if (gTownLoyalty[ gMineLocation[ ubMineIndex ].bAssociatedTown ].ubRating < LOW_MINE_LOYALTY_THRESHOLD)
if (gTownLoyalty[ gMineStatus[ ubMineIndex ].bAssociatedTown ].ubRating < LOW_MINE_LOYALTY_THRESHOLD)
{
// pretty disloyal
return(TRUE);
@@ -1252,6 +1280,7 @@ INT8 GetIdOfMineForSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
{
bMineIndex = GetMineIndexForSector( sSectorX, sSectorY );
}
#if 0
// handle for first level
else if( bSectorZ == 1 )
{
@@ -1300,37 +1329,47 @@ INT8 GetIdOfMineForSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ )
break;
}
}
#endif
for (std::vector<AssociatedMineSector>::iterator it = associatedMineSectors.begin();
it != associatedMineSectors.end(); ++it)
{
if (it->x == sSectorX && it->y == sSectorY && bSectorZ == it->z)
{
return it->mineID;
}
}
return( bMineIndex );
return( bMineIndex ); // == -1
}
// use this for miner (civilian) quotes when *underground* in a mine
BOOLEAN PlayerForgotToTakeOverMine( UINT8 ubMineIndex )
{
MINE_STATUS_TYPE *pMineStatus;
Assert( ( ubMineIndex >= 0 ) && ( ubMineIndex < MAX_NUMBER_OF_MINES ) );
pMineStatus = &(gMineStatus[ ubMineIndex ]);
// mine surface sector is player controlled
// mine not empty
// player hasn't spoken to the head miner, but hasn't attacked him either
// miner is alive
if ( (StrategicMap[( gMineLocation[ ubMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineLocation[ ubMineIndex ].sSectorY ) )].fEnemyControlled == FALSE ) &&
( !pMineStatus->fEmpty ) &&
( !pMineStatus->fSpokeToHeadMiner ) &&
( !pMineStatus->fAttackedHeadMiner ) &&
( gMercProfiles[ GetHeadMinerProfileIdForMine( ubMineIndex ) ].bLife > 0 ) )
{
return( TRUE );
}
return( FALSE );
}
//BOOLEAN PlayerForgotToTakeOverMine( UINT8 ubMineIndex )
//{
// MINE_STATUS_TYPE *pMineStatus;
//
//
// Assert( ( ubMineIndex >= 0 ) && ( ubMineIndex < MAX_NUMBER_OF_MINES ) );
//
// pMineStatus = &(gMineStatus[ ubMineIndex ]);
//
// // mine surface sector is player controlled
// // mine not empty
// // player hasn't spoken to the head miner, but hasn't attacked him either
// // miner is alive
// //if ( (StrategicMap[( gMineLocation[ ubMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineLocation[ ubMineIndex ].sSectorY ) )].fEnemyControlled == FALSE ) &&
// if ( (StrategicMap[( gMineStatus[ ubMineIndex ].sSectorX ) + ( MAP_WORLD_X * ( gMineStatus[ ubMineIndex ].sSectorY ) )].fEnemyControlled == FALSE ) &&
// ( !pMineStatus->fEmpty ) &&
// ( !pMineStatus->fSpokeToHeadMiner ) &&
// ( !pMineStatus->fAttackedHeadMiner ) &&
// ( gMercProfiles[ GetHeadMinerProfileIdForMine( ubMineIndex ) ].bLife > 0 ) )
// {
// return( TRUE );
// }
//
// return( FALSE );
//}
+42 -25
View File
@@ -4,7 +4,8 @@
// the .h to the mine management system
#include "Types.h"
#include "strategicmap.h"
#include "mapscreen.h"
// the mines
enum{
@@ -14,17 +15,17 @@ enum{
MINE_CAMBRIA,
MINE_CHITZENA,
MINE_GRUMM,
MAX_NUMBER_OF_MINES,
//MAX_NUMBER_OF_MINES,
};
enum{
MINER_FRED = 0,
MINER_MATT,
MINER_OSWALD,
MINER_CALVIN,
MINER_CARL,
NUM_HEAD_MINERS,
};
//enum{
// MINER_FRED = 0,
// MINER_MATT,
// MINER_OSWALD,
// MINER_CALVIN,
// MINER_CARL,
// NUM_HEAD_MINERS,
//};
// different types of mines
enum{
@@ -55,15 +56,20 @@ enum{
};
struct AssociatedMineSector
{
UINT8 mineID;
UINT8 x, y, z;
};
// the strategic mine structures
typedef struct MINE_LOCATION_TYPE
{
INT16 sSectorX; // x value of sector mine is in
INT16 sSectorY; // y value of sector mine is in
INT8 bAssociatedTown; // associated town of this mine
} MINE_LOCATION_TYPE;
//typedef struct MINE_LOCATION_TYPE
//{
// INT16 sSectorX; // x value of sector mine is in
// INT16 sSectorY; // y value of sector mine is in
// INT8 bAssociatedTown; // associated town of this mine
//
//} MINE_LOCATION_TYPE;
typedef struct MINE_STATUS_TYPE
{
@@ -90,16 +96,30 @@ typedef struct MINE_STATUS_TYPE
BYTE filler[11]; // reserved for expansion
// merge in MINE_LOCATION_TYPE
INT16 sSectorX; // x value of sector mine is in
INT16 sSectorY; // y value of sector mine is in
INT8 bAssociatedTown; // associated town of this mine
UINT32 StrategicIndex() { return CALCULATE_STRATEGIC_INDEX(sSectorX, sSectorY); };
BOOLEAN fInfectible;
} MINE_STATUS_TYPE;
typedef struct HEAD_MINER_TYPE
{
UINT16 usProfileId;
INT8 bQuoteNum[NUM_HEAD_MINER_STRATEGIC_QUOTES];
UINT8 ubExternalFace;
UINT8 ubExternalFaceIndex;
} HEAD_MINER_TYPE;
extern INT32 MAX_NUMBER_OF_MINES;
extern INT32 NUM_HEAD_MINERS;
extern std::vector<MINE_STATUS_TYPE> gMineStatus;
extern std::vector<AssociatedMineSector> associatedMineSectors;
extern std::vector<HEAD_MINER_TYPE> gHeadMinerData;
// init mines
void InitializeMines( void );
@@ -116,9 +136,6 @@ UINT32 GetMaxDailyRemovalFromMine( INT8 bMineIndex );
// which town does this mine belong to?
INT8 GetTownAssociatedWithMine( INT8 bMineIndex );
// which mine belongs tot his town
INT8 GetMineAssociatedWithThisTown( INT8 bTownValue );
// posts the actual mine production events daily
void PostEventsForMineProduction(void);
@@ -126,10 +143,10 @@ void PostEventsForMineProduction(void);
void HandleIncomeFromMines( void );
// predict income from mines
INT32 PredictIncomeFromPlayerMines( void );
INT32 PredictIncomeFromPlayerMines( BOOLEAN fIncludeFacilities );
// predict income from a mine
UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex );
UINT32 PredictDailyIncomeFromAMine( INT8 bMineIndex, BOOLEAN fIncludeFacilities );
// calculate maximum possible daily income from all mines
INT32 CalcMaxPlayerIncomeFromMines( void );
@@ -162,7 +179,7 @@ void MineShutdownIsPermanent( INT8 bMineIndex );
BOOLEAN IsMineShutDown( INT8 bMineIndex );
UINT8 GetHeadMinerIndexForMine( INT8 bMineIndex );
UINT16 GetHeadMinerProfileIdForMine( INT8 bMineIndex );
//UINT16 GetHeadMinerProfileIdForMine( INT8 bMineIndex );
// Find the sector location of a mine
void GetMineSector( UINT8 ubMineIndex, INT16 * psX, INT16 * psY );
@@ -193,7 +210,7 @@ BOOLEAN HasHisMineBeenProducingForPlayerForSomeTime( UINT8 ubMinerProfileId );
INT8 GetIdOfMineForSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
// use this for miner (civilian) quotes when *underground* in a mine
BOOLEAN PlayerForgotToTakeOverMine( UINT8 ubMineIndex );
//BOOLEAN PlayerForgotToTakeOverMine( UINT8 ubMineIndex );
// use this to determine whether or not to place miners into a underground mine level
BOOLEAN AreThereMinersInsideThisMine( UINT8 ubMineIndex );
+167 -25
View File
@@ -71,10 +71,9 @@ GROUP *gpPendingSimultaneousGroup = NULL;
extern BOOLEAN fMapScreenBottomDirty;
extern BOOLEAN gfUsePersistantPBI;
#ifdef JA2BETAVERSION
extern BOOLEAN gfExitViewer;
void ValidateGroups( GROUP *pGroup );
#endif
extern BOOLEAN gfExitViewer;
BOOLEAN ValidateGroups( GROUP *pGroup );
extern BOOLEAN gubNumAwareBattles;
extern INT8 SquadMovementGroups[ ];
@@ -1168,9 +1167,11 @@ BOOLEAN CheckConditionsForBattle( GROUP *pGroup )
//then we will go straight to autoresolve, where the enemy will likely annihilate them or capture them.
//If there are no alive mercs, then there is nothing anybody can do. The enemy will completely ignore
//this, and continue on.
#ifdef JA2BETAVERSION
ValidateGroups( pGroup );
#endif
// WANNE: ValidateGroups now returns a BOOLEAN Value (TRUE/FALSE) if the attacking is valid.
// This fixes the problem that 0 enemies could attack a sector
if (!ValidateGroups( pGroup ))
return FALSE;
StopTimeCompression();
@@ -1581,7 +1582,7 @@ void AddCorpsesToBloodcatLair( INT16 sSectorX, INT16 sSectorY )
Corpse.usFlags = ROTTING_CORPSE_FIND_SWEETSPOT_FROM_GRIDNO;
// 1st gridno
Corpse.sGridNo = 14319;
Corpse.sGridNo = 14319; //dnl!!!
ConvertGridNoToXY( Corpse.sGridNo, &sXPos, &sYPos );
Corpse.dXPos = (FLOAT)( CenterX( sXPos ) );
Corpse.dYPos = (FLOAT)( CenterY( sYPos ) );
@@ -1591,7 +1592,7 @@ void AddCorpsesToBloodcatLair( INT16 sSectorX, INT16 sSectorY )
// 2nd gridno
Corpse.sGridNo = 9835;
Corpse.sGridNo = 9835; //dnl!!!
ConvertGridNoToXY( Corpse.sGridNo, &sXPos, &sYPos );
Corpse.dXPos = (FLOAT)( CenterX( sXPos ) );
Corpse.dYPos = (FLOAT)( CenterY( sYPos ) );
@@ -1601,7 +1602,7 @@ void AddCorpsesToBloodcatLair( INT16 sSectorX, INT16 sSectorY )
// 3rd gridno
Corpse.sGridNo = 11262;
Corpse.sGridNo = 11262; //dnl!!!
ConvertGridNoToXY( Corpse.sGridNo, &sXPos, &sYPos );
Corpse.dXPos = (FLOAT)( CenterX( sXPos ) );
Corpse.dYPos = (FLOAT)( CenterY( sYPos ) );
@@ -3102,6 +3103,43 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup
if( iTraverseTime < iBestTraverseTime )
iBestTraverseTime = iTraverseTime;
}
///////////////////////////////////////////////////////////////////////////////
// SANDRO - STOMP traits - ranger reduces time needed for travelling around
if( pGroup->fPlayer && !fAir && gGameOptions.fNewTraitSystem)
{
// see if we have any ranger here
UINT8 ubRangerHere = 0;
curr = pGroup->pPlayerList;
while( curr )
{
pSoldier = curr->pSoldier;
if( HAS_SKILL_TRAIT( pSoldier, RANGER_NT ))
ubRangerHere += NUM_SKILL_TRAITS( pSoldier, RANGER_NT );
curr = curr->next;
}
// yes, we have...
if( ubRangerHere > 0 )
{
// no more than certain number of simultaneous bonuses
ubRangerHere = min( gSkillTraitValues.ubRAMaxBonusesToTravelSpeed, ubRangerHere );
// on foot, the bonus should be higher
if( fFoot )
{
// however, we cannot be quicker than the helicopter
iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ( ubRangerHere * gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot )) / 100));
}
// all other types (except air)
else
{
// however, we cannot be quicker than the helicopter
iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ( ubRangerHere * gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle )) / 100));
}
}
}
///////////////////////////////////////////////////////////////////////////////
return iBestTraverseTime;
}
@@ -3277,6 +3315,7 @@ void HandleArrivalOfReinforcements( GROUP *pGroup )
{
gfPendingEnemies = TRUE;
ResetMortarsOnTeamCount();
ResetNumSquadleadersInArmyGroup(); // added by SANDRO
AddPossiblePendingEnemiesToBattle();
}
//Update the known number of enemies in the sector.
@@ -4816,18 +4855,75 @@ BOOLEAN TestForBloodcatAmbush( GROUP *pGroup )
if( !fAlreadyAmbushed && PlacementType != BLOODCAT_PLACEMENT_STATIC && pSector->bBloodCats > 0 &&
!pGroup->fVehicle && !NumEnemiesInSector( pGroup->ubSectorX, pGroup->ubSectorY ) )
{
// Wilderness ambush, or the player has unwittingly entered the lair?
if( PlacementType == BLOODCAT_PLACEMENT_AMBUSH || !gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] )
///////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - STOMP traits - Scouting prevents the ambush of bloodcats
BOOLEAN fBloodCatAmbushPrevented = FALSE;
// The player has entered the lair
if(( PlacementType == BLOODCAT_PLACEMENT_LAIR )&& !gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] )
{
// Ambush occurs.
gubEnemyEncounterCode = BLOODCAT_AMBUSH_CODE;
// We know about the lair
if( gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] )
{
gubEnemyEncounterCode = ENTERING_BLOODCAT_LAIR_CODE;
}
else
{
if ( gGameOptions.fNewTraitSystem && ScoutIsPresentInSquad( pGroup->ubSectorX, pGroup->ubSectorY ) && gSkillTraitValues.fSCPreventsBloodcatsAmbushes)
{
// Ha..! We've found the lair, safely
if ( gSkillTraitValues.fSCThrowMessageIfAmbushPrevented )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_BLOODCATS_AMBUSH_PREVENTED] );
fBloodCatAmbushPrevented = TRUE;
gubEnemyEncounterCode = ENTERING_BLOODCAT_LAIR_CODE;
gubFact[ FACT_PLAYER_KNOWS_ABOUT_BLOODCAT_LAIR ] = TRUE;
}
else
{
// Ambush in the lair.
gubEnemyEncounterCode = BLOODCAT_AMBUSH_CODE;
}
}
}
// Wilderness ambush
else
{
// Player knowingly enters lair.
gubEnemyEncounterCode = ENTERING_BLOODCAT_LAIR_CODE;
if ( gGameOptions.fNewTraitSystem && ScoutIsPresentInSquad( pGroup->ubSectorX, pGroup->ubSectorY ) && gSkillTraitValues.fSCPreventsBloodcatsAmbushes)
{
// We are safe
if ( gSkillTraitValues.fSCThrowMessageIfAmbushPrevented )
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_BLOODCATS_AMBUSH_PREVENTED] );
fBloodCatAmbushPrevented = TRUE;
gubEnemyEncounterCode = NO_ENCOUNTER_CODE;
}
else
{
// Ambush occurs.
gubEnemyEncounterCode = BLOODCAT_AMBUSH_CODE;
}
}
return TRUE;
// merc recoeds - get a point to scouts
if ( fBloodCatAmbushPrevented )
{
for( UINT16 i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ )
{
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{
if ( MercPtrs[ i ]->sSectorX == pGroup->ubSectorX && MercPtrs[ i ]->sSectorY == pGroup->ubSectorY && MercPtrs[ i ]->bAssignment != ASSIGNMENT_POW && MercPtrs[ i ]->stats.bLife > OKLIFE )
{
if( HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ) && MercPtrs[ i ]->ubProfile != NO_PROFILE )
{
gMercProfiles[ MercPtrs[ i ]->ubProfile ].records.usAmbushesExperienced++;
}
}
}
}
}
return( ( gubEnemyEncounterCode == NO_ENCOUNTER_CODE ) ? FALSE : TRUE);
///////////////////////////////////////////////////////////////////////////////////////////
}
else
{
@@ -5088,8 +5184,13 @@ BOOLEAN WildernessSectorWithAllProfiledNPCsNotSpokenWith( INT16 sSectorX, INT16
MERCPROFILESTRUCT * pProfile;
BOOLEAN fFoundSomebody = FALSE;
for ( ubProfile = FIRST_RPC; ubProfile < GASTON; ubProfile++ )
//for ( ubProfile = FIRST_RPC; ubProfile < GASTON; ubProfile++ )
//new profiles by Jazz
for ( ubProfile = 0; ubProfile < NUM_PROFILES; ubProfile++ )
{
if ( gProfilesRPC[ubProfile].ProfilId == ubProfile || gProfilesNPC[ubProfile].ProfilId == ubProfile || gProfilesVehicle[ubProfile].ProfilId == ubProfile)
{
pProfile = &gMercProfiles[ ubProfile ];
@@ -5100,7 +5201,8 @@ BOOLEAN WildernessSectorWithAllProfiledNPCsNotSpokenWith( INT16 sSectorX, INT16
}
// skip vehicles
if ( ubProfile >= PROF_HUMMER && ubProfile <= PROF_HELICOPTER )
//if ( ubProfile >= PROF_HUMMER && ubProfile <= PROF_HELICOPTER )
if ( gProfilesVehicle[ubProfile].ProfilId == ubProfile )
{
continue;
}
@@ -5122,8 +5224,14 @@ BOOLEAN WildernessSectorWithAllProfiledNPCsNotSpokenWith( INT16 sSectorX, INT16
return( FALSE );
}
}
}
else
{
return( FALSE );
}
}
return( fFoundSomebody );
}
@@ -5234,13 +5342,20 @@ UINT8 NumberMercsInVehicleGroup( GROUP *pGroup )
return 0;
}
#ifdef JA2BETAVERSION
void ValidateGroups( GROUP *pGroup )
BOOLEAN ValidateGroups( GROUP *pGroup )
{
BOOLEAN isValid = TRUE;
//Do error checking, and report group
ValidatePlayersAreInOneGroupOnly();
#ifdef JA2BETAVERSION
ValidatePlayersAreInOneGroupOnly();
#endif
if( !pGroup->fPlayer && !pGroup->ubGroupSize )
{
isValid = FALSE;
//report error
CHAR16 str[ 512 ];
if( pGroup->ubSectorIDOfLastReassignment == 255 )
@@ -5260,7 +5375,34 @@ void ValidateGroups( GROUP *pGroup )
}
//correct error
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
#ifdef JA2BETAVERSION
DoScreenIndependantMessageBox( str, MSG_BOX_FLAG_OK, NULL );
#endif
}
return isValid;
}
#endif
// SANDRO - added check if we have a scout in group
BOOLEAN ScoutIsPresentInSquad( INT16 ubSectorNumX, INT16 ubSectorNumY )
{
BOOLEAN fScoutPresent = FALSE;
INT32 i;
for( i = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; i <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; i++ )
{
if( MercPtrs[ i ]->bActive && MercPtrs[ i ]->stats.bLife && !(MercPtrs[ i ]->flags.uiStatusFlags & SOLDIER_VEHICLE) )
{
if ( MercPtrs[ i ]->sSectorX == ubSectorNumX && MercPtrs[ i ]->sSectorY == ubSectorNumY && MercPtrs[ i ]->bAssignment != ASSIGNMENT_POW && MercPtrs[ i ]->stats.bLife > OKLIFE )
{
if( HAS_SKILL_TRAIT( MercPtrs[ i ], SCOUTING_NT ))
{
fScoutPresent = TRUE;
}
}
}
}
return ( fScoutPresent );
}
+2
View File
@@ -305,4 +305,6 @@ BOOLEAN DoesPlayerExistInPGroup( UINT8 ubGroupID, SOLDIERTYPE *pSoldier );
BOOLEAN GroupHasInTransitDeadOrPOWMercs( GROUP *pGroup );
BOOLEAN ScoutIsPresentInSquad( INT16 ubSectorNumX, INT16 ubSectorNumY ); // added by SANDRO
#endif
+46 -4
View File
@@ -39,6 +39,10 @@
#include "Facilities.h"
#endif
#include "Luaglobal.h"
#include "LuaInitNPCs.h"
#include "Interface.h"
// the max loyalty rating for any given town
#define MAX_LOYALTY_VALUE 100
@@ -678,6 +682,8 @@ void HandleMurderOfCivilian( SOLDIERTYPE *pSoldier, BOOLEAN fIntentional )
UINT32 uiChanceFalseAccusal = 0;
INT8 bKillerTeam = 0;
BOOLEAN fIncrement = FALSE;
UINT16 iCounter2;
// ubAttacker CAN be NOBODY... Don't treat is as murder if NOBODY killed us...
@@ -702,6 +708,18 @@ void HandleMurderOfCivilian( SOLDIERTYPE *pSoldier, BOOLEAN fIntentional )
}
}
// if civilian belongs to a civilian group
if ( pSoldier->ubCivilianGroup != NON_CIV_GROUP )
{
//New Group by Jazz
for( iCounter2 = REBEL_CIV_GROUP; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
{
if (zCivGroupName[iCounter2].Loyalty == FALSE)
return;
}
}
/*
// if civilian belongs to a civilian group
if ( pSoldier->ubCivilianGroup != NON_CIV_GROUP )
{
@@ -714,8 +732,17 @@ void HandleMurderOfCivilian( SOLDIERTYPE *pSoldier, BOOLEAN fIntentional )
case WARDEN_CIV_GROUP:
return;
}
//New Group by Jazz
for( iCounter2 = UNNAMED_CIV_GROUP_15; iCounter2 < NUM_CIV_GROUPS; iCounter2++ )
{
if (pSoldier->ubCivilianGroup == iCounter2)
return;
}
}
*/
// set killer team
bKillerTeam = Menptr[ pSoldier->ubAttackerID ].bTeam;
@@ -1605,8 +1632,7 @@ void DecrementTownLoyaltyEverywhere( UINT32 uiLoyaltyDecrease )
}
// this applies the change to every town differently, depending on the distance from the event
void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ)
{
INT32 iLoyaltyChange;
{
INT8 bTownId = 0;
if( bSectorZ == 0 )
@@ -1620,6 +1646,12 @@ void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY
{
return;
}
//move to lua scripts StrategicTownLoyalty.lua
#ifdef LUA_STRATEGY_TOWN_LOYALTY
LuaHandleGlobalLoyaltyEvent( ubEventType, sSectorX, sSectorY, bSectorZ, 0 );
#else
INT32 iLoyaltyChange;
// determine what the base loyalty change of this event type is worth
// these are->hundredths<- of loyalty points, so choose appropriate values accordingly!
@@ -1677,6 +1709,8 @@ void HandleGlobalLoyaltyEvent( UINT8 ubEventType, INT16 sSectorX, INT16 sSectorY
}
AffectAllTownsLoyaltyByDistanceFrom( iLoyaltyChange, sSectorX, sSectorY, bSectorZ);
#endif
}
@@ -1848,6 +1882,12 @@ void CheckIfEntireTownHasBeenLost( INT8 bTownId, INT16 sSectorX, INT16 sSectorY
void HandleLoyaltyChangeForNPCAction( UINT8 ubNPCProfileId )
{
//move to lua scripts StrategicTownLoyalty.lua
#ifdef LUA_STRATEGY_TOWN_LOYALTY
LetHandleLoyaltyChangeForNPCAction( ubNPCProfileId, 0 );
#else
switch ( ubNPCProfileId )
{
case MIGUEL:
@@ -1891,6 +1931,7 @@ void HandleLoyaltyChangeForNPCAction( UINT8 ubNPCProfileId )
break;
}
#endif
}
@@ -1973,7 +2014,8 @@ void HandleLoyaltyImplicationsOfMercRetreat( INT8 bRetreatCode, INT16 sSectorX,
if ( bRetreatCode == RETREAT_TACTICAL_TRAVERSAL )
{
// if not worse than 2:1 odds, then penalize morale
if ( gTacticalStatus.fEnemyInSector && ( PlayerStrength() * 2 >= EnemyStrength() ) )
// SANDRO - Set the odds based on difficulty level
if ( gTacticalStatus.fEnemyInSector && ( (PlayerStrength() * (2 + gGameOptions.ubDifficultyLevel)) >= EnemyStrength() ) )
{
HandleMoraleEvent( NULL, MORALE_RAN_AWAY, sSectorX, sSectorY, (INT8)sSectorZ );
}
+767
View File
@@ -0,0 +1,767 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="Strategic"
ProjectGUID="{AB8837DB-0435-40C7-916A-0AACF5CFF1C4}"
RootNamespace="Strategic"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Debug.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
RuntimeLibrary="0"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditor|Win32"
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
RuntimeLibrary="0"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="MapEditorD|Win32"
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
DisableSpecificWarnings="4100"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release_WithDebugInfo|Win32"
OutputDirectory="..\lib\VS2005\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2005\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2.vsprops"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/D &quot;_CRT_SECURE_NO_DEPRECATE&quot;"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;"
RuntimeLibrary="0"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\Assignments.h"
>
</File>
<File
RelativePath=".\Auto Resolve.h"
>
</File>
<File
RelativePath=".\Campaign Init.h"
>
</File>
<File
RelativePath=".\Campaign Types.h"
>
</File>
<File
RelativePath=".\Creature Spreading.h"
>
</File>
<File
RelativePath=".\Facilities.h"
>
</File>
<File
RelativePath=".\Game Clock.h"
>
</File>
<File
RelativePath=".\Game Event Hook.h"
>
</File>
<File
RelativePath=".\Game Events.h"
>
</File>
<File
RelativePath=".\Game Init.h"
>
</File>
<File
RelativePath=".\Luaglobal.h"
>
</File>
<File
RelativePath=".\LuaInitNPCs.h"
>
</File>
<File
RelativePath=".\Map Screen Helicopter.h"
>
</File>
<File
RelativePath=".\Map Screen Interface Border.h"
>
</File>
<File
RelativePath=".\Map Screen Interface Bottom.h"
>
</File>
<File
RelativePath=".\Map Screen Interface Map Inventory.h"
>
</File>
<File
RelativePath=".\Map Screen Interface Map.h"
>
</File>
<File
RelativePath=".\Map Screen Interface TownMine Info.h"
>
</File>
<File
RelativePath=".\Map Screen Interface.h"
>
</File>
<File
RelativePath=".\mapscreen.h"
>
</File>
<File
RelativePath=".\Meanwhile.h"
>
</File>
<File
RelativePath=".\Merc Contract.h"
>
</File>
<File
RelativePath=".\MilitiaSquads.h"
>
</File>
<File
RelativePath=".\Player Command.h"
>
</File>
<File
RelativePath=".\PreBattle Interface.h"
>
</File>
<File
RelativePath=".\Queen Command.h"
>
</File>
<File
RelativePath=".\Quest Debug System.h"
>
</File>
<File
RelativePath=".\Quests.h"
>
</File>
<File
RelativePath=".\QuestText.h"
>
</File>
<File
RelativePath=".\Reinforcement.h"
>
</File>
<File
RelativePath=".\Scheduling.h"
>
</File>
<File
RelativePath=".\Strategic AI.h"
>
</File>
<File
RelativePath=".\Strategic All.h"
>
</File>
<File
RelativePath=".\Strategic Event Handler.h"
>
</File>
<File
RelativePath=".\Strategic Merc Handler.h"
>
</File>
<File
RelativePath=".\Strategic Mines LUA.h"
>
</File>
<File
RelativePath=".\Strategic Mines.h"
>
</File>
<File
RelativePath=".\Strategic Movement.h"
>
</File>
<File
RelativePath=".\Strategic Pathing.h"
>
</File>
<File
RelativePath=".\Strategic Status.h"
>
</File>
<File
RelativePath=".\Strategic Town Loyalty.h"
>
</File>
<File
RelativePath=".\strategic town reputation.h"
>
</File>
<File
RelativePath=".\Strategic Turns.h"
>
</File>
<File
RelativePath=".\strategic.h"
>
</File>
<File
RelativePath=".\strategicmap.h"
>
</File>
<File
RelativePath=".\Town Militia.h"
>
</File>
<File
RelativePath=".\UndergroundInit.h"
>
</File>
</Filter>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AI Viewer.cpp"
>
</File>
<File
RelativePath=".\Assignments.cpp"
>
</File>
<File
RelativePath=".\Auto Resolve.cpp"
>
</File>
<File
RelativePath=".\Campaign Init.cpp"
>
</File>
<File
RelativePath=".\Creature Spreading.cpp"
>
</File>
<File
RelativePath=".\Facilities.cpp"
>
</File>
<File
RelativePath=".\Game Clock.cpp"
>
</File>
<File
RelativePath=".\Game Event Hook.cpp"
>
</File>
<File
RelativePath=".\Game Events.cpp"
>
</File>
<File
RelativePath=".\Game Init.cpp"
>
</File>
<File
RelativePath=".\Hourly Update.cpp"
>
</File>
<File
RelativePath=".\Luaglobal.cpp"
>
</File>
<File
RelativePath=".\LuaInitNPCs.cpp"
>
</File>
<File
RelativePath=".\Map Screen Helicopter.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface Border.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface Bottom.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface Map Inventory.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface Map.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface TownMine Info.cpp"
>
</File>
<File
RelativePath=".\Map Screen Interface.cpp"
>
</File>
<File
RelativePath=".\mapscreen.cpp"
>
</File>
<File
RelativePath=".\Meanwhile.cpp"
>
</File>
<File
RelativePath=".\Merc Contract.cpp"
>
</File>
<File
RelativePath=".\MilitiaSquads.cpp"
>
</File>
<File
RelativePath=".\Player Command.cpp"
>
</File>
<File
RelativePath=".\PreBattle Interface.cpp"
>
</File>
<File
RelativePath=".\Queen Command.cpp"
>
</File>
<File
RelativePath=".\Quest Debug System.cpp"
>
</File>
<File
RelativePath=".\Quests.cpp"
>
</File>
<File
RelativePath=".\QuestText.cpp"
>
</File>
<File
RelativePath=".\Reinforcement.cpp"
>
</File>
<File
RelativePath=".\Scheduling.cpp"
>
</File>
<File
RelativePath=".\Strategic AI.cpp"
>
</File>
<File
RelativePath=".\Strategic Event Handler.cpp"
>
</File>
<File
RelativePath=".\Strategic Merc Handler.cpp"
>
</File>
<File
RelativePath=".\Strategic Mines LUA.cpp"
>
</File>
<File
RelativePath=".\Strategic Mines.cpp"
>
</File>
<File
RelativePath=".\Strategic Movement Costs.cpp"
>
</File>
<File
RelativePath=".\Strategic Movement.cpp"
>
</File>
<File
RelativePath=".\Strategic Pathing.cpp"
>
</File>
<File
RelativePath=".\Strategic Status.cpp"
>
</File>
<File
RelativePath=".\Strategic Town Loyalty.cpp"
>
</File>
<File
RelativePath=".\strategic town reputation.cpp"
>
</File>
<File
RelativePath=".\Strategic Turns.cpp"
>
</File>
<File
RelativePath=".\strategic.cpp"
>
</File>
<File
RelativePath=".\strategicmap.cpp"
>
</File>
<File
RelativePath=".\Town Militia.cpp"
>
</File>
<File
RelativePath=".\UndergroundInit.cpp"
>
</File>
<File
RelativePath=".\XML_Army.cpp"
>
</File>
<File
RelativePath=".\XML_Bloodcats.cpp"
>
</File>
<File
RelativePath=".\XML_DynamicRestrictions.cpp"
>
</File>
<File
RelativePath=".\XML_ExtraItems.cpp"
>
</File>
<File
RelativePath=".\XML_Facilities.cpp"
>
</File>
<File
RelativePath=".\XML_FacilityTypes.cpp"
>
</File>
<File
RelativePath=".\XML_Roaming.cpp"
>
</File>
<File
RelativePath=".\XML_SectorNames.cpp"
>
</File>
<File
RelativePath=".\XML_UniformColors.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+29 -5
View File
@@ -21,7 +21,7 @@
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Debug.vsprops"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Debug.vsprops"
CharacterSet="0"
>
<Tool
@@ -83,7 +83,7 @@
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
InheritedPropertySheets="..\ja2.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
@@ -147,7 +147,7 @@
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Editor.vsprops"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
@@ -211,7 +211,7 @@
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops;..\ja2_VS2008Editor.vsprops"
InheritedPropertySheets="..\ja2.vsprops;..\ja2_Editor.vsprops"
CharacterSet="0"
>
<Tool
@@ -273,7 +273,7 @@
OutputDirectory="..\lib\VS2008\$(ConfigurationName)"
IntermediateDirectory="..\build\VS2008\$(ProjectName)_$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="..\ja2_VS2008.vsprops"
InheritedPropertySheets="..\ja2.vsprops"
CharacterSet="0"
WholeProgramOptimization="0"
>
@@ -379,6 +379,14 @@
RelativePath="Game Init.h"
>
</File>
<File
RelativePath=".\Luaglobal.h"
>
</File>
<File
RelativePath=".\LuaInitNPCs.h"
>
</File>
<File
RelativePath="Map Screen Helicopter.h"
>
@@ -471,6 +479,10 @@
RelativePath="Strategic Merc Handler.h"
>
</File>
<File
RelativePath=".\Strategic Mines LUA.h"
>
</File>
<File
RelativePath="Strategic Mines.h"
>
@@ -563,6 +575,14 @@
RelativePath="Hourly Update.cpp"
>
</File>
<File
RelativePath=".\Luaglobal.cpp"
>
</File>
<File
RelativePath=".\LuaInitNPCs.cpp"
>
</File>
<File
RelativePath="Map Screen Helicopter.cpp"
>
@@ -651,6 +671,10 @@
RelativePath="Strategic Merc Handler.cpp"
>
</File>
<File
RelativePath=".\Strategic Mines LUA.cpp"
>
</File>
<File
RelativePath="Strategic Mines.cpp"
>
+317
View File
@@ -0,0 +1,317 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="MapEditorD|Win32">
<Configuration>MapEditorD</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="MapEditor|Win32">
<Configuration>MapEditor</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Relese_WithDebugInfo|Win32">
<Configuration>Relese_WithDebugInfo</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Assignments.h" />
<ClInclude Include="Auto Resolve.h" />
<ClInclude Include="Campaign Init.h" />
<ClInclude Include="Campaign Types.h" />
<ClInclude Include="Creature Spreading.h" />
<ClInclude Include="Facilities.h" />
<ClInclude Include="Game Clock.h" />
<ClInclude Include="Game Event Hook.h" />
<ClInclude Include="Game Events.h" />
<ClInclude Include="Game Init.h" />
<ClInclude Include="Luaglobal.h" />
<ClInclude Include="LuaInitNPCs.h" />
<ClInclude Include="Map Screen Helicopter.h" />
<ClInclude Include="Map Screen Interface Border.h" />
<ClInclude Include="Map Screen Interface Bottom.h" />
<ClInclude Include="Map Screen Interface Map Inventory.h" />
<ClInclude Include="Map Screen Interface Map.h" />
<ClInclude Include="Map Screen Interface TownMine Info.h" />
<ClInclude Include="Map Screen Interface.h" />
<ClInclude Include="mapscreen.h" />
<ClInclude Include="Meanwhile.h" />
<ClInclude Include="Merc Contract.h" />
<ClInclude Include="MilitiaSquads.h" />
<ClInclude Include="Player Command.h" />
<ClInclude Include="PreBattle Interface.h" />
<ClInclude Include="Queen Command.h" />
<ClInclude Include="Quest Debug System.h" />
<ClInclude Include="Quests.h" />
<ClInclude Include="QuestText.h" />
<ClInclude Include="Reinforcement.h" />
<ClInclude Include="Scheduling.h" />
<ClInclude Include="Strategic AI.h" />
<ClInclude Include="Strategic All.h" />
<ClInclude Include="Strategic Event Handler.h" />
<ClInclude Include="Strategic Merc Handler.h" />
<ClInclude Include="Strategic Mines LUA.h" />
<ClInclude Include="Strategic Mines.h" />
<ClInclude Include="Strategic Movement.h" />
<ClInclude Include="Strategic Pathing.h" />
<ClInclude Include="Strategic Status.h" />
<ClInclude Include="Strategic Town Loyalty.h" />
<ClInclude Include="strategic town reputation.h" />
<ClInclude Include="Strategic Turns.h" />
<ClInclude Include="strategic.h" />
<ClInclude Include="strategicmap.h" />
<ClInclude Include="Town Militia.h" />
<ClInclude Include="UndergroundInit.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AI Viewer.cpp" />
<ClCompile Include="Assignments.cpp" />
<ClCompile Include="Auto Resolve.cpp" />
<ClCompile Include="Campaign Init.cpp" />
<ClCompile Include="Creature Spreading.cpp" />
<ClCompile Include="Facilities.cpp" />
<ClCompile Include="Game Clock.cpp" />
<ClCompile Include="Game Event Hook.cpp" />
<ClCompile Include="Game Events.cpp" />
<ClCompile Include="Game Init.cpp" />
<ClCompile Include="Hourly Update.cpp" />
<ClCompile Include="Luaglobal.cpp" />
<ClCompile Include="LuaInitNPCs.cpp" />
<ClCompile Include="Map Screen Helicopter.cpp" />
<ClCompile Include="Map Screen Interface Border.cpp" />
<ClCompile Include="Map Screen Interface Bottom.cpp" />
<ClCompile Include="Map Screen Interface Map Inventory.cpp" />
<ClCompile Include="Map Screen Interface Map.cpp" />
<ClCompile Include="Map Screen Interface TownMine Info.cpp" />
<ClCompile Include="Map Screen Interface.cpp" />
<ClCompile Include="mapscreen.cpp" />
<ClCompile Include="Meanwhile.cpp" />
<ClCompile Include="Merc Contract.cpp" />
<ClCompile Include="MilitiaSquads.cpp" />
<ClCompile Include="Player Command.cpp" />
<ClCompile Include="PreBattle Interface.cpp" />
<ClCompile Include="Queen Command.cpp" />
<ClCompile Include="Quest Debug System.cpp" />
<ClCompile Include="Quests.cpp" />
<ClCompile Include="QuestText.cpp" />
<ClCompile Include="Reinforcement.cpp" />
<ClCompile Include="Scheduling.cpp" />
<ClCompile Include="Strategic AI.cpp" />
<ClCompile Include="Strategic Event Handler.cpp" />
<ClCompile Include="Strategic Merc Handler.cpp" />
<ClCompile Include="Strategic Mines LUA.cpp" />
<ClCompile Include="Strategic Mines.cpp" />
<ClCompile Include="Strategic Movement Costs.cpp" />
<ClCompile Include="Strategic Movement.cpp" />
<ClCompile Include="Strategic Pathing.cpp" />
<ClCompile Include="Strategic Status.cpp" />
<ClCompile Include="Strategic Town Loyalty.cpp" />
<ClCompile Include="strategic town reputation.cpp" />
<ClCompile Include="Strategic Turns.cpp" />
<ClCompile Include="strategic.cpp" />
<ClCompile Include="strategicmap.cpp" />
<ClCompile Include="Town Militia.cpp" />
<ClCompile Include="UndergroundInit.cpp" />
<ClCompile Include="XML_Army.cpp" />
<ClCompile Include="XML_Bloodcats.cpp" />
<ClCompile Include="XML_DynamicRestrictions.cpp" />
<ClCompile Include="XML_ExtraItems.cpp" />
<ClCompile Include="XML_Facilities.cpp" />
<ClCompile Include="XML_FacilityTypes.cpp" />
<ClCompile Include="XML_Roaming.cpp" />
<ClCompile Include="XML_SectorNames.cpp" />
<ClCompile Include="XML_UniformColors.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{DE9B77CC-7CD5-4951-9B7F-BAC7B4A8169C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>Strategic</RootNamespace>
<ProjectName>Strategic</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ja2.props" />
<Import Project="..\ja2_Debug.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ja2.props" />
<Import Project="..\ja2_Debug.props" />
<Import Project="..\ja2_Editor.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ja2.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ja2.props" />
<Import Project="..\ja2_Editor.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\ja2.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
<IntDir>..\build\VS2010\$(ProjectName)_$(Configuration)\</IntDir>
<OutDir>..\lib\VS2010\$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditorD|Win32'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MapEditor|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Relese_WithDebugInfo|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>
</PrecompiledHeaderOutputFile>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+327
View File
@@ -0,0 +1,327 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{e965b12d-833b-4ed2-b5fe-b519e2d661e3}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{7fc727d5-3708-404e-8267-410283203b63}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Assignments.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Auto Resolve.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Campaign Init.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Campaign Types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Creature Spreading.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Facilities.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Game Clock.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Game Event Hook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Game Events.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Game Init.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Luaglobal.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LuaInitNPCs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Helicopter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface Border.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface Bottom.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface Map Inventory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface Map.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface TownMine Info.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Map Screen Interface.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mapscreen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Meanwhile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Merc Contract.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MilitiaSquads.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Player Command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PreBattle Interface.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Queen Command.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Quest Debug System.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Quests.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="QuestText.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Reinforcement.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Scheduling.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic AI.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic All.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Event Handler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Merc Handler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Mines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Movement.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Pathing.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Status.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Town Loyalty.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="strategic town reputation.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Turns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="strategic.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="strategicmap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Town Militia.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UndergroundInit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Strategic Mines LUA.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="AI Viewer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Assignments.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Auto Resolve.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Campaign Init.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Creature Spreading.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Facilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Game Clock.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Game Event Hook.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Game Events.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Game Init.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Hourly Update.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Luaglobal.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LuaInitNPCs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Helicopter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface Border.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface Bottom.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface Map Inventory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface Map.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface TownMine Info.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Map Screen Interface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mapscreen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Meanwhile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Merc Contract.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MilitiaSquads.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Player Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PreBattle Interface.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Queen Command.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Quest Debug System.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Quests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="QuestText.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Reinforcement.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Scheduling.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic AI.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Event Handler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Merc Handler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Mines.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Movement Costs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Movement.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Pathing.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Status.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Town Loyalty.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="strategic town reputation.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Turns.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="strategic.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="strategicmap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Town Militia.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UndergroundInit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Army.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Bloodcats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_DynamicRestrictions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_ExtraItems.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Facilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_FacilityTypes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Roaming.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_SectorNames.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_UniformColors.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Strategic Mines LUA.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+51 -14
View File
@@ -328,6 +328,8 @@ void TownMilitiaTrainingCompleted( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMa
IncrementTownLoyalty( ubTownId, uiTownLoyaltyBonus );
}
// SANDRO - merc records (num militia trained)
RecordNumMilitiaTrainedForMercs( sMapX, sMapY, pTrainer->bSectorZ, ubMilitiaTrained, FALSE );
}
// the trainer announces to player that he's finished his assignment. Make his sector flash!
@@ -882,6 +884,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Militia3");
SECTORINFO *pSectorInfo = &( SectorInfo[ SECTOR(pSoldier->sSectorX, pSoldier->sSectorY) ] );
BOOLEAN fUnfullSectorFound = FALSE;
// Test to see if not enough Town Militia
// HEADROCK HAM 4: No need for this check anymore. Militia can now be trained separately thanks to being
// able to keep them out of cities.
/*
if ( CountMilitia( pSectorInfo ) < gGameExternalOptions.iMaxMilitiaPerSector )
{
fUnfullSectorFound = TRUE;
@@ -925,6 +932,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Militia3");
DoContinueMilitiaTrainingMessageBox( sSectorX, sSectorY, sString, MSG_BOX_FLAG_OK, CantTrainMobileMilitiaOkBoxCallback );
return;
}
*/
//////////////////////////////////////////
// Capacity check in nearby sectors
@@ -1162,7 +1170,7 @@ void HandleMilitiaStatusInCurrentMapBeforeLoadingNewMap( void )
}
BOOLEAN CanNearbyMilitiaScoutThisSector( INT16 sSectorX, INT16 sSectorY )
BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN fScoutTraitCheck ) // added argument - SANDRO
{
INT16 sSectorValue = 0, sSector = 0;
INT16 sCounterA = 0, sCounterB = 0;
@@ -1184,18 +1192,36 @@ BOOLEAN CanNearbyMilitiaScoutThisSector( INT16 sSectorX, INT16 sSectorY )
sSectorValue = SECTOR( sCounterA, sCounterB );
// check if any sort of militia here
if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] )
// SANDRO - STOMP traits - Scouting check
if (fScoutTraitCheck && gGameOptions.fNewTraitSystem && ScoutIsPresentInSquad( sCounterA, sCounterB ))
{
return( TRUE );
// if diagonal sector and not allowed
if (!gSkillTraitValues.fSCDetectionInDiagonalSectors &&
((sCounterA - 1 == sSectorX && sCounterB + 1 == sSectorY) ||
(sCounterA - 1 == sSectorX && sCounterB - 1 == sSectorY) ||
(sCounterA + 1 == sSectorX && sCounterB + 1 == sSectorY) ||
(sCounterA + 1 == sSectorX && sCounterB - 1 == sSectorY)))
{
return( FALSE );
}
else
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] )
else
{
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{
return( TRUE );
// check if any sort of militia here
if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ GREEN_MILITIA ] )
{
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] )
{
return( TRUE );
}
else if( SectorInfo[ sSectorValue ].ubNumberOfCivsAtLevel[ ELITE_MILITIA ] )
{
return( TRUE );
}
}
}
}
@@ -1891,10 +1917,21 @@ UINT8 FindBestMilitiaTrainingLeadershipInSector ( INT16 sMapX, INT16 sMapY, INT8
{
usTrainerEffectiveLeadership = EffectiveLeadership(pCheckedTrainer);
// Effective leadership is modified by an INI-based percentage, once for every TEACHING trait level.
if ( gGameExternalOptions.usTeacherTraitEffectOnLeadership > 0 && gGameExternalOptions.usTeacherTraitEffectOnLeadership != 100 )
if ( gGameOptions.fNewTraitSystem ) // SANDRO - old/new traits
{
for (UINT8 i = 0; i < NUM_SKILL_TRAITS( pCheckedTrainer, TEACHING ); i++ )
// -10% penalty for untrained mercs
usTrainerEffectiveLeadership = (usTrainerEffectiveLeadership * (100 - gSkillTraitValues.bSpeedModifierTrainingMilitia) / 100);
if (HAS_SKILL_TRAIT( pCheckedTrainer, TEACHING_NT ))
{
// bonus from Teaching trait
usTrainerEffectiveLeadership = __min(100,(usTrainerEffectiveLeadership * (100 + gSkillTraitValues.ubTGEffectiveLDRToTrainMilitia) / 100 ));
}
}
// Effective leadership is modified by an INI-based percentage, once for every TEACHING trait level.
else if ( gGameExternalOptions.usTeacherTraitEffectOnLeadership > 0 && gGameExternalOptions.usTeacherTraitEffectOnLeadership != 100 )
{
for (UINT8 i = 0; i < NUM_SKILL_TRAITS( pCheckedTrainer, TEACHING_OT ); i++ )
{
// percentage-based.
usTrainerEffectiveLeadership = __min(100,((usTrainerEffectiveLeadership * gGameExternalOptions.usTeacherTraitEffectOnLeadership)/100));
@@ -2282,4 +2319,4 @@ UINT32 CalcMilitiaUpkeep( void )
}
return (uiTotalPayment);
}
}
+1 -1
View File
@@ -63,7 +63,7 @@ void HandleInterfaceMessageForContinuingTrainingMilitia( SOLDIERTYPE *pSoldier )
void HandleMilitiaStatusInCurrentMapBeforeLoadingNewMap( void );
// is there a town with militia here or nearby?
BOOLEAN CanNearbyMilitiaScoutThisSector( INT16 sSectorX, INT16 sSectorY );
BOOLEAN CanSomeoneNearbyScoutThisSector( INT16 sSectorX, INT16 sSectorY, BOOLEAN fScoutTraitCheck ); // changed - SANDRO
// is the town militia full?
BOOLEAN IsTownFullMilitia( INT8 bTownId, INT8 iMilitiaType );
+297 -75
View File
@@ -4,9 +4,9 @@
#include "UndergroundInit.h"
#include "Campaign Init.h"
#include "Campaign Types.h"
#include "FileMan.h"
#include "GameSettings.h"
#include "Game Clock.h"
extern "C" {
#include "lua.h"
@@ -14,107 +14,318 @@ extern "C" {
#include "lualib.h"
}
#include "lua_state.h"
#include "lua_table.h"
#include "lua_function.h"
#include "connect.h"
extern UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ );
// externals
UNDERGROUND_SECTORINFO* NewUndergroundNode( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ );
extern BOOLEAN gfGettingNameFromSaveLoadScreen;
static int l_addSector(lua_State *L);
static int lh_getIntegerFromTable(lua_State *L, char * fieldname);
static std::string lh_getStringFromTable(lua_State *L, char * fieldname);
static std::wstring lh_getWStringFromTable(lua_State *L, char * fieldname);
static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z);
// helper functions
static std::string XYZtoString(INT16 x, INT16 y, INT16 z);
using namespace std;
// keystroke savers
#define LF vfs::Log::endl
#define ON LuaLogger::ON
#define OFF LuaLogger::OFF
// global
LuaUnderground g_luaUnderground;
BOOLEAN LetLuaBuildUndergroundSectorInfoList()
template <>
bool LuaTable::getValue<UINT8>(const char * index, UINT8& value)
{
char * filename = "scripts\\initunderground.lua";
UINT32 size, bytesRead;
char* buffer;
int dummy;
bool b = getValue(index, dummy);
if (b)
{
value = static_cast<UINT8>(dummy);
return true;
}
return false;
}
// Calls into Lua script to let build underground sector list.
BOOLEAN LuaUnderground::InitializeSectorList()
{
// WANNE: Skip initialization in a multiplayer game, because some variables are not yet set
// No problem: Underground sectors are not currently used in a multiplayer game
if (!is_networked || gGameOptions.ubDifficultyLevel > 0)
{
LuaState L = GetLuaState();
LuaFunction initsectorlist_func(L, "BuildUndergroundSectorList");
initsectorlist_func
.TableOpen()
.TParam("difficultyLevel", int(gGameOptions.ubDifficultyLevel))
.TParam("gameStyle", int(gGameOptions.ubGameStyle))
.TableClose();
SGP_THROW_IFFALSE(initsectorlist_func.Call(1), "call to lua function BuildUndergroundSectorList failed");
LuaTable result(L, -1);
if (result.is_valid())
{
int len = result.length();
for (int i = 1; i <= result.length(); ++i)
{
LuaTable sectorData(result, i);
if (sectorData.is_valid())
{
std::string location;
sectorData.getValue("location", location);
UINT8 x, y, z;
if (locationStringToCoordinates(location, &x, &y, &z))
{
UNDERGROUND_SECTORINFO* s = NewUndergroundNode(x, y, z);
sectorData.getValue("numAdmins", s->ubNumAdmins);
sectorData.getValue("numTroops", s->ubNumTroops);
sectorData.getValue("numElites", s->ubNumElites);
sectorData.getValue("numBloodcats", s->ubNumBloodcats);
sectorData.getValue("numCreatures", s->ubNumCreatures);
sectorData.getValue("creatureHabitat", s->ubCreatureHabitat);
sectorData.getValue("music", s->ubMusicMode);
if (s->ubMusicMode < CM_COMPAT || CM_ALWAYS < s->ubMusicMode)
s->ubMusicMode = CM_COMPAT;
// logging only
{
m_log << "adding sector: " << location << LF;
m_log << "\t- Enemy garrison" << LF;
m_log << "\t\tAdmins: " << static_cast<int>(s->ubNumAdmins) << LF;
m_log << "\t\tTroops: " << static_cast<int>(s->ubNumTroops) << LF;
m_log << "\t\tElites: " << static_cast<int>(s->ubNumElites) << LF;
m_log << "\t- Creature population" << LF;
m_log << "\t\tBloodcats: " << static_cast<int>(s->ubNumBloodcats) << LF;
m_log << "\t\tCrepitus: " << static_cast<int>(s->ubNumCreatures) << LF;
m_log << "\t\t- Habitat: " << static_cast<int>(s->ubCreatureHabitat) << LF;
m_log << "\t\t- Music mode: ";
switch (s->ubMusicMode)
{
case CM_COMPAT: m_log << "compat" << LF; break;
case CM_AUTO: m_log << "auto" << LF; break;
case CM_NEVER: m_log << "never" << LF; break;
case CM_ALWAYS: m_log << "always" << LF; break;
}
m_log << LF;
}
}
else
m_log << "WARNING: ignoring invalid location ID: '" << location << "'" << LF;
m_log.Flush();
}
lua_pop(L(), 1); // sectorData
}
}
lua_pop(L(), 1); // result
}
else
{
return FALSE;
}
return TRUE;
}
// Calls into Lua script to get the loadscreen for a given sector.
void LuaUnderground::GetLoadscreen(INT16 x, INT16 y, INT16 z, std::string& loadscreen, std::string& format)
{
const std::string strSector = XYZtoString(x, y, z);
LuaState L = GetLuaState();
LuaFunction getLoadscreen_func(L, "GetLoadscreen");
getLoadscreen_func
.Param(strSector)
.Param(int(GetWorldMinutesInDay()));
SGP_THROW_IFFALSE(getLoadscreen_func.Call(2), "call to lua function GetLoadscreen failed");
{
if (lua_isstring(L(), -1))
{
format.append(lua_tostring(L(), -1));
}
else
m_log << "ERROR: GetLoadscreen('" << strSector << "'): return value #2 is not a valid string object" << LF;
lua_pop(L(), 1);
if (lua_isstring(L(), -1))
{
loadscreen.append(lua_tostring(L(), -1));
}
else
m_log << "ERROR: GetLoadscreen('" << strSector << "'): return value #1 is not a valid string object" << LF;
lua_pop(L(), 1);
}
return;
}
// Calls into Lua script in order to request a sector name for a given sector.
// pSector can be null, e.g. when saveloadscreen requests sector names;
// in this case we didn't initialize the sector list nor have we loaded it from savegame yet.
void LuaUnderground::GetSectorName(INT16 x, INT16 y, INT16 z, const UNDERGROUND_SECTORINFO* pSector, STR16 buffer, ::size_t bufSizeInWChar, BOOLEAN fDetailed)
{
const std::string coords = XYZtoString(x, y, z);
LuaState L = GetLuaState();
LuaFunction getSectorName_func(L, "GetSectorName");
getSectorName_func
.Param(coords)
.TableOpen()
.TParam("visited", gfGettingNameFromSaveLoadScreen || (pSector && pSector->fVisited))
.TParam("creaturesPresent", pSector && pSector->ubNumCreatures > 0)
.TParam("detailed", !!fDetailed) // conversion to C++ bool
.TableClose();
SGP_THROW_IFFALSE(getSectorName_func.Call(1), "call to lua func GetSectorName failed");
// TODO: check if this still makes a whole lot of sense now
{
memset(buffer, 0, bufSizeInWChar * sizeof(CHAR16));
if (lua_isstring(L(), -1))
{
const char * utf8 = lua_tostring(L(), -1);
int result = MultiByteToWideChar(CP_UTF8, 0, lua_tostring(L(), -1), -1, buffer, bufSizeInWChar-1);
if (result == 0)
{
// Houston, we have a problem...
buffer[bufSizeInWChar-1] = L'\0';
DWORD errorcode = GetLastError();
if (errorcode == ERROR_INSUFFICIENT_BUFFER)
{
// quick note on logging:
// we explicitly turn logging off once we encounter an error
// since this function gets called a lot (every frame or so)
m_log << "'" << utf8 << "': wchar representation too long" << LF << OFF;
}
else
{
m_log << "'" << utf8 << "': illegal unicode data" << LF << OFF;;
}
}
}
else
m_log << "ERROR: requesting sector name for '" << coords << "' failed, no valid string object has been returned" << LF << OFF;
lua_pop(L(), 1); // return value
}
return;
}
// Parse the scripts, set everything up.
void LuaUnderground::LoadScript(const char * langPrefix)
{
LuaState L = GetLuaState();
// #1: builds strategic underground layout
char * initunderground = "scripts\\initunderground.lua";
// #2: provides sector names; this is localized, build actual filename at runtime
char * sectornamesfile = "undergroundsectornames.lua";
std::string sectornames("scripts\\");
if (langPrefix != NULL)
sectornames.append(langPrefix);
sectornames.append(sectornamesfile);
// we don't use L.EvalFile because the lua parser dislikes UTF-8 BOMs (gonna strip them first)
RunScript(L, sectornames.c_str());
RunScript(L, initunderground);
// TODO: see if we can make this better
{
lua_getglobal(L(), "logging");
if (lua_isboolean(L(), -1) && lua_toboolean(L(), -1))
m_log << ON;
lua_pop(L(), -1);
}
return;
}
// Loads a Lua script and let the interpreter process it.
// Returns true if successful.
// Throws an exception if file not found.
bool LuaUnderground::RunScript(LuaState& L, const char * szFileName)
{
using namespace std;
// stupid file opening functions don't use const parameters...
vector<char> filenamebuffer(strlen(szFileName)+1);
strcpy(&filenamebuffer[0], szFileName);
char * filename = &filenamebuffer[0];
UINT32 size, bytesRead;
HWFILE file = FileOpen(filename, FILE_ACCESS_READ, FALSE);
if (!file)
return false;
{
string msg("Cannot open file: ");
msg.append(filename);
m_log << msg << LF;
m_log.Flush();
//throw sgp::Exception(msg.c_str(), __LINE__, _FUNCTION_FORMAT_, __FILE__);
SGP_THROW(msg);
}
size = FileSize(filename);
buffer = new char[size+1];
buffer[size] = 0;
FileRead(file, buffer, size, &bytesRead);
vector<char> buffer = vector<char>(size);
FileRead(file, &buffer[0], size, &bytesRead);
FileClose(file);
lua_State *L = lua_open();
luaL_openlibs(L);
lua_register(L, "addSector", l_addSector);
lua_pushinteger(L, gGameOptions.ubDifficultyLevel);
lua_setglobal(L, "difficultyLevel");
lua_pushinteger(L, gGameOptions.ubGameStyle);
lua_setglobal(L, "gameStyle");
if (luaL_dostring(L, buffer))
// simple UTF8 BOM check:
// replace with blanks if necessary since Lua HATES byte order marks
const unsigned char bom[] = { 0xEF, 0xBB, 0xBF };
if (memcmp(&buffer[0], bom, 3) == 0)
{
// oh noes, error
// TODO: write to log or something
return false;
buffer[0] = buffer[1] = buffer[2] = ' ';
}
lua_close(L);
delete[] buffer;
return true;
return L.EvalString(&buffer[0], buffer.size(), szFileName);
}
static int l_addSector(lua_State *L)
LuaUnderground::LuaUnderground()
: m_log("initunderground.log", false, true, vfs::Log::FLUSH_BUFFER)
{
UNDERGROUND_SECTORINFO* curr = NULL;
std::string sector_id = lh_getStringFromTable(L, "location");
UINT8 x, y, z;
if (locationStringToCoordinates(sector_id, &x, &y, &z))
{
curr = NewUndergroundNode(x, y, z);
curr->ubNumAdmins = lh_getIntegerFromTable(L, "numAdmins");
curr->ubNumTroops = lh_getIntegerFromTable(L, "numTroops");
curr->ubNumElites = lh_getIntegerFromTable(L, "numElites");
curr->ubCreatureHabitat = lh_getIntegerFromTable(L, "creatureHabitat");
curr->ubNumCreatures = lh_getIntegerFromTable(L, "numCreatures");
curr->ubNumBloodcats = lh_getIntegerFromTable(L, "numBloodcats");
}
return 0; // number of results
}
static int lh_getIntegerFromTable(lua_State *L, char * fieldname)
LuaUnderground::~LuaUnderground()
{
lua_getfield(L, -1, fieldname);
int i = lua_tointeger(L, -1);
lua_pop(L, 1);
return i;
// WANNE: Disabled, because it leads to an unhandled exception when shutting down ja2 1.13
/*m_log.Flush();*/
}
static std::string lh_getStringFromTable(lua_State *L, char * fieldname)
{
lua_getfield(L, -1, fieldname);
string s = lua_tostring(L, -1);
lua_pop(L, 1);
return s;
}
// extract x,y,z from strings like "D13-1"
static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z)
BOOLEAN locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z)
{
int length = loc.length();
@@ -132,7 +343,7 @@ static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UIN
// gather column
loc = loc.substr(1);
stringstream ss = stringstream();
std::stringstream ss;
if (loc[0] >= '0' && loc[0] <= '9')
{
ss << loc[0];
@@ -159,3 +370,14 @@ static bool locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UIN
return true;
}
static std::string XYZtoString(INT16 x, INT16 y, INT16 z)
{
using namespace std;
stringstream ss;
ss << static_cast<char>(y+'A'-1) << x << '-' << z;
string tmp;
ss >> tmp;
return tmp;
}
+55 -1
View File
@@ -1,8 +1,62 @@
#ifndef _UNDERGROUNDINIT_H
#define _UNDERGROUNDINIT_H
#include "Campaign Types.h"
#include "Types.h"
//#include "Strategic Mines LUA.h"
extern BOOLEAN LetLuaBuildUndergroundSectorInfoList();
#include "lua_state.h"
//BOOLEAN LetLuaBuildUndergroundSectorInfoList();
BOOLEAN locationStringToCoordinates(std::string loc, UINT8* x, UINT8* y, UINT8* z);
#include <vfs/Tools/vfs_log.h>
class LuaLogger
{
bool m_active;
vfs::Log& m_log;
public:
enum LoggingState
{
OFF,
ON,
};
LuaLogger(const vfs::Path filename, bool enable = true, bool append = false, vfs::Log::EFlushMode flushMode = vfs::Log::FLUSH_ON_ENDL)
: m_log(*vfs::Log::create(filename, append, flushMode)), m_active(enable) {}
~LuaLogger() { /*Flush();*/ }
void ToggleLogging(bool enable) { m_active = enable; }
void Flush() { m_log.flush(); }
template <typename T> LuaLogger& operator<<(const T& message) { if (m_active) m_log << message; return *this; }
template <> LuaLogger& operator<<(const vfs::Log::_endl& endl) { if (m_active) m_log << vfs::Log::endl; return *this; }
template <> LuaLogger& operator<<(const LoggingState& state) { m_active = state == ON; return *this; }
};
class LuaUnderground
{
public:
void LoadScript(const char * langPrefix);
BOOLEAN InitializeSectorList();
void GetLoadscreen(INT16 x, INT16 y, INT16 z, std::string& buffer, std::string& format);
void GetSectorName(INT16 x, INT16 y, INT16 z, const UNDERGROUND_SECTORINFO* pSector, STR16 buffer, size_t bufSizeInWChar, BOOLEAN fDetailed);
LuaUnderground();
virtual ~LuaUnderground();
private:
LuaState GetLuaState()
{
return LuaState::GET(lua::LUA_STATE_STRATEGIC_MINES_AND_UNDERGROUND);
}
void Reset();
bool RunScript(LuaState& L, const char * filename);
LuaLogger m_log;
};
extern LuaUnderground g_luaUnderground;
#endif
+3 -1
View File
@@ -197,6 +197,8 @@ BloodcatsEndElementHandle(void *userData, const XML_Char *name)
{
// Lair sector. There can be only one, and it is affected by the Quest. Bloodcats can regenerate
// their numbers here over time.
gubBloodcatLairSectorId = ubSectorId;
gBloodcatPlacements[ ubSectorId ][x].ubMinBloodcats = 0;
gBloodcatPlacements[ ubSectorId ][x].ubMaxBloodcats = pData->CurPlacement[x].ubMaxBloodcats;
gBloodcatPlacements[ ubSectorId ][x].ubAmbushChance = 0;
@@ -219,7 +221,7 @@ BloodcatsEndElementHandle(void *userData, const XML_Char *name)
pData->sCurSectorX = x;
pData->sCurSectorY = y;
}
THROWIFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in BloodcatPlacements.XML" );
SGP_THROW_IFFALSE( (SECTOR(x,y) >= 0 && SECTOR(x,y) < 256) , L"Illegal sector number in BloodcatPlacements.XML" );
}
else if(strcmp(name, "ubPlacementType") == 0 )
{
+2 -2
View File
@@ -55,7 +55,7 @@ dynamicroamingStartElementHandle(void *userData, const XML_Char *name, const XML
// Set all sector IDs to -1 ("unused")
for (UINT16 cnt=0; cnt<5001; cnt++)
{
gDynamicRestrictions[cnt].bSectorID = -1;
gDynamicRestrictions[cnt].sSectorID = -1;
}
pData->curElement = ELEMENT_LIST;
@@ -119,7 +119,7 @@ dynamicroamingEndElementHandle(void *userData, const XML_Char *name)
if (SECTOR(pData->sCurSectorX, pData->sCurSectorY) >= 0 && SECTOR(pData->sCurSectorX, pData->sCurSectorY) < 256)
{
pData->curIndex++;
gDynamicRestrictions[pData->curIndex].bSectorID = SECTOR(pData->sCurSectorX,pData->sCurSectorY);
gDynamicRestrictions[pData->curIndex].sSectorID = SECTOR(pData->sCurSectorX,pData->sCurSectorY);
gDynamicRestrictions[pData->curIndex].uiReqTownFlags |= pData->uiReqTownFlags;
}
}
+57 -32
View File
@@ -15,7 +15,8 @@ typedef enum
{
EXTRAITEMS_ELEMENT_NONE = 0,
EXTRAITEMS_ELEMENT_EXTRAITEMS,
EXTRAITEMS_ELEMENT_ITEM
EXTRAITEMS_ELEMENT_ITEM,
EXTRAITEMS_ELEMENT,
} EXTRAITEMS_PARSE_STAGE;
typedef struct
@@ -29,6 +30,7 @@ typedef struct
UINT32 quantity;
UINT32 condition;
UINT32 gridno;
BOOLEAN visible;
} ExtraItemsParseData;
@@ -56,35 +58,21 @@ ExtraItemsStartElementHandle(void *userData, const XML_Char *name, const XML_Cha
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
pData->maxReadDepth++; //we are not skipping this element
// Extract the attributes
// defaults
// set defaults
pData->quantity = 1;
pData->condition = 100;
pData->gridno = 0;
for(unsigned uiAttrIndex = 0;atts[uiAttrIndex] != NULL;uiAttrIndex += 2)
{
if(strcmp(atts[uiAttrIndex], "quantity") == 0)
{
pData->quantity = atol(atts[uiAttrIndex+1]);
if (pData->quantity < 1 || pData->quantity > 100) {
pData->quantity = 1;
}
}
else if(strcmp(atts[uiAttrIndex], "condition") == 0)
{
pData->condition = atol(atts[uiAttrIndex+1]);
if (pData->condition < 1 || pData->condition > 100) {
pData->condition = 100;
}
}
else if(strcmp(atts[uiAttrIndex], "gridno") == 0)
{
pData->gridno = atol(atts[uiAttrIndex+1]);
//if (pData->gridno < ???? || pData->gridno > ????) {
// pData->gridno = 0;
//}
}
}
pData->visible = FALSE;
}
else if(pData->curElement == EXTRAITEMS_ELEMENT_ITEM &&
(strcmp(name, "uiIndex") == 0 ||
strcmp(name, "quantity") == 0 ||
strcmp(name, "condition") == 0 ||
strcmp(name, "gridno") == 0 ||
strcmp(name, "visible") == 0 ))
{
pData->curElement = EXTRAITEMS_ELEMENT;
pData->maxReadDepth++;
}
pData->szCharData[0] = '\0';
}
@@ -111,24 +99,59 @@ ExtraItemsEndElementHandle(void *userData, const XML_Char *name)
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "ExtraItems") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_EXTRAITEMS)
if(pData->curElement == EXTRAITEMS_ELEMENT_EXTRAITEMS &&
strcmp(name, "ExtraItems") == 0)
{
pData->curElement = EXTRAITEMS_ELEMENT_NONE;
}
else if(strcmp(name, "Item") == 0 && pData->curElement == EXTRAITEMS_ELEMENT_ITEM)
else if(pData->curElement == EXTRAITEMS_ELEMENT_ITEM &&
strcmp(name, "Item") == 0 &&
pData->item > 0 && // Make sure not to create 0-index objects!
pData->quantity > 0 && // Quantity should be positive. Not sure what the LIMIT is, if any.
pData->condition > 0 && pData->condition <= 100 ) // Condition between 1 and 100!
{
pData->item = atol(pData->szCharData);
OBJECTTYPE object;
CreateItem(pData->item, pData->condition, &object);
for (unsigned cnt=1; cnt <= pData->quantity; ++cnt) {
if (gSectorIsLoaded) {
AddItemToPool( pData->gridno, &object, 1, 0, WORLD_ITEM_REACHABLE, 0 );
AddItemToPool( pData->gridno, &object, pData->visible, 0, WORLD_ITEM_REACHABLE, 0 );
} else {
AddItemsToUnLoadedSector( gX, gY, gZ, pData->gridno, 1, &object, 0, WORLD_ITEM_REACHABLE, 0, 1, 0 );
AddItemsToUnLoadedSector( gX, gY, gZ, pData->gridno, pData->visible, &object, 0, WORLD_ITEM_REACHABLE, 0, 1, 0 );
}
}
pData->curElement = EXTRAITEMS_ELEMENT_EXTRAITEMS;
}
else if( pData->curElement == EXTRAITEMS_ELEMENT &&
strcmp( name, "uiIndex" ) == 0)
{
pData->item = (UINT32)atol( pData->szCharData );
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
}
else if( pData->curElement == EXTRAITEMS_ELEMENT &&
strcmp( name, "quantity" ) == 0)
{
pData->quantity = (UINT32)atol( pData->szCharData );
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
}
else if( pData->curElement == EXTRAITEMS_ELEMENT &&
strcmp( name, "condition" ) == 0)
{
pData->condition = (UINT32)atol( pData->szCharData );
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
}
else if( pData->curElement == EXTRAITEMS_ELEMENT &&
strcmp( name, "gridno" ) == 0)
{
pData->gridno = (UINT32)atol( pData->szCharData );
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
}
else if( pData->curElement == EXTRAITEMS_ELEMENT &&
strcmp( name, "visible" ) == 0)
{
pData->visible = (UINT32)atol( pData->szCharData );
pData->curElement = EXTRAITEMS_ELEMENT_ITEM;
}
pData->maxReadDepth--;
}
pData->currentDepth--;
@@ -185,6 +208,8 @@ void AddExtraItems(UINT8 x, UINT8 y, UINT8 z, bool sectorIsLoaded)
break;
}
strcat(fileName, ".xml");
// Open extra items file
HWFILE hFile;
// Try "special" difficulty level file first
+132 -109
View File
@@ -57,6 +57,7 @@ struct
}
typedef facilitytypeParseData;
BOOLEAN FacilityTypes_TextOnly;
void InitFacilityTypeEntry( facilitytypeParseData *pData )
{
@@ -125,7 +126,7 @@ void InitAssignmentDataArray( facilitytypeParseData *pData )
// Set RISK data
for (UINT16 cnt = 0; cnt < NUM_RISKS; cnt++)
{
pData->curAssignmentData.Risk[cnt].ubChance = 0;
pData->curAssignmentData.Risk[cnt].usChance = 0;
pData->curAssignmentData.Risk[cnt].bBaseEffect = 0;
pData->curAssignmentData.Risk[cnt].ubRange = 0;
}
@@ -397,7 +398,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
}
else
{
THROWEXCEPTION(L"FacilityTypes.XML Error: Tag <FACILITYTYPES> encountered too early! Please make sure to close all opened tags first.");
SGP_THROW(L"FacilityTypes.XML Error: Tag <FACILITYTYPES> encountered too early! Please make sure to close all opened tags first.");
}
}
else if(strcmp(name, "FACILITYTYPE") == 0)
@@ -408,65 +409,77 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
if (pData->curIndex >= 1)
{
// Begin with basic facility data
wcscpy(gFacilityTypes[pData->curIndex].szFacilityName, pData->curFacilityTypeData.szFacilityName);
wcscpy(gFacilityTypes[pData->curIndex].szFacilityShortName, pData->curFacilityTypeData.szFacilityShortName);
gFacilityTypes[pData->curIndex].ubTotalStaffLimit = pData->curFacilityTypeData.ubTotalStaffLimit;
gFacilityTypes[pData->curIndex].ubMilitiaTrainersAllowed = pData->curFacilityTypeData.ubMilitiaTrainersAllowed;
gFacilityTypes[pData->curIndex].ubMobileMilitiaTrainersAllowed = pData->curFacilityTypeData.ubMobileMilitiaTrainersAllowed;
gFacilityTypes[pData->curIndex].usMilitiaTraining = pData->curFacilityTypeData.usMilitiaTraining;
gFacilityTypes[pData->curIndex].usMilitiaTraining = pData->curFacilityTypeData.usMilitiaTraining;
// Set assignment-specific data
for (UINT16 cnt = 0; cnt < NUM_FACILITY_ASSIGNMENTS; cnt++)
if (!FacilityTypes_TextOnly)
{
// Performance and limits
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usPerformance = pData->curFacilityTypeData.AssignmentData[cnt].usPerformance;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubStaffLimit = pData->curFacilityTypeData.AssignmentData[cnt].ubStaffLimit;
wcscpy(gFacilityTypes[pData->curIndex].AssignmentData[cnt].szTooltipText, pData->curFacilityTypeData.AssignmentData[cnt].szTooltipText);
gFacilityTypes[pData->curIndex].AssignmentData[cnt].sCostPerHour = pData->curFacilityTypeData.AssignmentData[cnt].sCostPerHour;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usFatigue = pData->curFacilityTypeData.AssignmentData[cnt].usFatigue;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usKitDegrade = pData->curFacilityTypeData.AssignmentData[cnt].usKitDegrade;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usSleep = pData->curFacilityTypeData.AssignmentData[cnt].usSleep;
// Begin with basic facility data
wcscpy(gFacilityTypes[pData->curIndex].szFacilityName, pData->curFacilityTypeData.szFacilityName);
wcscpy(gFacilityTypes[pData->curIndex].szFacilityShortName, pData->curFacilityTypeData.szFacilityShortName);
gFacilityTypes[pData->curIndex].ubTotalStaffLimit = pData->curFacilityTypeData.ubTotalStaffLimit;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMaximumBreath = pData->curFacilityTypeData.AssignmentData[cnt].ubMaximumBreath;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMaximumMorale = pData->curFacilityTypeData.AssignmentData[cnt].ubMaximumMorale;
gFacilityTypes[pData->curIndex].ubMilitiaTrainersAllowed = pData->curFacilityTypeData.ubMilitiaTrainersAllowed;
gFacilityTypes[pData->curIndex].ubMobileMilitiaTrainersAllowed = pData->curFacilityTypeData.ubMobileMilitiaTrainersAllowed;
gFacilityTypes[pData->curIndex].usMilitiaTraining = pData->curFacilityTypeData.usMilitiaTraining;
gFacilityTypes[pData->curIndex].usMilitiaTraining = pData->curFacilityTypeData.usMilitiaTraining;
// Detection abilities
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubDetectEnemiesImmediate = pData->curFacilityTypeData.AssignmentData[cnt].ubDetectEnemiesImmediate;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesDynamic = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesDynamic;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesLongrange = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesLongrange;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesAnywhere = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesAnywhere;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fCountEnemiesInWild = pData->curFacilityTypeData.AssignmentData[cnt].fCountEnemiesInWild;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fCountEnemiesInCities = pData->curFacilityTypeData.AssignmentData[cnt].fCountEnemiesInCities;
// Other strategic abilities
gFacilityTypes[pData->curIndex].AssignmentData[cnt].sSkyriderCostModifier = pData->curFacilityTypeData.AssignmentData[cnt].sSkyriderCostModifier;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usMineIncomeModifier = pData->curFacilityTypeData.AssignmentData[cnt].usMineIncomeModifier;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fOnlyLocalMineAffected = pData->curFacilityTypeData.AssignmentData[cnt].fOnlyLocalMineAffected;
// Conditions
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumStrength = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumStrength;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumAgility = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumAgility;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumDexterity = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumDexterity;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumHealth = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumHealth;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumWisdom = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumWisdom;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMarksmanship = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMarksmanship;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLeadership = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLeadership;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumExplosives = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumExplosives;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMechanical = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMechanical;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMedical = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMedical;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLevel = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLevel;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLoyaltyHere = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLoyaltyHere;
// Set risks associated with this assignment
for (UINT16 cntB = 0; cntB < NUM_RISKS; cntB++)
// Set assignment-specific data
for (UINT16 cnt = 0; cnt < NUM_FACILITY_ASSIGNMENTS; cnt++)
{
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].ubChance = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].ubChance;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].bBaseEffect = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].bBaseEffect;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].ubRange = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].ubRange;
// Performance and limits
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usPerformance = pData->curFacilityTypeData.AssignmentData[cnt].usPerformance;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubStaffLimit = pData->curFacilityTypeData.AssignmentData[cnt].ubStaffLimit;
wcscpy(gFacilityTypes[pData->curIndex].AssignmentData[cnt].szTooltipText, pData->curFacilityTypeData.AssignmentData[cnt].szTooltipText);
gFacilityTypes[pData->curIndex].AssignmentData[cnt].sCostPerHour = pData->curFacilityTypeData.AssignmentData[cnt].sCostPerHour;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usFatigue = pData->curFacilityTypeData.AssignmentData[cnt].usFatigue;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usKitDegrade = pData->curFacilityTypeData.AssignmentData[cnt].usKitDegrade;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usSleep = pData->curFacilityTypeData.AssignmentData[cnt].usSleep;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMaximumBreath = pData->curFacilityTypeData.AssignmentData[cnt].ubMaximumBreath;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMaximumMorale = pData->curFacilityTypeData.AssignmentData[cnt].ubMaximumMorale;
// Detection abilities
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubDetectEnemiesImmediate = pData->curFacilityTypeData.AssignmentData[cnt].ubDetectEnemiesImmediate;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesDynamic = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesDynamic;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesLongrange = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesLongrange;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fDetectEnemiesAnywhere = pData->curFacilityTypeData.AssignmentData[cnt].fDetectEnemiesAnywhere;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fCountEnemiesInWild = pData->curFacilityTypeData.AssignmentData[cnt].fCountEnemiesInWild;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fCountEnemiesInCities = pData->curFacilityTypeData.AssignmentData[cnt].fCountEnemiesInCities;
// Other strategic abilities
gFacilityTypes[pData->curIndex].AssignmentData[cnt].sSkyriderCostModifier = pData->curFacilityTypeData.AssignmentData[cnt].sSkyriderCostModifier;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].usMineIncomeModifier = pData->curFacilityTypeData.AssignmentData[cnt].usMineIncomeModifier;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].fOnlyLocalMineAffected = pData->curFacilityTypeData.AssignmentData[cnt].fOnlyLocalMineAffected;
// Conditions
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumStrength = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumStrength;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumAgility = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumAgility;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumDexterity = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumDexterity;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumHealth = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumHealth;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumWisdom = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumWisdom;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMarksmanship = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMarksmanship;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLeadership = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLeadership;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumExplosives = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumExplosives;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMechanical = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMechanical;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumMedical = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumMedical;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLevel = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLevel;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].ubMinimumLoyaltyHere = pData->curFacilityTypeData.AssignmentData[cnt].ubMinimumLoyaltyHere;
// Set risks associated with this assignment
for (UINT16 cntB = 0; cntB < NUM_RISKS; cntB++)
{
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].usChance = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].usChance;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].bBaseEffect = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].bBaseEffect;
gFacilityTypes[pData->curIndex].AssignmentData[cnt].Risk[cntB].ubRange = pData->curFacilityTypeData.AssignmentData[cnt].Risk[cntB].ubRange;
}
}
}
else
{
wcscpy(gFacilityTypes[pData->curIndex].szFacilityName, pData->curFacilityTypeData.szFacilityName);
wcscpy(gFacilityTypes[pData->curIndex].szFacilityShortName, pData->curFacilityTypeData.szFacilityShortName);
for (UINT16 cnt = 0; cnt < NUM_FACILITY_ASSIGNMENTS; cnt++)
{
wcscpy(gFacilityTypes[pData->curIndex].AssignmentData[cnt].szTooltipText, pData->curFacilityTypeData.AssignmentData[cnt].szTooltipText);
}
}
@@ -476,7 +489,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
}
else
{
THROWEXCEPTION(L"FacilityTypes.XML Error: A </FACILITYTYPE> tag was encountered too early! Please make sure all tags are closed properly.");
SGP_THROW(L"FacilityTypes.XML Error: A </FACILITYTYPE> tag was encountered too early! Please make sure all tags are closed properly.");
}
}
@@ -548,64 +561,72 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
{
CHAR16 sErrorString[256];
swprintf(sErrorString, L"FacilityTypes.XML Error: Assignment data for facility type %d is missing a <ubAssignmentType> tag", pData->curIndex);
THROWEXCEPTION(sErrorString);
SGP_THROW(sErrorString);
}
else if (pData->curAssignmentData.ubStaffLimit <= 0 &&
pData->curAssignmentType != FAC_AMBIENT )
else if (pData->curAssignmentData.ubStaffLimit <= 0 && pData->curAssignmentType != FAC_AMBIENT && !FacilityTypes_TextOnly)
{
CHAR16 sErrorString[256];
swprintf(sErrorString, L"FacilityTypes.XML Error: Assignment data for facility type %d is missing a <ubStaffLimit> tag, or the value of the tag is 0.", pData->curIndex);
THROWEXCEPTION(sErrorString);
SGP_THROW(sErrorString);
}
else
{
// Set assignment data from memory
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usPerformance = pData->curAssignmentData.usPerformance;
wcscpy(pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].szTooltipText, pData->curAssignmentData.szTooltipText);
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubStaffLimit = pData->curAssignmentData.ubStaffLimit;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].sCostPerHour = pData->curAssignmentData.sCostPerHour;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usFatigue = pData->curAssignmentData.usFatigue;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usSleep = pData->curAssignmentData.usSleep;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usKitDegrade = pData->curAssignmentData.usKitDegrade;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].sSkyriderCostModifier = pData->curAssignmentData.sSkyriderCostModifier;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usMineIncomeModifier = pData->curAssignmentData.usMineIncomeModifier;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fOnlyLocalMineAffected = pData->curAssignmentData.fOnlyLocalMineAffected;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumBreath = pData->curAssignmentData.ubMaximumBreath;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumMorale = pData->curAssignmentData.ubMaximumMorale;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fCountEnemiesInCities = pData->curAssignmentData.fCountEnemiesInCities;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fCountEnemiesInWild = pData->curAssignmentData.fCountEnemiesInWild;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesAnywhere = pData->curAssignmentData.fDetectEnemiesAnywhere;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesDynamic = pData->curAssignmentData.fDetectEnemiesDynamic;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubDetectEnemiesImmediate = pData->curAssignmentData.ubDetectEnemiesImmediate;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesLongrange = pData->curAssignmentData.fDetectEnemiesLongrange;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumAgility = pData->curAssignmentData.ubMinimumAgility;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumBreath = pData->curAssignmentData.ubMinimumBreath;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumDexterity = pData->curAssignmentData.ubMinimumDexterity;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumExplosives = pData->curAssignmentData.ubMinimumExplosives;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumHealth = pData->curAssignmentData.ubMinimumHealth;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLeadership = pData->curAssignmentData.ubMinimumLeadership;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLevel = pData->curAssignmentData.ubMinimumLevel;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLoyaltyHere = pData->curAssignmentData.ubMinimumLoyaltyHere;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMarksmanship = pData->curAssignmentData.ubMinimumMarksmanship;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMechanical = pData->curAssignmentData.ubMinimumMechanical;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMedical = pData->curAssignmentData.ubMinimumMedical;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMorale = pData->curAssignmentData.ubMinimumMorale;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumStrength = pData->curAssignmentData.ubMinimumStrength;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumWisdom = pData->curAssignmentData.ubMinimumWisdom;
// Set RISK data
for (UINT16 cnt = 0; cnt < NUM_RISKS; cnt++)
if (!FacilityTypes_TextOnly)
{
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].ubChance = pData->curAssignmentData.Risk[cnt].ubChance;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].bBaseEffect = pData->curAssignmentData.Risk[cnt].bBaseEffect;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].ubRange = pData->curAssignmentData.Risk[cnt].ubRange;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usPerformance = pData->curAssignmentData.usPerformance;
wcscpy(pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].szTooltipText, pData->curAssignmentData.szTooltipText);
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubStaffLimit = pData->curAssignmentData.ubStaffLimit;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].sCostPerHour = pData->curAssignmentData.sCostPerHour;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usFatigue = pData->curAssignmentData.usFatigue;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usSleep = pData->curAssignmentData.usSleep;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usKitDegrade = pData->curAssignmentData.usKitDegrade;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].sSkyriderCostModifier = pData->curAssignmentData.sSkyriderCostModifier;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].usMineIncomeModifier = pData->curAssignmentData.usMineIncomeModifier;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fOnlyLocalMineAffected = pData->curAssignmentData.fOnlyLocalMineAffected;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumBreath = pData->curAssignmentData.ubMaximumBreath;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMaximumMorale = pData->curAssignmentData.ubMaximumMorale;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fCountEnemiesInCities = pData->curAssignmentData.fCountEnemiesInCities;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fCountEnemiesInWild = pData->curAssignmentData.fCountEnemiesInWild;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesAnywhere = pData->curAssignmentData.fDetectEnemiesAnywhere;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesDynamic = pData->curAssignmentData.fDetectEnemiesDynamic;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubDetectEnemiesImmediate = pData->curAssignmentData.ubDetectEnemiesImmediate;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].fDetectEnemiesLongrange = pData->curAssignmentData.fDetectEnemiesLongrange;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumAgility = pData->curAssignmentData.ubMinimumAgility;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumBreath = pData->curAssignmentData.ubMinimumBreath;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumDexterity = pData->curAssignmentData.ubMinimumDexterity;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumExplosives = pData->curAssignmentData.ubMinimumExplosives;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumHealth = pData->curAssignmentData.ubMinimumHealth;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLeadership = pData->curAssignmentData.ubMinimumLeadership;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLevel = pData->curAssignmentData.ubMinimumLevel;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumLoyaltyHere = pData->curAssignmentData.ubMinimumLoyaltyHere;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMarksmanship = pData->curAssignmentData.ubMinimumMarksmanship;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMechanical = pData->curAssignmentData.ubMinimumMechanical;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMedical = pData->curAssignmentData.ubMinimumMedical;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumMorale = pData->curAssignmentData.ubMinimumMorale;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumStrength = pData->curAssignmentData.ubMinimumStrength;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].ubMinimumWisdom = pData->curAssignmentData.ubMinimumWisdom;
// Set RISK data
for (UINT16 cnt = 0; cnt < NUM_RISKS; cnt++)
{
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].usChance = pData->curAssignmentData.Risk[cnt].usChance;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].bBaseEffect = pData->curAssignmentData.Risk[cnt].bBaseEffect;
pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].Risk[cnt].ubRange = pData->curAssignmentData.Risk[cnt].ubRange;
}
}
else
{
wcscpy(pData->curFacilityTypeData.AssignmentData[pData->curAssignmentType].szTooltipText, pData->curAssignmentData.szTooltipText);
}
}
}
////////////////////////////////////////////////
@@ -795,7 +816,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
{
CHAR16 sErrorString[256];
swprintf(sErrorString, L"FacilityTypes.XML Error: Assignment type for facility %d is unrecognized!", pData->curIndex);
THROWEXCEPTION(sErrorString);
SGP_THROW(sErrorString);
}
}
@@ -1029,7 +1050,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
else if(strcmp(name, "ubChance") == 0 )
{
pData->curElement = FACILITYTYPE_RISK;
pData->curAssignmentData.Risk[pData->curRisk].ubChance = (UINT8) atol(pData->szCharData);
pData->curAssignmentData.Risk[pData->curRisk].usChance = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "bBaseEffect") == 0 )
@@ -1053,7 +1074,7 @@ facilitytypeEndElementHandle(void *userData, const XML_Char *name)
BOOLEAN ReadInFacilityTypes(STR fileName)
BOOLEAN ReadInFacilityTypes(STR fileName, BOOLEAN localizedVersion)
{
HWFILE hFile;
UINT32 uiBytesRead;
@@ -1062,13 +1083,15 @@ BOOLEAN ReadInFacilityTypes(STR fileName)
XML_Parser parser = XML_ParserCreate(NULL);
facilitytypeParseData pData;
FacilityTypes_TextOnly = localizedVersion;
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading FacilityTypes.xml" );
// Open merges file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
return( localizedVersion );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+111 -11
View File
@@ -19,6 +19,11 @@
// Four different sector names, used at different times.
extern CHAR16 gzSectorNames[256][4][MAX_SECTOR_NAME_LENGTH];
// moved to lua
//extern CHAR16 gzSectorUndergroundNames1[256][4][MAX_SECTOR_NAME_LENGTH];
//extern CHAR16 gzSectorUndergroundNames2[256][4][MAX_SECTOR_NAME_LENGTH];
//extern CHAR16 gzSectorUndergroundNames3[256][4][MAX_SECTOR_NAME_LENGTH];
typedef enum
{
SECTORNAME_ELEMENT_NONE = 0,
@@ -41,6 +46,10 @@ typedef struct
UINT32 maxReadDepth;
} SectorNameParseData;
BOOLEAN SectorName_TextOnly;
INT8 Sector_Level;
static void XMLCALL
SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **atts)
@@ -57,10 +66,38 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char **
// Initiate Array by setting first character to 0.
for (UINT16 x = 0; x < 256; x++)
{
gzSectorNames[x][0][0]=0;
gzSectorNames[x][1][0]=0;
gzSectorNames[x][2][0]=0;
gzSectorNames[x][3][0]=0;
if (Sector_Level == 0 )
{
gzSectorNames[x][0][0]=0;
gzSectorNames[x][1][0]=0;
gzSectorNames[x][2][0]=0;
gzSectorNames[x][3][0]=0;
}
// moved to lua
//if (Sector_Level == 1 )
//{
// gzSectorUndergroundNames1[x][0][0]=0;
// gzSectorUndergroundNames1[x][1][0]=0;
// gzSectorUndergroundNames1[x][2][0]=0;
// gzSectorUndergroundNames1[x][3][0]=0;
//}
// if (Sector_Level == 2 )
//{
// gzSectorUndergroundNames2[x][0][0]=0;
// gzSectorUndergroundNames2[x][1][0]=0;
// gzSectorUndergroundNames2[x][2][0]=0;
// gzSectorUndergroundNames2[x][3][0]=0;
//}
//if (Sector_Level == 3 )
//{
// gzSectorUndergroundNames3[x][0][0]=0;
// gzSectorUndergroundNames3[x][1][0]=0;
// gzSectorUndergroundNames3[x][2][0]=0;
// gzSectorUndergroundNames3[x][3][0]=0;
//}
}
}
@@ -119,11 +156,71 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
UINT8 ubSectorId = SECTOR(pData->sCurSectorX, pData->sCurSectorY);
if (ubSectorId >= 0 && ubSectorId < 256)
{
wcscpy(gzSectorNames[ubSectorId][0], pData->szCurUnexploredName);
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
}
if (!SectorName_TextOnly)
{
if (Sector_Level == 0 )
{
wcscpy(gzSectorNames[ubSectorId][0], pData->szCurUnexploredName);
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
}
// moved to lua
//else if (Sector_Level == 1 )
//{
// wcscpy(gzSectorUndergroundNames1[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][3], pData->szCurDetailedExploredName);
//}
//else if (Sector_Level == 2 )
//{
// wcscpy(gzSectorUndergroundNames2[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][3], pData->szCurDetailedExploredName);
//}
//else if (Sector_Level == 3 )
//{
// wcscpy(gzSectorUndergroundNames3[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][3], pData->szCurDetailedExploredName);
//}
}
else
{
if (Sector_Level == 0 )
{
wcscpy(gzSectorNames[ubSectorId][0], pData->szCurUnexploredName);
wcscpy(gzSectorNames[ubSectorId][1], pData->szCurDetailedUnexploredName);
wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName);
wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName);
}
// moved to lua
//else if (Sector_Level == 1 )
//{
// wcscpy(gzSectorUndergroundNames1[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames1[ubSectorId][3], pData->szCurDetailedExploredName);
//}
//else if (Sector_Level == 2 )
//{
// wcscpy(gzSectorUndergroundNames2[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames2[ubSectorId][3], pData->szCurDetailedExploredName);
//}
//else if (Sector_Level == 3 )
//{
// wcscpy(gzSectorUndergroundNames3[ubSectorId][0], pData->szCurUnexploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][1], pData->szCurDetailedUnexploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][2], pData->szCurExploredName);
// wcscpy(gzSectorUndergroundNames3[ubSectorId][3], pData->szCurDetailedExploredName);
//}
}
}
}
else if(strcmp(name, "SectorGrid") == 0 )
@@ -178,7 +275,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name)
}
BOOLEAN ReadInSectorNames(STR fileName)
BOOLEAN ReadInSectorNames(STR fileName, BOOLEAN localizedVersion, INT8 Level )
{
HWFILE hFile;
UINT32 uiBytesRead;
@@ -187,10 +284,13 @@ BOOLEAN ReadInSectorNames(STR fileName)
XML_Parser parser = XML_ParserCreate(NULL);
SectorNameParseData pData;
Sector_Level = Level;
SectorName_TextOnly = localizedVersion;
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
return( localizedVersion );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
+1 -1
View File
@@ -161,7 +161,7 @@ UniformEndElementHandle(void *userData, const XML_Char *name)
{
CHAR16 sString[256];
swprintf( sString, L"Error in UniformColors.XML: Uniform color for %s not found or not properly defined!", szUniformErrorStrings[ cnt ] );
THROWEXCEPTION( sString );
SGP_THROW( sString );
}
}
+261 -111
View File
@@ -113,6 +113,8 @@
#include "Animation Control.h"
// HEADROCK HAM 3.6: Include facilities for assignment display
#include "Facilities.h"
// HEADROCK HAM 4: Include Militia Squads for Manual Militia Restrictions toggle.
#include "MilitiaSquads.h"
#endif
#include "connect.h" //hayden
@@ -714,6 +716,9 @@ extern BOOLEAN fSelectedListOfMercsForMapScreen[ CODE_MAXIMUM_NUMBER_OF_PLAYER_S
extern INT32 iDialogueBox;
extern INT32 giMapInvDescButton;
// HEADROCK HAM 4: Extern tab buttons for UDB
extern INT32 giInvDescTabButton[3];
extern UINT32 guiBrownBackgroundForTeamPanel;
// the town mine info box
@@ -1131,7 +1136,7 @@ void BeginSellAllCallBack( UINT8 bExitValue )
{
return;
}
for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++)
for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++) //WS TODO: is "for(UINT32 wItem = 0; wItem < pInventoryPoolList.size(); wItem++)" better? It resolved a bug in the old SVN, but things have changed now. (It was likely only fighting symptons anyway)
{
if(pInventoryPoolList[wItem].object.exists() == true && (pInventoryPoolList[wItem].usFlags & WORLD_ITEM_REACHABLE))
{
@@ -1169,7 +1174,7 @@ void BeginDeleteAllCallBack( UINT8 bExitValue )
{
return;
}
for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++)
for(UINT32 wItem = 0; wItem < guiNumWorldItems; wItem++) //WS TODO: is "for(UINT32 wItem = 0; wItem < pInventoryPoolList.size(); wItem++)"
{
if(0 == pInventoryPoolList[wItem].object.MoveThisObjectTo(gItemPointer,-1,0,NUM_INV_SLOTS,MAX_OBJECTS_PER_SLOT))
{
@@ -2109,7 +2114,8 @@ void GlowItem( void )
if( fOldItemGlow == TRUE )
{
RestoreExternBackgroundRect( 3, 80, ( UINT16 )( 65 - 3 ), ( UINT16 )( 105 - 80 ) );
// this caused the attachment/burst/grenade star to disappear behind the item image
//RestoreExternBackgroundRect( 3, 80, ( UINT16 )( 65 - 3 ), ( UINT16 )( 105 - 80 ) );
}
fOldItemGlow = FALSE;
@@ -2424,11 +2430,15 @@ void DrawCharStats( INT16 sCharNum )
SetFontForeground(CHAR_TEXT_FONT_COLOR);
SetFontBackground(FONT_BLACK);
// strength
swprintf( sString, L"%d", pSoldier->stats.bStrength);
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeStrengthTime)&& ( pSoldier->timeChanges.uiChangeStrengthTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_STRENGTH] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeStrengthTime)&& ( pSoldier->timeChanges.uiChangeStrengthTime != 0 ) )
{
if( pSoldier->usValueGoneUp & STRENGTH_INCREASE )
{
@@ -2451,7 +2461,12 @@ void DrawCharStats( INT16 sCharNum )
// dexterity
swprintf( sString, L"%d", pSoldier->stats.bDexterity );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeDexterityTime ) && ( pSoldier->timeChanges.uiChangeDexterityTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_DEXTERITY] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeDexterityTime ) && ( pSoldier->timeChanges.uiChangeDexterityTime != 0 ) )
{
if( pSoldier->usValueGoneUp & DEX_INCREASE )
{
@@ -2473,8 +2488,13 @@ void DrawCharStats( INT16 sCharNum )
// agility
swprintf( sString, L"%d", pSoldier->stats.bAgility );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeAgilityTime)&& ( pSoldier->timeChanges.uiChangeAgilityTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_AGILITY] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeAgilityTime)&& ( pSoldier->timeChanges.uiChangeAgilityTime != 0 ) )
{
if( pSoldier->usValueGoneUp & AGIL_INCREASE )
{
@@ -2496,8 +2516,13 @@ void DrawCharStats( INT16 sCharNum )
// wisdom
swprintf( sString, L"%d", pSoldier->stats.bWisdom );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeWisdomTime )&&( pSoldier->timeChanges.uiChangeWisdomTime != 0 ))
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_WISDOM] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeWisdomTime )&&( pSoldier->timeChanges.uiChangeWisdomTime != 0 ))
{
if( pSoldier->usValueGoneUp & WIS_INCREASE )
{
@@ -2519,8 +2544,13 @@ void DrawCharStats( INT16 sCharNum )
// leadership
swprintf( sString, L"%d", pSoldier->stats.bLeadership );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeLeadershipTime ) && ( pSoldier->timeChanges.uiChangeLeadershipTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_LEADERSHIP] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeLeadershipTime ) && ( pSoldier->timeChanges.uiChangeLeadershipTime != 0 ) )
{
if( pSoldier->usValueGoneUp & LDR_INCREASE )
{
@@ -2566,7 +2596,12 @@ void DrawCharStats( INT16 sCharNum )
// marksmanship
swprintf( sString, L"%d", pSoldier->stats.bMarksmanship );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMarksmanshipTime) && ( pSoldier->timeChanges.uiChangeMarksmanshipTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_MARKSMANSHIP] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMarksmanshipTime) && ( pSoldier->timeChanges.uiChangeMarksmanshipTime != 0 ) )
{
if( pSoldier->usValueGoneUp & MRK_INCREASE )
{
@@ -2588,8 +2623,13 @@ void DrawCharStats( INT16 sCharNum )
// explosives
swprintf( sString, L"%d", pSoldier->stats.bExplosive );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeExplosivesTime)&& ( pSoldier->timeChanges.uiChangeExplosivesTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_EXPLOSIVES] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeExplosivesTime)&& ( pSoldier->timeChanges.uiChangeExplosivesTime != 0 ) )
{
if( pSoldier->usValueGoneUp & EXP_INCREASE )
{
@@ -2611,8 +2651,13 @@ void DrawCharStats( INT16 sCharNum )
// mechanical
swprintf( sString, L"%d", pSoldier->stats.bMechanical );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMechanicalTime )&& ( pSoldier->timeChanges.uiChangeMechanicalTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_MECHANICAL] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMechanicalTime )&& ( pSoldier->timeChanges.uiChangeMechanicalTime != 0 ) )
{
if( pSoldier->usValueGoneUp & MECH_INCREASE )
{
@@ -2635,7 +2680,12 @@ void DrawCharStats( INT16 sCharNum )
// medical
swprintf( sString, L"%d", pSoldier->stats.bMedical );
if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMedicalTime)&& ( pSoldier->timeChanges.uiChangeMedicalTime != 0 ) )
// SANDRO - if damaged stat we could regain, show in red until repaired
if( gGameOptions.fNewTraitSystem && ( pSoldier->ubCriticalStatDamage[DAMAGED_STAT_MEDICAL] > 0 ))
{
SetFontForeground( FONT_RED );
}
else if( ( GetJA2Clock() < CHANGE_STAT_RECENTLY_DURATION + pSoldier->timeChanges.uiChangeMedicalTime)&& ( pSoldier->timeChanges.uiChangeMedicalTime != 0 ) )
{
if( pSoldier->usValueGoneUp & MED_INCREASE )
{
@@ -3165,6 +3215,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sAgilityGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sAgilityGain+1)) / SubpointsPerPoint(AGILAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (AGL_Y-1);
ClipRect.iBottom = (AGL_Y-1) + STAT_HEI;
ClipRect.iLeft = AGL_X;
@@ -3176,6 +3227,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sDexterityGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sDexterityGain+1)) / SubpointsPerPoint(DEXTAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (DEX_Y-1);
ClipRect.iBottom = (DEX_Y-1) + STAT_HEI;
ClipRect.iLeft = DEX_X;
@@ -3187,6 +3239,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sStrengthGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sStrengthGain+1)) / SubpointsPerPoint(STRAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (STR_Y-1);
ClipRect.iBottom = (STR_Y-1) + STAT_HEI;
ClipRect.iLeft = STR_X;
@@ -3198,6 +3251,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sWisdomGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sWisdomGain+1)) / SubpointsPerPoint(WISDOMAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (WIS_Y-1);
ClipRect.iBottom = (WIS_Y-1) + STAT_HEI;
ClipRect.iLeft = WIS_X;
@@ -3209,6 +3263,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sMarksmanshipGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMarksmanshipGain+1)) / SubpointsPerPoint(MARKAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (MRK_Y-1);
ClipRect.iBottom = (MRK_Y-1) + STAT_HEI;
ClipRect.iLeft = MRK_X;
@@ -3220,6 +3275,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sLeadershipGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sLeadershipGain+1)) / SubpointsPerPoint(LDRAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (LDR_Y-1);
ClipRect.iBottom = (LDR_Y-1) + STAT_HEI;
ClipRect.iLeft = LDR_X;
@@ -3231,6 +3287,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sMechanicGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMechanicGain+1)) / SubpointsPerPoint(MECHANAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (MEC_Y-1);
ClipRect.iBottom = (MEC_Y-1) + STAT_HEI;
ClipRect.iLeft = MEC_X;
@@ -3242,6 +3299,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sExplosivesGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sExplosivesGain+1)) / SubpointsPerPoint(EXPLODEAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (EXP_Y-1);
ClipRect.iBottom = (EXP_Y-1) + STAT_HEI;
ClipRect.iLeft = EXP_X;
@@ -3253,6 +3311,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sMedicalGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sMedicalGain+1)) / SubpointsPerPoint(MEDICALAMT,0);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (MED_Y-1);
ClipRect.iBottom = (MED_Y-1) + STAT_HEI;
ClipRect.iLeft = MED_X;
@@ -3264,6 +3323,7 @@ void DisplayCharacterInfo( void )
if (gMercProfiles[ pSoldier->ubProfile ].sExpLevelGain)
{
ubBarWidth = (STAT_WID * (gMercProfiles[ pSoldier->ubProfile ].sExpLevelGain+1)) / SubpointsPerPoint(EXPERAMT, pSoldier->stats.bExpLevel);
ubBarWidth = __max(0, __min(ubBarWidth, STAT_WID));
ClipRect.iTop = (LVL_Y-1);
ClipRect.iBottom = (LVL_Y-1) + STAT_HEI;
ClipRect.iLeft = LVL_X;
@@ -3990,14 +4050,14 @@ void DrawMPPlayerList ()
//DrawString( (STR16)szPlayerName , usX,usY, MAP_SCREEN_FONT);
// WANNE: No team selection in DM or COOP
if (PLAYER_BSIDE == MP_TYPE_DEATHMATCH || PLAYER_BSIDE == MP_TYPE_COOP)
if (cGameType == MP_TYPE_DEATHMATCH || cGameType == MP_TYPE_COOP)
wcscpy(szTeam, gszMPTeamNames[4]);
else
wcscpy(szTeam,gszMPTeamNames[client_teams[i]]);
FindFontCenterCoordinates((short)MP_TEAM_X + 1, (short)(MP_ROWSTART_Y+(row*Y_SIZE)), (short)MP_TEAM_W, (short)Y_SIZE, szTeam, (long)MAP_SCREEN_FONT, &usX, &usY);
DrawString( szTeam,usX,(short)usY, MAP_SCREEN_FONT);
wcscpy(szCompass,(RANDOM_SPAWN==1 ? L"?" : gszMPEdgesText[client_edges[i]]));
wcscpy(szCompass,(gRandomStartingEdge==1 ? L"?" : gszMPEdgesText[client_edges[i]]));
FindFontCenterCoordinates((short)MP_COMPASS_X + 1, (short)(MP_ROWSTART_Y+(row*Y_SIZE)), (short)MP_COMPASS_W, (short)Y_SIZE, szCompass, (long)MAP_SCREEN_FONT, &usX, &usY);
DrawString(szCompass , usX,(short)usY, MAP_SCREEN_FONT);
@@ -4013,7 +4073,7 @@ void DrawMPPlayerList ()
// <TODO> change this text to wrap
/*wchar_t szServerName[30];
memset(szServerName,0,30*sizeof(wchar_t));
mbstowcs( szServerName,SERVER_NAME,30);
mbstowcs( szServerName,cServerName,30);
SetFontForeground( FONT_YELLOW );
DrawString( L"Server Name:" , MP_GAMEINFO_X ,MP_ROWSTART_Y, MAP_SCREEN_FONT);
@@ -4025,7 +4085,7 @@ void DrawMPPlayerList ()
DrawString( gszMPMapscreenText[0] , MP_GAMEINFO_X ,MP_ROWSTART_Y, MAP_SCREEN_FONT);
SetFontForeground( FONT_WHITE );
switch(PLAYER_BSIDE)
switch(cGameType)
{
case MP_TYPE_DEATHMATCH:
DrawString( gzMPHScreenText[MPH_DEATHMATCH_TEXT] , MP_GAMEINFO_X ,MP_ROWSTART_Y+(1*Y_SIZE), MAP_SCREEN_FONT);
@@ -4044,7 +4104,7 @@ void DrawMPPlayerList ()
SetFontForeground( FONT_WHITE );
wchar_t szMaxPlayers[10];
swprintf(szMaxPlayers,L"%i",MAX_CLIENTS);
swprintf(szMaxPlayers,L"%i",cMaxClients);
DrawString( szMaxPlayers , MP_GAMEINFO_X + StringPixLength(gszMPMapscreenText[1],MAP_SCREEN_FONT),MP_ROWSTART_Y+(2*Y_SIZE), MAP_SCREEN_FONT);
// Number of Mercs
@@ -4053,11 +4113,11 @@ void DrawMPPlayerList ()
SetFontForeground( FONT_WHITE );
wchar_t szSquadSize[10];
swprintf(szSquadSize,L"%i",MAX_MERCS);
swprintf(szSquadSize,L"%i",cMaxMercs);
DrawString( szSquadSize , MP_GAMEINFO_X + StringPixLength(gszMPMapscreenText[2],MAP_SCREEN_FONT),MP_ROWSTART_Y+(3*Y_SIZE), MAP_SCREEN_FONT);
row = 4;
if (RANDOM_MERCS)
if (gRandomMercs)
{
// Random Mercs
SetFontForeground( FONT_YELLOW );
@@ -5497,6 +5557,14 @@ UINT32 MapScreenHandle(void)
//UnMarkButtonDirty( giCharInfoButton[ 0 ] );
//UnMarkButtonDirty( giCharInfoButton[ 1 ] );
MarkAButtonDirty( giMapInvDescButton );
// HEADROCK HAM 4: Makes sure the Tab Buttons are always redrawn on top.
for (UINT8 cnt = 0; cnt < 3; cnt++)
{
if (giInvDescTabButton[cnt] != -1)
{
MarkAButtonDirty( giInvDescTabButton[ cnt ] );
}
}
}
else
{
@@ -5866,8 +5934,8 @@ void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont)
}
if ( gGameSettings.fOptions[TOPTION_STAT_PROGRESS_BARS] &&
(pSoldier->bAssignment >= TRAIN_SELF ||
pSoldier->bAssignment <= TRAIN_BY_OTHER ) &&
pSoldier->bAssignment >= TRAIN_SELF &&
pSoldier->bAssignment <= TRAIN_BY_OTHER &&
pSoldier->bAssignment != TRAIN_TEAMMATE )
{
// HEADROCK HAM 3.6: Draw militia training progress bar
@@ -5888,8 +5956,8 @@ void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont)
}
pDestBuf = LockVideoSurface( uiDestBuffer, &uiDestPitchBYTES );
UINT8 ubProgress;
UINT16 usMaxProgress;
UINT8 ubProgress = 0;
UINT16 usMaxProgress = 100;
UINT8 sMapX = (UINT8)pSoldier->sSectorX;
UINT8 sMapY = (UINT8)pSoldier->sSectorY;
if ( pSoldier->bAssignment == TRAIN_TOWN )
@@ -5947,6 +6015,7 @@ void DrawAssignment(INT16 sCharNumber, INT16 sRowIndex, INT32 iFont)
}
ubBarWidth = (ASSIGN_WIDTH * ubProgress) / usMaxProgress;
ubBarWidth = __max(0, __min(ubBarWidth, ASSIGN_WIDTH));
ClipRect.iTop = (usY+(Y_OFFSET*sRowIndex+1))-1;
ClipRect.iBottom = ClipRect.iTop + Y_SIZE;
ClipRect.iLeft = ASSIGN_X+2;
@@ -6903,25 +6972,8 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
StopAnyCurrentlyTalkingSpeech( );
break;
// multiplayer: Roman: Should be changed, because the keys are already bount to another feature
case F1:
// WANNE: No more needed
/*
if (is_networked)
{
mp_help();
break;
}
*/
case F2:
// WANNE: No more needed
/*
if (is_networked)
{
mp_help2();
break;
}
*/
case F3:
case F4:
case F5:
@@ -7141,13 +7193,6 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
case '5':
case '6':
case '7':
// WANNE: Only show the override panel when '7' is pressed
/*if (is_networked && InputEvent.usParam == '7')
{
// haydent
manual_overide();
break;
}*/
case '8':
case '9':
if(gGameExternalOptions.fEnableInventoryPoolQ && fShowMapInventoryPool == TRUE)//dnl ch51 081009
@@ -7166,8 +7211,7 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
SwitchToInventoryPoolQ('0');
break;
}
SelectAllCharactersInSquad( 9 ); // internal squad #s start at 0
if(is_networked)test_func2();
SelectAllCharactersInSquad( 9 ); // internal squad #s start at 0
break;
case '!':
@@ -7318,67 +7362,99 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
if(bSelectedInfoChar != -1)
{
SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ];
if(OK_CONTROLLABLE_MERC( pSoldier ))
//CHRISL: Try to update InSector value so we don't have to "activate" a sector
if(pSoldier->sSectorX == sSelMapX && pSoldier->sSectorY == sSelMapY && pSoldier->bSectorZ == iCurrentMapSectorZ && !pSoldier->flags.fBetweenSectors)
pSoldier->bInSector=TRUE;
if(OK_CONTROL_MERC( pSoldier ))
{
if(!fShowMapInventoryPool)
{
fShowMapInventoryPool = TRUE;
CreateDestroyMapInventoryPoolButtons( TRUE );
}
if(!fShowInventoryFlag)
{
fShowInventoryFlag = TRUE;
}
if( fCtrl )
{
//CHRISL: pickup all items to vehicle
if ( UsingNewInventorySystem() == true && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) && gGameExternalOptions.fVehicleInventory && (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE))
if(!fShowMapInventoryPool)
{
for(unsigned int i = 0; i<pInventoryPoolList.size(); i++)
fShowMapInventoryPool = TRUE;
CreateDestroyMapInventoryPoolButtons( TRUE );
}
if(!fShowInventoryFlag)
{
fShowInventoryFlag = TRUE;
}
if( fCtrl )
{
//CHRISL: pickup all items to vehicle
if ( UsingNewInventorySystem() == true && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) && gGameExternalOptions.fVehicleInventory && (pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE))
{
if(pInventoryPoolList[i].fExists == TRUE && (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE))
for(unsigned int i = 0; i<pInventoryPoolList.size(); i++)
{
for(int x = 0; x<NUM_INV_SLOTS; x++)
if(pInventoryPoolList[i].fExists == TRUE && (pInventoryPoolList[i].usFlags & WORLD_ITEM_REACHABLE))
{
if(vehicleInv[x] == FALSE)
continue;
if(pSoldier->inv[x].exists() == true)
for(int x = 0; x<NUM_INV_SLOTS; x++)
{
if(pSoldier->inv[x].usItem != pInventoryPoolList[i].object.usItem)
if(vehicleInv[x] == FALSE)
continue;
if(pSoldier->inv[x].exists() == true)
{
if(pSoldier->inv[x].usItem != pInventoryPoolList[i].object.usItem)
continue;
else
pInventoryPoolList[i].object.AddObjectsToStack(pSoldier->inv[x], -1, pSoldier, x);
}
else
pInventoryPoolList[i].object.AddObjectsToStack(pSoldier->inv[x], -1, pSoldier, x);
}
else
pInventoryPoolList[i].object.MoveThisObjectTo(pSoldier->inv[x], -1, pSoldier, x);
if(pInventoryPoolList[i].object.ubNumberOfObjects < 0)
{
//RemoveItemFromWorld(i);
break;
pInventoryPoolList[i].object.MoveThisObjectTo(pSoldier->inv[x], -1, pSoldier, x);
if(pInventoryPoolList[i].object.ubNumberOfObjects < 0)
{
//RemoveItemFromWorld(i);
break;
}
}
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
}
}
else
{
//CHRISL: drop all items
if ( bSelectedInfoChar != -1 && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) )
else if ( fAlt )
{
for(int i = BODYPOSFINAL; i<NUM_INV_SLOTS; i++)
//CHRISL: drop all items in backpack
if ( bSelectedInfoChar != -1 && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) )
{
if(pSoldier->inv[i].exists() == true)
for(int i = BIGPOCK4POS; i<=BIGPOCK7POS; i++)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
if(pSoldier->inv[i].exists() == true)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
for(int i = SMALLPOCK23POS; i<NUM_INV_SLOTS; i++)
{
if(pSoldier->inv[i].exists() == true)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
}
}
else
{
//CHRISL: drop all items
if ( bSelectedInfoChar != -1 && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) )
{
for(int i = BODYPOSFINAL; i<NUM_INV_SLOTS; i++)
{
if(pSoldier->inv[i].exists() == true)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
}
}
@@ -7410,7 +7486,7 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
//Toggle Frame Rate Display
gbFPSDisplay = !gbFPSDisplay;
DisableFPSOverlay( (BOOLEAN)!gbFPSDisplay );
}
}
}
break;
case 'h':
@@ -7808,6 +7884,65 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent )
}
break;
case 'W':
if( fAlt )
{
if ( CHEATER_CHEAT_LEVEL( ) )
{
if ( InItemDescriptionBox( ) )
{
CycleItemDescriptionItem( MAP_ITEMDESC_START_X, MAP_ITEMDESC_START_Y );
}
}
}
else
{
if(bSelectedInfoChar != -1)
{
SOLDIERTYPE *pSoldier = MercPtrs[ gCharactersList[ bSelectedInfoChar ].usSolID ];
//CHRISL: Try to update InSector value so we don't have to "activate" a sector
if(pSoldier->sSectorX == sSelMapX && pSoldier->sSectorY == sSelMapY && pSoldier->bSectorZ == iCurrentMapSectorZ && !pSoldier->flags.fBetweenSectors)
pSoldier->bInSector=TRUE;
if(OK_CONTROL_MERC( pSoldier ))
{
if(!fShowMapInventoryPool)
{
fShowMapInventoryPool = TRUE;
CreateDestroyMapInventoryPoolButtons( TRUE );
}
if(!fShowInventoryFlag)
{
fShowInventoryFlag = TRUE;
}
//tais: borrowed the drop all items code from CHRISL to make it drop EVERYTHING!
if ( bSelectedInfoChar != -1 && fShowInventoryFlag && fShowMapInventoryPool && !(gTacticalStatus.fEnemyInSector) )
{
for(int i = BODYPOSFINAL; i<NUM_INV_SLOTS; i++)
{
if(pSoldier->inv[i].exists() == true)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
for(int i = HELMETPOS; i<BODYPOSFINAL; i++)
{
if(pSoldier->inv[i].exists() == true)
{
AutoPlaceObjectInInventoryStash(&pSoldier->inv[i], pSoldier->sGridNo);
DeleteObj(&pSoldier->inv[i]);
}
fTeamPanelDirty = TRUE;
fMapPanelDirty = TRUE;
fInterfacePanelDirty = DIRTYLEVEL2;
}
}
}
}
}
break;
case 'w':
if( fAlt )
{
@@ -8565,7 +8700,27 @@ void PollRightButtonInMapView( UINT32 *puiNewEvent )
}
*/
if( ( sSelMapX != sMapX ) || ( sSelMapY != sMapY ) )
// HEADROCK HAM 4: Toggle Militia Restrictions manually. This occurs when the Mobile Restrictions
// view is turned on. Each click advances the sector's classification by 1. If max is reached,
// loops back to start.
if ( fShowMobileRestrictionsFlag == TRUE )
{
// Restrict more.
if ( gubManualRestrictMilitia[ SECTOR( sMapX, sMapY ) ] > MANUAL_MOBILE_NO_ENTER )
{
gubManualRestrictMilitia[ SECTOR( sMapX, sMapY ) ]--;
}
else
{
// Wrap back to highest.
gubManualRestrictMilitia[ SECTOR( sMapX, sMapY ) ] = MANUAL_MOBILE_NO_RESTRICTION;
}
fMapPanelDirty = TRUE;
// Skip the rest of this function.
return;
}
// don't change sectors if we've just done the militia restrictions thing.
else if( ( sSelMapX != sMapX ) || ( sSelMapY != sMapY ) )
{
ChangeSelectedMapSector( sMapX, sMapY, ( INT8 )iCurrentMapSectorZ );
}
@@ -9890,12 +10045,6 @@ void MPReadyButtonCallback( GUI_BUTTON *btn, INT32 reason )
// warn the user that cannot change once buying has commenced
ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, gszMPMapscreenText[4]);
}
/*
else if (RANDOM_SPAWN)
{
ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"Cannot change edge, the game is set to random spawn");
}
*/
}
else
{
@@ -9958,7 +10107,7 @@ void MPTeamChangeCallback( MOUSE_REGION * pReason, INT32 iReason)
// warn the user that cannot change once buying has commenced
ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, gszMPMapscreenText[4]);
}
else if (RANDOM_SPAWN)
else if (gRandomStartingEdge)
{
ScreenMsg( FONT_LTBLUE, MSG_MPSYSTEM, L"Cannot change edge, the game is set to random spawn");
}
@@ -11460,7 +11609,7 @@ void HandleShadingOfLinesForContractMenu( void )
}
// WANNE - MP: Disable "Dismiss" button when Random merc was selected, because we cannot hire any new merc
if (is_networked && RANDOM_MERCS)
if (is_networked && gRandomMercs)
{
ShadeStringInBox( ghContractBox, CONTRACT_MENU_TERMINATE );
}
@@ -15013,7 +15162,8 @@ void HandleNewDestConfirmation( INT16 sMapX, INT16 sMapY )
if(gGameSettings.fOptions[ TOPTION_SILENT_SKYRIDER ] == FALSE) SkyRiderTalk( CONFIRM_DESTINATION );
}
}
else
//CHRISL: If we're allowing Skyrider to drop mercs into a hot LZ, we don't need Skyrider telling us he isn't going to drop the mercs off.
else if(gGameExternalOptions.ubSkyriderHotLZ == 0)
{
// ok, but... you know there are enemies there...
SkyRiderTalk( BELIEVED_ENEMY_SECTOR );
@@ -15950,7 +16100,7 @@ INT32 GetTotalContractExpenses ( void )
{
iTotalCost += ( gMercProfiles[ pSoldier->ubProfile ].uiBiWeeklySalary / 14 );
}
if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_1_WEEK )
else if( pSoldier->bTypeOfLastContract == CONTRACT_EXTEND_1_WEEK )
{
iTotalCost += ( gMercProfiles[ pSoldier->ubProfile ].uiWeeklySalary / 7 );
}
+12
View File
@@ -8,6 +8,8 @@
#define MAP_WORLD_X 18
#define MAP_WORLD_Y 18
extern int MAP_ITEMDESC_START_Y;
extern int MAP_ITEMDESC_START_X;
#define MAX_TOWN_NAME_LENGHT 32
#define MAX_SECTOR_NAME_LENGTH 128
@@ -99,4 +101,14 @@ BOOLEAN InitializeInvPanelCoordsVehicle( );
// HEADROCK HAM 3.6: Calculate daily cost for all mercs who have one.
INT32 GetTotalContractExpenses ( void );
// HEADROCK HAM 4: enumarate Manual Militia Restriction states
enum
{
MANUAL_MOBILE_RESTRICTED,
MANUAL_MOBILE_NO_ENTER,
MANUAL_MOBILE_NO_LEAVE,
MANUAL_MOBILE_NO_RESTRICTION,
NUM_MANUAL_MOBILE_STATES,
};
#endif
+13 -5
View File
@@ -39,8 +39,11 @@ void InitializeProfilesForTownReputation( void )
UINT32 uiProfileId = 0;
// initialize the town opinion values in each recruitable merc's profile structure
for( uiProfileId = 0; uiProfileId < FIRST_NPC; uiProfileId++ )
//for( uiProfileId = 0; uiProfileId < FIRST_NPC; uiProfileId++ )
//new profiles by Jazz
for( uiProfileId = 0; uiProfileId < NUM_PROFILES; uiProfileId++ )
{
if ( gProfilesIMP[uiProfileId].ProfilId == uiProfileId || gProfilesRPC[uiProfileId].ProfilId == uiProfileId || gProfilesAIM[uiProfileId].ProfilId == uiProfileId || gProfilesMERC[uiProfileId].ProfilId == uiProfileId)
memset( &( gMercProfiles[ uiProfileId ].bMercTownReputation ), INITIAL_TOWN_REPUTATION, sizeof( gMercProfiles[ uiProfileId ].bMercTownReputation ) );
}
}
@@ -62,7 +65,8 @@ void PostEventsForSpreadOfTownOpinion( void )
UINT8 GetTownOpinionOfMerc( UINT8 ubProfileId, UINT8 ubTownId )
{
Assert(ubProfileId < FIRST_NPC);
//new profiles by Jazz
//Assert(ubProfileId < FIRST_NPC);
Assert(ubTownId < NUM_TOWNS);
// return amount
@@ -87,7 +91,8 @@ UINT8 GetTownOpinionOfMercForSoldier( SOLDIERTYPE *pSoldier, UINT8 ubTownId )
void UpdateTownOpinionOfThisMerc( UINT8 ubProfileId, UINT8 ubTownId, INT8 bAmount )
{
Assert(ubProfileId < FIRST_NPC);
//new profiles by Jazz
//Assert(ubProfileId < FIRST_NPC);
Assert(ubTownId < NUM_TOWNS);
// check if opinion would be affected too greatly
@@ -132,8 +137,11 @@ void HandleSpreadOfAllTownsOpinion( void )
ScreenMsg( MSG_FONT_RED, MSG_DEBUG, L"%s - Spreading town opinions about mercs", WORLDTIMESTR );
// run though all player-recruitable profiles and update towns opinion of mercs
for( ubProfileId = 0; ubProfileId < FIRST_NPC; ubProfileId++ )
//for( ubProfileId = 0; ubProfileId < FIRST_NPC; ubProfileId++ )
//new profiles by Jazz
for( ubProfileId = 0; ubProfileId < NUM_PROFILES; ubProfileId++ )
{
if ( gProfilesIMP[ubProfileId].ProfilId == ubProfileId || gProfilesAIM[ubProfileId].ProfilId == ubProfileId || gProfilesMERC[ubProfileId].ProfilId == ubProfileId || gProfilesRPC[ubProfileId].ProfilId == ubProfileId)
HandleSpreadOfTownOpinionForMerc( ubProfileId );
}
}
@@ -146,7 +154,7 @@ void HandleSpreadOfTownOpinionForMerc( UINT8 ubProfileId )
INT8 iCounterA, iCounterB;
INT8 bOpinionOfTownA, bOpinionOfTownB;
Assert(ubProfileId < FIRST_NPC);
//Assert(ubProfileId < FIRST_NPC);
for( iCounterA = FIRST_TOWN; iCounterA < NUM_TOWNS; iCounterA++ )
{
+431 -190
View File
@@ -108,9 +108,11 @@
#include "connect.h" //hayden added alot ""'s to get around client spawing random/different placed AI
#include "SaveLoadGame.h"
#include "Strategic Mines.h"
#include "Strategic Mines LUA.h"
#include "UndergroundInit.h"
#include "VFS/vfs.h"
#include "VFS/Tools/Log.h"
#include "sgp_logger.h"
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
@@ -136,7 +138,9 @@ BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode );
extern INT32 gsRobotGridNo;
extern BOOLEAN gfUndergroundTacticalTraversal;
extern MINE_LOCATION_TYPE gMineLocation[MAX_NUMBER_OF_MINES];
//extern MINE_LOCATION_TYPE gMineLocation[MAX_NUMBER_OF_MINES];
//extern MINE_STATUS_TYPE gMineStatus[MAX_NUMBER_OF_MINES];
extern void CalculateNonPersistantPBIInfo();
@@ -299,6 +303,11 @@ STR8 pHortStrings[]={
// HEADROCK HAM 3.6: Array to hold user-defined sector names
CHAR16 gzSectorNames[256][4][MAX_SECTOR_NAME_LENGTH];
// moved to lua
//CHAR16 gzSectorUndergroundNames1[256][4][MAX_SECTOR_NAME_LENGTH];
//CHAR16 gzSectorUndergroundNames2[256][4][MAX_SECTOR_NAME_LENGTH];
//CHAR16 gzSectorUndergroundNames3[256][4][MAX_SECTOR_NAME_LENGTH];
BOOLEAN ReadInStrategicMapSectorTownNames(STR fileName, BOOLEAN localizedVersion);
void DoneFadeOutAdjacentSector( void );
@@ -623,7 +632,7 @@ samsiteEndElementHandle(void *userData, const XML_Char *name)
{
pData->curElement = SAMSITE_ELEMENT_SAM;
pData->curSamInfo.samGridNoA = (INT16)atol(pData->szCharData);
pData->curSamInfo.samGridNoA = atol(pData->szCharData);
if ( pData->curSamInfo.samGridNoA >= WORLD_MAX )
{
pData->curSamInfo.samGridNoA = 0;
@@ -633,7 +642,7 @@ samsiteEndElementHandle(void *userData, const XML_Char *name)
{
pData->curElement = SAMSITE_ELEMENT_SAM;
pData->curSamInfo.samGridNoB = (INT16)atol(pData->szCharData);
pData->curSamInfo.samGridNoB = atol(pData->szCharData);
if ( pData->curSamInfo.samGridNoB >= WORLD_MAX )
{
pData->curSamInfo.samGridNoB = 1;
@@ -1456,40 +1465,43 @@ void EndLoadScreen( )
fclose( fp );
}
#else
CLog timeResults(L"TimeResults.txt", true);
sgp::Logger_ID time_log_id = sgp::Logger::instance().createLogger();
sgp::Logger::instance().connectFile(time_log_id, L"TimeResults.txt", true, sgp::Logger::FLUSH_ON_ENDL);
sgp::Logger::LogInstance timeResults = SGP_LOG(time_log_id);
ScreenMsg( FONT_YELLOW, MSG_TESTVERSION, L"See JA2\\Data\\TimeResults.txt for more detailed timings." );
//Record all of the timings.
timeResults << str << CLog::ENDL;
timeResults << "EnterSector() supersets LoadWorld(). This includes other external sections." << CLog::ENDL;
timeResults << str << sgp::endl;
timeResults << "EnterSector() supersets LoadWorld(). This includes other external sections." << vfs::Log::endl;
//FileRead()
timeResults << CLog::ENDL << CLog::ENDL << "VARIOUS FUNCTION TIMINGS (exclusive of actual function timings in second heading)" << CLog::ENDL;
timeResults << sgp::endl << vfs::Log::endl << "VARIOUS FUNCTION TIMINGS (exclusive of actual function timings in second heading)" << sgp::endl;
uiSeconds = uiTotalFileReadTime / 1000;
uiHundreths = (uiTotalFileReadTime / 10) % 100;
//fprintf( fp, "FileRead: %d.%02d (called %d times)\n", uiSeconds, uiHundreths, uiTotalFileReadCalls );
timeResults << "FileRead: " <<uiSeconds<< "." << uiHundreths << " (called " << uiTotalFileReadCalls << " times)" << CLog::ENDL;
timeResults << "FileRead: " <<uiSeconds<< "." << uiHundreths << " (called " << uiTotalFileReadCalls << " times)" << sgp::endl;
timeResults.endl().endl() << "SECTIONS OF LOADWORLD (all parts should add up to 100%)" << CLog::ENDL;
timeResults << sgp::endl << sgp::endl << "SECTIONS OF LOADWORLD (all parts should add up to 100%)" << sgp::endl;
//TrashWorld()
uiSeconds = uiTrashWorldTime / 1000;
uiHundreths = (uiTrashWorldTime / 10) % 100;
timeResults << "TrashWorld: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << "TrashWorld: " << uiSeconds << "." << uiHundreths << sgp::endl;
//LoadMapTilesets()
uiSeconds = uiLoadMapTilesetTime / 1000;
uiHundreths = (uiLoadMapTilesetTime / 10) % 100;
timeResults << "LoadMapTileset: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << "LoadMapTileset: " << uiSeconds << "." << uiHundreths << sgp::endl;
//LoadMapLights()
uiSeconds = uiLoadMapLightsTime / 1000;
uiHundreths = (uiLoadMapLightsTime / 10) % 100;
timeResults << "LoadMapLights: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << "LoadMapLights: " << uiSeconds << "." << uiHundreths << sgp::endl;
uiSeconds = uiBuildShadeTableTime / 1000;
uiHundreths = (uiBuildShadeTableTime / 10) % 100;
timeResults << " 1) BuildShadeTables: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << " 1) BuildShadeTables: " << uiSeconds << "." << uiHundreths << sgp::endl;
uiPercentage = uiNumImagesReloaded * 100 / NUMBEROFTILETYPES;
timeResults << " 2) " << uiPercentage << "% of the tileset images were actually reloaded." << CLog::ENDL;
timeResults << " 2) " << uiPercentage << "% of the tileset images were actually reloaded." << sgp::endl;
if ( ( uiNumTablesSaved+uiNumTablesLoaded ) != 0 )
{
uiPercentage = uiNumTablesSaved * 100 / (uiNumTablesSaved+uiNumTablesLoaded);
@@ -1498,21 +1510,21 @@ void EndLoadScreen( )
{
uiPercentage = 0;
}
timeResults << " 3) Of that, " << uiPercentage << "% of the shade tables were generated (not loaded)." << CLog::ENDL;
timeResults << " 3) Of that, " << uiPercentage << "% of the shade tables were generated (not loaded)." << sgp::endl;
if( gfForceBuildShadeTables )
{
timeResults << " NOTE: Force building of shadetables enabled on this local computer." << CLog::ENDL;
timeResults << " NOTE: Force building of shadetables enabled on this local computer." << sgp::endl;
}
//Unaccounted
uiUnaccounted = uiLoadWorldTime - uiTrashWorldTime - uiLoadMapTilesetTime - uiLoadMapLightsTime;
uiSeconds = uiUnaccounted / 1000;
uiHundreths = (uiUnaccounted / 10) % 100;
timeResults << "Unaccounted: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << "Unaccounted: " << uiSeconds << "." << uiHundreths << sgp::endl;
//LoadWorld()
uiSeconds = uiLoadWorldTime / 1000;
uiHundreths = (uiLoadWorldTime / 10) % 100;
timeResults.endl() << "Total: " << uiSeconds << "." << uiHundreths << CLog::ENDL;
timeResults << vfs::Log::endl << "Total: " << uiSeconds << "." << uiHundreths << sgp::endl;
#endif // USE_VFS
#endif
}
@@ -1818,6 +1830,8 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
}
else
#endif
// reset goggle warning
gogglewarning = FALSE;
// is the sector already loaded?
if( ( gWorldSectorX == sMapX ) && ( sMapY == gWorldSectorY) && ( bMapZ == gbWorldSectorZ) )
{
@@ -1832,7 +1846,7 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
if (is_networked)
{
if(is_server && ENEMY_ENABLED==1)
if(is_server && gEnemyEnabled == 1)
PrepareEnemyForSectorBattle();
}
else
@@ -1859,7 +1873,7 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
{
if (is_networked)
{
if(is_server && CREATURE_ENABLED==1)
if(is_server && gCreatureEnabled == 1)
PrepareCreaturesForBattle();
}
else
@@ -2024,8 +2038,8 @@ BOOLEAN SetCurrentWorldSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ )
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
if( (gubMusicMode != MUSIC_TACTICAL_ENEMYPRESENT && gubMusicMode != MUSIC_TACTICAL_BATTLE) ||
(!NumHostilesInSector( sMapX, sMapY, bMapZ ) && gubMusicMode == MUSIC_TACTICAL_ENEMYPRESENT) )
if( (GetMusicMode() != MUSIC_TACTICAL_ENEMYPRESENT && GetMusicMode() != MUSIC_TACTICAL_BATTLE) ||
(!NumHostilesInSector( sMapX, sMapY, bMapZ ) && GetMusicMode() == MUSIC_TACTICAL_ENEMYPRESENT) )
{
// ATE; Fade FA.T....
SetMusicFadeSpeed( 5 );
@@ -2173,19 +2187,19 @@ void PrepareLoadedSector()
if (is_networked)
{
if( is_server && fAddCivs && CIV_ENABLED==1)//hayden its around here we apply .ini choices for Ai
if( is_server && fAddCivs && gCivEnabled == 1)//hayden its around here we apply .ini choices for Ai
{
AddSoldierInitListTeamToWorld( CIV_TEAM, 255 );
}
}
else
else if (fAddCivs)
{
AddSoldierInitListTeamToWorld( CIV_TEAM, 255 );
}
if (is_networked)
{
if(is_server && MILITIA_ENABLED==1)
if(is_server && gMilitiaEnabled == 1)
AddSoldierInitListTeamToWorld( MILITIA_TEAM, 255 );
}
else
@@ -2195,7 +2209,7 @@ void PrepareLoadedSector()
if (is_networked)
{
if(is_server && CREATURE_ENABLED==1)
if(is_server && gCreatureEnabled == 1)
AddSoldierInitListBloodcats();
}
else
@@ -2235,11 +2249,11 @@ void PrepareLoadedSector()
// Haydent
if (is_networked)
{
if(is_server && CREATURE_ENABLED==1)
if(is_server && gCreatureEnabled == 1)
PrepareCreaturesForBattle();
// Haydent
if(is_server && MILITIA_ENABLED==1)
if(is_server && gMilitiaEnabled == 1)
PrepareMilitiaForTactical(FALSE);
}
else
@@ -2262,7 +2276,7 @@ void PrepareLoadedSector()
if (is_networked)
{
if(is_server && CIV_ENABLED==1)
if(is_server && gCivEnabled == 1)
AddProfilesNotUsingProfileInsertionData(); //hayden: is just for civ's
}
else
@@ -2274,7 +2288,7 @@ void PrepareLoadedSector()
{
if (is_networked)
{
if(is_server && ENEMY_ENABLED==1)
if(is_server && gEnemyEnabled == 1)
fEnemyPresenceInThisSector = PrepareEnemyForSectorBattle();
}
else
@@ -2344,16 +2358,17 @@ void PrepareLoadedSector()
#define RANDOM_HEAD_MINERS 4
void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bNewSectorZ )
{
UINT8 ubRandomMiner[RANDOM_HEAD_MINERS] = { 106, 156, 157, 158 };
UINT8 ubMiner, ubMinersPlaced;
UINT8 ubMine, ubThisMine;
//UINT8 ubRandomMiner[RANDOM_HEAD_MINERS] = { 106, 156, 157, 158 };
//UINT8 ubMiner, ubMinersPlaced, ubMine;
UINT8 ubThisMine;
UINT8 cnt;
SOLDIERTYPE * pSoldier;
if ( CheckFact( FACT_ALL_TERRORISTS_KILLED, 0 ) )
{
// end terrorist quest
EndQuest( QUEST_KILL_TERRORISTS, gMercProfiles[ CARMEN ].sSectorX, gMercProfiles[ CARMEN ].sSectorY );
// SANDRO - removed ending quest from here, placed to Interface Dialogue
//EndQuest( QUEST_KILL_TERRORISTS, gMercProfiles[ CARMEN ].sSectorX, gMercProfiles[ CARMEN ].sSectorY );
// remove Carmen
gMercProfiles[ CARMEN ].sSectorX = 0;
gMercProfiles[ CARMEN ].sSectorY = 0;
@@ -2368,8 +2383,12 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
// SET HEAD MINER LOCATIONS
ubThisMine = GetMineIndexForSector( sNewSectorX, sNewSectorY );
if (ubThisMine != MINE_SAN_MONA) // San Mona is abandoned
// hardcoded logic has been moved to Lua script
if (g_luaMines.InitializeHeadMiners(ubThisMine))
SetFactTrue( FACT_MINERS_PLACED );
#if 0
//if (ubThisMine != MINE_SAN_MONA) // San Mona is abandoned
if (!gMineStatus[ubThisMine].fEmpty)
{
ubMinersPlaced = 0;
@@ -2379,7 +2398,8 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
gMercProfiles[ 106 ].sSectorX = sNewSectorX;
gMercProfiles[ 106 ].sSectorY = sNewSectorY;
gMercProfiles[ 106 ].bSectorZ = 0;
gMercProfiles[ 106 ].bTown = gMineLocation[ ubThisMine ].bAssociatedTown;
//gMercProfiles[ 106 ].bTown = gMineLocation[ ubThisMine ].bAssociatedTown;
gMercProfiles[ 106 ].bTown = gMineStatus[ ubThisMine ].bAssociatedTown;
// mark miner as placed
ubRandomMiner[ 0 ] = 0;
@@ -2405,7 +2425,8 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
GetMineSector( ubMine, (INT16 *)&(gMercProfiles[ ubRandomMiner[ ubMiner ] ].sSectorX),
(INT16 *)&(gMercProfiles[ ubRandomMiner[ ubMiner ] ].sSectorY) );
gMercProfiles[ ubRandomMiner[ ubMiner ] ].bSectorZ = 0;
gMercProfiles[ ubRandomMiner[ ubMiner ] ].bTown = gMineLocation[ ubMine ].bAssociatedTown;
//gMercProfiles[ ubRandomMiner[ ubMiner ] ].bTown = gMineLocation[ ubMine ].bAssociatedTown;
gMercProfiles[ ubRandomMiner[ ubMiner ] ].bTown = gMineStatus[ ubMine ].bAssociatedTown;
// mark miner as placed
ubRandomMiner[ ubMiner ] = 0;
@@ -2419,6 +2440,7 @@ void HandleQuestCodeOnSectorEntry( INT16 sNewSectorX, INT16 sNewSectorY, INT8 bN
SetFactTrue( FACT_MINERS_PLACED );
}
#endif
}
}
@@ -2552,6 +2574,12 @@ BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY , INT8 bSectorZ )
// This has tobe done before loadworld, as it will remmove old gridnos if present
RemoveMercsInSector( );
// SANDRO - reset number of enemies here
if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) )
{
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
}
if( AreInMeanwhile() == FALSE )
{
SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_ALREADY_VISITED );
@@ -2999,7 +3027,6 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS
SECTORINFO *pSector = NULL;
UNDERGROUND_SECTORINFO *pUnderground;
INT8 bTownNameID;
INT8 bMineIndex;
UINT8 ubSectorID = 0;
UINT8 ubLandType = 0;
@@ -3007,47 +3034,144 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS
{
//swprintf( zString, L"%s", pErrorStrings[0] );
}
else if( bSectorZ != 0 )
else if( bSectorZ != 0 ) // UNDERGROUND SECTORS
{
pUnderground = FindUnderGroundSector( sSectorX, sSectorY, bSectorZ );
if( pUnderground && ( pUnderground->fVisited || gfGettingNameFromSaveLoadScreen ) )
#if 0 // reading sector names from lua now
////////////////////////////////////
// Read and verify XML sector names
INT8 bMineIndex;
ubSectorID = (UINT8)SECTOR( sSectorX, sSectorY );
AssertGE(ubSectorID, 0);
AssertLT(ubSectorID,256);
pSector = &SectorInfo[ ubSectorID ];
ubLandType = pSector->ubTraversability[ 4 ];
swprintf( zString, L"%c%d: ", 'A' + sSectorY - 1, sSectorX );
BOOLEAN fSectorHasXMLNames = TRUE;
CHAR16 zUnexploredUnderground[MAX_SECTOR_NAME_LENGTH];
CHAR16 zDetailedUnexploredUnderground[MAX_SECTOR_NAME_LENGTH];
CHAR16 zExploredUnderground[MAX_SECTOR_NAME_LENGTH];
CHAR16 zDetailedExploredUnderground[MAX_SECTOR_NAME_LENGTH];
if ( bSectorZ == 1 )
{
wcscpy( zUnexploredUnderground, gzSectorUndergroundNames1[ ubSectorID ][0] );
wcscpy( zDetailedUnexploredUnderground, gzSectorUndergroundNames1[ ubSectorID ][1] );
wcscpy( zExploredUnderground, gzSectorUndergroundNames1[ ubSectorID ][2] );
wcscpy( zDetailedExploredUnderground, gzSectorUndergroundNames1[ ubSectorID ][3] );
}
else if ( bSectorZ == 2 )
{
bMineIndex = GetIdOfMineForSector( sSectorX, sSectorY, bSectorZ );
if( bMineIndex != -1 )
wcscpy( zUnexploredUnderground, gzSectorUndergroundNames2[ ubSectorID ][0] );
wcscpy( zDetailedUnexploredUnderground, gzSectorUndergroundNames2[ ubSectorID ][1] );
wcscpy( zExploredUnderground, gzSectorUndergroundNames2[ ubSectorID ][2] );
wcscpy( zDetailedExploredUnderground, gzSectorUndergroundNames2[ ubSectorID ][3] );
}
else if ( bSectorZ == 3 )
{
wcscpy( zUnexploredUnderground, gzSectorUndergroundNames3[ ubSectorID ][0] );
wcscpy( zDetailedUnexploredUnderground, gzSectorUndergroundNames3[ ubSectorID ][1] );
wcscpy( zExploredUnderground, gzSectorUndergroundNames3[ ubSectorID ][2] );
wcscpy( zDetailedExploredUnderground, gzSectorUndergroundNames3[ ubSectorID ][3] );
}
if (zUnexploredUnderground[0] == 0 || zDetailedUnexploredUnderground[0] == 0 || zExploredUnderground[0] == 0 || zDetailedExploredUnderground[0] == 0)
{
fSectorHasXMLNames = FALSE;
}
if (fSectorHasXMLNames) // UNDERGROUND XML
{
if ( pUnderground )
{
swprintf( zString, L"%c%d: %s %s", 'A' + sSectorY - 1, sSectorX, pTownNames[ GetTownAssociatedWithMine( bMineIndex ) ], pwMineStrings[ 0 ] );
}
else switch( SECTOR( sSectorX, sSectorY ) )
{
case SEC_A10:
swprintf( zString, L"A10: %s", pLandTypeStrings[ REBEL_HIDEOUT ] );
break;
case SEC_J9:
swprintf( zString, L"J9: %s", pLandTypeStrings[ TIXA_DUNGEON ] );
break;
case SEC_K4:
swprintf( zString, L"K4: %s", pLandTypeStrings[ ORTA_BASEMENT ] );
break;
case SEC_O3:
swprintf( zString, L"O3: %s", pLandTypeStrings[ TUNNEL ] );
break;
case SEC_P3:
swprintf( zString, L"P3: %s", pLandTypeStrings[ SHELTER ] );
break;
default:
if (pUnderground->ubNumCreatures)
swprintf( zString, L"%c%d: %s", 'A' + sSectorY - 1, sSectorX, pLandTypeStrings[ CREATURE_LAIR ] );
bMineIndex = GetIdOfMineForSector( sSectorX, sSectorY, bSectorZ );
if( bMineIndex != -1 )
{
swprintf( zString, L"%c%d: %s %s", 'A' + sSectorY - 1, sSectorX, pTownNames[ GetTownAssociatedWithMine( bMineIndex ) ], pwMineStrings[ 0 ] );
}
else if ( pUnderground->fVisited )
{
if (fDetailed)
{
wcscat( zString, zDetailedExploredUnderground );
}
else
swprintf( zString, L"%c%d-%d", 'A' + sSectorY - 1, sSectorX, bSectorZ );
break;
{
wcscat( zString, zExploredUnderground );
}
}
else
{
if (fDetailed)
{
wcscat( zString, zDetailedUnexploredUnderground );
}
else
{
wcscat( zString, zUnexploredUnderground );
}
}
if (pUnderground->ubNumCreatures)
swprintf( zString, L"%c%d: %s", 'A' + sSectorY - 1, sSectorX, pLandTypeStrings[ CREATURE_LAIR ] );
//else
// swprintf( zString, L"%c%d-%d", 'A' + sSectorY - 1, sSectorX, bSectorZ );
}
}
else // UNDERGROUND HARDCODED
{
pUnderground = FindUnderGroundSector( sSectorX, sSectorY, bSectorZ );
if( pUnderground && ( pUnderground->fVisited || gfGettingNameFromSaveLoadScreen ) )
{
bMineIndex = GetIdOfMineForSector( sSectorX, sSectorY, bSectorZ );
if( bMineIndex != -1 )
{
swprintf( zString, L"%c%d: %s %s", 'A' + sSectorY - 1, sSectorX, pTownNames[ GetTownAssociatedWithMine( bMineIndex ) ], pwMineStrings[ 0 ] );
}
else switch( SECTOR( sSectorX, sSectorY ) )
{
case SEC_A10:
swprintf( zString, L"A10: %s", pLandTypeStrings[ REBEL_HIDEOUT ] );
break;
case SEC_J9:
swprintf( zString, L"J9: %s", pLandTypeStrings[ TIXA_DUNGEON ] );
break;
case SEC_K4:
swprintf( zString, L"K4: %s", pLandTypeStrings[ ORTA_BASEMENT ] );
break;
case SEC_O3:
swprintf( zString, L"O3: %s", pLandTypeStrings[ TUNNEL ] );
break;
case SEC_P3:
swprintf( zString, L"P3: %s", pLandTypeStrings[ SHELTER ] );
break;
default:
if (pUnderground->ubNumCreatures)
swprintf( zString, L"%c%d: %s", 'A' + sSectorY - 1, sSectorX, pLandTypeStrings[ CREATURE_LAIR ] );
else
swprintf( zString, L"%c%d-%d", 'A' + sSectorY - 1, sSectorX, bSectorZ );
break;
}
}
else
{ //Display nothing
wcscpy( zString, L"" );
}
}
else
{ //Display nothing
wcscpy( zString, L"" );
}
#else
// TODO: the code is riddled with (potential) buffer overruns
// this totally needs to be fixed sometime
// anyway, only trying to not create another one here
// found calls to this function with buffers as small as 50 elements
g_luaUnderground.GetSectorName(sSectorX, sSectorY, bSectorZ, pUnderground, zString, 50, fDetailed);
#endif
}
else
else // SECTORS ABOVE GROUND
{
bTownNameID = StrategicMap[ CALCULATE_STRATEGIC_INDEX( sSectorX, sSectorY ) ].bNameId;
@@ -3076,7 +3200,7 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS
fSectorHasXMLNames = FALSE;
}
if (fSectorHasXMLNames)
if (fSectorHasXMLNames) // ABOVE GROUND XML
{
// HEADROCK HAM 3.6: The program can now read custom names from XML for all above-ground sectors.
// In the event that a specific name or set of names is missing, the program generates a default
@@ -3121,111 +3245,111 @@ void GetSectorIDString( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ , STR16 zS
}
}
}
else
else // ABOVE GROUND HARDCODED
{
// Default JA2 Name selection
if ( bTownNameID == BLANK_SECTOR )
{
// OK, build string id like J11
// are we dealing with the unfound towns?
switch( ubSectorID )
if ( bTownNameID == BLANK_SECTOR )
{
case SEC_D2: //Chitzena SAM
if( !fSamSiteFound[ SAM_SITE_ONE ] )
wcscat( zString, pLandTypeStrings[ TROPICS ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ TROPICS_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
break;
case SEC_D15: //Drassen SAM
if( !fSamSiteFound[ SAM_SITE_TWO ] )
wcscat( zString, pLandTypeStrings[ SPARSE ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ SPARSE_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
break;
case SEC_I8: //Cambria SAM
if( !fSamSiteFound[ SAM_SITE_THREE ] )
wcscat( zString, pLandTypeStrings[ SAND ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ SAND_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
break;
default:
wcscat( zString, pLandTypeStrings[ ubLandType ] );
break;
}
}
else
{
switch( ubSectorID )
{
case SEC_B13:
if( fDetailed )
wcscat( zString, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] );
else
wcscat( zString, pTownNames[ DRASSEN ] );
break;
case SEC_F8:
if( fDetailed )
wcscat( zString, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] );
else
wcscat( zString, pTownNames[ CAMBRIA ] );
break;
case SEC_J9: //Tixa
if( !fFoundTixa )
wcscat( zString, pLandTypeStrings[ SAND ] );
else
wcscat( zString, pTownNames[ TIXA ] );
break;
case SEC_K4: //Orta
if( !fFoundOrta )
wcscat( zString, pLandTypeStrings[ SWAMP ] );
else
wcscat( zString, pTownNames[ ORTA ] );
break;
case SEC_N3:
if( fDetailed )
wcscat( zString, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] );
else
wcscat( zString, pTownNames[ MEDUNA ] );
break;
default:
if( ubSectorID == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] )
{ //Meduna's SAM site
if( fDetailed )
wcscat( zString, pLandTypeStrings[ MEDUNA_SAM_SITE ] );
// OK, build string id like J11
// are we dealing with the unfound towns?
switch( ubSectorID )
{
case SEC_D2: //Chitzena SAM
if( !fSamSiteFound[ SAM_SITE_ONE ] )
wcscat( zString, pLandTypeStrings[ TROPICS ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ TROPICS_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
}
else
{ //All other towns that are known since beginning of the game.
wcscat( zString, pTownNames[ bTownNameID ] );
break;
case SEC_D15: //Drassen SAM
if( !fSamSiteFound[ SAM_SITE_TWO ] )
wcscat( zString, pLandTypeStrings[ SPARSE ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ SPARSE_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
break;
case SEC_I8: //Cambria SAM
if( !fSamSiteFound[ SAM_SITE_THREE ] )
wcscat( zString, pLandTypeStrings[ SAND ] );
else if( fDetailed )
wcscat( zString, pLandTypeStrings[ SAND_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
break;
default:
wcscat( zString, pLandTypeStrings[ ubLandType ] );
break;
}
}
else
{
switch( ubSectorID )
{
case SEC_B13:
if( fDetailed )
{
switch( ubSectorID )
{ //Append the word, "mine" for town sectors containing a mine.
case SEC_B2:
case SEC_D4:
case SEC_D13:
case SEC_H3:
case SEC_H8:
case SEC_I14:
wcscat( zString, L" " ); //space
wcscat( zString, pwMineStrings[ 0 ] ); //then "Mine"
break;
wcscat( zString, pLandTypeStrings[ DRASSEN_AIRPORT_SITE ] );
else
wcscat( zString, pTownNames[ DRASSEN ] );
break;
case SEC_F8:
if( fDetailed )
wcscat( zString, pLandTypeStrings[ CAMBRIA_HOSPITAL_SITE ] );
else
wcscat( zString, pTownNames[ CAMBRIA ] );
break;
case SEC_J9: //Tixa
if( !fFoundTixa )
wcscat( zString, pLandTypeStrings[ SAND ] );
else
wcscat( zString, pTownNames[ TIXA ] );
break;
case SEC_K4: //Orta
if( !fFoundOrta )
wcscat( zString, pLandTypeStrings[ SWAMP ] );
else
wcscat( zString, pTownNames[ ORTA ] );
break;
case SEC_N3:
if( fDetailed )
wcscat( zString, pLandTypeStrings[ MEDUNA_AIRPORT_SITE ] );
else
wcscat( zString, pTownNames[ MEDUNA ] );
break;
default:
if( ubSectorID == SEC_N4 && fSamSiteFound[ SAM_SITE_FOUR ] )
{ //Meduna's SAM site
if( fDetailed )
wcscat( zString, pLandTypeStrings[ MEDUNA_SAM_SITE ] );
else
wcscat( zString, pLandTypeStrings[ SAM_SITE ] );
}
else
{ //All other towns that are known since beginning of the game.
wcscat( zString, pTownNames[ bTownNameID ] );
if( fDetailed )
{
switch( ubSectorID )
{ //Append the word, "mine" for town sectors containing a mine.
case SEC_B2:
case SEC_D4:
case SEC_D13:
case SEC_H3:
case SEC_H8:
case SEC_I14:
wcscat( zString, L" " ); //space
wcscat( zString, pwMineStrings[ 0 ] ); //then "Mine"
break;
}
}
}
}
break;
break;
}
}
}
}
}
}
UINT8 SetInsertionDataFromAdjacentMoveDirection( SOLDIERTYPE *pSoldier, UINT8 ubTacticalDirection, INT32 sAdditionalData )//dnl ch56 151009
@@ -3653,16 +3777,52 @@ void AllMercsWalkedToExitGrid()
{
PLAYERGROUP *pPlayer;
BOOLEAN fDone;
// SANDRO was here.. made some tweaks, fixed some stuff
BOOLEAN fEnemiesInLoadedSector = FALSE;
if( NumEnemiesInAnySector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
{
fEnemiesInLoadedSector = TRUE;
////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if enemies are in sector, handle morale hit for fleeing
// Minor bug fix - check certain circumstances and don't reduce the morale if the fight is not over yet
// if all mercs leaving, morale gets hit
// if one merc only leaves, but there are others fighting on, don't reduce the morale
// if sector is about to be loaded and there are enemies in the current, then all mercs are leaving, so the morale gets hit
if( ( gubAdjacentJumpCode == JUMP_ALL_NO_LOAD && gpAdjacentGroup->ubGroupSize >= PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, (UINT8)gbWorldSectorZ )) ||
( gubAdjacentJumpCode == JUMP_SINGLE_NO_LOAD && PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, (UINT8)gbWorldSectorZ ) <= 1 ) ||
( gubAdjacentJumpCode == JUMP_ALL_LOAD_NEW || gubAdjacentJumpCode == JUMP_SINGLE_LOAD_NEW ) )
{
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
// End inetrrogation quest if we left the sector, but haven't killed all enemies
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[ QUEST_INTERROGATION ] == QUESTINPROGRESS )
{
// Finish quest, although not give points here...
InternalEndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE );
// ... give them manually, but halved
GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
// Also get us know, we finished the quest
ResetHistoryFact( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
}
}
////////////////////////////////////////////////////////////////////////////////////////
HandlePotentialMoraleHitForSkimmingSectors( gpAdjacentGroup );
HandlePotentialMoraleHitForSkimmingSectors( gpAdjacentGroup );
}
if( gubAdjacentJumpCode == JUMP_ALL_NO_LOAD || gubAdjacentJumpCode == JUMP_SINGLE_NO_LOAD )
{
Assert( gpAdjacentGroup );
pPlayer = gpAdjacentGroup->pPlayerList;
//pPlayer = gpAdjacentGroup->pPlayerList; // SANDRO - why was this here twice?
pPlayer = gpAdjacentGroup->pPlayerList;
while( pPlayer )
{
/////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
if( fEnemiesInLoadedSector && pPlayer->pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pPlayer->pSoldier->ubProfile ].records.usBattlesRetreated++;
/////////////////////////////////////////////////////////////////////////////////
SetInsertionDataFromAdjacentMoveDirection( pPlayer->pSoldier, gubTacticalDirection, gsAdditionalData );
RemoveSoldierFromTacticalSector( pPlayer->pSoldier, TRUE );
@@ -3675,9 +3835,19 @@ void AllMercsWalkedToExitGrid()
SetDefaultSquadOnSectorEntry( TRUE );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - reset num enemies here if the sector was unloaded
if( gWorldSectorX == 0 && gWorldSectorX == 0 && gbWorldSectorZ == -1 )
{
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else
{
// SANDRO - reset number of enemies here, we are about to load a new sector
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
//Because we are actually loading the new map, and we are physically traversing, we don't want
//to bring up the prebattle interface when we arrive if there are enemies there. This flag
//ignores the initialization of the prebattle interface and clears the flag.
@@ -3698,6 +3868,7 @@ void AllMercsWalkedToExitGrid()
AddCharacterToUniqueSquad( pPlayer->pSoldier );
break;
}
InitSoldierOppList( pPlayer->pSoldier );
pPlayer = pPlayer->next;
}
if( !pPlayer )
@@ -3711,6 +3882,12 @@ void AllMercsWalkedToExitGrid()
pPlayer = gpAdjacentGroup->pPlayerList;
while( pPlayer )
{
/////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
if( fEnemiesInLoadedSector && pPlayer->pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pPlayer->pSoldier->ubProfile ].records.usBattlesRetreated++;
/////////////////////////////////////////////////////////////////////////////////
SetInsertionDataFromAdjacentMoveDirection( pPlayer->pSoldier, gubTacticalDirection, gsAdditionalData );
pPlayer = pPlayer->next;
@@ -3721,10 +3898,11 @@ void AllMercsWalkedToExitGrid()
gFadeOutDoneCallback = DoneFadeOutExitGridSector;
FadeOutGameScreen( );
}
if( !PlayerMercsInSector( (UINT8)gsAdjacentSectorX, (UINT8)gsAdjacentSectorY, (UINT8)gbAdjacentSectorZ ) )
{
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gsAdjacentSectorX, gsAdjacentSectorY, gbAdjacentSectorZ );
}
// SANDRO - This actually never happeneds, moved up
//if( !PlayerMercsInSector( (UINT8)gsAdjacentSectorX, (UINT8)gsAdjacentSectorY, (UINT8)gbAdjacentSectorZ ) )
//{
// HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gsAdjacentSectorX, gsAdjacentSectorY, gbAdjacentSectorZ );
//}
if( gubAdjacentJumpCode == JUMP_ALL_NO_LOAD || gubAdjacentJumpCode == JUMP_SINGLE_NO_LOAD )
{
gfTacticalTraversal = FALSE;
@@ -3782,10 +3960,32 @@ void AllMercsHaveWalkedOffSector( )
if( NumEnemiesInAnySector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) )
{
fEnemiesInLoadedSector = TRUE;
////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if enemies are in sector, handle morale hit for fleeing
// Minor bug fix - check certain circumstances and don't reduce the morale if the fight is not over yet
// if all mercs leaving, morale gets hit
// if one merc only leaves, but there are others fighting on, don't reduce the morale
// if sector is about to be loaded and there are enemies in the current, then all mercs are leaving alway
if( ( gubAdjacentJumpCode == JUMP_ALL_NO_LOAD && gpAdjacentGroup->ubGroupSize >= PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, (UINT8)gbWorldSectorZ )) ||
( gubAdjacentJumpCode == JUMP_SINGLE_NO_LOAD && PlayerMercsInSector( (UINT8)gWorldSectorX, (UINT8)gWorldSectorY, (UINT8)gbWorldSectorZ ) <= 1 ) ||
( gubAdjacentJumpCode == JUMP_ALL_LOAD_NEW || gubAdjacentJumpCode == JUMP_SINGLE_LOAD_NEW ) )
{
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
// End inetrrogation quest if we left the sector, but haven't killed all enemies
if ( gWorldSectorX == 7 && gWorldSectorY == 14 && gbWorldSectorZ == 0 && gubQuest[ QUEST_INTERROGATION ] == QUESTINPROGRESS )
{
// Finish quest, although not give points here...
InternalEndQuest( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY, FALSE );
// ... give them manually, but halved
GiveQuestRewardPoint( gWorldSectorX, gWorldSectorY, 4, NO_PROFILE );
// Also get us know, we finished the quest
ResetHistoryFact( QUEST_INTERROGATION, gWorldSectorX, gWorldSectorY );
}
}
////////////////////////////////////////////////////////////////////////////////////////
}
HandleLoyaltyImplicationsOfMercRetreat( RETREAT_TACTICAL_TRAVERSAL, gWorldSectorX, gWorldSectorY, gbWorldSectorZ );
//Setup strategic traversal information
if( guiAdjacentTraverseTime <= 5 )
{
@@ -3813,15 +4013,41 @@ void AllMercsHaveWalkedOffSector( )
pPlayer = gpAdjacentGroup->pPlayerList;
while( pPlayer )
{
/////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
if( fEnemiesInLoadedSector && pPlayer->pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pPlayer->pSoldier->ubProfile ].records.usBattlesRetreated++;
/////////////////////////////////////////////////////////////////////////////////
RemoveSoldierFromTacticalSector( pPlayer->pSoldier, TRUE );
pPlayer = pPlayer->next;
}
SetDefaultSquadOnSectorEntry( TRUE );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - reset num enemies here if the sector was unloaded
if( !fEnemiesInLoadedSector || (gWorldSectorX == 0 && gWorldSectorX == 0 && gbWorldSectorZ == -1 ) )
{
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else
{
// SANDRO - reset number of enemies here, we are about to load a new sector
memset( &(gTacticalStatus.bNumFoughtInBattle), 0, MAXTEAMS );
if( fEnemiesInLoadedSector )
{ //We are retreating from a sector with enemies in it and there are no mercs left so
{
/////////////////////////////////////////////////////////////////////////////////
// SANDRO - merc records - times retreated counter
pPlayer = gpAdjacentGroup->pPlayerList;
while( pPlayer )
{
if( fEnemiesInLoadedSector && pPlayer->pSoldier->ubProfile != NO_PROFILE )
gMercProfiles[ pPlayer->pSoldier->ubProfile ].records.usBattlesRetreated++;
pPlayer = pPlayer->next;
}
/////////////////////////////////////////////////////////////////////////////////
//We are retreating from a sector with enemies in it and there are no mercs left so
//warp the game time by 5 minutes to simulate the actual retreat. This restricts the
//player from immediately coming back to the same sector they left to perhaps take advantage
//of the tactical placement gui to get into better position. Additionally, if there are any
@@ -5438,8 +5664,6 @@ void HandleSlayDailyEvent( void )
}
}
BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY )
{
// HEADROCK HAM 3.5: Fix for assertion errors associated with rain checks.
@@ -5448,7 +5672,10 @@ BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY )
return( FALSE );
}
if ( SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == SAND )
// SANDRO - added more terrain types for heat intolerant feature
if ( SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == SAND ||
SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == SAND_ROAD ||
SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == SAND_SAM_SITE )
{
// desert
return( TRUE );
@@ -5458,7 +5685,20 @@ BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY )
return( FALSE );
}
}
// SANDRO - added function
BOOLEAN IsSectorTropical( INT16 sSectorX, INT16 sSectorY )
{
if (SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == TROPICS ||
SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == TROPICS_ROAD ||
SectorInfo[ SECTOR(sSectorX, sSectorY) ].ubTraversability[ THROUGH_STRATEGIC_MOVE ] == TROPICS_SAM_SITE )
{
return ( TRUE );
}
else
{
return ( FALSE );
}
}
BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode )
@@ -5800,7 +6040,7 @@ void SetupProfileInsertionDataForSoldier( SOLDIERTYPE *pSoldier )
void HandlePotentialMoraleHitForSkimmingSectors( GROUP *pGroup )
{
PLAYERGROUP *pPlayer;
//PLAYERGROUP *pPlayer;
if ( !gTacticalStatus.fHasEnteredCombatModeSinceEntering && gTacticalStatus.fEnemyInSector )
{
@@ -5810,16 +6050,17 @@ void HandlePotentialMoraleHitForSkimmingSectors( GROUP *pGroup )
//time to setup a good ambush!
pGroup->uiFlags |= GROUPFLAG_HIGH_POTENTIAL_FOR_AMBUSH;
pPlayer = pGroup->pPlayerList;
//SANDRO - WTF?!?
//pPlayer = pGroup->pPlayerList;
while( pPlayer )
{
// Do morale hit...
// CC look here!
// pPlayer->pSoldier
//while( pPlayer )
//{
// // Do morale hit...
// // CC look here!
// // pPlayer->pSoldier
pPlayer = pPlayer->next;
}
// pPlayer = pPlayer->next;
//}
}
}
+1
View File
@@ -160,6 +160,7 @@ INT32 GetNumberOfSAMSitesUnderPlayerControl( void );
BOOLEAN IsThereAFunctionalSAMSiteInSector( INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ );
BOOLEAN IsSectorDesert( INT16 sSectorX, INT16 sSectorY );
BOOLEAN IsSectorTropical( INT16 sSectorX, INT16 sSectorY ); // added by SANDRO
// sam site under players control?
INT32 SAMSitesUnderPlayerControl( INT16 sX, INT16 sY );